[Github] Label lldb-dap PRs (#125139)
[llvm-project.git] / clang / lib / Sema / TreeTransform.h
blob808b56448e1ea6e17166d8e5854c480ea6ad8e77
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.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
14 #define LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
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>
53 using namespace llvm::omp;
55 namespace clang {
56 using namespace sema;
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.
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()).
109 template<typename Derived>
110 class 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::ArgumentPackSubstitutionIndexRAII ResetPackSubstIndex;
121 public:
122 ForgetPartiallySubstitutedPackRAII(Derived &Self)
123 : Self(Self), ResetPackSubstIndex(Self.getSema(), -1) {
124 Old = Self.ForgetPartiallySubstitutedPack();
127 ~ForgetPartiallySubstitutedPackRAII() {
128 Self.RememberPartiallySubstitutedPack(Old);
132 protected:
133 Sema &SemaRef;
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;
140 public:
141 /// Initializes a new tree transformer.
142 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
144 /// Retrieves a reference to the derived class.
145 Derived &getDerived() { return static_cast<Derived&>(*this); }
147 /// Retrieves a reference to the derived class.
148 const Derived &getDerived() const {
149 return static_cast<const Derived&>(*this);
152 static inline ExprResult Owned(Expr *E) { return E; }
153 static inline StmtResult Owned(Stmt *S) { return S; }
155 /// Retrieves a reference to the semantic analysis object used for
156 /// this tree transform.
157 Sema &getSema() const { return SemaRef; }
159 /// Whether the transformation should always rebuild AST nodes, even
160 /// if none of the children have changed.
162 /// Subclasses may override this function to specify when the transformation
163 /// should rebuild all AST nodes.
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 SemaRef.ArgumentPackSubstitutionIndex != -1; }
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; }
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; }
182 /// Returns the location of the entity being transformed, if that
183 /// information was not available elsewhere in the AST.
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(); }
190 /// Returns the name of the entity being transformed, if that
191 /// information was not available elsewhere in the AST.
193 /// By default, returns an empty name. Subclasses can provide an alternative
194 /// implementation with a more precise name.
195 DeclarationName getBaseEntity() { return DeclarationName(); }
197 /// Sets the "base" location and entity when that
198 /// information is known based on another transformation.
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) { }
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;
211 public:
212 TemporaryBase(TreeTransform &Self, SourceLocation Location,
213 DeclarationName Entity) : Self(Self) {
214 OldLocation = Self.getDerived().getBaseLocation();
215 OldEntity = Self.getDerived().getBaseEntity();
217 if (Location.isValid())
218 Self.getDerived().setBase(Location, Entity);
221 ~TemporaryBase() {
222 Self.getDerived().setBase(OldLocation, OldEntity);
226 /// Determine whether the given type \p T has already been
227 /// transformed.
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();
237 /// Transform a template parameter depth level.
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;
245 /// Determine whether the given call argument should be dropped, e.g.,
246 /// because it is a default argument.
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();
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.
259 /// By default, the transformer never tries to expand pack expansions.
260 /// Subclasses can override this routine to provide different behavior.
262 /// \param EllipsisLoc The location of the ellipsis that identifies the
263 /// pack expansion.
265 /// \param PatternRange The source range that covers the entire pattern of
266 /// the pack expansion.
268 /// \param Unexpanded The set of unexpanded parameter packs within the
269 /// pattern.
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.
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.
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.
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 std::optional<unsigned> &NumExpansions) {
297 ShouldExpand = false;
298 return false;
301 /// "Forget" about the partially-substituted pack template argument,
302 /// when performing an instantiation that must preserve the parameter pack
303 /// use.
305 /// This routine is meant to be overridden by the template instantiator.
306 TemplateArgument ForgetPartiallySubstitutedPack() {
307 return TemplateArgument();
310 /// "Remember" the partially-substituted pack template argument
311 /// after performing an instantiation that must preserve the parameter pack
312 /// use.
314 /// This routine is meant to be overridden by the template instantiator.
315 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
317 /// Note to the derived class when a function parameter pack is
318 /// being expanded.
319 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
321 /// Transforms the given type into another type.
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.
329 /// \returns the transformed type.
330 QualType TransformType(QualType T);
332 /// Transforms the given type-with-location into a new
333 /// type-with-location.
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);
342 /// Transform the given type-with-location into a new
343 /// type, collecting location information in the given builder
344 /// as necessary.
346 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
348 /// Transform a type that is permitted to produce a
349 /// DeducedTemplateSpecializationType.
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 /// @}
359 /// The reason why the value of a statement is not discarded, if any.
360 enum StmtDiscardKind {
361 SDK_Discarded,
362 SDK_NotDiscarded,
363 SDK_StmtExprResult,
366 /// Transform the given statement.
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.
374 /// \returns the transformed statement.
375 StmtResult TransformStmt(Stmt *S, StmtDiscardKind SDK = SDK_Discarded);
377 /// Transform the given statement.
379 /// By default, this routine transforms a statement by delegating to the
380 /// appropriate TransformOMPXXXClause function to transform a specific kind
381 /// of clause. Subclasses may override this function to transform statements
382 /// using some other mechanism.
384 /// \returns the transformed OpenMP clause.
385 OMPClause *TransformOMPClause(OMPClause *S);
387 /// Transform the given attribute.
389 /// By default, this routine transforms a statement by delegating to the
390 /// appropriate TransformXXXAttr function to transform a specific kind
391 /// of attribute. Subclasses may override this function to transform
392 /// attributed statements/types using some other mechanism.
394 /// \returns the transformed attribute
395 const Attr *TransformAttr(const Attr *S);
397 // Transform the given statement attribute.
399 // Delegates to the appropriate TransformXXXAttr function to transform a
400 // specific kind of statement attribute. Unlike the non-statement taking
401 // version of this, this implements all attributes, not just pragmas.
402 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
403 const Attr *A);
405 // Transform the specified attribute.
407 // Subclasses should override the transformation of attributes with a pragma
408 // spelling to transform expressions stored within the attribute.
410 // \returns the transformed attribute.
411 #define ATTR(X) \
412 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
413 #include "clang/Basic/AttrList.inc"
415 // Transform the specified attribute.
417 // Subclasses should override the transformation of attributes to do
418 // transformation and checking of statement attributes. By default, this
419 // delegates to the non-statement taking version.
421 // \returns the transformed attribute.
422 #define ATTR(X) \
423 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
424 const X##Attr *A) { \
425 return getDerived().Transform##X##Attr(A); \
427 #include "clang/Basic/AttrList.inc"
429 /// Transform the given expression.
431 /// By default, this routine transforms an expression by delegating to the
432 /// appropriate TransformXXXExpr function to build a new expression.
433 /// Subclasses may override this function to transform expressions using some
434 /// other mechanism.
436 /// \returns the transformed expression.
437 ExprResult TransformExpr(Expr *E);
439 /// Transform the given initializer.
441 /// By default, this routine transforms an initializer by stripping off the
442 /// semantic nodes added by initialization, then passing the result to
443 /// TransformExpr or TransformExprs.
445 /// \returns the transformed initializer.
446 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
448 /// Transform the given list of expressions.
450 /// This routine transforms a list of expressions by invoking
451 /// \c TransformExpr() for each subexpression. However, it also provides
452 /// support for variadic templates by expanding any pack expansions (if the
453 /// derived class permits such expansion) along the way. When pack expansions
454 /// are present, the number of outputs may not equal the number of inputs.
456 /// \param Inputs The set of expressions to be transformed.
458 /// \param NumInputs The number of expressions in \c Inputs.
460 /// \param IsCall If \c true, then this transform is being performed on
461 /// function-call arguments, and any arguments that should be dropped, will
462 /// be.
464 /// \param Outputs The transformed input expressions will be added to this
465 /// vector.
467 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
468 /// due to transformation.
470 /// \returns true if an error occurred, false otherwise.
471 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
472 SmallVectorImpl<Expr *> &Outputs,
473 bool *ArgChanged = nullptr);
475 /// Transform the given declaration, which is referenced from a type
476 /// or expression.
478 /// By default, acts as the identity function on declarations, unless the
479 /// transformer has had to transform the declaration itself. Subclasses
480 /// may override this function to provide alternate behavior.
481 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
482 llvm::DenseMap<Decl *, Decl *>::iterator Known
483 = TransformedLocalDecls.find(D);
484 if (Known != TransformedLocalDecls.end())
485 return Known->second;
487 return D;
490 /// Transform the specified condition.
492 /// By default, this transforms the variable and expression and rebuilds
493 /// the condition.
494 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
495 Expr *Expr,
496 Sema::ConditionKind Kind);
498 /// Transform the attributes associated with the given declaration and
499 /// place them on the new declaration.
501 /// By default, this operation does nothing. Subclasses may override this
502 /// behavior to transform attributes.
503 void transformAttrs(Decl *Old, Decl *New) { }
505 /// Note that a local declaration has been transformed by this
506 /// transformer.
508 /// Local declarations are typically transformed via a call to
509 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
510 /// the transformer itself has to transform the declarations. This routine
511 /// can be overridden by a subclass that keeps track of such mappings.
512 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
513 assert(New.size() == 1 &&
514 "must override transformedLocalDecl if performing pack expansion");
515 TransformedLocalDecls[Old] = New.front();
518 /// Transform the definition of the given declaration.
520 /// By default, invokes TransformDecl() to transform the declaration.
521 /// Subclasses may override this function to provide alternate behavior.
522 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
523 return getDerived().TransformDecl(Loc, D);
526 /// Transform the given declaration, which was the first part of a
527 /// nested-name-specifier in a member access expression.
529 /// This specific declaration transformation only applies to the first
530 /// identifier in a nested-name-specifier of a member access expression, e.g.,
531 /// the \c T in \c x->T::member
533 /// By default, invokes TransformDecl() to transform the declaration.
534 /// Subclasses may override this function to provide alternate behavior.
535 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
536 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
539 /// Transform the set of declarations in an OverloadExpr.
540 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
541 LookupResult &R);
543 /// Transform the given nested-name-specifier with source-location
544 /// information.
546 /// By default, transforms all of the types and declarations within the
547 /// nested-name-specifier. Subclasses may override this function to provide
548 /// alternate behavior.
549 NestedNameSpecifierLoc
550 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
551 QualType ObjectType = QualType(),
552 NamedDecl *FirstQualifierInScope = nullptr);
554 /// Transform the given declaration name.
556 /// By default, transforms the types of conversion function, constructor,
557 /// and destructor names and then (if needed) rebuilds the declaration name.
558 /// Identifiers and selectors are returned unmodified. Subclasses may
559 /// override this function to provide alternate behavior.
560 DeclarationNameInfo
561 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
563 bool TransformRequiresExprRequirements(
564 ArrayRef<concepts::Requirement *> Reqs,
565 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
566 concepts::TypeRequirement *
567 TransformTypeRequirement(concepts::TypeRequirement *Req);
568 concepts::ExprRequirement *
569 TransformExprRequirement(concepts::ExprRequirement *Req);
570 concepts::NestedRequirement *
571 TransformNestedRequirement(concepts::NestedRequirement *Req);
573 /// Transform the given template name.
575 /// \param SS The nested-name-specifier that qualifies the template
576 /// name. This nested-name-specifier must already have been transformed.
578 /// \param Name The template name to transform.
580 /// \param NameLoc The source location of the template name.
582 /// \param ObjectType If we're translating a template name within a member
583 /// access expression, this is the type of the object whose member template
584 /// is being referenced.
586 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
587 /// also refers to a name within the current (lexical) scope, this is the
588 /// declaration it refers to.
590 /// By default, transforms the template name by transforming the declarations
591 /// and nested-name-specifiers that occur within the template name.
592 /// Subclasses may override this function to provide alternate behavior.
593 TemplateName
594 TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
595 SourceLocation NameLoc,
596 QualType ObjectType = QualType(),
597 NamedDecl *FirstQualifierInScope = nullptr,
598 bool AllowInjectedClassName = false);
600 /// Transform the given template argument.
602 /// By default, this operation transforms the type, expression, or
603 /// declaration stored within the template argument and constructs a
604 /// new template argument from the transformed result. Subclasses may
605 /// override this function to provide alternate behavior.
607 /// Returns true if there was an error.
608 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
609 TemplateArgumentLoc &Output,
610 bool Uneval = false);
612 /// Transform the given set of template arguments.
614 /// By default, this operation transforms all of the template arguments
615 /// in the input set using \c TransformTemplateArgument(), and appends
616 /// the transformed arguments to the output list.
618 /// Note that this overload of \c TransformTemplateArguments() is merely
619 /// a convenience function. Subclasses that wish to override this behavior
620 /// should override the iterator-based member template version.
622 /// \param Inputs The set of template arguments to be transformed.
624 /// \param NumInputs The number of template arguments in \p Inputs.
626 /// \param Outputs The set of transformed template arguments output by this
627 /// routine.
629 /// Returns true if an error occurred.
630 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
631 unsigned NumInputs,
632 TemplateArgumentListInfo &Outputs,
633 bool Uneval = false) {
634 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
635 Uneval);
638 /// Transform the given set of template arguments.
640 /// By default, this operation transforms all of the template arguments
641 /// in the input set using \c TransformTemplateArgument(), and appends
642 /// the transformed arguments to the output list.
644 /// \param First An iterator to the first template argument.
646 /// \param Last An iterator one step past the last template argument.
648 /// \param Outputs The set of transformed template arguments output by this
649 /// routine.
651 /// Returns true if an error occurred.
652 template<typename InputIterator>
653 bool TransformTemplateArguments(InputIterator First,
654 InputIterator Last,
655 TemplateArgumentListInfo &Outputs,
656 bool Uneval = false);
658 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
659 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
660 TemplateArgumentLoc &ArgLoc);
662 /// Fakes up a TypeSourceInfo for a type.
663 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
664 return SemaRef.Context.getTrivialTypeSourceInfo(T,
665 getDerived().getBaseLocation());
668 #define ABSTRACT_TYPELOC(CLASS, PARENT)
669 #define TYPELOC(CLASS, PARENT) \
670 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
671 #include "clang/AST/TypeLocNodes.def"
673 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
674 TemplateTypeParmTypeLoc TL,
675 bool SuppressObjCLifetime);
676 QualType
677 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
678 SubstTemplateTypeParmPackTypeLoc TL,
679 bool SuppressObjCLifetime);
681 template<typename Fn>
682 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
683 FunctionProtoTypeLoc TL,
684 CXXRecordDecl *ThisContext,
685 Qualifiers ThisTypeQuals,
686 Fn TransformExceptionSpec);
688 bool TransformExceptionSpec(SourceLocation Loc,
689 FunctionProtoType::ExceptionSpecInfo &ESI,
690 SmallVectorImpl<QualType> &Exceptions,
691 bool &Changed);
693 StmtResult TransformSEHHandler(Stmt *Handler);
695 QualType
696 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
697 TemplateSpecializationTypeLoc TL,
698 TemplateName Template);
700 QualType
701 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
702 DependentTemplateSpecializationTypeLoc TL,
703 TemplateName Template,
704 CXXScopeSpec &SS);
706 QualType TransformDependentTemplateSpecializationType(
707 TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
708 NestedNameSpecifierLoc QualifierLoc);
710 /// Transforms the parameters of a function type into the
711 /// given vectors.
713 /// The result vectors should be kept in sync; null entries in the
714 /// variables vector are acceptable.
716 /// LastParamTransformed, if non-null, will be set to the index of the last
717 /// parameter on which transfromation was started. In the event of an error,
718 /// this will contain the parameter which failed to instantiate.
720 /// Return true on error.
721 bool TransformFunctionTypeParams(
722 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
723 const QualType *ParamTypes,
724 const FunctionProtoType::ExtParameterInfo *ParamInfos,
725 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
726 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
728 bool TransformFunctionTypeParams(
729 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
730 const QualType *ParamTypes,
731 const FunctionProtoType::ExtParameterInfo *ParamInfos,
732 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
733 Sema::ExtParameterInfoBuilder &PInfos) {
734 return getDerived().TransformFunctionTypeParams(
735 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
738 /// Transforms the parameters of a requires expresison into the given vectors.
740 /// The result vectors should be kept in sync; null entries in the
741 /// variables vector are acceptable.
743 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
744 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
745 /// which are cases where transformation shouldn't continue.
746 ExprResult TransformRequiresTypeParams(
747 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
748 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
749 SmallVectorImpl<QualType> &PTypes,
750 SmallVectorImpl<ParmVarDecl *> &TransParams,
751 Sema::ExtParameterInfoBuilder &PInfos) {
752 if (getDerived().TransformFunctionTypeParams(
753 KWLoc, Params, /*ParamTypes=*/nullptr,
754 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
755 return ExprError();
757 return ExprResult{};
760 /// Transforms a single function-type parameter. Return null
761 /// on error.
763 /// \param indexAdjustment - A number to add to the parameter's
764 /// scope index; can be negative
765 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
766 int indexAdjustment,
767 std::optional<unsigned> NumExpansions,
768 bool ExpectParameterPack);
770 /// Transform the body of a lambda-expression.
771 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
772 /// Alternative implementation of TransformLambdaBody that skips transforming
773 /// the body.
774 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
776 CXXRecordDecl::LambdaDependencyKind
777 ComputeLambdaDependency(LambdaScopeInfo *LSI) {
778 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
779 LSI->Lambda->getLambdaDependencyKind());
782 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
784 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
785 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
787 TemplateParameterList *TransformTemplateParameterList(
788 TemplateParameterList *TPL) {
789 return TPL;
792 ExprResult TransformAddressOfOperand(Expr *E);
794 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
795 bool IsAddressOfOperand,
796 TypeSourceInfo **RecoveryTSI);
798 ExprResult TransformParenDependentScopeDeclRefExpr(
799 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
800 TypeSourceInfo **RecoveryTSI);
802 ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,
803 bool IsAddressOfOperand);
805 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
807 StmtResult TransformOMPInformationalDirective(OMPExecutableDirective *S);
809 // FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
810 // amount of stack usage with clang.
811 #define STMT(Node, Parent) \
812 LLVM_ATTRIBUTE_NOINLINE \
813 StmtResult Transform##Node(Node *S);
814 #define VALUESTMT(Node, Parent) \
815 LLVM_ATTRIBUTE_NOINLINE \
816 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
817 #define EXPR(Node, Parent) \
818 LLVM_ATTRIBUTE_NOINLINE \
819 ExprResult Transform##Node(Node *E);
820 #define ABSTRACT_STMT(Stmt)
821 #include "clang/AST/StmtNodes.inc"
823 #define GEN_CLANG_CLAUSE_CLASS
824 #define CLAUSE_CLASS(Enum, Str, Class) \
825 LLVM_ATTRIBUTE_NOINLINE \
826 OMPClause *Transform##Class(Class *S);
827 #include "llvm/Frontend/OpenMP/OMP.inc"
829 /// Build a new qualified type given its unqualified type and type location.
831 /// By default, this routine adds type qualifiers only to types that can
832 /// have qualifiers, and silently suppresses those qualifiers that are not
833 /// permitted. Subclasses may override this routine to provide different
834 /// behavior.
835 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
837 /// Build a new pointer type given its pointee type.
839 /// By default, performs semantic analysis when building the pointer type.
840 /// Subclasses may override this routine to provide different behavior.
841 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
843 /// Build a new block pointer type given its pointee type.
845 /// By default, performs semantic analysis when building the block pointer
846 /// type. Subclasses may override this routine to provide different behavior.
847 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
849 /// Build a new reference type given the type it references.
851 /// By default, performs semantic analysis when building the
852 /// reference type. Subclasses may override this routine to provide
853 /// different behavior.
855 /// \param LValue whether the type was written with an lvalue sigil
856 /// or an rvalue sigil.
857 QualType RebuildReferenceType(QualType ReferentType,
858 bool LValue,
859 SourceLocation Sigil);
861 /// Build a new member pointer type given the pointee type and the
862 /// class type it refers into.
864 /// By default, performs semantic analysis when building the member pointer
865 /// type. Subclasses may override this routine to provide different behavior.
866 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
867 SourceLocation Sigil);
869 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
870 SourceLocation ProtocolLAngleLoc,
871 ArrayRef<ObjCProtocolDecl *> Protocols,
872 ArrayRef<SourceLocation> ProtocolLocs,
873 SourceLocation ProtocolRAngleLoc);
875 /// Build an Objective-C object type.
877 /// By default, performs semantic analysis when building the object type.
878 /// Subclasses may override this routine to provide different behavior.
879 QualType RebuildObjCObjectType(QualType BaseType,
880 SourceLocation Loc,
881 SourceLocation TypeArgsLAngleLoc,
882 ArrayRef<TypeSourceInfo *> TypeArgs,
883 SourceLocation TypeArgsRAngleLoc,
884 SourceLocation ProtocolLAngleLoc,
885 ArrayRef<ObjCProtocolDecl *> Protocols,
886 ArrayRef<SourceLocation> ProtocolLocs,
887 SourceLocation ProtocolRAngleLoc);
889 /// Build a new Objective-C object pointer type given the pointee type.
891 /// By default, directly builds the pointer type, with no additional semantic
892 /// analysis.
893 QualType RebuildObjCObjectPointerType(QualType PointeeType,
894 SourceLocation Star);
896 /// Build a new array type given the element type, size
897 /// modifier, size of the array (if known), size expression, and index type
898 /// qualifiers.
900 /// By default, performs semantic analysis when building the array type.
901 /// Subclasses may override this routine to provide different behavior.
902 /// Also by default, all of the other Rebuild*Array
903 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
904 const llvm::APInt *Size, Expr *SizeExpr,
905 unsigned IndexTypeQuals, SourceRange BracketsRange);
907 /// Build a new constant array type given the element type, size
908 /// modifier, (known) size of the array, and index type qualifiers.
910 /// By default, performs semantic analysis when building the array type.
911 /// Subclasses may override this routine to provide different behavior.
912 QualType RebuildConstantArrayType(QualType ElementType,
913 ArraySizeModifier SizeMod,
914 const llvm::APInt &Size, Expr *SizeExpr,
915 unsigned IndexTypeQuals,
916 SourceRange BracketsRange);
918 /// Build a new incomplete array type given the element type, size
919 /// modifier, and index type qualifiers.
921 /// By default, performs semantic analysis when building the array type.
922 /// Subclasses may override this routine to provide different behavior.
923 QualType RebuildIncompleteArrayType(QualType ElementType,
924 ArraySizeModifier SizeMod,
925 unsigned IndexTypeQuals,
926 SourceRange BracketsRange);
928 /// Build a new variable-length array type given the element type,
929 /// size modifier, size expression, and index type qualifiers.
931 /// By default, performs semantic analysis when building the array type.
932 /// Subclasses may override this routine to provide different behavior.
933 QualType RebuildVariableArrayType(QualType ElementType,
934 ArraySizeModifier SizeMod, Expr *SizeExpr,
935 unsigned IndexTypeQuals,
936 SourceRange BracketsRange);
938 /// Build a new dependent-sized array type given the element type,
939 /// size modifier, size expression, and index type qualifiers.
941 /// By default, performs semantic analysis when building the array type.
942 /// Subclasses may override this routine to provide different behavior.
943 QualType RebuildDependentSizedArrayType(QualType ElementType,
944 ArraySizeModifier SizeMod,
945 Expr *SizeExpr,
946 unsigned IndexTypeQuals,
947 SourceRange BracketsRange);
949 /// Build a new vector type given the element type and
950 /// number of elements.
952 /// By default, performs semantic analysis when building the vector type.
953 /// Subclasses may override this routine to provide different behavior.
954 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
955 VectorKind VecKind);
957 /// Build a new potentially dependently-sized extended vector type
958 /// given the element type and number of elements.
960 /// By default, performs semantic analysis when building the vector type.
961 /// Subclasses may override this routine to provide different behavior.
962 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
963 SourceLocation AttributeLoc, VectorKind);
965 /// Build a new extended vector type given the element type and
966 /// number of elements.
968 /// By default, performs semantic analysis when building the vector type.
969 /// Subclasses may override this routine to provide different behavior.
970 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
971 SourceLocation AttributeLoc);
973 /// Build a new potentially dependently-sized extended vector type
974 /// given the element type and number of elements.
976 /// By default, performs semantic analysis when building the vector type.
977 /// Subclasses may override this routine to provide different behavior.
978 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
979 Expr *SizeExpr,
980 SourceLocation AttributeLoc);
982 /// Build a new matrix type given the element type and dimensions.
983 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
984 unsigned NumColumns);
986 /// Build a new matrix type given the type and dependently-defined
987 /// dimensions.
988 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
989 Expr *ColumnExpr,
990 SourceLocation AttributeLoc);
992 /// Build a new DependentAddressSpaceType or return the pointee
993 /// type variable with the correct address space (retrieved from
994 /// AddrSpaceExpr) applied to it. The former will be returned in cases
995 /// where the address space remains dependent.
997 /// By default, performs semantic analysis when building the type with address
998 /// space applied. Subclasses may override this routine to provide different
999 /// behavior.
1000 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
1001 Expr *AddrSpaceExpr,
1002 SourceLocation AttributeLoc);
1004 /// Build a new function type.
1006 /// By default, performs semantic analysis when building the function type.
1007 /// Subclasses may override this routine to provide different behavior.
1008 QualType RebuildFunctionProtoType(QualType T,
1009 MutableArrayRef<QualType> ParamTypes,
1010 const FunctionProtoType::ExtProtoInfo &EPI);
1012 /// Build a new unprototyped function type.
1013 QualType RebuildFunctionNoProtoType(QualType ResultType);
1015 /// Rebuild an unresolved typename type, given the decl that
1016 /// the UnresolvedUsingTypenameDecl was transformed to.
1017 QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D);
1019 /// Build a new type found via an alias.
1020 QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying) {
1021 return SemaRef.Context.getUsingType(Found, Underlying);
1024 /// Build a new typedef type.
1025 QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
1026 return SemaRef.Context.getTypeDeclType(Typedef);
1029 /// Build a new MacroDefined type.
1030 QualType RebuildMacroQualifiedType(QualType T,
1031 const IdentifierInfo *MacroII) {
1032 return SemaRef.Context.getMacroQualifiedType(T, MacroII);
1035 /// Build a new class/struct/union type.
1036 QualType RebuildRecordType(RecordDecl *Record) {
1037 return SemaRef.Context.getTypeDeclType(Record);
1040 /// Build a new Enum type.
1041 QualType RebuildEnumType(EnumDecl *Enum) {
1042 return SemaRef.Context.getTypeDeclType(Enum);
1045 /// Build a new typeof(expr) type.
1047 /// By default, performs semantic analysis when building the typeof type.
1048 /// Subclasses may override this routine to provide different behavior.
1049 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1050 TypeOfKind Kind);
1052 /// Build a new typeof(type) type.
1054 /// By default, builds a new TypeOfType with the given underlying type.
1055 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1057 /// Build a new unary transform type.
1058 QualType RebuildUnaryTransformType(QualType BaseType,
1059 UnaryTransformType::UTTKind UKind,
1060 SourceLocation Loc);
1062 /// Build a new C++11 decltype type.
1064 /// By default, performs semantic analysis when building the decltype type.
1065 /// Subclasses may override this routine to provide different behavior.
1066 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1068 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1069 SourceLocation Loc,
1070 SourceLocation EllipsisLoc,
1071 bool FullySubstituted,
1072 ArrayRef<QualType> Expansions = {});
1074 /// Build a new C++11 auto type.
1076 /// By default, builds a new AutoType with the given deduced type.
1077 QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword,
1078 ConceptDecl *TypeConstraintConcept,
1079 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1080 // Note, IsDependent is always false here: we implicitly convert an 'auto'
1081 // which has been deduced to a dependent type into an undeduced 'auto', so
1082 // that we'll retry deduction after the transformation.
1083 return SemaRef.Context.getAutoType(Deduced, Keyword,
1084 /*IsDependent*/ false, /*IsPack=*/false,
1085 TypeConstraintConcept,
1086 TypeConstraintArgs);
1089 /// By default, builds a new DeducedTemplateSpecializationType with the given
1090 /// deduced type.
1091 QualType RebuildDeducedTemplateSpecializationType(TemplateName Template,
1092 QualType Deduced) {
1093 return SemaRef.Context.getDeducedTemplateSpecializationType(
1094 Template, Deduced, /*IsDependent*/ false);
1097 /// Build a new template specialization type.
1099 /// By default, performs semantic analysis when building the template
1100 /// specialization type. Subclasses may override this routine to provide
1101 /// different behavior.
1102 QualType RebuildTemplateSpecializationType(TemplateName Template,
1103 SourceLocation TemplateLoc,
1104 TemplateArgumentListInfo &Args);
1106 /// Build a new parenthesized type.
1108 /// By default, builds a new ParenType type from the inner type.
1109 /// Subclasses may override this routine to provide different behavior.
1110 QualType RebuildParenType(QualType InnerType) {
1111 return SemaRef.BuildParenType(InnerType);
1114 /// Build a new qualified name type.
1116 /// By default, builds a new ElaboratedType type from the keyword,
1117 /// the nested-name-specifier and the named type.
1118 /// Subclasses may override this routine to provide different behavior.
1119 QualType RebuildElaboratedType(SourceLocation KeywordLoc,
1120 ElaboratedTypeKeyword Keyword,
1121 NestedNameSpecifierLoc QualifierLoc,
1122 QualType Named) {
1123 return SemaRef.Context.getElaboratedType(Keyword,
1124 QualifierLoc.getNestedNameSpecifier(),
1125 Named);
1128 /// Build a new typename type that refers to a template-id.
1130 /// By default, builds a new DependentNameType type from the
1131 /// nested-name-specifier and the given type. Subclasses may override
1132 /// this routine to provide different behavior.
1133 QualType RebuildDependentTemplateSpecializationType(
1134 ElaboratedTypeKeyword Keyword,
1135 NestedNameSpecifierLoc QualifierLoc,
1136 SourceLocation TemplateKWLoc,
1137 const IdentifierInfo *Name,
1138 SourceLocation NameLoc,
1139 TemplateArgumentListInfo &Args,
1140 bool AllowInjectedClassName) {
1141 // Rebuild the template name.
1142 // TODO: avoid TemplateName abstraction
1143 CXXScopeSpec SS;
1144 SS.Adopt(QualifierLoc);
1145 TemplateName InstName = getDerived().RebuildTemplateName(
1146 SS, TemplateKWLoc, *Name, NameLoc, QualType(), nullptr,
1147 AllowInjectedClassName);
1149 if (InstName.isNull())
1150 return QualType();
1152 // If it's still dependent, make a dependent specialization.
1153 if (InstName.getAsDependentTemplateName())
1154 return SemaRef.Context.getDependentTemplateSpecializationType(
1155 Keyword, QualifierLoc.getNestedNameSpecifier(), Name,
1156 Args.arguments());
1158 // Otherwise, make an elaborated type wrapping a non-dependent
1159 // specialization.
1160 QualType T =
1161 getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
1162 if (T.isNull())
1163 return QualType();
1164 return SemaRef.Context.getElaboratedType(
1165 Keyword, QualifierLoc.getNestedNameSpecifier(), T);
1168 /// Build a new typename type that refers to an identifier.
1170 /// By default, performs semantic analysis when building the typename type
1171 /// (or elaborated type). Subclasses may override this routine to provide
1172 /// different behavior.
1173 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1174 SourceLocation KeywordLoc,
1175 NestedNameSpecifierLoc QualifierLoc,
1176 const IdentifierInfo *Id,
1177 SourceLocation IdLoc,
1178 bool DeducedTSTContext) {
1179 CXXScopeSpec SS;
1180 SS.Adopt(QualifierLoc);
1182 if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
1183 // If the name is still dependent, just build a new dependent name type.
1184 if (!SemaRef.computeDeclContext(SS))
1185 return SemaRef.Context.getDependentNameType(Keyword,
1186 QualifierLoc.getNestedNameSpecifier(),
1187 Id);
1190 if (Keyword == ElaboratedTypeKeyword::None ||
1191 Keyword == ElaboratedTypeKeyword::Typename) {
1192 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1193 *Id, IdLoc, DeducedTSTContext);
1196 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1198 // We had a dependent elaborated-type-specifier that has been transformed
1199 // into a non-dependent elaborated-type-specifier. Find the tag we're
1200 // referring to.
1201 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1202 DeclContext *DC = SemaRef.computeDeclContext(SS, false);
1203 if (!DC)
1204 return QualType();
1206 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1207 return QualType();
1209 TagDecl *Tag = nullptr;
1210 SemaRef.LookupQualifiedName(Result, DC);
1211 switch (Result.getResultKind()) {
1212 case LookupResult::NotFound:
1213 case LookupResult::NotFoundInCurrentInstantiation:
1214 break;
1216 case LookupResult::Found:
1217 Tag = Result.getAsSingle<TagDecl>();
1218 break;
1220 case LookupResult::FoundOverloaded:
1221 case LookupResult::FoundUnresolvedValue:
1222 llvm_unreachable("Tag lookup cannot find non-tags");
1224 case LookupResult::Ambiguous:
1225 // Let the LookupResult structure handle ambiguities.
1226 return QualType();
1229 if (!Tag) {
1230 // Check where the name exists but isn't a tag type and use that to emit
1231 // better diagnostics.
1232 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1233 SemaRef.LookupQualifiedName(Result, DC);
1234 switch (Result.getResultKind()) {
1235 case LookupResult::Found:
1236 case LookupResult::FoundOverloaded:
1237 case LookupResult::FoundUnresolvedValue: {
1238 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1239 Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind);
1240 SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag)
1241 << SomeDecl << NTK << llvm::to_underlying(Kind);
1242 SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
1243 break;
1245 default:
1246 SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
1247 << llvm::to_underlying(Kind) << Id << DC
1248 << QualifierLoc.getSourceRange();
1249 break;
1251 return QualType();
1254 if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false,
1255 IdLoc, Id)) {
1256 SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
1257 SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
1258 return QualType();
1261 // Build the elaborated-type-specifier type.
1262 QualType T = SemaRef.Context.getTypeDeclType(Tag);
1263 return SemaRef.Context.getElaboratedType(Keyword,
1264 QualifierLoc.getNestedNameSpecifier(),
1268 /// Build a new pack expansion type.
1270 /// By default, builds a new PackExpansionType type from the given pattern.
1271 /// Subclasses may override this routine to provide different behavior.
1272 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1273 SourceLocation EllipsisLoc,
1274 std::optional<unsigned> NumExpansions) {
1275 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1276 NumExpansions);
1279 /// Build a new atomic type given its value type.
1281 /// By default, performs semantic analysis when building the atomic type.
1282 /// Subclasses may override this routine to provide different behavior.
1283 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1285 /// Build a new pipe type given its value type.
1286 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1287 bool isReadPipe);
1289 /// Build a bit-precise int given its value type.
1290 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1291 SourceLocation Loc);
1293 /// Build a dependent bit-precise int given its value type.
1294 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1295 SourceLocation Loc);
1297 /// Build a new template name given a nested name specifier, a flag
1298 /// indicating whether the "template" keyword was provided, and the template
1299 /// that the template name refers to.
1301 /// By default, builds the new template name directly. Subclasses may override
1302 /// this routine to provide different behavior.
1303 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1304 bool TemplateKW,
1305 TemplateDecl *Template);
1307 /// Build a new template name given a nested name specifier and the
1308 /// name that is referred to as a template.
1310 /// By default, performs semantic analysis to determine whether the name can
1311 /// be resolved to a specific template, then builds the appropriate kind of
1312 /// template name. Subclasses may override this routine to provide different
1313 /// behavior.
1314 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1315 SourceLocation TemplateKWLoc,
1316 const IdentifierInfo &Name,
1317 SourceLocation NameLoc, QualType ObjectType,
1318 NamedDecl *FirstQualifierInScope,
1319 bool AllowInjectedClassName);
1321 /// Build a new template name given a nested name specifier and the
1322 /// overloaded operator name that is referred to as a template.
1324 /// By default, performs semantic analysis to determine whether the name can
1325 /// be resolved to a specific template, then builds the appropriate kind of
1326 /// template name. Subclasses may override this routine to provide different
1327 /// behavior.
1328 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1329 SourceLocation TemplateKWLoc,
1330 OverloadedOperatorKind Operator,
1331 SourceLocation NameLoc, QualType ObjectType,
1332 bool AllowInjectedClassName);
1334 /// Build a new template name given a template template parameter pack
1335 /// and the
1337 /// By default, performs semantic analysis to determine whether the name can
1338 /// be resolved to a specific template, then builds the appropriate kind of
1339 /// template name. Subclasses may override this routine to provide different
1340 /// behavior.
1341 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1342 Decl *AssociatedDecl, unsigned Index,
1343 bool Final) {
1344 return getSema().Context.getSubstTemplateTemplateParmPack(
1345 ArgPack, AssociatedDecl, Index, Final);
1348 /// Build a new compound statement.
1350 /// By default, performs semantic analysis to build the new statement.
1351 /// Subclasses may override this routine to provide different behavior.
1352 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1353 MultiStmtArg Statements,
1354 SourceLocation RBraceLoc,
1355 bool IsStmtExpr) {
1356 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1357 IsStmtExpr);
1360 /// Build a new case statement.
1362 /// By default, performs semantic analysis to build the new statement.
1363 /// Subclasses may override this routine to provide different behavior.
1364 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1365 Expr *LHS,
1366 SourceLocation EllipsisLoc,
1367 Expr *RHS,
1368 SourceLocation ColonLoc) {
1369 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1370 ColonLoc);
1373 /// Attach the body to a new case statement.
1375 /// By default, performs semantic analysis to build the new statement.
1376 /// Subclasses may override this routine to provide different behavior.
1377 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1378 getSema().ActOnCaseStmtBody(S, Body);
1379 return S;
1382 /// Build a new default statement.
1384 /// By default, performs semantic analysis to build the new statement.
1385 /// Subclasses may override this routine to provide different behavior.
1386 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1387 SourceLocation ColonLoc,
1388 Stmt *SubStmt) {
1389 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1390 /*CurScope=*/nullptr);
1393 /// Build a new label statement.
1395 /// By default, performs semantic analysis to build the new statement.
1396 /// Subclasses may override this routine to provide different behavior.
1397 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1398 SourceLocation ColonLoc, Stmt *SubStmt) {
1399 return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt);
1402 /// Build a new attributed statement.
1404 /// By default, performs semantic analysis to build the new statement.
1405 /// Subclasses may override this routine to provide different behavior.
1406 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1407 ArrayRef<const Attr *> Attrs,
1408 Stmt *SubStmt) {
1409 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1410 return StmtError();
1411 return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt);
1414 /// Build a new "if" statement.
1416 /// By default, performs semantic analysis to build the new statement.
1417 /// Subclasses may override this routine to provide different behavior.
1418 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1419 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1420 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1421 SourceLocation ElseLoc, Stmt *Else) {
1422 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1423 Then, ElseLoc, Else);
1426 /// Start building a new switch statement.
1428 /// By default, performs semantic analysis to build the new statement.
1429 /// Subclasses may override this routine to provide different behavior.
1430 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1431 SourceLocation LParenLoc, Stmt *Init,
1432 Sema::ConditionResult Cond,
1433 SourceLocation RParenLoc) {
1434 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1435 RParenLoc);
1438 /// Attach the body to the switch statement.
1440 /// By default, performs semantic analysis to build the new statement.
1441 /// Subclasses may override this routine to provide different behavior.
1442 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1443 Stmt *Switch, Stmt *Body) {
1444 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1447 /// Build a new while statement.
1449 /// By default, performs semantic analysis to build the new statement.
1450 /// Subclasses may override this routine to provide different behavior.
1451 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1452 Sema::ConditionResult Cond,
1453 SourceLocation RParenLoc, Stmt *Body) {
1454 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1457 /// Build a new do-while statement.
1459 /// By default, performs semantic analysis to build the new statement.
1460 /// Subclasses may override this routine to provide different behavior.
1461 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1462 SourceLocation WhileLoc, SourceLocation LParenLoc,
1463 Expr *Cond, SourceLocation RParenLoc) {
1464 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1465 Cond, RParenLoc);
1468 /// Build a new for statement.
1470 /// By default, performs semantic analysis to build the new statement.
1471 /// Subclasses may override this routine to provide different behavior.
1472 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1473 Stmt *Init, Sema::ConditionResult Cond,
1474 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1475 Stmt *Body) {
1476 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1477 Inc, RParenLoc, Body);
1480 /// Build a new goto statement.
1482 /// By default, performs semantic analysis to build the new statement.
1483 /// Subclasses may override this routine to provide different behavior.
1484 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1485 LabelDecl *Label) {
1486 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1489 /// Build a new indirect goto statement.
1491 /// By default, performs semantic analysis to build the new statement.
1492 /// Subclasses may override this routine to provide different behavior.
1493 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1494 SourceLocation StarLoc,
1495 Expr *Target) {
1496 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1499 /// Build a new return statement.
1501 /// By default, performs semantic analysis to build the new statement.
1502 /// Subclasses may override this routine to provide different behavior.
1503 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1504 return getSema().BuildReturnStmt(ReturnLoc, Result);
1507 /// Build a new declaration statement.
1509 /// By default, performs semantic analysis to build the new statement.
1510 /// Subclasses may override this routine to provide different behavior.
1511 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1512 SourceLocation StartLoc, SourceLocation EndLoc) {
1513 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1514 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1517 /// Build a new inline asm statement.
1519 /// By default, performs semantic analysis to build the new statement.
1520 /// Subclasses may override this routine to provide different behavior.
1521 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1522 bool IsVolatile, unsigned NumOutputs,
1523 unsigned NumInputs, IdentifierInfo **Names,
1524 MultiExprArg Constraints, MultiExprArg Exprs,
1525 Expr *AsmString, MultiExprArg Clobbers,
1526 unsigned NumLabels,
1527 SourceLocation RParenLoc) {
1528 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1529 NumInputs, Names, Constraints, Exprs,
1530 AsmString, Clobbers, NumLabels, RParenLoc);
1533 /// Build a new MS style inline asm statement.
1535 /// By default, performs semantic analysis to build the new statement.
1536 /// Subclasses may override this routine to provide different behavior.
1537 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1538 ArrayRef<Token> AsmToks,
1539 StringRef AsmString,
1540 unsigned NumOutputs, unsigned NumInputs,
1541 ArrayRef<StringRef> Constraints,
1542 ArrayRef<StringRef> Clobbers,
1543 ArrayRef<Expr*> Exprs,
1544 SourceLocation EndLoc) {
1545 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1546 NumOutputs, NumInputs,
1547 Constraints, Clobbers, Exprs, EndLoc);
1550 /// Build a new co_return statement.
1552 /// By default, performs semantic analysis to build the new statement.
1553 /// Subclasses may override this routine to provide different behavior.
1554 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1555 bool IsImplicit) {
1556 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1559 /// Build a new co_await expression.
1561 /// By default, performs semantic analysis to build the new expression.
1562 /// Subclasses may override this routine to provide different behavior.
1563 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1564 UnresolvedLookupExpr *OpCoawaitLookup,
1565 bool IsImplicit) {
1566 // This function rebuilds a coawait-expr given its operator.
1567 // For an explicit coawait-expr, the rebuild involves the full set
1568 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1569 // including calling await_transform().
1570 // For an implicit coawait-expr, we need to rebuild the "operator
1571 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1572 // This mirrors how the implicit CoawaitExpr is originally created
1573 // in Sema::ActOnCoroutineBodyStart().
1574 if (IsImplicit) {
1575 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1576 CoawaitLoc, Operand, OpCoawaitLookup);
1577 if (Suspend.isInvalid())
1578 return ExprError();
1579 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1580 Suspend.get(), true);
1583 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1584 OpCoawaitLookup);
1587 /// Build a new co_await expression.
1589 /// By default, performs semantic analysis to build the new expression.
1590 /// Subclasses may override this routine to provide different behavior.
1591 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1592 Expr *Result,
1593 UnresolvedLookupExpr *Lookup) {
1594 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1597 /// Build a new co_yield expression.
1599 /// By default, performs semantic analysis to build the new expression.
1600 /// Subclasses may override this routine to provide different behavior.
1601 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1602 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1605 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1606 return getSema().BuildCoroutineBodyStmt(Args);
1609 /// Build a new Objective-C \@try statement.
1611 /// By default, performs semantic analysis to build the new statement.
1612 /// Subclasses may override this routine to provide different behavior.
1613 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1614 Stmt *TryBody,
1615 MultiStmtArg CatchStmts,
1616 Stmt *Finally) {
1617 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1618 Finally);
1621 /// Rebuild an Objective-C exception declaration.
1623 /// By default, performs semantic analysis to build the new declaration.
1624 /// Subclasses may override this routine to provide different behavior.
1625 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1626 TypeSourceInfo *TInfo, QualType T) {
1627 return getSema().ObjC().BuildObjCExceptionDecl(
1628 TInfo, T, ExceptionDecl->getInnerLocStart(),
1629 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1632 /// Build a new Objective-C \@catch statement.
1634 /// By default, performs semantic analysis to build the new statement.
1635 /// Subclasses may override this routine to provide different behavior.
1636 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1637 SourceLocation RParenLoc,
1638 VarDecl *Var,
1639 Stmt *Body) {
1640 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1643 /// Build a new Objective-C \@finally statement.
1645 /// By default, performs semantic analysis to build the new statement.
1646 /// Subclasses may override this routine to provide different behavior.
1647 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1648 Stmt *Body) {
1649 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1652 /// Build a new Objective-C \@throw statement.
1654 /// By default, performs semantic analysis to build the new statement.
1655 /// Subclasses may override this routine to provide different behavior.
1656 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1657 Expr *Operand) {
1658 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1661 /// Build a new OpenMP Canonical loop.
1663 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1664 /// OMPCanonicalLoop.
1665 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1666 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1669 /// Build a new OpenMP executable directive.
1671 /// By default, performs semantic analysis to build the new statement.
1672 /// Subclasses may override this routine to provide different behavior.
1673 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
1674 DeclarationNameInfo DirName,
1675 OpenMPDirectiveKind CancelRegion,
1676 ArrayRef<OMPClause *> Clauses,
1677 Stmt *AStmt, SourceLocation StartLoc,
1678 SourceLocation EndLoc) {
1680 return getSema().OpenMP().ActOnOpenMPExecutableDirective(
1681 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1684 /// Build a new OpenMP informational directive.
1685 StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,
1686 DeclarationNameInfo DirName,
1687 ArrayRef<OMPClause *> Clauses,
1688 Stmt *AStmt,
1689 SourceLocation StartLoc,
1690 SourceLocation EndLoc) {
1692 return getSema().OpenMP().ActOnOpenMPInformationalDirective(
1693 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1696 /// Build a new OpenMP 'if' clause.
1698 /// By default, performs semantic analysis to build the new OpenMP clause.
1699 /// Subclasses may override this routine to provide different behavior.
1700 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1701 Expr *Condition, SourceLocation StartLoc,
1702 SourceLocation LParenLoc,
1703 SourceLocation NameModifierLoc,
1704 SourceLocation ColonLoc,
1705 SourceLocation EndLoc) {
1706 return getSema().OpenMP().ActOnOpenMPIfClause(
1707 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1708 EndLoc);
1711 /// Build a new OpenMP 'final' clause.
1713 /// By default, performs semantic analysis to build the new OpenMP clause.
1714 /// Subclasses may override this routine to provide different behavior.
1715 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1716 SourceLocation LParenLoc,
1717 SourceLocation EndLoc) {
1718 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1719 LParenLoc, EndLoc);
1722 /// Build a new OpenMP 'num_threads' clause.
1724 /// By default, performs semantic analysis to build the new OpenMP clause.
1725 /// Subclasses may override this routine to provide different behavior.
1726 OMPClause *RebuildOMPNumThreadsClause(Expr *NumThreads,
1727 SourceLocation StartLoc,
1728 SourceLocation LParenLoc,
1729 SourceLocation EndLoc) {
1730 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc,
1731 LParenLoc, EndLoc);
1734 /// Build a new OpenMP 'safelen' clause.
1736 /// By default, performs semantic analysis to build the new OpenMP clause.
1737 /// Subclasses may override this routine to provide different behavior.
1738 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1739 SourceLocation LParenLoc,
1740 SourceLocation EndLoc) {
1741 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1742 EndLoc);
1745 /// Build a new OpenMP 'simdlen' clause.
1747 /// By default, performs semantic analysis to build the new OpenMP clause.
1748 /// Subclasses may override this routine to provide different behavior.
1749 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1750 SourceLocation LParenLoc,
1751 SourceLocation EndLoc) {
1752 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1753 EndLoc);
1756 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1757 SourceLocation StartLoc,
1758 SourceLocation LParenLoc,
1759 SourceLocation EndLoc) {
1760 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1761 EndLoc);
1764 /// Build a new OpenMP 'permutation' clause.
1765 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,
1766 SourceLocation StartLoc,
1767 SourceLocation LParenLoc,
1768 SourceLocation EndLoc) {
1769 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1770 LParenLoc, EndLoc);
1773 /// Build a new OpenMP 'full' clause.
1774 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1775 SourceLocation EndLoc) {
1776 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1779 /// Build a new OpenMP 'partial' clause.
1780 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1781 SourceLocation LParenLoc,
1782 SourceLocation EndLoc) {
1783 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1784 LParenLoc, EndLoc);
1787 /// Build a new OpenMP 'allocator' clause.
1789 /// By default, performs semantic analysis to build the new OpenMP clause.
1790 /// Subclasses may override this routine to provide different behavior.
1791 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1792 SourceLocation LParenLoc,
1793 SourceLocation EndLoc) {
1794 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1795 EndLoc);
1798 /// Build a new OpenMP 'collapse' clause.
1800 /// By default, performs semantic analysis to build the new OpenMP clause.
1801 /// Subclasses may override this routine to provide different behavior.
1802 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1803 SourceLocation LParenLoc,
1804 SourceLocation EndLoc) {
1805 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1806 LParenLoc, EndLoc);
1809 /// Build a new OpenMP 'default' clause.
1811 /// By default, performs semantic analysis to build the new OpenMP clause.
1812 /// Subclasses may override this routine to provide different behavior.
1813 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1814 SourceLocation StartLoc,
1815 SourceLocation LParenLoc,
1816 SourceLocation EndLoc) {
1817 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1818 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1821 /// Build a new OpenMP 'proc_bind' clause.
1823 /// By default, performs semantic analysis to build the new OpenMP clause.
1824 /// Subclasses may override this routine to provide different behavior.
1825 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1826 SourceLocation KindKwLoc,
1827 SourceLocation StartLoc,
1828 SourceLocation LParenLoc,
1829 SourceLocation EndLoc) {
1830 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1831 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1834 /// Build a new OpenMP 'schedule' clause.
1836 /// By default, performs semantic analysis to build the new OpenMP clause.
1837 /// Subclasses may override this routine to provide different behavior.
1838 OMPClause *RebuildOMPScheduleClause(
1839 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1840 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1841 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1842 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1843 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1844 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1845 CommaLoc, EndLoc);
1848 /// Build a new OpenMP 'ordered' clause.
1850 /// By default, performs semantic analysis to build the new OpenMP clause.
1851 /// Subclasses may override this routine to provide different behavior.
1852 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1853 SourceLocation EndLoc,
1854 SourceLocation LParenLoc, Expr *Num) {
1855 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1856 LParenLoc, Num);
1859 /// Build a new OpenMP 'private' clause.
1861 /// By default, performs semantic analysis to build the new OpenMP clause.
1862 /// Subclasses may override this routine to provide different behavior.
1863 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1864 SourceLocation StartLoc,
1865 SourceLocation LParenLoc,
1866 SourceLocation EndLoc) {
1867 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1868 LParenLoc, EndLoc);
1871 /// Build a new OpenMP 'firstprivate' clause.
1873 /// By default, performs semantic analysis to build the new OpenMP clause.
1874 /// Subclasses may override this routine to provide different behavior.
1875 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1876 SourceLocation StartLoc,
1877 SourceLocation LParenLoc,
1878 SourceLocation EndLoc) {
1879 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1880 LParenLoc, EndLoc);
1883 /// Build a new OpenMP 'lastprivate' clause.
1885 /// By default, performs semantic analysis to build the new OpenMP clause.
1886 /// Subclasses may override this routine to provide different behavior.
1887 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1888 OpenMPLastprivateModifier LPKind,
1889 SourceLocation LPKindLoc,
1890 SourceLocation ColonLoc,
1891 SourceLocation StartLoc,
1892 SourceLocation LParenLoc,
1893 SourceLocation EndLoc) {
1894 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1895 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1898 /// Build a new OpenMP 'shared' clause.
1900 /// By default, performs semantic analysis to build the new OpenMP clause.
1901 /// Subclasses may override this routine to provide different behavior.
1902 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1903 SourceLocation StartLoc,
1904 SourceLocation LParenLoc,
1905 SourceLocation EndLoc) {
1906 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1907 LParenLoc, EndLoc);
1910 /// Build a new OpenMP 'reduction' clause.
1912 /// By default, performs semantic analysis to build the new statement.
1913 /// Subclasses may override this routine to provide different behavior.
1914 OMPClause *RebuildOMPReductionClause(
1915 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1916 SourceLocation StartLoc, SourceLocation LParenLoc,
1917 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1918 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1919 const DeclarationNameInfo &ReductionId,
1920 ArrayRef<Expr *> UnresolvedReductions) {
1921 return getSema().OpenMP().ActOnOpenMPReductionClause(
1922 VarList, Modifier, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
1923 ReductionIdScopeSpec, ReductionId, UnresolvedReductions);
1926 /// Build a new OpenMP 'task_reduction' clause.
1928 /// By default, performs semantic analysis to build the new statement.
1929 /// Subclasses may override this routine to provide different behavior.
1930 OMPClause *RebuildOMPTaskReductionClause(
1931 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1932 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1933 CXXScopeSpec &ReductionIdScopeSpec,
1934 const DeclarationNameInfo &ReductionId,
1935 ArrayRef<Expr *> UnresolvedReductions) {
1936 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
1937 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1938 ReductionId, UnresolvedReductions);
1941 /// Build a new OpenMP 'in_reduction' clause.
1943 /// By default, performs semantic analysis to build the new statement.
1944 /// Subclasses may override this routine to provide different behavior.
1945 OMPClause *
1946 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1947 SourceLocation LParenLoc, SourceLocation ColonLoc,
1948 SourceLocation EndLoc,
1949 CXXScopeSpec &ReductionIdScopeSpec,
1950 const DeclarationNameInfo &ReductionId,
1951 ArrayRef<Expr *> UnresolvedReductions) {
1952 return getSema().OpenMP().ActOnOpenMPInReductionClause(
1953 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1954 ReductionId, UnresolvedReductions);
1957 /// Build a new OpenMP 'linear' clause.
1959 /// By default, performs semantic analysis to build the new OpenMP clause.
1960 /// Subclasses may override this routine to provide different behavior.
1961 OMPClause *RebuildOMPLinearClause(
1962 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1963 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1964 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1965 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
1966 return getSema().OpenMP().ActOnOpenMPLinearClause(
1967 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
1968 StepModifierLoc, EndLoc);
1971 /// Build a new OpenMP 'aligned' clause.
1973 /// By default, performs semantic analysis to build the new OpenMP clause.
1974 /// Subclasses may override this routine to provide different behavior.
1975 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
1976 SourceLocation StartLoc,
1977 SourceLocation LParenLoc,
1978 SourceLocation ColonLoc,
1979 SourceLocation EndLoc) {
1980 return getSema().OpenMP().ActOnOpenMPAlignedClause(
1981 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
1984 /// Build a new OpenMP 'copyin' clause.
1986 /// By default, performs semantic analysis to build the new OpenMP clause.
1987 /// Subclasses may override this routine to provide different behavior.
1988 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
1989 SourceLocation StartLoc,
1990 SourceLocation LParenLoc,
1991 SourceLocation EndLoc) {
1992 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
1993 LParenLoc, EndLoc);
1996 /// Build a new OpenMP 'copyprivate' clause.
1998 /// By default, performs semantic analysis to build the new OpenMP clause.
1999 /// Subclasses may override this routine to provide different behavior.
2000 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
2001 SourceLocation StartLoc,
2002 SourceLocation LParenLoc,
2003 SourceLocation EndLoc) {
2004 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
2005 LParenLoc, EndLoc);
2008 /// Build a new OpenMP 'flush' pseudo clause.
2010 /// By default, performs semantic analysis to build the new OpenMP clause.
2011 /// Subclasses may override this routine to provide different behavior.
2012 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
2013 SourceLocation StartLoc,
2014 SourceLocation LParenLoc,
2015 SourceLocation EndLoc) {
2016 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2017 LParenLoc, EndLoc);
2020 /// Build a new OpenMP 'depobj' pseudo clause.
2022 /// By default, performs semantic analysis to build the new OpenMP clause.
2023 /// Subclasses may override this routine to provide different behavior.
2024 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2025 SourceLocation LParenLoc,
2026 SourceLocation EndLoc) {
2027 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2028 LParenLoc, EndLoc);
2031 /// Build a new OpenMP 'depend' pseudo clause.
2033 /// By default, performs semantic analysis to build the new OpenMP clause.
2034 /// Subclasses may override this routine to provide different behavior.
2035 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2036 Expr *DepModifier, ArrayRef<Expr *> VarList,
2037 SourceLocation StartLoc,
2038 SourceLocation LParenLoc,
2039 SourceLocation EndLoc) {
2040 return getSema().OpenMP().ActOnOpenMPDependClause(
2041 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2044 /// Build a new OpenMP 'device' clause.
2046 /// By default, performs semantic analysis to build the new statement.
2047 /// Subclasses may override this routine to provide different behavior.
2048 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2049 Expr *Device, SourceLocation StartLoc,
2050 SourceLocation LParenLoc,
2051 SourceLocation ModifierLoc,
2052 SourceLocation EndLoc) {
2053 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2054 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2057 /// Build a new OpenMP 'map' clause.
2059 /// By default, performs semantic analysis to build the new OpenMP clause.
2060 /// Subclasses may override this routine to provide different behavior.
2061 OMPClause *RebuildOMPMapClause(
2062 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2063 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2064 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2065 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2066 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2067 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2068 return getSema().OpenMP().ActOnOpenMPMapClause(
2069 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2070 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2071 ColonLoc, VarList, Locs,
2072 /*NoDiagnose=*/false, UnresolvedMappers);
2075 /// Build a new OpenMP 'allocate' clause.
2077 /// By default, performs semantic analysis to build the new OpenMP clause.
2078 /// Subclasses may override this routine to provide different behavior.
2079 OMPClause *
2080 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,
2081 OpenMPAllocateClauseModifier FirstModifier,
2082 SourceLocation FirstModifierLoc,
2083 OpenMPAllocateClauseModifier SecondModifier,
2084 SourceLocation SecondModifierLoc,
2085 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2086 SourceLocation LParenLoc, SourceLocation ColonLoc,
2087 SourceLocation EndLoc) {
2088 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2089 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,
2090 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2093 /// Build a new OpenMP 'num_teams' clause.
2095 /// By default, performs semantic analysis to build the new statement.
2096 /// Subclasses may override this routine to provide different behavior.
2097 OMPClause *RebuildOMPNumTeamsClause(ArrayRef<Expr *> VarList,
2098 SourceLocation StartLoc,
2099 SourceLocation LParenLoc,
2100 SourceLocation EndLoc) {
2101 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(VarList, StartLoc,
2102 LParenLoc, EndLoc);
2105 /// Build a new OpenMP 'thread_limit' clause.
2107 /// By default, performs semantic analysis to build the new statement.
2108 /// Subclasses may override this routine to provide different behavior.
2109 OMPClause *RebuildOMPThreadLimitClause(ArrayRef<Expr *> VarList,
2110 SourceLocation StartLoc,
2111 SourceLocation LParenLoc,
2112 SourceLocation EndLoc) {
2113 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(VarList, StartLoc,
2114 LParenLoc, EndLoc);
2117 /// Build a new OpenMP 'priority' clause.
2119 /// By default, performs semantic analysis to build the new statement.
2120 /// Subclasses may override this routine to provide different behavior.
2121 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2122 SourceLocation LParenLoc,
2123 SourceLocation EndLoc) {
2124 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2125 LParenLoc, EndLoc);
2128 /// Build a new OpenMP 'grainsize' clause.
2130 /// By default, performs semantic analysis to build the new statement.
2131 /// Subclasses may override this routine to provide different behavior.
2132 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2133 Expr *Device, SourceLocation StartLoc,
2134 SourceLocation LParenLoc,
2135 SourceLocation ModifierLoc,
2136 SourceLocation EndLoc) {
2137 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2138 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2141 /// Build a new OpenMP 'num_tasks' clause.
2143 /// By default, performs semantic analysis to build the new statement.
2144 /// Subclasses may override this routine to provide different behavior.
2145 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2146 Expr *NumTasks, SourceLocation StartLoc,
2147 SourceLocation LParenLoc,
2148 SourceLocation ModifierLoc,
2149 SourceLocation EndLoc) {
2150 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2151 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2154 /// Build a new OpenMP 'hint' clause.
2156 /// By default, performs semantic analysis to build the new statement.
2157 /// Subclasses may override this routine to provide different behavior.
2158 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2159 SourceLocation LParenLoc,
2160 SourceLocation EndLoc) {
2161 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2162 EndLoc);
2165 /// Build a new OpenMP 'detach' clause.
2167 /// By default, performs semantic analysis to build the new statement.
2168 /// Subclasses may override this routine to provide different behavior.
2169 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2170 SourceLocation LParenLoc,
2171 SourceLocation EndLoc) {
2172 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2173 EndLoc);
2176 /// Build a new OpenMP 'dist_schedule' clause.
2178 /// By default, performs semantic analysis to build the new OpenMP clause.
2179 /// Subclasses may override this routine to provide different behavior.
2180 OMPClause *
2181 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2182 Expr *ChunkSize, SourceLocation StartLoc,
2183 SourceLocation LParenLoc, SourceLocation KindLoc,
2184 SourceLocation CommaLoc, SourceLocation EndLoc) {
2185 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2186 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2189 /// Build a new OpenMP 'to' clause.
2191 /// By default, performs semantic analysis to build the new statement.
2192 /// Subclasses may override this routine to provide different behavior.
2193 OMPClause *
2194 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2195 ArrayRef<SourceLocation> MotionModifiersLoc,
2196 CXXScopeSpec &MapperIdScopeSpec,
2197 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2198 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2199 ArrayRef<Expr *> UnresolvedMappers) {
2200 return getSema().OpenMP().ActOnOpenMPToClause(
2201 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2202 ColonLoc, VarList, Locs, UnresolvedMappers);
2205 /// Build a new OpenMP 'from' clause.
2207 /// By default, performs semantic analysis to build the new statement.
2208 /// Subclasses may override this routine to provide different behavior.
2209 OMPClause *
2210 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2211 ArrayRef<SourceLocation> MotionModifiersLoc,
2212 CXXScopeSpec &MapperIdScopeSpec,
2213 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2214 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2215 ArrayRef<Expr *> UnresolvedMappers) {
2216 return getSema().OpenMP().ActOnOpenMPFromClause(
2217 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2218 ColonLoc, VarList, Locs, UnresolvedMappers);
2221 /// Build a new OpenMP 'use_device_ptr' clause.
2223 /// By default, performs semantic analysis to build the new OpenMP clause.
2224 /// Subclasses may override this routine to provide different behavior.
2225 OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
2226 const OMPVarListLocTy &Locs) {
2227 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2230 /// Build a new OpenMP 'use_device_addr' clause.
2232 /// By default, performs semantic analysis to build the new OpenMP clause.
2233 /// Subclasses may override this routine to provide different behavior.
2234 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2235 const OMPVarListLocTy &Locs) {
2236 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2239 /// Build a new OpenMP 'is_device_ptr' clause.
2241 /// By default, performs semantic analysis to build the new OpenMP clause.
2242 /// Subclasses may override this routine to provide different behavior.
2243 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2244 const OMPVarListLocTy &Locs) {
2245 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2248 /// Build a new OpenMP 'has_device_addr' clause.
2250 /// By default, performs semantic analysis to build the new OpenMP clause.
2251 /// Subclasses may override this routine to provide different behavior.
2252 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2253 const OMPVarListLocTy &Locs) {
2254 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2257 /// Build a new OpenMP 'defaultmap' clause.
2259 /// By default, performs semantic analysis to build the new OpenMP clause.
2260 /// Subclasses may override this routine to provide different behavior.
2261 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2262 OpenMPDefaultmapClauseKind Kind,
2263 SourceLocation StartLoc,
2264 SourceLocation LParenLoc,
2265 SourceLocation MLoc,
2266 SourceLocation KindLoc,
2267 SourceLocation EndLoc) {
2268 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2269 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2272 /// Build a new OpenMP 'nontemporal' clause.
2274 /// By default, performs semantic analysis to build the new OpenMP clause.
2275 /// Subclasses may override this routine to provide different behavior.
2276 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2277 SourceLocation StartLoc,
2278 SourceLocation LParenLoc,
2279 SourceLocation EndLoc) {
2280 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2281 LParenLoc, EndLoc);
2284 /// Build a new OpenMP 'inclusive' clause.
2286 /// By default, performs semantic analysis to build the new OpenMP clause.
2287 /// Subclasses may override this routine to provide different behavior.
2288 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2289 SourceLocation StartLoc,
2290 SourceLocation LParenLoc,
2291 SourceLocation EndLoc) {
2292 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2293 LParenLoc, EndLoc);
2296 /// Build a new OpenMP 'exclusive' clause.
2298 /// By default, performs semantic analysis to build the new OpenMP clause.
2299 /// Subclasses may override this routine to provide different behavior.
2300 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2301 SourceLocation StartLoc,
2302 SourceLocation LParenLoc,
2303 SourceLocation EndLoc) {
2304 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2305 LParenLoc, EndLoc);
2308 /// Build a new OpenMP 'uses_allocators' clause.
2310 /// By default, performs semantic analysis to build the new OpenMP clause.
2311 /// Subclasses may override this routine to provide different behavior.
2312 OMPClause *RebuildOMPUsesAllocatorsClause(
2313 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2314 SourceLocation LParenLoc, SourceLocation EndLoc) {
2315 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2316 StartLoc, LParenLoc, EndLoc, Data);
2319 /// Build a new OpenMP 'affinity' clause.
2321 /// By default, performs semantic analysis to build the new OpenMP clause.
2322 /// Subclasses may override this routine to provide different behavior.
2323 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2324 SourceLocation LParenLoc,
2325 SourceLocation ColonLoc,
2326 SourceLocation EndLoc, Expr *Modifier,
2327 ArrayRef<Expr *> Locators) {
2328 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2329 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2332 /// Build a new OpenMP 'order' clause.
2334 /// By default, performs semantic analysis to build the new OpenMP clause.
2335 /// Subclasses may override this routine to provide different behavior.
2336 OMPClause *RebuildOMPOrderClause(
2337 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2338 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2339 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2340 return getSema().OpenMP().ActOnOpenMPOrderClause(
2341 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2344 /// Build a new OpenMP 'init' clause.
2346 /// By default, performs semantic analysis to build the new OpenMP clause.
2347 /// Subclasses may override this routine to provide different behavior.
2348 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2349 SourceLocation StartLoc,
2350 SourceLocation LParenLoc,
2351 SourceLocation VarLoc,
2352 SourceLocation EndLoc) {
2353 return getSema().OpenMP().ActOnOpenMPInitClause(
2354 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2357 /// Build a new OpenMP 'use' clause.
2359 /// By default, performs semantic analysis to build the new OpenMP clause.
2360 /// Subclasses may override this routine to provide different behavior.
2361 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2362 SourceLocation LParenLoc,
2363 SourceLocation VarLoc, SourceLocation EndLoc) {
2364 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2365 LParenLoc, VarLoc, EndLoc);
2368 /// Build a new OpenMP 'destroy' clause.
2370 /// By default, performs semantic analysis to build the new OpenMP clause.
2371 /// Subclasses may override this routine to provide different behavior.
2372 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2373 SourceLocation LParenLoc,
2374 SourceLocation VarLoc,
2375 SourceLocation EndLoc) {
2376 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2377 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2380 /// Build a new OpenMP 'novariants' clause.
2382 /// By default, performs semantic analysis to build the new OpenMP clause.
2383 /// Subclasses may override this routine to provide different behavior.
2384 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2385 SourceLocation StartLoc,
2386 SourceLocation LParenLoc,
2387 SourceLocation EndLoc) {
2388 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2389 LParenLoc, EndLoc);
2392 /// Build a new OpenMP 'nocontext' clause.
2394 /// By default, performs semantic analysis to build the new OpenMP clause.
2395 /// Subclasses may override this routine to provide different behavior.
2396 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2397 SourceLocation LParenLoc,
2398 SourceLocation EndLoc) {
2399 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2400 LParenLoc, EndLoc);
2403 /// Build a new OpenMP 'filter' clause.
2405 /// By default, performs semantic analysis to build the new OpenMP clause.
2406 /// Subclasses may override this routine to provide different behavior.
2407 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2408 SourceLocation LParenLoc,
2409 SourceLocation EndLoc) {
2410 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2411 LParenLoc, EndLoc);
2414 /// Build a new OpenMP 'bind' clause.
2416 /// By default, performs semantic analysis to build the new OpenMP clause.
2417 /// Subclasses may override this routine to provide different behavior.
2418 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2419 SourceLocation KindLoc,
2420 SourceLocation StartLoc,
2421 SourceLocation LParenLoc,
2422 SourceLocation EndLoc) {
2423 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2424 LParenLoc, EndLoc);
2427 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2429 /// By default, performs semantic analysis to build the new OpenMP clause.
2430 /// Subclasses may override this routine to provide different behavior.
2431 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2432 SourceLocation LParenLoc,
2433 SourceLocation EndLoc) {
2434 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2435 LParenLoc, EndLoc);
2438 /// Build a new OpenMP 'ompx_attribute' clause.
2440 /// By default, performs semantic analysis to build the new OpenMP clause.
2441 /// Subclasses may override this routine to provide different behavior.
2442 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2443 SourceLocation StartLoc,
2444 SourceLocation LParenLoc,
2445 SourceLocation EndLoc) {
2446 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2447 LParenLoc, EndLoc);
2450 /// Build a new OpenMP 'ompx_bare' clause.
2452 /// By default, performs semantic analysis to build the new OpenMP clause.
2453 /// Subclasses may override this routine to provide different behavior.
2454 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2455 SourceLocation EndLoc) {
2456 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2459 /// Build a new OpenMP 'align' clause.
2461 /// By default, performs semantic analysis to build the new OpenMP clause.
2462 /// Subclasses may override this routine to provide different behavior.
2463 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2464 SourceLocation LParenLoc,
2465 SourceLocation EndLoc) {
2466 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2467 EndLoc);
2470 /// Build a new OpenMP 'at' clause.
2472 /// By default, performs semantic analysis to build the new OpenMP clause.
2473 /// Subclasses may override this routine to provide different behavior.
2474 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2475 SourceLocation StartLoc,
2476 SourceLocation LParenLoc,
2477 SourceLocation EndLoc) {
2478 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2479 LParenLoc, EndLoc);
2482 /// Build a new OpenMP 'severity' clause.
2484 /// By default, performs semantic analysis to build the new OpenMP clause.
2485 /// Subclasses may override this routine to provide different behavior.
2486 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2487 SourceLocation KwLoc,
2488 SourceLocation StartLoc,
2489 SourceLocation LParenLoc,
2490 SourceLocation EndLoc) {
2491 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2492 LParenLoc, EndLoc);
2495 /// Build a new OpenMP 'message' clause.
2497 /// By default, performs semantic analysis to build the new OpenMP clause.
2498 /// Subclasses may override this routine to provide different behavior.
2499 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2500 SourceLocation LParenLoc,
2501 SourceLocation EndLoc) {
2502 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2503 EndLoc);
2506 /// Build a new OpenMP 'doacross' clause.
2508 /// By default, performs semantic analysis to build the new OpenMP clause.
2509 /// Subclasses may override this routine to provide different behavior.
2510 OMPClause *
2511 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2512 SourceLocation DepLoc, SourceLocation ColonLoc,
2513 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2514 SourceLocation LParenLoc, SourceLocation EndLoc) {
2515 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2516 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2519 /// Build a new OpenMP 'holds' clause.
2520 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,
2521 SourceLocation LParenLoc,
2522 SourceLocation EndLoc) {
2523 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2524 EndLoc);
2527 /// Rebuild the operand to an Objective-C \@synchronized statement.
2529 /// By default, performs semantic analysis to build the new statement.
2530 /// Subclasses may override this routine to provide different behavior.
2531 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2532 Expr *object) {
2533 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2536 /// Build a new Objective-C \@synchronized statement.
2538 /// By default, performs semantic analysis to build the new statement.
2539 /// Subclasses may override this routine to provide different behavior.
2540 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2541 Expr *Object, Stmt *Body) {
2542 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2545 /// Build a new Objective-C \@autoreleasepool statement.
2547 /// By default, performs semantic analysis to build the new statement.
2548 /// Subclasses may override this routine to provide different behavior.
2549 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2550 Stmt *Body) {
2551 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2554 /// Build a new Objective-C fast enumeration statement.
2556 /// By default, performs semantic analysis to build the new statement.
2557 /// Subclasses may override this routine to provide different behavior.
2558 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2559 Stmt *Element,
2560 Expr *Collection,
2561 SourceLocation RParenLoc,
2562 Stmt *Body) {
2563 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2564 ForLoc, Element, Collection, RParenLoc);
2565 if (ForEachStmt.isInvalid())
2566 return StmtError();
2568 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2569 Body);
2572 /// Build a new C++ exception declaration.
2574 /// By default, performs semantic analysis to build the new decaration.
2575 /// Subclasses may override this routine to provide different behavior.
2576 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2577 TypeSourceInfo *Declarator,
2578 SourceLocation StartLoc,
2579 SourceLocation IdLoc,
2580 IdentifierInfo *Id) {
2581 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2582 StartLoc, IdLoc, Id);
2583 if (Var)
2584 getSema().CurContext->addDecl(Var);
2585 return Var;
2588 /// Build a new C++ catch statement.
2590 /// By default, performs semantic analysis to build the new statement.
2591 /// Subclasses may override this routine to provide different behavior.
2592 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2593 VarDecl *ExceptionDecl,
2594 Stmt *Handler) {
2595 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2596 Handler));
2599 /// Build a new C++ try statement.
2601 /// By default, performs semantic analysis to build the new statement.
2602 /// Subclasses may override this routine to provide different behavior.
2603 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2604 ArrayRef<Stmt *> Handlers) {
2605 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2608 /// Build a new C++0x range-based for statement.
2610 /// By default, performs semantic analysis to build the new statement.
2611 /// Subclasses may override this routine to provide different behavior.
2612 StmtResult RebuildCXXForRangeStmt(
2613 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2614 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2615 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2616 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2617 // If we've just learned that the range is actually an Objective-C
2618 // collection, treat this as an Objective-C fast enumeration loop.
2619 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
2620 if (RangeStmt->isSingleDecl()) {
2621 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
2622 if (RangeVar->isInvalidDecl())
2623 return StmtError();
2625 Expr *RangeExpr = RangeVar->getInit();
2626 if (!RangeExpr->isTypeDependent() &&
2627 RangeExpr->getType()->isObjCObjectPointerType()) {
2628 // FIXME: Support init-statements in Objective-C++20 ranged for
2629 // statement.
2630 if (Init) {
2631 return SemaRef.Diag(Init->getBeginLoc(),
2632 diag::err_objc_for_range_init_stmt)
2633 << Init->getSourceRange();
2635 return getSema().ObjC().ActOnObjCForCollectionStmt(
2636 ForLoc, LoopVar, RangeExpr, RParenLoc);
2642 return getSema().BuildCXXForRangeStmt(
2643 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2644 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2647 /// Build a new C++0x range-based for statement.
2649 /// By default, performs semantic analysis to build the new statement.
2650 /// Subclasses may override this routine to provide different behavior.
2651 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2652 bool IsIfExists,
2653 NestedNameSpecifierLoc QualifierLoc,
2654 DeclarationNameInfo NameInfo,
2655 Stmt *Nested) {
2656 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2657 QualifierLoc, NameInfo, Nested);
2660 /// Attach body to a C++0x range-based for statement.
2662 /// By default, performs semantic analysis to finish the new statement.
2663 /// Subclasses may override this routine to provide different behavior.
2664 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2665 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2668 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2669 Stmt *TryBlock, Stmt *Handler) {
2670 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2673 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2674 Stmt *Block) {
2675 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2678 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2679 return SEHFinallyStmt::Create(getSema().getASTContext(), Loc, Block);
2682 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2683 SourceLocation LParen,
2684 SourceLocation RParen,
2685 TypeSourceInfo *TSI) {
2686 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2687 TSI);
2690 /// Build a new predefined expression.
2692 /// By default, performs semantic analysis to build the new expression.
2693 /// Subclasses may override this routine to provide different behavior.
2694 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2695 return getSema().BuildPredefinedExpr(Loc, IK);
2698 /// Build a new expression that references a declaration.
2700 /// By default, performs semantic analysis to build the new expression.
2701 /// Subclasses may override this routine to provide different behavior.
2702 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2703 LookupResult &R,
2704 bool RequiresADL) {
2705 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2709 /// Build a new expression that references a declaration.
2711 /// By default, performs semantic analysis to build the new expression.
2712 /// Subclasses may override this routine to provide different behavior.
2713 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2714 ValueDecl *VD,
2715 const DeclarationNameInfo &NameInfo,
2716 NamedDecl *Found,
2717 TemplateArgumentListInfo *TemplateArgs) {
2718 CXXScopeSpec SS;
2719 SS.Adopt(QualifierLoc);
2720 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2721 TemplateArgs);
2724 /// Build a new expression in parentheses.
2726 /// By default, performs semantic analysis to build the new expression.
2727 /// Subclasses may override this routine to provide different behavior.
2728 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2729 SourceLocation RParen) {
2730 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2733 /// Build a new pseudo-destructor expression.
2735 /// By default, performs semantic analysis to build the new expression.
2736 /// Subclasses may override this routine to provide different behavior.
2737 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2738 SourceLocation OperatorLoc,
2739 bool isArrow,
2740 CXXScopeSpec &SS,
2741 TypeSourceInfo *ScopeType,
2742 SourceLocation CCLoc,
2743 SourceLocation TildeLoc,
2744 PseudoDestructorTypeStorage Destroyed);
2746 /// Build a new unary operator expression.
2748 /// By default, performs semantic analysis to build the new expression.
2749 /// Subclasses may override this routine to provide different behavior.
2750 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2751 UnaryOperatorKind Opc,
2752 Expr *SubExpr) {
2753 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2756 /// Build a new builtin offsetof expression.
2758 /// By default, performs semantic analysis to build the new expression.
2759 /// Subclasses may override this routine to provide different behavior.
2760 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2761 TypeSourceInfo *Type,
2762 ArrayRef<Sema::OffsetOfComponent> Components,
2763 SourceLocation RParenLoc) {
2764 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2765 RParenLoc);
2768 /// Build a new sizeof, alignof or vec_step expression with a
2769 /// type argument.
2771 /// By default, performs semantic analysis to build the new expression.
2772 /// Subclasses may override this routine to provide different behavior.
2773 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2774 SourceLocation OpLoc,
2775 UnaryExprOrTypeTrait ExprKind,
2776 SourceRange R) {
2777 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2780 /// Build a new sizeof, alignof or vec step expression with an
2781 /// expression argument.
2783 /// By default, performs semantic analysis to build the new expression.
2784 /// Subclasses may override this routine to provide different behavior.
2785 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2786 UnaryExprOrTypeTrait ExprKind,
2787 SourceRange R) {
2788 ExprResult Result
2789 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2790 if (Result.isInvalid())
2791 return ExprError();
2793 return Result;
2796 /// Build a new array subscript expression.
2798 /// By default, performs semantic analysis to build the new expression.
2799 /// Subclasses may override this routine to provide different behavior.
2800 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2801 SourceLocation LBracketLoc,
2802 Expr *RHS,
2803 SourceLocation RBracketLoc) {
2804 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2805 LBracketLoc, RHS,
2806 RBracketLoc);
2809 /// Build a new matrix subscript expression.
2811 /// By default, performs semantic analysis to build the new expression.
2812 /// Subclasses may override this routine to provide different behavior.
2813 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2814 Expr *ColumnIdx,
2815 SourceLocation RBracketLoc) {
2816 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2817 RBracketLoc);
2820 /// Build a new array section expression.
2822 /// By default, performs semantic analysis to build the new expression.
2823 /// Subclasses may override this routine to provide different behavior.
2824 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2825 SourceLocation LBracketLoc,
2826 Expr *LowerBound,
2827 SourceLocation ColonLocFirst,
2828 SourceLocation ColonLocSecond,
2829 Expr *Length, Expr *Stride,
2830 SourceLocation RBracketLoc) {
2831 if (IsOMPArraySection)
2832 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2833 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2834 Stride, RBracketLoc);
2836 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2837 "Stride/second colon not allowed for OpenACC");
2839 return getSema().OpenACC().ActOnArraySectionExpr(
2840 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2843 /// Build a new array shaping expression.
2845 /// By default, performs semantic analysis to build the new expression.
2846 /// Subclasses may override this routine to provide different behavior.
2847 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2848 SourceLocation RParenLoc,
2849 ArrayRef<Expr *> Dims,
2850 ArrayRef<SourceRange> BracketsRanges) {
2851 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2852 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2855 /// Build a new iterator expression.
2857 /// By default, performs semantic analysis to build the new expression.
2858 /// Subclasses may override this routine to provide different behavior.
2859 ExprResult
2860 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2861 SourceLocation RLoc,
2862 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2863 return getSema().OpenMP().ActOnOMPIteratorExpr(
2864 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2867 /// Build a new call expression.
2869 /// By default, performs semantic analysis to build the new expression.
2870 /// Subclasses may override this routine to provide different behavior.
2871 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2872 MultiExprArg Args,
2873 SourceLocation RParenLoc,
2874 Expr *ExecConfig = nullptr) {
2875 return getSema().ActOnCallExpr(
2876 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2879 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2880 MultiExprArg Args,
2881 SourceLocation RParenLoc) {
2882 return getSema().ActOnArraySubscriptExpr(
2883 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2886 /// Build a new member access expression.
2888 /// By default, performs semantic analysis to build the new expression.
2889 /// Subclasses may override this routine to provide different behavior.
2890 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2891 bool isArrow,
2892 NestedNameSpecifierLoc QualifierLoc,
2893 SourceLocation TemplateKWLoc,
2894 const DeclarationNameInfo &MemberNameInfo,
2895 ValueDecl *Member,
2896 NamedDecl *FoundDecl,
2897 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2898 NamedDecl *FirstQualifierInScope) {
2899 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2900 isArrow);
2901 if (!Member->getDeclName()) {
2902 // We have a reference to an unnamed field. This is always the
2903 // base of an anonymous struct/union member access, i.e. the
2904 // field is always of record type.
2905 assert(Member->getType()->isRecordType() &&
2906 "unnamed member not of record type?");
2908 BaseResult =
2909 getSema().PerformObjectMemberConversion(BaseResult.get(),
2910 QualifierLoc.getNestedNameSpecifier(),
2911 FoundDecl, Member);
2912 if (BaseResult.isInvalid())
2913 return ExprError();
2914 Base = BaseResult.get();
2916 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
2917 // from the AST, so we need to re-insert them if needed (since
2918 // `BuildFieldRefereneExpr()` doesn't do this).
2919 if (!isArrow && Base->isPRValue()) {
2920 BaseResult = getSema().TemporaryMaterializationConversion(Base);
2921 if (BaseResult.isInvalid())
2922 return ExprError();
2923 Base = BaseResult.get();
2926 CXXScopeSpec EmptySS;
2927 return getSema().BuildFieldReferenceExpr(
2928 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
2929 DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()),
2930 MemberNameInfo);
2933 CXXScopeSpec SS;
2934 SS.Adopt(QualifierLoc);
2936 Base = BaseResult.get();
2937 if (Base->containsErrors())
2938 return ExprError();
2940 QualType BaseType = Base->getType();
2942 if (isArrow && !BaseType->isPointerType())
2943 return ExprError();
2945 // FIXME: this involves duplicating earlier analysis in a lot of
2946 // cases; we should avoid this when possible.
2947 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2948 R.addDecl(FoundDecl);
2949 R.resolveKind();
2951 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2952 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {
2953 if (auto *ThisClass = cast<CXXThisExpr>(Base)
2954 ->getType()
2955 ->getPointeeType()
2956 ->getAsCXXRecordDecl()) {
2957 auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());
2958 // In unevaluated contexts, an expression supposed to be a member access
2959 // might reference a member in an unrelated class.
2960 if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))
2961 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2962 VK_LValue, Member->getLocation());
2966 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2967 SS, TemplateKWLoc,
2968 FirstQualifierInScope,
2969 R, ExplicitTemplateArgs,
2970 /*S*/nullptr);
2973 /// Build a new binary operator expression.
2975 /// By default, performs semantic analysis to build the new expression.
2976 /// Subclasses may override this routine to provide different behavior.
2977 ExprResult RebuildBinaryOperator(SourceLocation OpLoc,
2978 BinaryOperatorKind Opc,
2979 Expr *LHS, Expr *RHS) {
2980 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS);
2983 /// Build a new rewritten operator expression.
2985 /// By default, performs semantic analysis to build the new expression.
2986 /// Subclasses may override this routine to provide different behavior.
2987 ExprResult RebuildCXXRewrittenBinaryOperator(
2988 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2989 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2990 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2991 RHS, /*RequiresADL*/false);
2994 /// Build a new conditional operator expression.
2996 /// By default, performs semantic analysis to build the new expression.
2997 /// Subclasses may override this routine to provide different behavior.
2998 ExprResult RebuildConditionalOperator(Expr *Cond,
2999 SourceLocation QuestionLoc,
3000 Expr *LHS,
3001 SourceLocation ColonLoc,
3002 Expr *RHS) {
3003 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
3004 LHS, RHS);
3007 /// Build a new C-style cast expression.
3009 /// By default, performs semantic analysis to build the new expression.
3010 /// Subclasses may override this routine to provide different behavior.
3011 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
3012 TypeSourceInfo *TInfo,
3013 SourceLocation RParenLoc,
3014 Expr *SubExpr) {
3015 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3016 SubExpr);
3019 /// Build a new compound literal expression.
3021 /// By default, performs semantic analysis to build the new expression.
3022 /// Subclasses may override this routine to provide different behavior.
3023 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
3024 TypeSourceInfo *TInfo,
3025 SourceLocation RParenLoc,
3026 Expr *Init) {
3027 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3028 Init);
3031 /// Build a new extended vector element access expression.
3033 /// By default, performs semantic analysis to build the new expression.
3034 /// Subclasses may override this routine to provide different behavior.
3035 ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,
3036 bool IsArrow,
3037 SourceLocation AccessorLoc,
3038 IdentifierInfo &Accessor) {
3040 CXXScopeSpec SS;
3041 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3042 return getSema().BuildMemberReferenceExpr(
3043 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3044 /*FirstQualifierInScope*/ nullptr, NameInfo,
3045 /* TemplateArgs */ nullptr,
3046 /*S*/ nullptr);
3049 /// Build a new initializer list expression.
3051 /// By default, performs semantic analysis to build the new expression.
3052 /// Subclasses may override this routine to provide different behavior.
3053 ExprResult RebuildInitList(SourceLocation LBraceLoc,
3054 MultiExprArg Inits,
3055 SourceLocation RBraceLoc) {
3056 return SemaRef.BuildInitList(LBraceLoc, Inits, RBraceLoc);
3059 /// Build a new designated initializer expression.
3061 /// By default, performs semantic analysis to build the new expression.
3062 /// Subclasses may override this routine to provide different behavior.
3063 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3064 MultiExprArg ArrayExprs,
3065 SourceLocation EqualOrColonLoc,
3066 bool GNUSyntax,
3067 Expr *Init) {
3068 ExprResult Result
3069 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3070 Init);
3071 if (Result.isInvalid())
3072 return ExprError();
3074 return Result;
3077 /// Build a new value-initialized expression.
3079 /// By default, builds the implicit value initialization without performing
3080 /// any semantic analysis. Subclasses may override this routine to provide
3081 /// different behavior.
3082 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3083 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3086 /// Build a new \c va_arg expression.
3088 /// By default, performs semantic analysis to build the new expression.
3089 /// Subclasses may override this routine to provide different behavior.
3090 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3091 Expr *SubExpr, TypeSourceInfo *TInfo,
3092 SourceLocation RParenLoc) {
3093 return getSema().BuildVAArgExpr(BuiltinLoc,
3094 SubExpr, TInfo,
3095 RParenLoc);
3098 /// Build a new expression list in parentheses.
3100 /// By default, performs semantic analysis to build the new expression.
3101 /// Subclasses may override this routine to provide different behavior.
3102 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3103 MultiExprArg SubExprs,
3104 SourceLocation RParenLoc) {
3105 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3108 /// Build a new address-of-label expression.
3110 /// By default, performs semantic analysis, using the name of the label
3111 /// rather than attempting to map the label statement itself.
3112 /// Subclasses may override this routine to provide different behavior.
3113 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3114 SourceLocation LabelLoc, LabelDecl *Label) {
3115 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3118 /// Build a new GNU statement expression.
3120 /// By default, performs semantic analysis to build the new expression.
3121 /// Subclasses may override this routine to provide different behavior.
3122 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3123 SourceLocation RParenLoc, unsigned TemplateDepth) {
3124 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3125 TemplateDepth);
3128 /// Build a new __builtin_choose_expr expression.
3130 /// By default, performs semantic analysis to build the new expression.
3131 /// Subclasses may override this routine to provide different behavior.
3132 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3133 Expr *Cond, Expr *LHS, Expr *RHS,
3134 SourceLocation RParenLoc) {
3135 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3136 Cond, LHS, RHS,
3137 RParenLoc);
3140 /// Build a new generic selection expression with an expression predicate.
3142 /// By default, performs semantic analysis to build the new expression.
3143 /// Subclasses may override this routine to provide different behavior.
3144 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3145 SourceLocation DefaultLoc,
3146 SourceLocation RParenLoc,
3147 Expr *ControllingExpr,
3148 ArrayRef<TypeSourceInfo *> Types,
3149 ArrayRef<Expr *> Exprs) {
3150 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3151 /*PredicateIsExpr=*/true,
3152 ControllingExpr, Types, Exprs);
3155 /// Build a new generic selection expression with a type predicate.
3157 /// By default, performs semantic analysis to build the new expression.
3158 /// Subclasses may override this routine to provide different behavior.
3159 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3160 SourceLocation DefaultLoc,
3161 SourceLocation RParenLoc,
3162 TypeSourceInfo *ControllingType,
3163 ArrayRef<TypeSourceInfo *> Types,
3164 ArrayRef<Expr *> Exprs) {
3165 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3166 /*PredicateIsExpr=*/false,
3167 ControllingType, Types, Exprs);
3170 /// Build a new overloaded operator call expression.
3172 /// By default, performs semantic analysis to build the new expression.
3173 /// The semantic analysis provides the behavior of template instantiation,
3174 /// copying with transformations that turn what looks like an overloaded
3175 /// operator call into a use of a builtin operator, performing
3176 /// argument-dependent lookup, etc. Subclasses may override this routine to
3177 /// provide different behavior.
3178 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3179 SourceLocation OpLoc,
3180 SourceLocation CalleeLoc,
3181 bool RequiresADL,
3182 const UnresolvedSetImpl &Functions,
3183 Expr *First, Expr *Second);
3185 /// Build a new C++ "named" cast expression, such as static_cast or
3186 /// reinterpret_cast.
3188 /// By default, this routine dispatches to one of the more-specific routines
3189 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3190 /// Subclasses may override this routine to provide different behavior.
3191 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3192 Stmt::StmtClass Class,
3193 SourceLocation LAngleLoc,
3194 TypeSourceInfo *TInfo,
3195 SourceLocation RAngleLoc,
3196 SourceLocation LParenLoc,
3197 Expr *SubExpr,
3198 SourceLocation RParenLoc) {
3199 switch (Class) {
3200 case Stmt::CXXStaticCastExprClass:
3201 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3202 RAngleLoc, LParenLoc,
3203 SubExpr, RParenLoc);
3205 case Stmt::CXXDynamicCastExprClass:
3206 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3207 RAngleLoc, LParenLoc,
3208 SubExpr, RParenLoc);
3210 case Stmt::CXXReinterpretCastExprClass:
3211 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3212 RAngleLoc, LParenLoc,
3213 SubExpr,
3214 RParenLoc);
3216 case Stmt::CXXConstCastExprClass:
3217 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3218 RAngleLoc, LParenLoc,
3219 SubExpr, RParenLoc);
3221 case Stmt::CXXAddrspaceCastExprClass:
3222 return getDerived().RebuildCXXAddrspaceCastExpr(
3223 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3225 default:
3226 llvm_unreachable("Invalid C++ named cast");
3230 /// Build a new C++ static_cast expression.
3232 /// By default, performs semantic analysis to build the new expression.
3233 /// Subclasses may override this routine to provide different behavior.
3234 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3235 SourceLocation LAngleLoc,
3236 TypeSourceInfo *TInfo,
3237 SourceLocation RAngleLoc,
3238 SourceLocation LParenLoc,
3239 Expr *SubExpr,
3240 SourceLocation RParenLoc) {
3241 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3242 TInfo, SubExpr,
3243 SourceRange(LAngleLoc, RAngleLoc),
3244 SourceRange(LParenLoc, RParenLoc));
3247 /// Build a new C++ dynamic_cast expression.
3249 /// By default, performs semantic analysis to build the new expression.
3250 /// Subclasses may override this routine to provide different behavior.
3251 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3252 SourceLocation LAngleLoc,
3253 TypeSourceInfo *TInfo,
3254 SourceLocation RAngleLoc,
3255 SourceLocation LParenLoc,
3256 Expr *SubExpr,
3257 SourceLocation RParenLoc) {
3258 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3259 TInfo, SubExpr,
3260 SourceRange(LAngleLoc, RAngleLoc),
3261 SourceRange(LParenLoc, RParenLoc));
3264 /// Build a new C++ reinterpret_cast expression.
3266 /// By default, performs semantic analysis to build the new expression.
3267 /// Subclasses may override this routine to provide different behavior.
3268 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3269 SourceLocation LAngleLoc,
3270 TypeSourceInfo *TInfo,
3271 SourceLocation RAngleLoc,
3272 SourceLocation LParenLoc,
3273 Expr *SubExpr,
3274 SourceLocation RParenLoc) {
3275 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3276 TInfo, SubExpr,
3277 SourceRange(LAngleLoc, RAngleLoc),
3278 SourceRange(LParenLoc, RParenLoc));
3281 /// Build a new C++ const_cast expression.
3283 /// By default, performs semantic analysis to build the new expression.
3284 /// Subclasses may override this routine to provide different behavior.
3285 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3286 SourceLocation LAngleLoc,
3287 TypeSourceInfo *TInfo,
3288 SourceLocation RAngleLoc,
3289 SourceLocation LParenLoc,
3290 Expr *SubExpr,
3291 SourceLocation RParenLoc) {
3292 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3293 TInfo, SubExpr,
3294 SourceRange(LAngleLoc, RAngleLoc),
3295 SourceRange(LParenLoc, RParenLoc));
3298 ExprResult
3299 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3300 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3301 SourceLocation LParenLoc, Expr *SubExpr,
3302 SourceLocation RParenLoc) {
3303 return getSema().BuildCXXNamedCast(
3304 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3305 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3308 /// Build a new C++ functional-style cast expression.
3310 /// By default, performs semantic analysis to build the new expression.
3311 /// Subclasses may override this routine to provide different behavior.
3312 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3313 SourceLocation LParenLoc,
3314 Expr *Sub,
3315 SourceLocation RParenLoc,
3316 bool ListInitialization) {
3317 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3318 // CXXParenListInitExpr. Pass its expanded arguments so that the
3319 // CXXParenListInitExpr can be rebuilt.
3320 if (auto *PLE = dyn_cast<ParenListExpr>(Sub))
3321 return getSema().BuildCXXTypeConstructExpr(
3322 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3323 RParenLoc, ListInitialization);
3324 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3325 MultiExprArg(&Sub, 1), RParenLoc,
3326 ListInitialization);
3329 /// Build a new C++ __builtin_bit_cast expression.
3331 /// By default, performs semantic analysis to build the new expression.
3332 /// Subclasses may override this routine to provide different behavior.
3333 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3334 TypeSourceInfo *TSI, Expr *Sub,
3335 SourceLocation RParenLoc) {
3336 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3339 /// Build a new C++ typeid(type) expression.
3341 /// By default, performs semantic analysis to build the new expression.
3342 /// Subclasses may override this routine to provide different behavior.
3343 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3344 SourceLocation TypeidLoc,
3345 TypeSourceInfo *Operand,
3346 SourceLocation RParenLoc) {
3347 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3348 RParenLoc);
3352 /// Build a new C++ typeid(expr) expression.
3354 /// By default, performs semantic analysis to build the new expression.
3355 /// Subclasses may override this routine to provide different behavior.
3356 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3357 SourceLocation TypeidLoc,
3358 Expr *Operand,
3359 SourceLocation RParenLoc) {
3360 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3361 RParenLoc);
3364 /// Build a new C++ __uuidof(type) expression.
3366 /// By default, performs semantic analysis to build the new expression.
3367 /// Subclasses may override this routine to provide different behavior.
3368 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3369 TypeSourceInfo *Operand,
3370 SourceLocation RParenLoc) {
3371 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3374 /// Build a new C++ __uuidof(expr) expression.
3376 /// By default, performs semantic analysis to build the new expression.
3377 /// Subclasses may override this routine to provide different behavior.
3378 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3379 Expr *Operand, SourceLocation RParenLoc) {
3380 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3383 /// Build a new C++ "this" expression.
3385 /// By default, performs semantic analysis to build a new "this" expression.
3386 /// Subclasses may override this routine to provide different behavior.
3387 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3388 QualType ThisType,
3389 bool isImplicit) {
3390 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3391 return ExprError();
3392 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3395 /// Build a new C++ throw expression.
3397 /// By default, performs semantic analysis to build the new expression.
3398 /// Subclasses may override this routine to provide different behavior.
3399 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3400 bool IsThrownVariableInScope) {
3401 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3404 /// Build a new C++ default-argument expression.
3406 /// By default, builds a new default-argument expression, which does not
3407 /// require any semantic analysis. Subclasses may override this routine to
3408 /// provide different behavior.
3409 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3410 Expr *RewrittenExpr) {
3411 return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param,
3412 RewrittenExpr, getSema().CurContext);
3415 /// Build a new C++11 default-initialization expression.
3417 /// By default, builds a new default field initialization expression, which
3418 /// does not require any semantic analysis. Subclasses may override this
3419 /// routine to provide different behavior.
3420 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3421 FieldDecl *Field) {
3422 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3425 /// Build a new C++ zero-initialization expression.
3427 /// By default, performs semantic analysis to build the new expression.
3428 /// Subclasses may override this routine to provide different behavior.
3429 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3430 SourceLocation LParenLoc,
3431 SourceLocation RParenLoc) {
3432 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3433 /*ListInitialization=*/false);
3436 /// Build a new C++ "new" expression.
3438 /// By default, performs semantic analysis to build the new expression.
3439 /// Subclasses may override this routine to provide different behavior.
3440 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3441 SourceLocation PlacementLParen,
3442 MultiExprArg PlacementArgs,
3443 SourceLocation PlacementRParen,
3444 SourceRange TypeIdParens, QualType AllocatedType,
3445 TypeSourceInfo *AllocatedTypeInfo,
3446 std::optional<Expr *> ArraySize,
3447 SourceRange DirectInitRange, Expr *Initializer) {
3448 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3449 PlacementLParen,
3450 PlacementArgs,
3451 PlacementRParen,
3452 TypeIdParens,
3453 AllocatedType,
3454 AllocatedTypeInfo,
3455 ArraySize,
3456 DirectInitRange,
3457 Initializer);
3460 /// Build a new C++ "delete" expression.
3462 /// By default, performs semantic analysis to build the new expression.
3463 /// Subclasses may override this routine to provide different behavior.
3464 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3465 bool IsGlobalDelete,
3466 bool IsArrayForm,
3467 Expr *Operand) {
3468 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3469 Operand);
3472 /// Build a new type trait expression.
3474 /// By default, performs semantic analysis to build the new expression.
3475 /// Subclasses may override this routine to provide different behavior.
3476 ExprResult RebuildTypeTrait(TypeTrait Trait,
3477 SourceLocation StartLoc,
3478 ArrayRef<TypeSourceInfo *> Args,
3479 SourceLocation RParenLoc) {
3480 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3483 /// Build a new array type trait expression.
3485 /// By default, performs semantic analysis to build the new expression.
3486 /// Subclasses may override this routine to provide different behavior.
3487 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3488 SourceLocation StartLoc,
3489 TypeSourceInfo *TSInfo,
3490 Expr *DimExpr,
3491 SourceLocation RParenLoc) {
3492 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3495 /// Build a new expression trait expression.
3497 /// By default, performs semantic analysis to build the new expression.
3498 /// Subclasses may override this routine to provide different behavior.
3499 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3500 SourceLocation StartLoc,
3501 Expr *Queried,
3502 SourceLocation RParenLoc) {
3503 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3506 /// Build a new (previously unresolved) declaration reference
3507 /// expression.
3509 /// By default, performs semantic analysis to build the new expression.
3510 /// Subclasses may override this routine to provide different behavior.
3511 ExprResult RebuildDependentScopeDeclRefExpr(
3512 NestedNameSpecifierLoc QualifierLoc,
3513 SourceLocation TemplateKWLoc,
3514 const DeclarationNameInfo &NameInfo,
3515 const TemplateArgumentListInfo *TemplateArgs,
3516 bool IsAddressOfOperand,
3517 TypeSourceInfo **RecoveryTSI) {
3518 CXXScopeSpec SS;
3519 SS.Adopt(QualifierLoc);
3521 if (TemplateArgs || TemplateKWLoc.isValid())
3522 return getSema().BuildQualifiedTemplateIdExpr(
3523 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3525 return getSema().BuildQualifiedDeclarationNameExpr(
3526 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3529 /// Build a new template-id expression.
3531 /// By default, performs semantic analysis to build the new expression.
3532 /// Subclasses may override this routine to provide different behavior.
3533 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3534 SourceLocation TemplateKWLoc,
3535 LookupResult &R,
3536 bool RequiresADL,
3537 const TemplateArgumentListInfo *TemplateArgs) {
3538 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3539 TemplateArgs);
3542 /// Build a new object-construction expression.
3544 /// By default, performs semantic analysis to build the new expression.
3545 /// Subclasses may override this routine to provide different behavior.
3546 ExprResult RebuildCXXConstructExpr(
3547 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3548 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3549 bool ListInitialization, bool StdInitListInitialization,
3550 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3551 SourceRange ParenRange) {
3552 // Reconstruct the constructor we originally found, which might be
3553 // different if this is a call to an inherited constructor.
3554 CXXConstructorDecl *FoundCtor = Constructor;
3555 if (Constructor->isInheritingConstructor())
3556 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3558 SmallVector<Expr *, 8> ConvertedArgs;
3559 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3560 ConvertedArgs))
3561 return ExprError();
3563 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3564 IsElidable,
3565 ConvertedArgs,
3566 HadMultipleCandidates,
3567 ListInitialization,
3568 StdInitListInitialization,
3569 RequiresZeroInit, ConstructKind,
3570 ParenRange);
3573 /// Build a new implicit construction via inherited constructor
3574 /// expression.
3575 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3576 CXXConstructorDecl *Constructor,
3577 bool ConstructsVBase,
3578 bool InheritedFromVBase) {
3579 return new (getSema().Context) CXXInheritedCtorInitExpr(
3580 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3583 /// Build a new object-construction expression.
3585 /// By default, performs semantic analysis to build the new expression.
3586 /// Subclasses may override this routine to provide different behavior.
3587 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3588 SourceLocation LParenOrBraceLoc,
3589 MultiExprArg Args,
3590 SourceLocation RParenOrBraceLoc,
3591 bool ListInitialization) {
3592 return getSema().BuildCXXTypeConstructExpr(
3593 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3596 /// Build a new object-construction expression.
3598 /// By default, performs semantic analysis to build the new expression.
3599 /// Subclasses may override this routine to provide different behavior.
3600 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3601 SourceLocation LParenLoc,
3602 MultiExprArg Args,
3603 SourceLocation RParenLoc,
3604 bool ListInitialization) {
3605 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3606 RParenLoc, ListInitialization);
3609 /// Build a new member reference expression.
3611 /// By default, performs semantic analysis to build the new expression.
3612 /// Subclasses may override this routine to provide different behavior.
3613 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3614 QualType BaseType,
3615 bool IsArrow,
3616 SourceLocation OperatorLoc,
3617 NestedNameSpecifierLoc QualifierLoc,
3618 SourceLocation TemplateKWLoc,
3619 NamedDecl *FirstQualifierInScope,
3620 const DeclarationNameInfo &MemberNameInfo,
3621 const TemplateArgumentListInfo *TemplateArgs) {
3622 CXXScopeSpec SS;
3623 SS.Adopt(QualifierLoc);
3625 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3626 OperatorLoc, IsArrow,
3627 SS, TemplateKWLoc,
3628 FirstQualifierInScope,
3629 MemberNameInfo,
3630 TemplateArgs, /*S*/nullptr);
3633 /// Build a new member reference expression.
3635 /// By default, performs semantic analysis to build the new expression.
3636 /// Subclasses may override this routine to provide different behavior.
3637 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3638 SourceLocation OperatorLoc,
3639 bool IsArrow,
3640 NestedNameSpecifierLoc QualifierLoc,
3641 SourceLocation TemplateKWLoc,
3642 NamedDecl *FirstQualifierInScope,
3643 LookupResult &R,
3644 const TemplateArgumentListInfo *TemplateArgs) {
3645 CXXScopeSpec SS;
3646 SS.Adopt(QualifierLoc);
3648 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3649 OperatorLoc, IsArrow,
3650 SS, TemplateKWLoc,
3651 FirstQualifierInScope,
3652 R, TemplateArgs, /*S*/nullptr);
3655 /// Build a new noexcept expression.
3657 /// By default, performs semantic analysis to build the new expression.
3658 /// Subclasses may override this routine to provide different behavior.
3659 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3660 return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd());
3663 /// Build a new expression to compute the length of a parameter pack.
3664 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3665 SourceLocation PackLoc,
3666 SourceLocation RParenLoc,
3667 std::optional<unsigned> Length,
3668 ArrayRef<TemplateArgument> PartialArgs) {
3669 return SizeOfPackExpr::Create(SemaRef.Context, OperatorLoc, Pack, PackLoc,
3670 RParenLoc, Length, PartialArgs);
3673 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3674 SourceLocation RSquareLoc,
3675 Expr *PackIdExpression, Expr *IndexExpr,
3676 ArrayRef<Expr *> ExpandedExprs,
3677 bool FullySubstituted = false) {
3678 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3679 IndexExpr, RSquareLoc, ExpandedExprs,
3680 FullySubstituted);
3683 ExprResult RebuildResolvedUnexpandedPackExpr(SourceLocation BeginLoc,
3684 QualType T,
3685 ArrayRef<Expr *> Exprs) {
3686 return ResolvedUnexpandedPackExpr::Create(SemaRef.Context, BeginLoc, T,
3687 Exprs);
3690 /// Build a new expression representing a call to a source location
3691 /// builtin.
3693 /// By default, performs semantic analysis to build the new expression.
3694 /// Subclasses may override this routine to provide different behavior.
3695 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3696 SourceLocation BuiltinLoc,
3697 SourceLocation RPLoc,
3698 DeclContext *ParentContext) {
3699 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3700 ParentContext);
3703 /// Build a new Objective-C boxed expression.
3705 /// By default, performs semantic analysis to build the new expression.
3706 /// Subclasses may override this routine to provide different behavior.
3707 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3708 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3709 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3710 TemplateArgumentListInfo *TALI) {
3711 CXXScopeSpec SS;
3712 SS.Adopt(NNS);
3713 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3714 ConceptNameInfo,
3715 FoundDecl,
3716 NamedConcept, TALI);
3717 if (Result.isInvalid())
3718 return ExprError();
3719 return Result;
3722 /// \brief Build a new requires expression.
3724 /// By default, performs semantic analysis to build the new expression.
3725 /// Subclasses may override this routine to provide different behavior.
3726 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3727 RequiresExprBodyDecl *Body,
3728 SourceLocation LParenLoc,
3729 ArrayRef<ParmVarDecl *> LocalParameters,
3730 SourceLocation RParenLoc,
3731 ArrayRef<concepts::Requirement *> Requirements,
3732 SourceLocation ClosingBraceLoc) {
3733 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3734 LocalParameters, RParenLoc, Requirements,
3735 ClosingBraceLoc);
3738 concepts::TypeRequirement *
3739 RebuildTypeRequirement(
3740 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3741 return SemaRef.BuildTypeRequirement(SubstDiag);
3744 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3745 return SemaRef.BuildTypeRequirement(T);
3748 concepts::ExprRequirement *
3749 RebuildExprRequirement(
3750 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3751 SourceLocation NoexceptLoc,
3752 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3753 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
3754 std::move(Ret));
3757 concepts::ExprRequirement *
3758 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3759 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3760 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
3761 std::move(Ret));
3764 concepts::NestedRequirement *
3765 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3766 const ASTConstraintSatisfaction &Satisfaction) {
3767 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3768 Satisfaction);
3771 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3772 return SemaRef.BuildNestedRequirement(Constraint);
3775 /// \brief Build a new Objective-C boxed expression.
3777 /// By default, performs semantic analysis to build the new expression.
3778 /// Subclasses may override this routine to provide different behavior.
3779 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3780 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3783 /// Build a new Objective-C array literal.
3785 /// By default, performs semantic analysis to build the new expression.
3786 /// Subclasses may override this routine to provide different behavior.
3787 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3788 Expr **Elements, unsigned NumElements) {
3789 return getSema().ObjC().BuildObjCArrayLiteral(
3790 Range, MultiExprArg(Elements, NumElements));
3793 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3794 Expr *Base, Expr *Key,
3795 ObjCMethodDecl *getterMethod,
3796 ObjCMethodDecl *setterMethod) {
3797 return getSema().ObjC().BuildObjCSubscriptExpression(
3798 RB, Base, Key, getterMethod, setterMethod);
3801 /// Build a new Objective-C dictionary literal.
3803 /// By default, performs semantic analysis to build the new expression.
3804 /// Subclasses may override this routine to provide different behavior.
3805 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3806 MutableArrayRef<ObjCDictionaryElement> Elements) {
3807 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3810 /// Build a new Objective-C \@encode expression.
3812 /// By default, performs semantic analysis to build the new expression.
3813 /// Subclasses may override this routine to provide different behavior.
3814 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3815 TypeSourceInfo *EncodeTypeInfo,
3816 SourceLocation RParenLoc) {
3817 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
3818 RParenLoc);
3821 /// Build a new Objective-C class message.
3822 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3823 Selector Sel,
3824 ArrayRef<SourceLocation> SelectorLocs,
3825 ObjCMethodDecl *Method,
3826 SourceLocation LBracLoc,
3827 MultiExprArg Args,
3828 SourceLocation RBracLoc) {
3829 return SemaRef.ObjC().BuildClassMessage(
3830 ReceiverTypeInfo, ReceiverTypeInfo->getType(),
3831 /*SuperLoc=*/SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3832 RBracLoc, Args);
3835 /// Build a new Objective-C instance message.
3836 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3837 Selector Sel,
3838 ArrayRef<SourceLocation> SelectorLocs,
3839 ObjCMethodDecl *Method,
3840 SourceLocation LBracLoc,
3841 MultiExprArg Args,
3842 SourceLocation RBracLoc) {
3843 return SemaRef.ObjC().BuildInstanceMessage(Receiver, Receiver->getType(),
3844 /*SuperLoc=*/SourceLocation(),
3845 Sel, Method, LBracLoc,
3846 SelectorLocs, RBracLoc, Args);
3849 /// Build a new Objective-C instance/class message to 'super'.
3850 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3851 Selector Sel,
3852 ArrayRef<SourceLocation> SelectorLocs,
3853 QualType SuperType,
3854 ObjCMethodDecl *Method,
3855 SourceLocation LBracLoc,
3856 MultiExprArg Args,
3857 SourceLocation RBracLoc) {
3858 return Method->isInstanceMethod()
3859 ? SemaRef.ObjC().BuildInstanceMessage(
3860 nullptr, SuperType, SuperLoc, Sel, Method, LBracLoc,
3861 SelectorLocs, RBracLoc, Args)
3862 : SemaRef.ObjC().BuildClassMessage(nullptr, SuperType, SuperLoc,
3863 Sel, Method, LBracLoc,
3864 SelectorLocs, RBracLoc, Args);
3867 /// Build a new Objective-C ivar reference expression.
3869 /// By default, performs semantic analysis to build the new expression.
3870 /// Subclasses may override this routine to provide different behavior.
3871 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3872 SourceLocation IvarLoc,
3873 bool IsArrow, bool IsFreeIvar) {
3874 CXXScopeSpec SS;
3875 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3876 ExprResult Result = getSema().BuildMemberReferenceExpr(
3877 BaseArg, BaseArg->getType(),
3878 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3879 /*FirstQualifierInScope=*/nullptr, NameInfo,
3880 /*TemplateArgs=*/nullptr,
3881 /*S=*/nullptr);
3882 if (IsFreeIvar && Result.isUsable())
3883 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
3884 return Result;
3887 /// Build a new Objective-C property reference expression.
3889 /// By default, performs semantic analysis to build the new expression.
3890 /// Subclasses may override this routine to provide different behavior.
3891 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3892 ObjCPropertyDecl *Property,
3893 SourceLocation PropertyLoc) {
3894 CXXScopeSpec SS;
3895 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3896 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3897 /*FIXME:*/PropertyLoc,
3898 /*IsArrow=*/false,
3899 SS, SourceLocation(),
3900 /*FirstQualifierInScope=*/nullptr,
3901 NameInfo,
3902 /*TemplateArgs=*/nullptr,
3903 /*S=*/nullptr);
3906 /// Build a new Objective-C property reference expression.
3908 /// By default, performs semantic analysis to build the new expression.
3909 /// Subclasses may override this routine to provide different behavior.
3910 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3911 ObjCMethodDecl *Getter,
3912 ObjCMethodDecl *Setter,
3913 SourceLocation PropertyLoc) {
3914 // Since these expressions can only be value-dependent, we do not
3915 // need to perform semantic analysis again.
3916 return Owned(
3917 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3918 VK_LValue, OK_ObjCProperty,
3919 PropertyLoc, Base));
3922 /// Build a new Objective-C "isa" expression.
3924 /// By default, performs semantic analysis to build the new expression.
3925 /// Subclasses may override this routine to provide different behavior.
3926 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
3927 SourceLocation OpLoc, bool IsArrow) {
3928 CXXScopeSpec SS;
3929 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3930 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3931 OpLoc, IsArrow,
3932 SS, SourceLocation(),
3933 /*FirstQualifierInScope=*/nullptr,
3934 NameInfo,
3935 /*TemplateArgs=*/nullptr,
3936 /*S=*/nullptr);
3939 /// Build a new shuffle vector expression.
3941 /// By default, performs semantic analysis to build the new expression.
3942 /// Subclasses may override this routine to provide different behavior.
3943 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
3944 MultiExprArg SubExprs,
3945 SourceLocation RParenLoc) {
3946 // Find the declaration for __builtin_shufflevector
3947 const IdentifierInfo &Name
3948 = SemaRef.Context.Idents.get("__builtin_shufflevector");
3949 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
3950 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
3951 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3953 // Build a reference to the __builtin_shufflevector builtin
3954 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
3955 Expr *Callee = new (SemaRef.Context)
3956 DeclRefExpr(SemaRef.Context, Builtin, false,
3957 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3958 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
3959 Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
3960 CK_BuiltinFnToFnPtr).get();
3962 // Build the CallExpr
3963 ExprResult TheCall = CallExpr::Create(
3964 SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
3965 Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc,
3966 FPOptionsOverride());
3968 // Type-check the __builtin_shufflevector expression.
3969 return SemaRef.BuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
3972 /// Build a new convert vector expression.
3973 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
3974 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3975 SourceLocation RParenLoc) {
3976 return SemaRef.ConvertVectorExpr(SrcExpr, DstTInfo, BuiltinLoc, RParenLoc);
3979 /// Build a new template argument pack expansion.
3981 /// By default, performs semantic analysis to build a new pack expansion
3982 /// for a template argument. Subclasses may override this routine to provide
3983 /// different behavior.
3984 TemplateArgumentLoc
3985 RebuildPackExpansion(TemplateArgumentLoc Pattern, SourceLocation EllipsisLoc,
3986 std::optional<unsigned> NumExpansions) {
3987 switch (Pattern.getArgument().getKind()) {
3988 case TemplateArgument::Expression: {
3989 ExprResult Result
3990 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
3991 EllipsisLoc, NumExpansions);
3992 if (Result.isInvalid())
3993 return TemplateArgumentLoc();
3995 return TemplateArgumentLoc(Result.get(), Result.get());
3998 case TemplateArgument::Template:
3999 return TemplateArgumentLoc(
4000 SemaRef.Context,
4001 TemplateArgument(Pattern.getArgument().getAsTemplate(),
4002 NumExpansions),
4003 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
4004 EllipsisLoc);
4006 case TemplateArgument::Null:
4007 case TemplateArgument::Integral:
4008 case TemplateArgument::Declaration:
4009 case TemplateArgument::StructuralValue:
4010 case TemplateArgument::Pack:
4011 case TemplateArgument::TemplateExpansion:
4012 case TemplateArgument::NullPtr:
4013 llvm_unreachable("Pack expansion pattern has no parameter packs");
4015 case TemplateArgument::Type:
4016 if (TypeSourceInfo *Expansion
4017 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4018 EllipsisLoc,
4019 NumExpansions))
4020 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4021 Expansion);
4022 break;
4025 return TemplateArgumentLoc();
4028 /// Build a new expression pack expansion.
4030 /// By default, performs semantic analysis to build a new pack expansion
4031 /// for an expression. Subclasses may override this routine to provide
4032 /// different behavior.
4033 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4034 std::optional<unsigned> NumExpansions) {
4035 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4038 /// Build a new C++1z fold-expression.
4040 /// By default, performs semantic analysis in order to build a new fold
4041 /// expression.
4042 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4043 SourceLocation LParenLoc, Expr *LHS,
4044 BinaryOperatorKind Operator,
4045 SourceLocation EllipsisLoc, Expr *RHS,
4046 SourceLocation RParenLoc,
4047 std::optional<unsigned> NumExpansions) {
4048 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4049 EllipsisLoc, RHS, RParenLoc,
4050 NumExpansions);
4053 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4054 LambdaScopeInfo *LSI) {
4055 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4056 if (Expr *Init = PVD->getInit())
4057 LSI->ContainsUnexpandedParameterPack |=
4058 Init->containsUnexpandedParameterPack();
4059 else if (PVD->hasUninstantiatedDefaultArg())
4060 LSI->ContainsUnexpandedParameterPack |=
4061 PVD->getUninstantiatedDefaultArg()
4062 ->containsUnexpandedParameterPack();
4064 return getSema().BuildLambdaExpr(StartLoc, EndLoc, LSI);
4067 /// Build an empty C++1z fold-expression with the given operator.
4069 /// By default, produces the fallback value for the fold-expression, or
4070 /// produce an error if there is no fallback value.
4071 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4072 BinaryOperatorKind Operator) {
4073 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4076 /// Build a new atomic operation expression.
4078 /// By default, performs semantic analysis to build the new expression.
4079 /// Subclasses may override this routine to provide different behavior.
4080 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4081 AtomicExpr::AtomicOp Op,
4082 SourceLocation RParenLoc) {
4083 // Use this for all of the locations, since we don't know the difference
4084 // between the call and the expr at this point.
4085 SourceRange Range{BuiltinLoc, RParenLoc};
4086 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4087 Sema::AtomicArgumentOrder::AST);
4090 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4091 ArrayRef<Expr *> SubExprs, QualType Type) {
4092 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4095 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4096 SourceLocation BeginLoc,
4097 SourceLocation DirLoc,
4098 SourceLocation EndLoc,
4099 ArrayRef<OpenACCClause *> Clauses,
4100 StmtResult StrBlock) {
4101 return getSema().OpenACC().ActOnEndStmtDirective(
4102 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4103 SourceLocation{}, EndLoc, Clauses, StrBlock);
4106 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4107 SourceLocation DirLoc,
4108 SourceLocation EndLoc,
4109 ArrayRef<OpenACCClause *> Clauses,
4110 StmtResult Loop) {
4111 return getSema().OpenACC().ActOnEndStmtDirective(
4112 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4113 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, Loop);
4116 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4117 SourceLocation BeginLoc,
4118 SourceLocation DirLoc,
4119 SourceLocation EndLoc,
4120 ArrayRef<OpenACCClause *> Clauses,
4121 StmtResult Loop) {
4122 return getSema().OpenACC().ActOnEndStmtDirective(
4123 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4124 SourceLocation{}, EndLoc, Clauses, Loop);
4127 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,
4128 SourceLocation DirLoc,
4129 SourceLocation EndLoc,
4130 ArrayRef<OpenACCClause *> Clauses,
4131 StmtResult StrBlock) {
4132 return getSema().OpenACC().ActOnEndStmtDirective(
4133 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4134 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, StrBlock);
4137 StmtResult
4138 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,
4139 SourceLocation DirLoc, SourceLocation EndLoc,
4140 ArrayRef<OpenACCClause *> Clauses) {
4141 return getSema().OpenACC().ActOnEndStmtDirective(
4142 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},
4143 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
4146 StmtResult
4147 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,
4148 SourceLocation DirLoc, SourceLocation EndLoc,
4149 ArrayRef<OpenACCClause *> Clauses) {
4150 return getSema().OpenACC().ActOnEndStmtDirective(
4151 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},
4152 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
4155 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,
4156 SourceLocation DirLoc,
4157 SourceLocation EndLoc,
4158 ArrayRef<OpenACCClause *> Clauses,
4159 StmtResult StrBlock) {
4160 return getSema().OpenACC().ActOnEndStmtDirective(
4161 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},
4162 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, StrBlock);
4165 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
4166 SourceLocation DirLoc,
4167 SourceLocation EndLoc,
4168 ArrayRef<OpenACCClause *> Clauses) {
4169 return getSema().OpenACC().ActOnEndStmtDirective(
4170 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4171 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
4174 StmtResult
4175 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
4176 SourceLocation DirLoc, SourceLocation EndLoc,
4177 ArrayRef<OpenACCClause *> Clauses) {
4178 return getSema().OpenACC().ActOnEndStmtDirective(
4179 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
4180 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
4183 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,
4184 SourceLocation DirLoc,
4185 SourceLocation EndLoc,
4186 ArrayRef<OpenACCClause *> Clauses) {
4187 return getSema().OpenACC().ActOnEndStmtDirective(
4188 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4189 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
4192 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,
4193 SourceLocation DirLoc,
4194 SourceLocation EndLoc,
4195 ArrayRef<OpenACCClause *> Clauses) {
4196 return getSema().OpenACC().ActOnEndStmtDirective(
4197 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4198 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
4201 StmtResult RebuildOpenACCWaitConstruct(
4202 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4203 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4204 SourceLocation RParenLoc, SourceLocation EndLoc,
4205 ArrayRef<OpenACCClause *> Clauses) {
4206 llvm::SmallVector<Expr *> Exprs;
4207 Exprs.push_back(DevNumExpr);
4208 Exprs.insert(Exprs.end(), QueueIdExprs.begin(), QueueIdExprs.end());
4209 return getSema().OpenACC().ActOnEndStmtDirective(
4210 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4211 Exprs, RParenLoc, EndLoc, Clauses, {});
4214 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4215 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4218 private:
4219 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
4220 QualType ObjectType,
4221 NamedDecl *FirstQualifierInScope,
4222 CXXScopeSpec &SS);
4224 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4225 QualType ObjectType,
4226 NamedDecl *FirstQualifierInScope,
4227 CXXScopeSpec &SS);
4229 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
4230 NamedDecl *FirstQualifierInScope,
4231 CXXScopeSpec &SS);
4233 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4234 DependentNameTypeLoc TL,
4235 bool DeducibleTSTContext);
4237 llvm::SmallVector<OpenACCClause *>
4238 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4239 ArrayRef<const OpenACCClause *> OldClauses);
4241 OpenACCClause *
4242 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4243 OpenACCDirectiveKind DirKind,
4244 const OpenACCClause *OldClause);
4247 template <typename Derived>
4248 StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4249 if (!S)
4250 return S;
4252 switch (S->getStmtClass()) {
4253 case Stmt::NoStmtClass: break;
4255 // Transform individual statement nodes
4256 // Pass SDK into statements that can produce a value
4257 #define STMT(Node, Parent) \
4258 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4259 #define VALUESTMT(Node, Parent) \
4260 case Stmt::Node##Class: \
4261 return getDerived().Transform##Node(cast<Node>(S), SDK);
4262 #define ABSTRACT_STMT(Node)
4263 #define EXPR(Node, Parent)
4264 #include "clang/AST/StmtNodes.inc"
4266 // Transform expressions by calling TransformExpr.
4267 #define STMT(Node, Parent)
4268 #define ABSTRACT_STMT(Stmt)
4269 #define EXPR(Node, Parent) case Stmt::Node##Class:
4270 #include "clang/AST/StmtNodes.inc"
4272 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
4274 if (SDK == SDK_StmtExprResult)
4275 E = getSema().ActOnStmtExprResult(E);
4276 return getSema().ActOnExprStmt(E, SDK == SDK_Discarded);
4280 return S;
4283 template<typename Derived>
4284 OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4285 if (!S)
4286 return S;
4288 switch (S->getClauseKind()) {
4289 default: break;
4290 // Transform individual clause nodes
4291 #define GEN_CLANG_CLAUSE_CLASS
4292 #define CLAUSE_CLASS(Enum, Str, Class) \
4293 case Enum: \
4294 return getDerived().Transform##Class(cast<Class>(S));
4295 #include "llvm/Frontend/OpenMP/OMP.inc"
4298 return S;
4302 template<typename Derived>
4303 ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4304 if (!E)
4305 return E;
4307 switch (E->getStmtClass()) {
4308 case Stmt::NoStmtClass: break;
4309 #define STMT(Node, Parent) case Stmt::Node##Class: break;
4310 #define ABSTRACT_STMT(Stmt)
4311 #define EXPR(Node, Parent) \
4312 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4313 #include "clang/AST/StmtNodes.inc"
4316 return E;
4319 template<typename Derived>
4320 ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4321 bool NotCopyInit) {
4322 // Initializers are instantiated like expressions, except that various outer
4323 // layers are stripped.
4324 if (!Init)
4325 return Init;
4327 if (auto *FE = dyn_cast<FullExpr>(Init))
4328 Init = FE->getSubExpr();
4330 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {
4331 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4332 Init = OVE->getSourceExpr();
4335 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
4336 Init = MTE->getSubExpr();
4338 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
4339 Init = Binder->getSubExpr();
4341 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
4342 Init = ICE->getSubExprAsWritten();
4344 if (CXXStdInitializerListExpr *ILE =
4345 dyn_cast<CXXStdInitializerListExpr>(Init))
4346 return TransformInitializer(ILE->getSubExpr(), NotCopyInit);
4348 // If this is copy-initialization, we only need to reconstruct
4349 // InitListExprs. Other forms of copy-initialization will be a no-op if
4350 // the initializer is already the right type.
4351 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
4352 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4353 return getDerived().TransformExpr(Init);
4355 // Revert value-initialization back to empty parens.
4356 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
4357 SourceRange Parens = VIE->getSourceRange();
4358 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4359 Parens.getEnd());
4362 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4363 if (isa<ImplicitValueInitExpr>(Init))
4364 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4365 SourceLocation());
4367 // Revert initialization by constructor back to a parenthesized or braced list
4368 // of expressions. Any other form of initializer can just be reused directly.
4369 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
4370 return getDerived().TransformExpr(Init);
4372 // If the initialization implicitly converted an initializer list to a
4373 // std::initializer_list object, unwrap the std::initializer_list too.
4374 if (Construct && Construct->isStdInitListInitialization())
4375 return TransformInitializer(Construct->getArg(0), NotCopyInit);
4377 // Enter a list-init context if this was list initialization.
4378 EnterExpressionEvaluationContext Context(
4379 getSema(), EnterExpressionEvaluationContext::InitList,
4380 Construct->isListInitialization());
4382 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4383 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4384 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4385 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4386 SmallVector<Expr*, 8> NewArgs;
4387 bool ArgChanged = false;
4388 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4389 /*IsCall*/true, NewArgs, &ArgChanged))
4390 return ExprError();
4392 // If this was list initialization, revert to syntactic list form.
4393 if (Construct->isListInitialization())
4394 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4395 Construct->getEndLoc());
4397 // Build a ParenListExpr to represent anything else.
4398 SourceRange Parens = Construct->getParenOrBraceRange();
4399 if (Parens.isInvalid()) {
4400 // This was a variable declaration's initialization for which no initializer
4401 // was specified.
4402 assert(NewArgs.empty() &&
4403 "no parens or braces but have direct init with arguments?");
4404 return ExprEmpty();
4406 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4407 Parens.getEnd());
4410 template<typename Derived>
4411 bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4412 unsigned NumInputs,
4413 bool IsCall,
4414 SmallVectorImpl<Expr *> &Outputs,
4415 bool *ArgChanged) {
4416 for (unsigned I = 0; I != NumInputs; ++I) {
4417 // If requested, drop call arguments that need to be dropped.
4418 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4419 if (ArgChanged)
4420 *ArgChanged = true;
4422 break;
4425 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
4426 Expr *Pattern = Expansion->getPattern();
4428 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4429 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4430 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4432 // Determine whether the set of unexpanded parameter packs can and should
4433 // be expanded.
4434 bool Expand = true;
4435 bool RetainExpansion = false;
4436 std::optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions();
4437 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4438 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4439 Pattern->getSourceRange(),
4440 Unexpanded,
4441 Expand, RetainExpansion,
4442 NumExpansions))
4443 return true;
4445 if (!Expand) {
4446 // The transform has determined that we should perform a simple
4447 // transformation on the pack expansion, producing another pack
4448 // expansion.
4449 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4450 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4451 if (OutPattern.isInvalid())
4452 return true;
4454 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4455 Expansion->getEllipsisLoc(),
4456 NumExpansions);
4457 if (Out.isInvalid())
4458 return true;
4460 if (ArgChanged)
4461 *ArgChanged = true;
4462 Outputs.push_back(Out.get());
4463 continue;
4466 // Record right away that the argument was changed. This needs
4467 // to happen even if the array expands to nothing.
4468 if (ArgChanged) *ArgChanged = true;
4470 // The transform has determined that we should perform an elementwise
4471 // expansion of the pattern. Do so.
4472 for (unsigned I = 0; I != *NumExpansions; ++I) {
4473 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4474 ExprResult Out = getDerived().TransformExpr(Pattern);
4475 if (Out.isInvalid())
4476 return true;
4478 if (Out.get()->containsUnexpandedParameterPack()) {
4479 Out = getDerived().RebuildPackExpansion(
4480 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4481 if (Out.isInvalid())
4482 return true;
4485 Outputs.push_back(Out.get());
4488 // If we're supposed to retain a pack expansion, do so by temporarily
4489 // forgetting the partially-substituted parameter pack.
4490 if (RetainExpansion) {
4491 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4493 ExprResult Out = getDerived().TransformExpr(Pattern);
4494 if (Out.isInvalid())
4495 return true;
4497 Out = getDerived().RebuildPackExpansion(
4498 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4499 if (Out.isInvalid())
4500 return true;
4502 Outputs.push_back(Out.get());
4505 continue;
4508 ExprResult Result =
4509 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4510 : getDerived().TransformExpr(Inputs[I]);
4511 if (Result.isInvalid())
4512 return true;
4514 if (Result.get() != Inputs[I] && ArgChanged)
4515 *ArgChanged = true;
4517 Outputs.push_back(Result.get());
4520 return false;
4523 template <typename Derived>
4524 Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4525 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4526 if (Var) {
4527 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4528 getDerived().TransformDefinition(Var->getLocation(), Var));
4530 if (!ConditionVar)
4531 return Sema::ConditionError();
4533 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4536 if (Expr) {
4537 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4539 if (CondExpr.isInvalid())
4540 return Sema::ConditionError();
4542 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4543 /*MissingOK=*/true);
4546 return Sema::ConditionResult();
4549 template <typename Derived>
4550 NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4551 NestedNameSpecifierLoc NNS, QualType ObjectType,
4552 NamedDecl *FirstQualifierInScope) {
4553 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4555 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4556 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4557 Qualifier = Qualifier.getPrefix())
4558 Qualifiers.push_back(Qualifier);
4560 insertNNS(NNS);
4562 CXXScopeSpec SS;
4563 while (!Qualifiers.empty()) {
4564 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4565 NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
4567 switch (QNNS->getKind()) {
4568 case NestedNameSpecifier::Identifier: {
4569 Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
4570 Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
4571 ObjectType);
4572 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false,
4573 SS, FirstQualifierInScope, false))
4574 return NestedNameSpecifierLoc();
4575 break;
4578 case NestedNameSpecifier::Namespace: {
4579 NamespaceDecl *NS =
4580 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4581 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4582 SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
4583 break;
4586 case NestedNameSpecifier::NamespaceAlias: {
4587 NamespaceAliasDecl *Alias =
4588 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4589 Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
4590 SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
4591 Q.getLocalEndLoc());
4592 break;
4595 case NestedNameSpecifier::Global:
4596 // There is no meaningful transformation that one could perform on the
4597 // global scope.
4598 SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
4599 break;
4601 case NestedNameSpecifier::Super: {
4602 CXXRecordDecl *RD =
4603 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4604 SourceLocation(), QNNS->getAsRecordDecl()));
4605 SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc());
4606 break;
4609 case NestedNameSpecifier::TypeSpecWithTemplate:
4610 case NestedNameSpecifier::TypeSpec: {
4611 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4612 FirstQualifierInScope, SS);
4614 if (!TL)
4615 return NestedNameSpecifierLoc();
4617 QualType T = TL.getType();
4618 if (T->isDependentType() || T->isRecordType() ||
4619 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4620 if (T->isEnumeralType())
4621 SemaRef.Diag(TL.getBeginLoc(),
4622 diag::warn_cxx98_compat_enum_nested_name_spec);
4624 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4625 SS.Adopt(ETL.getQualifierLoc());
4626 TL = ETL.getNamedTypeLoc();
4629 SS.Extend(SemaRef.Context, TL.getTemplateKeywordLoc(), TL,
4630 Q.getLocalEndLoc());
4631 break;
4633 // If the nested-name-specifier is an invalid type def, don't emit an
4634 // error because a previous error should have already been emitted.
4635 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4636 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4637 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
4638 << T << SS.getRange();
4640 return NestedNameSpecifierLoc();
4644 // The qualifier-in-scope and object type only apply to the leftmost entity.
4645 FirstQualifierInScope = nullptr;
4646 ObjectType = QualType();
4649 // Don't rebuild the nested-name-specifier if we don't have to.
4650 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4651 !getDerived().AlwaysRebuild())
4652 return NNS;
4654 // If we can re-use the source-location data from the original
4655 // nested-name-specifier, do so.
4656 if (SS.location_size() == NNS.getDataLength() &&
4657 memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)
4658 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4660 // Allocate new nested-name-specifier location information.
4661 return SS.getWithLocInContext(SemaRef.Context);
4664 template<typename Derived>
4665 DeclarationNameInfo
4666 TreeTransform<Derived>
4667 ::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4668 DeclarationName Name = NameInfo.getName();
4669 if (!Name)
4670 return DeclarationNameInfo();
4672 switch (Name.getNameKind()) {
4673 case DeclarationName::Identifier:
4674 case DeclarationName::ObjCZeroArgSelector:
4675 case DeclarationName::ObjCOneArgSelector:
4676 case DeclarationName::ObjCMultiArgSelector:
4677 case DeclarationName::CXXOperatorName:
4678 case DeclarationName::CXXLiteralOperatorName:
4679 case DeclarationName::CXXUsingDirective:
4680 return NameInfo;
4682 case DeclarationName::CXXDeductionGuideName: {
4683 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4684 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4685 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4686 if (!NewTemplate)
4687 return DeclarationNameInfo();
4689 DeclarationNameInfo NewNameInfo(NameInfo);
4690 NewNameInfo.setName(
4691 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(NewTemplate));
4692 return NewNameInfo;
4695 case DeclarationName::CXXConstructorName:
4696 case DeclarationName::CXXDestructorName:
4697 case DeclarationName::CXXConversionFunctionName: {
4698 TypeSourceInfo *NewTInfo;
4699 CanQualType NewCanTy;
4700 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4701 NewTInfo = getDerived().TransformType(OldTInfo);
4702 if (!NewTInfo)
4703 return DeclarationNameInfo();
4704 NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
4706 else {
4707 NewTInfo = nullptr;
4708 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4709 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4710 if (NewT.isNull())
4711 return DeclarationNameInfo();
4712 NewCanTy = SemaRef.Context.getCanonicalType(NewT);
4715 DeclarationName NewName
4716 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
4717 NewCanTy);
4718 DeclarationNameInfo NewNameInfo(NameInfo);
4719 NewNameInfo.setName(NewName);
4720 NewNameInfo.setNamedTypeInfo(NewTInfo);
4721 return NewNameInfo;
4725 llvm_unreachable("Unknown name kind.");
4728 template<typename Derived>
4729 TemplateName
4730 TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
4731 TemplateName Name,
4732 SourceLocation NameLoc,
4733 QualType ObjectType,
4734 NamedDecl *FirstQualifierInScope,
4735 bool AllowInjectedClassName) {
4736 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4737 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4738 assert(Template && "qualified template name must refer to a template");
4740 TemplateDecl *TransTemplate
4741 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4742 Template));
4743 if (!TransTemplate)
4744 return TemplateName();
4746 if (!getDerived().AlwaysRebuild() &&
4747 SS.getScopeRep() == QTN->getQualifier() &&
4748 TransTemplate == Template)
4749 return Name;
4751 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4752 TransTemplate);
4755 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4756 if (SS.getScopeRep()) {
4757 // These apply to the scope specifier, not the template.
4758 ObjectType = QualType();
4759 FirstQualifierInScope = nullptr;
4762 if (!getDerived().AlwaysRebuild() &&
4763 SS.getScopeRep() == DTN->getQualifier() &&
4764 ObjectType.isNull())
4765 return Name;
4767 // FIXME: Preserve the location of the "template" keyword.
4768 SourceLocation TemplateKWLoc = NameLoc;
4770 if (DTN->isIdentifier()) {
4771 return getDerived().RebuildTemplateName(SS,
4772 TemplateKWLoc,
4773 *DTN->getIdentifier(),
4774 NameLoc,
4775 ObjectType,
4776 FirstQualifierInScope,
4777 AllowInjectedClassName);
4780 return getDerived().RebuildTemplateName(SS, TemplateKWLoc,
4781 DTN->getOperator(), NameLoc,
4782 ObjectType, AllowInjectedClassName);
4785 // FIXME: Try to preserve more of the TemplateName.
4786 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4787 TemplateDecl *TransTemplate
4788 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4789 Template));
4790 if (!TransTemplate)
4791 return TemplateName();
4793 return getDerived().RebuildTemplateName(SS, /*TemplateKeyword=*/false,
4794 TransTemplate);
4797 if (SubstTemplateTemplateParmPackStorage *SubstPack
4798 = Name.getAsSubstTemplateTemplateParmPack()) {
4799 return getDerived().RebuildTemplateName(
4800 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4801 SubstPack->getIndex(), SubstPack->getFinal());
4804 // These should be getting filtered out before they reach the AST.
4805 llvm_unreachable("overloaded function decl survived to here");
4808 template<typename Derived>
4809 void TreeTransform<Derived>::InventTemplateArgumentLoc(
4810 const TemplateArgument &Arg,
4811 TemplateArgumentLoc &Output) {
4812 Output = getSema().getTrivialTemplateArgumentLoc(
4813 Arg, QualType(), getDerived().getBaseLocation());
4816 template <typename Derived>
4817 bool TreeTransform<Derived>::TransformTemplateArgument(
4818 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4819 bool Uneval) {
4820 const TemplateArgument &Arg = Input.getArgument();
4821 switch (Arg.getKind()) {
4822 case TemplateArgument::Null:
4823 case TemplateArgument::Pack:
4824 llvm_unreachable("Unexpected TemplateArgument");
4826 case TemplateArgument::Integral:
4827 case TemplateArgument::NullPtr:
4828 case TemplateArgument::Declaration:
4829 case TemplateArgument::StructuralValue: {
4830 // Transform a resolved template argument straight to a resolved template
4831 // argument. We get here when substituting into an already-substituted
4832 // template type argument during concept satisfaction checking.
4833 QualType T = Arg.getNonTypeTemplateArgumentType();
4834 QualType NewT = getDerived().TransformType(T);
4835 if (NewT.isNull())
4836 return true;
4838 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
4839 ? Arg.getAsDecl()
4840 : nullptr;
4841 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4842 getDerived().getBaseLocation(), D))
4843 : nullptr;
4844 if (D && !NewD)
4845 return true;
4847 if (NewT == T && D == NewD)
4848 Output = Input;
4849 else if (Arg.getKind() == TemplateArgument::Integral)
4850 Output = TemplateArgumentLoc(
4851 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4852 TemplateArgumentLocInfo());
4853 else if (Arg.getKind() == TemplateArgument::NullPtr)
4854 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4855 TemplateArgumentLocInfo());
4856 else if (Arg.getKind() == TemplateArgument::Declaration)
4857 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4858 TemplateArgumentLocInfo());
4859 else if (Arg.getKind() == TemplateArgument::StructuralValue)
4860 Output = TemplateArgumentLoc(
4861 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
4862 TemplateArgumentLocInfo());
4863 else
4864 llvm_unreachable("unexpected template argument kind");
4866 return false;
4869 case TemplateArgument::Type: {
4870 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4871 if (!DI)
4872 DI = InventTypeSourceInfo(Input.getArgument().getAsType());
4874 DI = getDerived().TransformType(DI);
4875 if (!DI)
4876 return true;
4878 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4879 return false;
4882 case TemplateArgument::Template: {
4883 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4884 if (QualifierLoc) {
4885 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4886 if (!QualifierLoc)
4887 return true;
4890 CXXScopeSpec SS;
4891 SS.Adopt(QualifierLoc);
4892 TemplateName Template = getDerived().TransformTemplateName(
4893 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4894 if (Template.isNull())
4895 return true;
4897 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4898 QualifierLoc, Input.getTemplateNameLoc());
4899 return false;
4902 case TemplateArgument::TemplateExpansion:
4903 llvm_unreachable("Caller should expand pack expansions");
4905 case TemplateArgument::Expression: {
4906 // Template argument expressions are constant expressions.
4907 EnterExpressionEvaluationContext Unevaluated(
4908 getSema(),
4909 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
4910 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
4911 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4912 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
4914 Expr *InputExpr = Input.getSourceExpression();
4915 if (!InputExpr)
4916 InputExpr = Input.getArgument().getAsExpr();
4918 ExprResult E = getDerived().TransformExpr(InputExpr);
4919 E = SemaRef.ActOnConstantExpression(E);
4920 if (E.isInvalid())
4921 return true;
4922 Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
4923 return false;
4927 // Work around bogus GCC warning
4928 return true;
4931 /// Iterator adaptor that invents template argument location information
4932 /// for each of the template arguments in its underlying iterator.
4933 template<typename Derived, typename InputIterator>
4934 class TemplateArgumentLocInventIterator {
4935 TreeTransform<Derived> &Self;
4936 InputIterator Iter;
4938 public:
4939 typedef TemplateArgumentLoc value_type;
4940 typedef TemplateArgumentLoc reference;
4941 typedef typename std::iterator_traits<InputIterator>::difference_type
4942 difference_type;
4943 typedef std::input_iterator_tag iterator_category;
4945 class pointer {
4946 TemplateArgumentLoc Arg;
4948 public:
4949 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4951 const TemplateArgumentLoc *operator->() const { return &Arg; }
4954 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
4955 InputIterator Iter)
4956 : Self(Self), Iter(Iter) { }
4958 TemplateArgumentLocInventIterator &operator++() {
4959 ++Iter;
4960 return *this;
4963 TemplateArgumentLocInventIterator operator++(int) {
4964 TemplateArgumentLocInventIterator Old(*this);
4965 ++(*this);
4966 return Old;
4969 reference operator*() const {
4970 TemplateArgumentLoc Result;
4971 Self.InventTemplateArgumentLoc(*Iter, Result);
4972 return Result;
4975 pointer operator->() const { return pointer(**this); }
4977 friend bool operator==(const TemplateArgumentLocInventIterator &X,
4978 const TemplateArgumentLocInventIterator &Y) {
4979 return X.Iter == Y.Iter;
4982 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
4983 const TemplateArgumentLocInventIterator &Y) {
4984 return X.Iter != Y.Iter;
4988 template<typename Derived>
4989 template<typename InputIterator>
4990 bool TreeTransform<Derived>::TransformTemplateArguments(
4991 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
4992 bool Uneval) {
4993 for (; First != Last; ++First) {
4994 TemplateArgumentLoc Out;
4995 TemplateArgumentLoc In = *First;
4997 if (In.getArgument().getKind() == TemplateArgument::Pack) {
4998 // Unpack argument packs, which we translate them into separate
4999 // arguments.
5000 // FIXME: We could do much better if we could guarantee that the
5001 // TemplateArgumentLocInfo for the pack expansion would be usable for
5002 // all of the template arguments in the argument pack.
5003 typedef TemplateArgumentLocInventIterator<Derived,
5004 TemplateArgument::pack_iterator>
5005 PackLocIterator;
5006 if (TransformTemplateArguments(PackLocIterator(*this,
5007 In.getArgument().pack_begin()),
5008 PackLocIterator(*this,
5009 In.getArgument().pack_end()),
5010 Outputs, Uneval))
5011 return true;
5013 continue;
5016 if (In.getArgument().isPackExpansion()) {
5017 // We have a pack expansion, for which we will be substituting into
5018 // the pattern.
5019 SourceLocation Ellipsis;
5020 std::optional<unsigned> OrigNumExpansions;
5021 TemplateArgumentLoc Pattern
5022 = getSema().getTemplateArgumentPackExpansionPattern(
5023 In, Ellipsis, OrigNumExpansions);
5025 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5026 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5027 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5029 // Determine whether the set of unexpanded parameter packs can and should
5030 // be expanded.
5031 bool Expand = true;
5032 bool RetainExpansion = false;
5033 std::optional<unsigned> NumExpansions = OrigNumExpansions;
5034 if (getDerived().TryExpandParameterPacks(Ellipsis,
5035 Pattern.getSourceRange(),
5036 Unexpanded,
5037 Expand,
5038 RetainExpansion,
5039 NumExpansions))
5040 return true;
5042 if (!Expand) {
5043 // The transform has determined that we should perform a simple
5044 // transformation on the pack expansion, producing another pack
5045 // expansion.
5046 TemplateArgumentLoc OutPattern;
5047 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
5048 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5049 return true;
5051 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
5052 NumExpansions);
5053 if (Out.getArgument().isNull())
5054 return true;
5056 Outputs.addArgument(Out);
5057 continue;
5060 // The transform has determined that we should perform an elementwise
5061 // expansion of the pattern. Do so.
5062 for (unsigned I = 0; I != *NumExpansions; ++I) {
5063 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
5065 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
5066 return true;
5068 if (Out.getArgument().containsUnexpandedParameterPack()) {
5069 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
5070 OrigNumExpansions);
5071 if (Out.getArgument().isNull())
5072 return true;
5075 Outputs.addArgument(Out);
5078 // If we're supposed to retain a pack expansion, do so by temporarily
5079 // forgetting the partially-substituted parameter pack.
5080 if (RetainExpansion) {
5081 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5083 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
5084 return true;
5086 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
5087 OrigNumExpansions);
5088 if (Out.getArgument().isNull())
5089 return true;
5091 Outputs.addArgument(Out);
5094 continue;
5097 // The simple case:
5098 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5099 return true;
5101 Outputs.addArgument(Out);
5104 return false;
5108 //===----------------------------------------------------------------------===//
5109 // Type transformation
5110 //===----------------------------------------------------------------------===//
5112 template<typename Derived>
5113 QualType TreeTransform<Derived>::TransformType(QualType T) {
5114 if (getDerived().AlreadyTransformed(T))
5115 return T;
5117 // Temporary workaround. All of these transformations should
5118 // eventually turn into transformations on TypeLocs.
5119 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5120 getDerived().getBaseLocation());
5122 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
5124 if (!NewDI)
5125 return QualType();
5127 return NewDI->getType();
5130 template<typename Derived>
5131 TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
5132 // Refine the base location to the type's location.
5133 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5134 getDerived().getBaseEntity());
5135 if (getDerived().AlreadyTransformed(DI->getType()))
5136 return DI;
5138 TypeLocBuilder TLB;
5140 TypeLoc TL = DI->getTypeLoc();
5141 TLB.reserve(TL.getFullDataSize());
5143 QualType Result = getDerived().TransformType(TLB, TL);
5144 if (Result.isNull())
5145 return nullptr;
5147 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5150 template<typename Derived>
5151 QualType
5152 TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5153 switch (T.getTypeLocClass()) {
5154 #define ABSTRACT_TYPELOC(CLASS, PARENT)
5155 #define TYPELOC(CLASS, PARENT) \
5156 case TypeLoc::CLASS: \
5157 return getDerived().Transform##CLASS##Type(TLB, \
5158 T.castAs<CLASS##TypeLoc>());
5159 #include "clang/AST/TypeLocNodes.def"
5162 llvm_unreachable("unhandled type loc!");
5165 template<typename Derived>
5166 QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5167 if (!isa<DependentNameType>(T))
5168 return TransformType(T);
5170 if (getDerived().AlreadyTransformed(T))
5171 return T;
5172 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5173 getDerived().getBaseLocation());
5174 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
5175 return NewDI ? NewDI->getType() : QualType();
5178 template<typename Derived>
5179 TypeSourceInfo *
5180 TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
5181 if (!isa<DependentNameType>(DI->getType()))
5182 return TransformType(DI);
5184 // Refine the base location to the type's location.
5185 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5186 getDerived().getBaseEntity());
5187 if (getDerived().AlreadyTransformed(DI->getType()))
5188 return DI;
5190 TypeLocBuilder TLB;
5192 TypeLoc TL = DI->getTypeLoc();
5193 TLB.reserve(TL.getFullDataSize());
5195 auto QTL = TL.getAs<QualifiedTypeLoc>();
5196 if (QTL)
5197 TL = QTL.getUnqualifiedLoc();
5199 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5201 QualType Result = getDerived().TransformDependentNameType(
5202 TLB, DNTL, /*DeducedTSTContext*/true);
5203 if (Result.isNull())
5204 return nullptr;
5206 if (QTL) {
5207 Result = getDerived().RebuildQualifiedType(Result, QTL);
5208 if (Result.isNull())
5209 return nullptr;
5210 TLB.TypeWasModifiedSafely(Result);
5213 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5216 template<typename Derived>
5217 QualType
5218 TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5219 QualifiedTypeLoc T) {
5220 QualType Result;
5221 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5222 auto SuppressObjCLifetime =
5223 T.getType().getLocalQualifiers().hasObjCLifetime();
5224 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5225 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5226 SuppressObjCLifetime);
5227 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5228 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5229 TLB, STTP, SuppressObjCLifetime);
5230 } else {
5231 Result = getDerived().TransformType(TLB, UnqualTL);
5234 if (Result.isNull())
5235 return QualType();
5237 Result = getDerived().RebuildQualifiedType(Result, T);
5239 if (Result.isNull())
5240 return QualType();
5242 // RebuildQualifiedType might have updated the type, but not in a way
5243 // that invalidates the TypeLoc. (There's no location information for
5244 // qualifiers.)
5245 TLB.TypeWasModifiedSafely(Result);
5247 return Result;
5250 template <typename Derived>
5251 QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5252 QualifiedTypeLoc TL) {
5254 SourceLocation Loc = TL.getBeginLoc();
5255 Qualifiers Quals = TL.getType().getLocalQualifiers();
5257 if ((T.getAddressSpace() != LangAS::Default &&
5258 Quals.getAddressSpace() != LangAS::Default) &&
5259 T.getAddressSpace() != Quals.getAddressSpace()) {
5260 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)
5261 << TL.getType() << T;
5262 return QualType();
5265 // C++ [dcl.fct]p7:
5266 // [When] adding cv-qualifications on top of the function type [...] the
5267 // cv-qualifiers are ignored.
5268 if (T->isFunctionType()) {
5269 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5270 Quals.getAddressSpace());
5271 return T;
5274 // C++ [dcl.ref]p1:
5275 // when the cv-qualifiers are introduced through the use of a typedef-name
5276 // or decltype-specifier [...] the cv-qualifiers are ignored.
5277 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5278 // applied to a reference type.
5279 if (T->isReferenceType()) {
5280 // The only qualifier that applies to a reference type is restrict.
5281 if (!Quals.hasRestrict())
5282 return T;
5283 Quals = Qualifiers::fromCVRMask(Qualifiers::Restrict);
5286 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5287 // resulting type.
5288 if (Quals.hasObjCLifetime()) {
5289 if (!T->isObjCLifetimeType() && !T->isDependentType())
5290 Quals.removeObjCLifetime();
5291 else if (T.getObjCLifetime()) {
5292 // Objective-C ARC:
5293 // A lifetime qualifier applied to a substituted template parameter
5294 // overrides the lifetime qualifier from the template argument.
5295 const AutoType *AutoTy;
5296 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
5297 // 'auto' types behave the same way as template parameters.
5298 QualType Deduced = AutoTy->getDeducedType();
5299 Qualifiers Qs = Deduced.getQualifiers();
5300 Qs.removeObjCLifetime();
5301 Deduced =
5302 SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);
5303 T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),
5304 AutoTy->isDependentType(),
5305 /*isPack=*/false,
5306 AutoTy->getTypeConstraintConcept(),
5307 AutoTy->getTypeConstraintArguments());
5308 } else {
5309 // Otherwise, complain about the addition of a qualifier to an
5310 // already-qualified type.
5311 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5312 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
5313 Quals.removeObjCLifetime();
5318 return SemaRef.BuildQualifiedType(T, Loc, Quals);
5321 template<typename Derived>
5322 TypeLoc
5323 TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
5324 QualType ObjectType,
5325 NamedDecl *UnqualLookup,
5326 CXXScopeSpec &SS) {
5327 if (getDerived().AlreadyTransformed(TL.getType()))
5328 return TL;
5330 TypeSourceInfo *TSI =
5331 TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS);
5332 if (TSI)
5333 return TSI->getTypeLoc();
5334 return TypeLoc();
5337 template<typename Derived>
5338 TypeSourceInfo *
5339 TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5340 QualType ObjectType,
5341 NamedDecl *UnqualLookup,
5342 CXXScopeSpec &SS) {
5343 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5344 return TSInfo;
5346 return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType,
5347 UnqualLookup, SS);
5350 template <typename Derived>
5351 TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5352 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5353 CXXScopeSpec &SS) {
5354 QualType T = TL.getType();
5355 assert(!getDerived().AlreadyTransformed(T));
5357 TypeLocBuilder TLB;
5358 QualType Result;
5360 if (isa<TemplateSpecializationType>(T)) {
5361 TemplateSpecializationTypeLoc SpecTL =
5362 TL.castAs<TemplateSpecializationTypeLoc>();
5364 TemplateName Template = getDerived().TransformTemplateName(
5365 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5366 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5367 if (Template.isNull())
5368 return nullptr;
5370 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5371 Template);
5372 } else if (isa<DependentTemplateSpecializationType>(T)) {
5373 DependentTemplateSpecializationTypeLoc SpecTL =
5374 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5376 TemplateName Template
5377 = getDerived().RebuildTemplateName(SS,
5378 SpecTL.getTemplateKeywordLoc(),
5379 *SpecTL.getTypePtr()->getIdentifier(),
5380 SpecTL.getTemplateNameLoc(),
5381 ObjectType, UnqualLookup,
5382 /*AllowInjectedClassName*/true);
5383 if (Template.isNull())
5384 return nullptr;
5386 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5387 SpecTL,
5388 Template,
5389 SS);
5390 } else {
5391 // Nothing special needs to be done for these.
5392 Result = getDerived().TransformType(TLB, TL);
5395 if (Result.isNull())
5396 return nullptr;
5398 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5401 template <class TyLoc> static inline
5402 QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5403 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5404 NewT.setNameLoc(T.getNameLoc());
5405 return T.getType();
5408 template<typename Derived>
5409 QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5410 BuiltinTypeLoc T) {
5411 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
5412 NewT.setBuiltinLoc(T.getBuiltinLoc());
5413 if (T.needsExtraLocalData())
5414 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5415 return T.getType();
5418 template<typename Derived>
5419 QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5420 ComplexTypeLoc T) {
5421 // FIXME: recurse?
5422 return TransformTypeSpecType(TLB, T);
5425 template <typename Derived>
5426 QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5427 AdjustedTypeLoc TL) {
5428 // Adjustments applied during transformation are handled elsewhere.
5429 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5432 template<typename Derived>
5433 QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5434 DecayedTypeLoc TL) {
5435 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5436 if (OriginalType.isNull())
5437 return QualType();
5439 QualType Result = TL.getType();
5440 if (getDerived().AlwaysRebuild() ||
5441 OriginalType != TL.getOriginalLoc().getType())
5442 Result = SemaRef.Context.getDecayedType(OriginalType);
5443 TLB.push<DecayedTypeLoc>(Result);
5444 // Nothing to set for DecayedTypeLoc.
5445 return Result;
5448 template <typename Derived>
5449 QualType
5450 TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5451 ArrayParameterTypeLoc TL) {
5452 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5453 if (OriginalType.isNull())
5454 return QualType();
5456 QualType Result = TL.getType();
5457 if (getDerived().AlwaysRebuild() ||
5458 OriginalType != TL.getElementLoc().getType())
5459 Result = SemaRef.Context.getArrayParameterType(OriginalType);
5460 TLB.push<ArrayParameterTypeLoc>(Result);
5461 // Nothing to set for ArrayParameterTypeLoc.
5462 return Result;
5465 template<typename Derived>
5466 QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5467 PointerTypeLoc TL) {
5468 QualType PointeeType
5469 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5470 if (PointeeType.isNull())
5471 return QualType();
5473 QualType Result = TL.getType();
5474 if (PointeeType->getAs<ObjCObjectType>()) {
5475 // A dependent pointer type 'T *' has is being transformed such
5476 // that an Objective-C class type is being replaced for 'T'. The
5477 // resulting pointer type is an ObjCObjectPointerType, not a
5478 // PointerType.
5479 Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
5481 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
5482 NewT.setStarLoc(TL.getStarLoc());
5483 return Result;
5486 if (getDerived().AlwaysRebuild() ||
5487 PointeeType != TL.getPointeeLoc().getType()) {
5488 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5489 if (Result.isNull())
5490 return QualType();
5493 // Objective-C ARC can add lifetime qualifiers to the type that we're
5494 // pointing to.
5495 TLB.TypeWasModifiedSafely(Result->getPointeeType());
5497 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
5498 NewT.setSigilLoc(TL.getSigilLoc());
5499 return Result;
5502 template<typename Derived>
5503 QualType
5504 TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5505 BlockPointerTypeLoc TL) {
5506 QualType PointeeType
5507 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5508 if (PointeeType.isNull())
5509 return QualType();
5511 QualType Result = TL.getType();
5512 if (getDerived().AlwaysRebuild() ||
5513 PointeeType != TL.getPointeeLoc().getType()) {
5514 Result = getDerived().RebuildBlockPointerType(PointeeType,
5515 TL.getSigilLoc());
5516 if (Result.isNull())
5517 return QualType();
5520 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
5521 NewT.setSigilLoc(TL.getSigilLoc());
5522 return Result;
5525 /// Transforms a reference type. Note that somewhat paradoxically we
5526 /// don't care whether the type itself is an l-value type or an r-value
5527 /// type; we only care if the type was *written* as an l-value type
5528 /// or an r-value type.
5529 template<typename Derived>
5530 QualType
5531 TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5532 ReferenceTypeLoc TL) {
5533 const ReferenceType *T = TL.getTypePtr();
5535 // Note that this works with the pointee-as-written.
5536 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5537 if (PointeeType.isNull())
5538 return QualType();
5540 QualType Result = TL.getType();
5541 if (getDerived().AlwaysRebuild() ||
5542 PointeeType != T->getPointeeTypeAsWritten()) {
5543 Result = getDerived().RebuildReferenceType(PointeeType,
5544 T->isSpelledAsLValue(),
5545 TL.getSigilLoc());
5546 if (Result.isNull())
5547 return QualType();
5550 // Objective-C ARC can add lifetime qualifiers to the type that we're
5551 // referring to.
5552 TLB.TypeWasModifiedSafely(
5553 Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5555 // r-value references can be rebuilt as l-value references.
5556 ReferenceTypeLoc NewTL;
5557 if (isa<LValueReferenceType>(Result))
5558 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
5559 else
5560 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
5561 NewTL.setSigilLoc(TL.getSigilLoc());
5563 return Result;
5566 template<typename Derived>
5567 QualType
5568 TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5569 LValueReferenceTypeLoc TL) {
5570 return TransformReferenceType(TLB, TL);
5573 template<typename Derived>
5574 QualType
5575 TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5576 RValueReferenceTypeLoc TL) {
5577 return TransformReferenceType(TLB, TL);
5580 template<typename Derived>
5581 QualType
5582 TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5583 MemberPointerTypeLoc TL) {
5584 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5585 if (PointeeType.isNull())
5586 return QualType();
5588 TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
5589 TypeSourceInfo *NewClsTInfo = nullptr;
5590 if (OldClsTInfo) {
5591 NewClsTInfo = getDerived().TransformType(OldClsTInfo);
5592 if (!NewClsTInfo)
5593 return QualType();
5596 const MemberPointerType *T = TL.getTypePtr();
5597 QualType OldClsType = QualType(T->getClass(), 0);
5598 QualType NewClsType;
5599 if (NewClsTInfo)
5600 NewClsType = NewClsTInfo->getType();
5601 else {
5602 NewClsType = getDerived().TransformType(OldClsType);
5603 if (NewClsType.isNull())
5604 return QualType();
5607 QualType Result = TL.getType();
5608 if (getDerived().AlwaysRebuild() ||
5609 PointeeType != T->getPointeeType() ||
5610 NewClsType != OldClsType) {
5611 Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
5612 TL.getStarLoc());
5613 if (Result.isNull())
5614 return QualType();
5617 // If we had to adjust the pointee type when building a member pointer, make
5618 // sure to push TypeLoc info for it.
5619 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5620 if (MPT && PointeeType != MPT->getPointeeType()) {
5621 assert(isa<AdjustedType>(MPT->getPointeeType()));
5622 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
5625 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
5626 NewTL.setSigilLoc(TL.getSigilLoc());
5627 NewTL.setClassTInfo(NewClsTInfo);
5629 return Result;
5632 template<typename Derived>
5633 QualType
5634 TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5635 ConstantArrayTypeLoc TL) {
5636 const ConstantArrayType *T = TL.getTypePtr();
5637 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5638 if (ElementType.isNull())
5639 return QualType();
5641 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5642 Expr *OldSize = TL.getSizeExpr();
5643 if (!OldSize)
5644 OldSize = const_cast<Expr*>(T->getSizeExpr());
5645 Expr *NewSize = nullptr;
5646 if (OldSize) {
5647 EnterExpressionEvaluationContext Unevaluated(
5648 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5649 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5650 NewSize = SemaRef.ActOnConstantExpression(NewSize).get();
5653 QualType Result = TL.getType();
5654 if (getDerived().AlwaysRebuild() ||
5655 ElementType != T->getElementType() ||
5656 (T->getSizeExpr() && NewSize != OldSize)) {
5657 Result = getDerived().RebuildConstantArrayType(ElementType,
5658 T->getSizeModifier(),
5659 T->getSize(), NewSize,
5660 T->getIndexTypeCVRQualifiers(),
5661 TL.getBracketsRange());
5662 if (Result.isNull())
5663 return QualType();
5666 // We might have either a ConstantArrayType or a VariableArrayType now:
5667 // a ConstantArrayType is allowed to have an element type which is a
5668 // VariableArrayType if the type is dependent. Fortunately, all array
5669 // types have the same location layout.
5670 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5671 NewTL.setLBracketLoc(TL.getLBracketLoc());
5672 NewTL.setRBracketLoc(TL.getRBracketLoc());
5673 NewTL.setSizeExpr(NewSize);
5675 return Result;
5678 template<typename Derived>
5679 QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5680 TypeLocBuilder &TLB,
5681 IncompleteArrayTypeLoc TL) {
5682 const IncompleteArrayType *T = TL.getTypePtr();
5683 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5684 if (ElementType.isNull())
5685 return QualType();
5687 QualType Result = TL.getType();
5688 if (getDerived().AlwaysRebuild() ||
5689 ElementType != T->getElementType()) {
5690 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5691 T->getSizeModifier(),
5692 T->getIndexTypeCVRQualifiers(),
5693 TL.getBracketsRange());
5694 if (Result.isNull())
5695 return QualType();
5698 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
5699 NewTL.setLBracketLoc(TL.getLBracketLoc());
5700 NewTL.setRBracketLoc(TL.getRBracketLoc());
5701 NewTL.setSizeExpr(nullptr);
5703 return Result;
5706 template<typename Derived>
5707 QualType
5708 TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5709 VariableArrayTypeLoc TL) {
5710 const VariableArrayType *T = TL.getTypePtr();
5711 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5712 if (ElementType.isNull())
5713 return QualType();
5715 ExprResult SizeResult;
5717 EnterExpressionEvaluationContext Context(
5718 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5719 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5721 if (SizeResult.isInvalid())
5722 return QualType();
5723 SizeResult =
5724 SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);
5725 if (SizeResult.isInvalid())
5726 return QualType();
5728 Expr *Size = SizeResult.get();
5730 QualType Result = TL.getType();
5731 if (getDerived().AlwaysRebuild() ||
5732 ElementType != T->getElementType() ||
5733 Size != T->getSizeExpr()) {
5734 Result = getDerived().RebuildVariableArrayType(ElementType,
5735 T->getSizeModifier(),
5736 Size,
5737 T->getIndexTypeCVRQualifiers(),
5738 TL.getBracketsRange());
5739 if (Result.isNull())
5740 return QualType();
5743 // We might have constant size array now, but fortunately it has the same
5744 // location layout.
5745 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5746 NewTL.setLBracketLoc(TL.getLBracketLoc());
5747 NewTL.setRBracketLoc(TL.getRBracketLoc());
5748 NewTL.setSizeExpr(Size);
5750 return Result;
5753 template<typename Derived>
5754 QualType
5755 TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5756 DependentSizedArrayTypeLoc TL) {
5757 const DependentSizedArrayType *T = TL.getTypePtr();
5758 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5759 if (ElementType.isNull())
5760 return QualType();
5762 // Array bounds are constant expressions.
5763 EnterExpressionEvaluationContext Unevaluated(
5764 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5766 // If we have a VLA then it won't be a constant.
5767 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5769 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5770 Expr *origSize = TL.getSizeExpr();
5771 if (!origSize) origSize = T->getSizeExpr();
5773 ExprResult sizeResult
5774 = getDerived().TransformExpr(origSize);
5775 sizeResult = SemaRef.ActOnConstantExpression(sizeResult);
5776 if (sizeResult.isInvalid())
5777 return QualType();
5779 Expr *size = sizeResult.get();
5781 QualType Result = TL.getType();
5782 if (getDerived().AlwaysRebuild() ||
5783 ElementType != T->getElementType() ||
5784 size != origSize) {
5785 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5786 T->getSizeModifier(),
5787 size,
5788 T->getIndexTypeCVRQualifiers(),
5789 TL.getBracketsRange());
5790 if (Result.isNull())
5791 return QualType();
5794 // We might have any sort of array type now, but fortunately they
5795 // all have the same location layout.
5796 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5797 NewTL.setLBracketLoc(TL.getLBracketLoc());
5798 NewTL.setRBracketLoc(TL.getRBracketLoc());
5799 NewTL.setSizeExpr(size);
5801 return Result;
5804 template <typename Derived>
5805 QualType TreeTransform<Derived>::TransformDependentVectorType(
5806 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5807 const DependentVectorType *T = TL.getTypePtr();
5808 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5809 if (ElementType.isNull())
5810 return QualType();
5812 EnterExpressionEvaluationContext Unevaluated(
5813 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5815 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5816 Size = SemaRef.ActOnConstantExpression(Size);
5817 if (Size.isInvalid())
5818 return QualType();
5820 QualType Result = TL.getType();
5821 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5822 Size.get() != T->getSizeExpr()) {
5823 Result = getDerived().RebuildDependentVectorType(
5824 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5825 if (Result.isNull())
5826 return QualType();
5829 // Result might be dependent or not.
5830 if (isa<DependentVectorType>(Result)) {
5831 DependentVectorTypeLoc NewTL =
5832 TLB.push<DependentVectorTypeLoc>(Result);
5833 NewTL.setNameLoc(TL.getNameLoc());
5834 } else {
5835 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5836 NewTL.setNameLoc(TL.getNameLoc());
5839 return Result;
5842 template<typename Derived>
5843 QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5844 TypeLocBuilder &TLB,
5845 DependentSizedExtVectorTypeLoc TL) {
5846 const DependentSizedExtVectorType *T = TL.getTypePtr();
5848 // FIXME: ext vector locs should be nested
5849 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5850 if (ElementType.isNull())
5851 return QualType();
5853 // Vector sizes are constant expressions.
5854 EnterExpressionEvaluationContext Unevaluated(
5855 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5857 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5858 Size = SemaRef.ActOnConstantExpression(Size);
5859 if (Size.isInvalid())
5860 return QualType();
5862 QualType Result = TL.getType();
5863 if (getDerived().AlwaysRebuild() ||
5864 ElementType != T->getElementType() ||
5865 Size.get() != T->getSizeExpr()) {
5866 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5867 Size.get(),
5868 T->getAttributeLoc());
5869 if (Result.isNull())
5870 return QualType();
5873 // Result might be dependent or not.
5874 if (isa<DependentSizedExtVectorType>(Result)) {
5875 DependentSizedExtVectorTypeLoc NewTL
5876 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
5877 NewTL.setNameLoc(TL.getNameLoc());
5878 } else {
5879 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5880 NewTL.setNameLoc(TL.getNameLoc());
5883 return Result;
5886 template <typename Derived>
5887 QualType
5888 TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5889 ConstantMatrixTypeLoc TL) {
5890 const ConstantMatrixType *T = TL.getTypePtr();
5891 QualType ElementType = getDerived().TransformType(T->getElementType());
5892 if (ElementType.isNull())
5893 return QualType();
5895 QualType Result = TL.getType();
5896 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5897 Result = getDerived().RebuildConstantMatrixType(
5898 ElementType, T->getNumRows(), T->getNumColumns());
5899 if (Result.isNull())
5900 return QualType();
5903 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);
5904 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5905 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5906 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5907 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5909 return Result;
5912 template <typename Derived>
5913 QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5914 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5915 const DependentSizedMatrixType *T = TL.getTypePtr();
5917 QualType ElementType = getDerived().TransformType(T->getElementType());
5918 if (ElementType.isNull()) {
5919 return QualType();
5922 // Matrix dimensions are constant expressions.
5923 EnterExpressionEvaluationContext Unevaluated(
5924 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5926 Expr *origRows = TL.getAttrRowOperand();
5927 if (!origRows)
5928 origRows = T->getRowExpr();
5929 Expr *origColumns = TL.getAttrColumnOperand();
5930 if (!origColumns)
5931 origColumns = T->getColumnExpr();
5933 ExprResult rowResult = getDerived().TransformExpr(origRows);
5934 rowResult = SemaRef.ActOnConstantExpression(rowResult);
5935 if (rowResult.isInvalid())
5936 return QualType();
5938 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5939 columnResult = SemaRef.ActOnConstantExpression(columnResult);
5940 if (columnResult.isInvalid())
5941 return QualType();
5943 Expr *rows = rowResult.get();
5944 Expr *columns = columnResult.get();
5946 QualType Result = TL.getType();
5947 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5948 rows != origRows || columns != origColumns) {
5949 Result = getDerived().RebuildDependentSizedMatrixType(
5950 ElementType, rows, columns, T->getAttributeLoc());
5952 if (Result.isNull())
5953 return QualType();
5956 // We might have any sort of matrix type now, but fortunately they
5957 // all have the same location layout.
5958 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);
5959 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5960 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5961 NewTL.setAttrRowOperand(rows);
5962 NewTL.setAttrColumnOperand(columns);
5963 return Result;
5966 template <typename Derived>
5967 QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
5968 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
5969 const DependentAddressSpaceType *T = TL.getTypePtr();
5971 QualType pointeeType =
5972 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
5974 if (pointeeType.isNull())
5975 return QualType();
5977 // Address spaces are constant expressions.
5978 EnterExpressionEvaluationContext Unevaluated(
5979 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5981 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
5982 AddrSpace = SemaRef.ActOnConstantExpression(AddrSpace);
5983 if (AddrSpace.isInvalid())
5984 return QualType();
5986 QualType Result = TL.getType();
5987 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
5988 AddrSpace.get() != T->getAddrSpaceExpr()) {
5989 Result = getDerived().RebuildDependentAddressSpaceType(
5990 pointeeType, AddrSpace.get(), T->getAttributeLoc());
5991 if (Result.isNull())
5992 return QualType();
5995 // Result might be dependent or not.
5996 if (isa<DependentAddressSpaceType>(Result)) {
5997 DependentAddressSpaceTypeLoc NewTL =
5998 TLB.push<DependentAddressSpaceTypeLoc>(Result);
6000 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6001 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6002 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6004 } else {
6005 TLB.TypeWasModifiedSafely(Result);
6008 return Result;
6011 template <typename Derived>
6012 QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6013 VectorTypeLoc TL) {
6014 const VectorType *T = TL.getTypePtr();
6015 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6016 if (ElementType.isNull())
6017 return QualType();
6019 QualType Result = TL.getType();
6020 if (getDerived().AlwaysRebuild() ||
6021 ElementType != T->getElementType()) {
6022 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6023 T->getVectorKind());
6024 if (Result.isNull())
6025 return QualType();
6028 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
6029 NewTL.setNameLoc(TL.getNameLoc());
6031 return Result;
6034 template<typename Derived>
6035 QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6036 ExtVectorTypeLoc TL) {
6037 const VectorType *T = TL.getTypePtr();
6038 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6039 if (ElementType.isNull())
6040 return QualType();
6042 QualType Result = TL.getType();
6043 if (getDerived().AlwaysRebuild() ||
6044 ElementType != T->getElementType()) {
6045 Result = getDerived().RebuildExtVectorType(ElementType,
6046 T->getNumElements(),
6047 /*FIXME*/ SourceLocation());
6048 if (Result.isNull())
6049 return QualType();
6052 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
6053 NewTL.setNameLoc(TL.getNameLoc());
6055 return Result;
6058 template <typename Derived>
6059 ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6060 ParmVarDecl *OldParm, int indexAdjustment,
6061 std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
6062 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
6063 TypeSourceInfo *NewDI = nullptr;
6065 if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
6066 // If we're substituting into a pack expansion type and we know the
6067 // length we want to expand to, just substitute for the pattern.
6068 TypeLoc OldTL = OldDI->getTypeLoc();
6069 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6071 TypeLocBuilder TLB;
6072 TypeLoc NewTL = OldDI->getTypeLoc();
6073 TLB.reserve(NewTL.getFullDataSize());
6075 QualType Result = getDerived().TransformType(TLB,
6076 OldExpansionTL.getPatternLoc());
6077 if (Result.isNull())
6078 return nullptr;
6080 Result = RebuildPackExpansionType(Result,
6081 OldExpansionTL.getPatternLoc().getSourceRange(),
6082 OldExpansionTL.getEllipsisLoc(),
6083 NumExpansions);
6084 if (Result.isNull())
6085 return nullptr;
6087 PackExpansionTypeLoc NewExpansionTL
6088 = TLB.push<PackExpansionTypeLoc>(Result);
6089 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6090 NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result);
6091 } else
6092 NewDI = getDerived().TransformType(OldDI);
6093 if (!NewDI)
6094 return nullptr;
6096 if (NewDI == OldDI && indexAdjustment == 0)
6097 return OldParm;
6099 ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context,
6100 OldParm->getDeclContext(),
6101 OldParm->getInnerLocStart(),
6102 OldParm->getLocation(),
6103 OldParm->getIdentifier(),
6104 NewDI->getType(),
6105 NewDI,
6106 OldParm->getStorageClass(),
6107 /* DefArg */ nullptr);
6108 newParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
6109 OldParm->getFunctionScopeIndex() + indexAdjustment);
6110 transformedLocalDecl(OldParm, {newParm});
6111 return newParm;
6114 template <typename Derived>
6115 bool TreeTransform<Derived>::TransformFunctionTypeParams(
6116 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6117 const QualType *ParamTypes,
6118 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6119 SmallVectorImpl<QualType> &OutParamTypes,
6120 SmallVectorImpl<ParmVarDecl *> *PVars,
6121 Sema::ExtParameterInfoBuilder &PInfos,
6122 unsigned *LastParamTransformed) {
6123 int indexAdjustment = 0;
6125 unsigned NumParams = Params.size();
6126 for (unsigned i = 0; i != NumParams; ++i) {
6127 if (LastParamTransformed)
6128 *LastParamTransformed = i;
6129 if (ParmVarDecl *OldParm = Params[i]) {
6130 assert(OldParm->getFunctionScopeIndex() == i);
6132 std::optional<unsigned> NumExpansions;
6133 ParmVarDecl *NewParm = nullptr;
6134 if (OldParm->isParameterPack()) {
6135 // We have a function parameter pack that may need to be expanded.
6136 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6138 // Find the parameter packs that could be expanded.
6139 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6140 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6141 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6142 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
6144 // Determine whether we should expand the parameter packs.
6145 bool ShouldExpand = false;
6146 bool RetainExpansion = false;
6147 std::optional<unsigned> OrigNumExpansions;
6148 if (Unexpanded.size() > 0) {
6149 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6150 NumExpansions = OrigNumExpansions;
6151 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
6152 Pattern.getSourceRange(),
6153 Unexpanded,
6154 ShouldExpand,
6155 RetainExpansion,
6156 NumExpansions)) {
6157 return true;
6159 } else {
6160 #ifndef NDEBUG
6161 const AutoType *AT =
6162 Pattern.getType().getTypePtr()->getContainedAutoType();
6163 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6164 "Could not find parameter packs or undeduced auto type!");
6165 #endif
6168 if (ShouldExpand) {
6169 // Expand the function parameter pack into multiple, separate
6170 // parameters.
6171 getDerived().ExpandingFunctionParameterPack(OldParm);
6172 for (unsigned I = 0; I != *NumExpansions; ++I) {
6173 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6174 ParmVarDecl *NewParm
6175 = getDerived().TransformFunctionTypeParam(OldParm,
6176 indexAdjustment++,
6177 OrigNumExpansions,
6178 /*ExpectParameterPack=*/false);
6179 if (!NewParm)
6180 return true;
6182 if (ParamInfos)
6183 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6184 OutParamTypes.push_back(NewParm->getType());
6185 if (PVars)
6186 PVars->push_back(NewParm);
6189 // If we're supposed to retain a pack expansion, do so by temporarily
6190 // forgetting the partially-substituted parameter pack.
6191 if (RetainExpansion) {
6192 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6193 ParmVarDecl *NewParm
6194 = getDerived().TransformFunctionTypeParam(OldParm,
6195 indexAdjustment++,
6196 OrigNumExpansions,
6197 /*ExpectParameterPack=*/false);
6198 if (!NewParm)
6199 return true;
6201 if (ParamInfos)
6202 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6203 OutParamTypes.push_back(NewParm->getType());
6204 if (PVars)
6205 PVars->push_back(NewParm);
6208 // The next parameter should have the same adjustment as the
6209 // last thing we pushed, but we post-incremented indexAdjustment
6210 // on every push. Also, if we push nothing, the adjustment should
6211 // go down by one.
6212 indexAdjustment--;
6214 // We're done with the pack expansion.
6215 continue;
6218 // We'll substitute the parameter now without expanding the pack
6219 // expansion.
6220 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6221 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6222 indexAdjustment,
6223 NumExpansions,
6224 /*ExpectParameterPack=*/true);
6225 assert(NewParm->isParameterPack() &&
6226 "Parameter pack no longer a parameter pack after "
6227 "transformation.");
6228 } else {
6229 NewParm = getDerived().TransformFunctionTypeParam(
6230 OldParm, indexAdjustment, std::nullopt,
6231 /*ExpectParameterPack=*/false);
6234 if (!NewParm)
6235 return true;
6237 if (ParamInfos)
6238 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6239 OutParamTypes.push_back(NewParm->getType());
6240 if (PVars)
6241 PVars->push_back(NewParm);
6242 continue;
6245 // Deal with the possibility that we don't have a parameter
6246 // declaration for this parameter.
6247 assert(ParamTypes);
6248 QualType OldType = ParamTypes[i];
6249 bool IsPackExpansion = false;
6250 std::optional<unsigned> NumExpansions;
6251 QualType NewType;
6252 if (const PackExpansionType *Expansion
6253 = dyn_cast<PackExpansionType>(OldType)) {
6254 // We have a function parameter pack that may need to be expanded.
6255 QualType Pattern = Expansion->getPattern();
6256 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6257 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6259 // Determine whether we should expand the parameter packs.
6260 bool ShouldExpand = false;
6261 bool RetainExpansion = false;
6262 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
6263 Unexpanded,
6264 ShouldExpand,
6265 RetainExpansion,
6266 NumExpansions)) {
6267 return true;
6270 if (ShouldExpand) {
6271 // Expand the function parameter pack into multiple, separate
6272 // parameters.
6273 for (unsigned I = 0; I != *NumExpansions; ++I) {
6274 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6275 QualType NewType = getDerived().TransformType(Pattern);
6276 if (NewType.isNull())
6277 return true;
6279 if (NewType->containsUnexpandedParameterPack()) {
6280 NewType = getSema().getASTContext().getPackExpansionType(
6281 NewType, std::nullopt);
6283 if (NewType.isNull())
6284 return true;
6287 if (ParamInfos)
6288 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6289 OutParamTypes.push_back(NewType);
6290 if (PVars)
6291 PVars->push_back(nullptr);
6294 // We're done with the pack expansion.
6295 continue;
6298 // If we're supposed to retain a pack expansion, do so by temporarily
6299 // forgetting the partially-substituted parameter pack.
6300 if (RetainExpansion) {
6301 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6302 QualType NewType = getDerived().TransformType(Pattern);
6303 if (NewType.isNull())
6304 return true;
6306 if (ParamInfos)
6307 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6308 OutParamTypes.push_back(NewType);
6309 if (PVars)
6310 PVars->push_back(nullptr);
6313 // We'll substitute the parameter now without expanding the pack
6314 // expansion.
6315 OldType = Expansion->getPattern();
6316 IsPackExpansion = true;
6317 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6318 NewType = getDerived().TransformType(OldType);
6319 } else {
6320 NewType = getDerived().TransformType(OldType);
6323 if (NewType.isNull())
6324 return true;
6326 if (IsPackExpansion)
6327 NewType = getSema().Context.getPackExpansionType(NewType,
6328 NumExpansions);
6330 if (ParamInfos)
6331 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6332 OutParamTypes.push_back(NewType);
6333 if (PVars)
6334 PVars->push_back(nullptr);
6337 #ifndef NDEBUG
6338 if (PVars) {
6339 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6340 if (ParmVarDecl *parm = (*PVars)[i])
6341 assert(parm->getFunctionScopeIndex() == i);
6343 #endif
6345 return false;
6348 template<typename Derived>
6349 QualType
6350 TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6351 FunctionProtoTypeLoc TL) {
6352 SmallVector<QualType, 4> ExceptionStorage;
6353 return getDerived().TransformFunctionProtoType(
6354 TLB, TL, nullptr, Qualifiers(),
6355 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6356 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6357 ExceptionStorage, Changed);
6361 template<typename Derived> template<typename Fn>
6362 QualType TreeTransform<Derived>::TransformFunctionProtoType(
6363 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6364 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6366 // Transform the parameters and return type.
6368 // We are required to instantiate the params and return type in source order.
6369 // When the function has a trailing return type, we instantiate the
6370 // parameters before the return type, since the return type can then refer
6371 // to the parameters themselves (via decltype, sizeof, etc.).
6373 SmallVector<QualType, 4> ParamTypes;
6374 SmallVector<ParmVarDecl*, 4> ParamDecls;
6375 Sema::ExtParameterInfoBuilder ExtParamInfos;
6376 const FunctionProtoType *T = TL.getTypePtr();
6378 QualType ResultType;
6380 if (T->hasTrailingReturn()) {
6381 if (getDerived().TransformFunctionTypeParams(
6382 TL.getBeginLoc(), TL.getParams(),
6383 TL.getTypePtr()->param_type_begin(),
6384 T->getExtParameterInfosOrNull(),
6385 ParamTypes, &ParamDecls, ExtParamInfos))
6386 return QualType();
6389 // C++11 [expr.prim.general]p3:
6390 // If a declaration declares a member function or member function
6391 // template of a class X, the expression this is a prvalue of type
6392 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6393 // and the end of the function-definition, member-declarator, or
6394 // declarator.
6395 auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.getCurLexicalContext());
6396 Sema::CXXThisScopeRAII ThisScope(
6397 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6399 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6400 if (ResultType.isNull())
6401 return QualType();
6404 else {
6405 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6406 if (ResultType.isNull())
6407 return QualType();
6409 if (getDerived().TransformFunctionTypeParams(
6410 TL.getBeginLoc(), TL.getParams(),
6411 TL.getTypePtr()->param_type_begin(),
6412 T->getExtParameterInfosOrNull(),
6413 ParamTypes, &ParamDecls, ExtParamInfos))
6414 return QualType();
6417 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6419 bool EPIChanged = false;
6420 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6421 return QualType();
6423 // Handle extended parameter information.
6424 if (auto NewExtParamInfos =
6425 ExtParamInfos.getPointerOrNull(ParamTypes.size())) {
6426 if (!EPI.ExtParameterInfos ||
6427 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6428 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6429 EPIChanged = true;
6431 EPI.ExtParameterInfos = NewExtParamInfos;
6432 } else if (EPI.ExtParameterInfos) {
6433 EPIChanged = true;
6434 EPI.ExtParameterInfos = nullptr;
6437 // Transform any function effects with unevaluated conditions.
6438 // Hold this set in a local for the rest of this function, since EPI
6439 // may need to hold a FunctionEffectsRef pointing into it.
6440 std::optional<FunctionEffectSet> NewFX;
6441 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6442 NewFX.emplace();
6443 EnterExpressionEvaluationContext Unevaluated(
6444 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6446 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6447 FunctionEffectWithCondition NewEC = PrevEC;
6448 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6449 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6450 if (NewExpr.isInvalid())
6451 return QualType();
6452 std::optional<FunctionEffectMode> Mode =
6453 SemaRef.ActOnEffectExpression(NewExpr.get(), PrevEC.Effect.name());
6454 if (!Mode)
6455 return QualType();
6457 // The condition expression has been transformed, and re-evaluated.
6458 // It may or may not have become constant.
6459 switch (*Mode) {
6460 case FunctionEffectMode::True:
6461 NewEC.Cond = {};
6462 break;
6463 case FunctionEffectMode::False:
6464 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6465 NewEC.Cond = {};
6466 break;
6467 case FunctionEffectMode::Dependent:
6468 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6469 break;
6470 case FunctionEffectMode::None:
6471 llvm_unreachable(
6472 "FunctionEffectMode::None shouldn't be possible here");
6475 if (!SemaRef.diagnoseConflictingFunctionEffect(*NewFX, NewEC,
6476 TL.getBeginLoc())) {
6477 FunctionEffectSet::Conflicts Errs;
6478 NewFX->insert(NewEC, Errs);
6479 assert(Errs.empty());
6482 EPI.FunctionEffects = *NewFX;
6483 EPIChanged = true;
6486 QualType Result = TL.getType();
6487 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6488 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6489 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6490 if (Result.isNull())
6491 return QualType();
6494 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
6495 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6496 NewTL.setLParenLoc(TL.getLParenLoc());
6497 NewTL.setRParenLoc(TL.getRParenLoc());
6498 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6499 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6500 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6501 NewTL.setParam(i, ParamDecls[i]);
6503 return Result;
6506 template<typename Derived>
6507 bool TreeTransform<Derived>::TransformExceptionSpec(
6508 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6509 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6510 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6512 // Instantiate a dynamic noexcept expression, if any.
6513 if (isComputedNoexcept(ESI.Type)) {
6514 // Update this scrope because ContextDecl in Sema will be used in
6515 // TransformExpr.
6516 auto *Method = dyn_cast_if_present<CXXMethodDecl>(ESI.SourceTemplate);
6517 Sema::CXXThisScopeRAII ThisScope(
6518 SemaRef, Method ? Method->getParent() : nullptr,
6519 Method ? Method->getMethodQualifiers() : Qualifiers{},
6520 Method != nullptr);
6521 EnterExpressionEvaluationContext Unevaluated(
6522 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6523 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6524 if (NoexceptExpr.isInvalid())
6525 return true;
6527 ExceptionSpecificationType EST = ESI.Type;
6528 NoexceptExpr =
6529 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6530 if (NoexceptExpr.isInvalid())
6531 return true;
6533 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6534 Changed = true;
6535 ESI.NoexceptExpr = NoexceptExpr.get();
6536 ESI.Type = EST;
6539 if (ESI.Type != EST_Dynamic)
6540 return false;
6542 // Instantiate a dynamic exception specification's type.
6543 for (QualType T : ESI.Exceptions) {
6544 if (const PackExpansionType *PackExpansion =
6545 T->getAs<PackExpansionType>()) {
6546 Changed = true;
6548 // We have a pack expansion. Instantiate it.
6549 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6550 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
6551 Unexpanded);
6552 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6554 // Determine whether the set of unexpanded parameter packs can and
6555 // should
6556 // be expanded.
6557 bool Expand = false;
6558 bool RetainExpansion = false;
6559 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
6560 // FIXME: Track the location of the ellipsis (and track source location
6561 // information for the types in the exception specification in general).
6562 if (getDerived().TryExpandParameterPacks(
6563 Loc, SourceRange(), Unexpanded, Expand,
6564 RetainExpansion, NumExpansions))
6565 return true;
6567 if (!Expand) {
6568 // We can't expand this pack expansion into separate arguments yet;
6569 // just substitute into the pattern and create a new pack expansion
6570 // type.
6571 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6572 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6573 if (U.isNull())
6574 return true;
6576 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
6577 Exceptions.push_back(U);
6578 continue;
6581 // Substitute into the pack expansion pattern for each slice of the
6582 // pack.
6583 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6584 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
6586 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6587 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6588 return true;
6590 Exceptions.push_back(U);
6592 } else {
6593 QualType U = getDerived().TransformType(T);
6594 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6595 return true;
6596 if (T != U)
6597 Changed = true;
6599 Exceptions.push_back(U);
6603 ESI.Exceptions = Exceptions;
6604 if (ESI.Exceptions.empty())
6605 ESI.Type = EST_DynamicNone;
6606 return false;
6609 template<typename Derived>
6610 QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6611 TypeLocBuilder &TLB,
6612 FunctionNoProtoTypeLoc TL) {
6613 const FunctionNoProtoType *T = TL.getTypePtr();
6614 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6615 if (ResultType.isNull())
6616 return QualType();
6618 QualType Result = TL.getType();
6619 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6620 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6622 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
6623 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6624 NewTL.setLParenLoc(TL.getLParenLoc());
6625 NewTL.setRParenLoc(TL.getRParenLoc());
6626 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6628 return Result;
6631 template <typename Derived>
6632 QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6633 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6634 const UnresolvedUsingType *T = TL.getTypePtr();
6635 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6636 if (!D)
6637 return QualType();
6639 QualType Result = TL.getType();
6640 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6641 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6642 if (Result.isNull())
6643 return QualType();
6646 // We might get an arbitrary type spec type back. We should at
6647 // least always get a type spec type, though.
6648 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result);
6649 NewTL.setNameLoc(TL.getNameLoc());
6651 return Result;
6654 template <typename Derived>
6655 QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6656 UsingTypeLoc TL) {
6657 const UsingType *T = TL.getTypePtr();
6659 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6660 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6661 if (!Found)
6662 return QualType();
6664 QualType Underlying = getDerived().TransformType(T->desugar());
6665 if (Underlying.isNull())
6666 return QualType();
6668 QualType Result = TL.getType();
6669 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6670 Underlying != T->getUnderlyingType()) {
6671 Result = getDerived().RebuildUsingType(Found, Underlying);
6672 if (Result.isNull())
6673 return QualType();
6676 TLB.pushTypeSpec(Result).setNameLoc(TL.getNameLoc());
6677 return Result;
6680 template<typename Derived>
6681 QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6682 TypedefTypeLoc TL) {
6683 const TypedefType *T = TL.getTypePtr();
6684 TypedefNameDecl *Typedef
6685 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6686 T->getDecl()));
6687 if (!Typedef)
6688 return QualType();
6690 QualType Result = TL.getType();
6691 if (getDerived().AlwaysRebuild() ||
6692 Typedef != T->getDecl()) {
6693 Result = getDerived().RebuildTypedefType(Typedef);
6694 if (Result.isNull())
6695 return QualType();
6698 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
6699 NewTL.setNameLoc(TL.getNameLoc());
6701 return Result;
6704 template<typename Derived>
6705 QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6706 TypeOfExprTypeLoc TL) {
6707 // typeof expressions are not potentially evaluated contexts
6708 EnterExpressionEvaluationContext Unevaluated(
6709 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6710 Sema::ReuseLambdaContextDecl);
6712 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6713 if (E.isInvalid())
6714 return QualType();
6716 E = SemaRef.HandleExprEvaluationContextForTypeof(E.get());
6717 if (E.isInvalid())
6718 return QualType();
6720 QualType Result = TL.getType();
6721 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
6722 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6723 Result =
6724 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6725 if (Result.isNull())
6726 return QualType();
6729 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
6730 NewTL.setTypeofLoc(TL.getTypeofLoc());
6731 NewTL.setLParenLoc(TL.getLParenLoc());
6732 NewTL.setRParenLoc(TL.getRParenLoc());
6734 return Result;
6737 template<typename Derived>
6738 QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6739 TypeOfTypeLoc TL) {
6740 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6741 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6742 if (!New_Under_TI)
6743 return QualType();
6745 QualType Result = TL.getType();
6746 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
6747 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6748 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6749 if (Result.isNull())
6750 return QualType();
6753 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
6754 NewTL.setTypeofLoc(TL.getTypeofLoc());
6755 NewTL.setLParenLoc(TL.getLParenLoc());
6756 NewTL.setRParenLoc(TL.getRParenLoc());
6757 NewTL.setUnmodifiedTInfo(New_Under_TI);
6759 return Result;
6762 template<typename Derived>
6763 QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6764 DecltypeTypeLoc TL) {
6765 const DecltypeType *T = TL.getTypePtr();
6767 // decltype expressions are not potentially evaluated contexts
6768 EnterExpressionEvaluationContext Unevaluated(
6769 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
6770 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
6772 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6773 if (E.isInvalid())
6774 return QualType();
6776 E = getSema().ActOnDecltypeExpression(E.get());
6777 if (E.isInvalid())
6778 return QualType();
6780 QualType Result = TL.getType();
6781 if (getDerived().AlwaysRebuild() ||
6782 E.get() != T->getUnderlyingExpr()) {
6783 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6784 if (Result.isNull())
6785 return QualType();
6787 else E.get();
6789 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
6790 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6791 NewTL.setRParenLoc(TL.getRParenLoc());
6792 return Result;
6795 template <typename Derived>
6796 QualType
6797 TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
6798 PackIndexingTypeLoc TL) {
6799 // Transform the index
6800 ExprResult IndexExpr;
6802 EnterExpressionEvaluationContext ConstantContext(
6803 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6805 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
6806 if (IndexExpr.isInvalid())
6807 return QualType();
6809 QualType Pattern = TL.getPattern();
6811 const PackIndexingType *PIT = TL.getTypePtr();
6812 SmallVector<QualType, 5> SubtitutedTypes;
6813 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
6815 bool NotYetExpanded = Types.empty();
6816 bool FullySubstituted = true;
6818 if (Types.empty() && !PIT->expandsToEmptyPack())
6819 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
6821 for (QualType T : Types) {
6822 if (!T->containsUnexpandedParameterPack()) {
6823 QualType Transformed = getDerived().TransformType(T);
6824 if (Transformed.isNull())
6825 return QualType();
6826 SubtitutedTypes.push_back(Transformed);
6827 continue;
6830 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6831 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
6832 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6833 // Determine whether the set of unexpanded parameter packs can and should
6834 // be expanded.
6835 bool ShouldExpand = true;
6836 bool RetainExpansion = false;
6837 std::optional<unsigned> OrigNumExpansions;
6838 std::optional<unsigned> NumExpansions = OrigNumExpansions;
6839 if (getDerived().TryExpandParameterPacks(TL.getEllipsisLoc(), SourceRange(),
6840 Unexpanded, ShouldExpand,
6841 RetainExpansion, NumExpansions))
6842 return QualType();
6843 if (!ShouldExpand) {
6844 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6845 // FIXME: should we keep TypeLoc for individual expansions in
6846 // PackIndexingTypeLoc?
6847 TypeSourceInfo *TI =
6848 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, TL.getBeginLoc());
6849 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
6850 if (Pack.isNull())
6851 return QualType();
6852 if (NotYetExpanded) {
6853 FullySubstituted = false;
6854 QualType Out = getDerived().RebuildPackIndexingType(
6855 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6856 FullySubstituted);
6857 if (Out.isNull())
6858 return QualType();
6860 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6861 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6862 return Out;
6864 SubtitutedTypes.push_back(Pack);
6865 continue;
6867 for (unsigned I = 0; I != *NumExpansions; ++I) {
6868 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6869 QualType Out = getDerived().TransformType(T);
6870 if (Out.isNull())
6871 return QualType();
6872 SubtitutedTypes.push_back(Out);
6873 FullySubstituted &= !Out->containsUnexpandedParameterPack();
6875 // If we're supposed to retain a pack expansion, do so by temporarily
6876 // forgetting the partially-substituted parameter pack.
6877 if (RetainExpansion) {
6878 FullySubstituted = false;
6879 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6880 QualType Out = getDerived().TransformType(T);
6881 if (Out.isNull())
6882 return QualType();
6883 SubtitutedTypes.push_back(Out);
6887 // A pack indexing type can appear in a larger pack expansion,
6888 // e.g. `Pack...[pack_of_indexes]...`
6889 // so we need to temporarily disable substitution of pack elements
6890 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6891 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
6893 QualType Out = getDerived().RebuildPackIndexingType(
6894 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6895 FullySubstituted, SubtitutedTypes);
6896 if (Out.isNull())
6897 return Out;
6899 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6900 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6901 return Out;
6904 template<typename Derived>
6905 QualType TreeTransform<Derived>::TransformUnaryTransformType(
6906 TypeLocBuilder &TLB,
6907 UnaryTransformTypeLoc TL) {
6908 QualType Result = TL.getType();
6909 if (Result->isDependentType()) {
6910 const UnaryTransformType *T = TL.getTypePtr();
6912 TypeSourceInfo *NewBaseTSI =
6913 getDerived().TransformType(TL.getUnderlyingTInfo());
6914 if (!NewBaseTSI)
6915 return QualType();
6916 QualType NewBase = NewBaseTSI->getType();
6918 Result = getDerived().RebuildUnaryTransformType(NewBase,
6919 T->getUTTKind(),
6920 TL.getKWLoc());
6921 if (Result.isNull())
6922 return QualType();
6925 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
6926 NewTL.setKWLoc(TL.getKWLoc());
6927 NewTL.setParensRange(TL.getParensRange());
6928 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6929 return Result;
6932 template<typename Derived>
6933 QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6934 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6935 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6937 CXXScopeSpec SS;
6938 TemplateName TemplateName = getDerived().TransformTemplateName(
6939 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6940 if (TemplateName.isNull())
6941 return QualType();
6943 QualType OldDeduced = T->getDeducedType();
6944 QualType NewDeduced;
6945 if (!OldDeduced.isNull()) {
6946 NewDeduced = getDerived().TransformType(OldDeduced);
6947 if (NewDeduced.isNull())
6948 return QualType();
6951 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
6952 TemplateName, NewDeduced);
6953 if (Result.isNull())
6954 return QualType();
6956 DeducedTemplateSpecializationTypeLoc NewTL =
6957 TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
6958 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6960 return Result;
6963 template<typename Derived>
6964 QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
6965 RecordTypeLoc TL) {
6966 const RecordType *T = TL.getTypePtr();
6967 RecordDecl *Record
6968 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6969 T->getDecl()));
6970 if (!Record)
6971 return QualType();
6973 QualType Result = TL.getType();
6974 if (getDerived().AlwaysRebuild() ||
6975 Record != T->getDecl()) {
6976 Result = getDerived().RebuildRecordType(Record);
6977 if (Result.isNull())
6978 return QualType();
6981 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
6982 NewTL.setNameLoc(TL.getNameLoc());
6984 return Result;
6987 template<typename Derived>
6988 QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
6989 EnumTypeLoc TL) {
6990 const EnumType *T = TL.getTypePtr();
6991 EnumDecl *Enum
6992 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6993 T->getDecl()));
6994 if (!Enum)
6995 return QualType();
6997 QualType Result = TL.getType();
6998 if (getDerived().AlwaysRebuild() ||
6999 Enum != T->getDecl()) {
7000 Result = getDerived().RebuildEnumType(Enum);
7001 if (Result.isNull())
7002 return QualType();
7005 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
7006 NewTL.setNameLoc(TL.getNameLoc());
7008 return Result;
7011 template<typename Derived>
7012 QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7013 TypeLocBuilder &TLB,
7014 InjectedClassNameTypeLoc TL) {
7015 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
7016 TL.getTypePtr()->getDecl());
7017 if (!D) return QualType();
7019 QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
7020 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
7021 return T;
7024 template<typename Derived>
7025 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7026 TypeLocBuilder &TLB,
7027 TemplateTypeParmTypeLoc TL) {
7028 return getDerived().TransformTemplateTypeParmType(
7029 TLB, TL,
7030 /*SuppressObjCLifetime=*/false);
7033 template <typename Derived>
7034 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7035 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7036 return TransformTypeSpecType(TLB, TL);
7039 template<typename Derived>
7040 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7041 TypeLocBuilder &TLB,
7042 SubstTemplateTypeParmTypeLoc TL) {
7043 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7045 Decl *NewReplaced =
7046 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7048 // Substitute into the replacement type, which itself might involve something
7049 // that needs to be transformed. This only tends to occur with default
7050 // template arguments of template template parameters.
7051 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7052 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7053 if (Replacement.isNull())
7054 return QualType();
7056 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7057 Replacement, NewReplaced, T->getIndex(), T->getPackIndex());
7059 // Propagate type-source information.
7060 SubstTemplateTypeParmTypeLoc NewTL
7061 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
7062 NewTL.setNameLoc(TL.getNameLoc());
7063 return Result;
7067 template<typename Derived>
7068 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7069 TypeLocBuilder &TLB,
7070 SubstTemplateTypeParmPackTypeLoc TL) {
7071 return getDerived().TransformSubstTemplateTypeParmPackType(
7072 TLB, TL, /*SuppressObjCLifetime=*/false);
7075 template <typename Derived>
7076 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7077 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7078 return TransformTypeSpecType(TLB, TL);
7081 template<typename Derived>
7082 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7083 TypeLocBuilder &TLB,
7084 TemplateSpecializationTypeLoc TL) {
7085 const TemplateSpecializationType *T = TL.getTypePtr();
7087 // The nested-name-specifier never matters in a TemplateSpecializationType,
7088 // because we can't have a dependent nested-name-specifier anyway.
7089 CXXScopeSpec SS;
7090 TemplateName Template
7091 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
7092 TL.getTemplateNameLoc());
7093 if (Template.isNull())
7094 return QualType();
7096 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
7099 template<typename Derived>
7100 QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7101 AtomicTypeLoc TL) {
7102 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7103 if (ValueType.isNull())
7104 return QualType();
7106 QualType Result = TL.getType();
7107 if (getDerived().AlwaysRebuild() ||
7108 ValueType != TL.getValueLoc().getType()) {
7109 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7110 if (Result.isNull())
7111 return QualType();
7114 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
7115 NewTL.setKWLoc(TL.getKWLoc());
7116 NewTL.setLParenLoc(TL.getLParenLoc());
7117 NewTL.setRParenLoc(TL.getRParenLoc());
7119 return Result;
7122 template <typename Derived>
7123 QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7124 PipeTypeLoc TL) {
7125 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7126 if (ValueType.isNull())
7127 return QualType();
7129 QualType Result = TL.getType();
7130 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7131 const PipeType *PT = Result->castAs<PipeType>();
7132 bool isReadPipe = PT->isReadOnly();
7133 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7134 if (Result.isNull())
7135 return QualType();
7138 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);
7139 NewTL.setKWLoc(TL.getKWLoc());
7141 return Result;
7144 template <typename Derived>
7145 QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7146 BitIntTypeLoc TL) {
7147 const BitIntType *EIT = TL.getTypePtr();
7148 QualType Result = TL.getType();
7150 if (getDerived().AlwaysRebuild()) {
7151 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7152 EIT->getNumBits(), TL.getNameLoc());
7153 if (Result.isNull())
7154 return QualType();
7157 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
7158 NewTL.setNameLoc(TL.getNameLoc());
7159 return Result;
7162 template <typename Derived>
7163 QualType TreeTransform<Derived>::TransformDependentBitIntType(
7164 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7165 const DependentBitIntType *EIT = TL.getTypePtr();
7167 EnterExpressionEvaluationContext Unevaluated(
7168 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7169 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7170 BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr);
7172 if (BitsExpr.isInvalid())
7173 return QualType();
7175 QualType Result = TL.getType();
7177 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7178 Result = getDerived().RebuildDependentBitIntType(
7179 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7181 if (Result.isNull())
7182 return QualType();
7185 if (isa<DependentBitIntType>(Result)) {
7186 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);
7187 NewTL.setNameLoc(TL.getNameLoc());
7188 } else {
7189 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
7190 NewTL.setNameLoc(TL.getNameLoc());
7192 return Result;
7195 /// Simple iterator that traverses the template arguments in a
7196 /// container that provides a \c getArgLoc() member function.
7198 /// This iterator is intended to be used with the iterator form of
7199 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7200 template<typename ArgLocContainer>
7201 class TemplateArgumentLocContainerIterator {
7202 ArgLocContainer *Container;
7203 unsigned Index;
7205 public:
7206 typedef TemplateArgumentLoc value_type;
7207 typedef TemplateArgumentLoc reference;
7208 typedef int difference_type;
7209 typedef std::input_iterator_tag iterator_category;
7211 class pointer {
7212 TemplateArgumentLoc Arg;
7214 public:
7215 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7217 const TemplateArgumentLoc *operator->() const {
7218 return &Arg;
7223 TemplateArgumentLocContainerIterator() {}
7225 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7226 unsigned Index)
7227 : Container(&Container), Index(Index) { }
7229 TemplateArgumentLocContainerIterator &operator++() {
7230 ++Index;
7231 return *this;
7234 TemplateArgumentLocContainerIterator operator++(int) {
7235 TemplateArgumentLocContainerIterator Old(*this);
7236 ++(*this);
7237 return Old;
7240 TemplateArgumentLoc operator*() const {
7241 return Container->getArgLoc(Index);
7244 pointer operator->() const {
7245 return pointer(Container->getArgLoc(Index));
7248 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7249 const TemplateArgumentLocContainerIterator &Y) {
7250 return X.Container == Y.Container && X.Index == Y.Index;
7253 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7254 const TemplateArgumentLocContainerIterator &Y) {
7255 return !(X == Y);
7259 template<typename Derived>
7260 QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7261 AutoTypeLoc TL) {
7262 const AutoType *T = TL.getTypePtr();
7263 QualType OldDeduced = T->getDeducedType();
7264 QualType NewDeduced;
7265 if (!OldDeduced.isNull()) {
7266 NewDeduced = getDerived().TransformType(OldDeduced);
7267 if (NewDeduced.isNull())
7268 return QualType();
7271 ConceptDecl *NewCD = nullptr;
7272 TemplateArgumentListInfo NewTemplateArgs;
7273 NestedNameSpecifierLoc NewNestedNameSpec;
7274 if (T->isConstrained()) {
7275 assert(TL.getConceptReference());
7276 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7277 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7279 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7280 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7281 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7282 if (getDerived().TransformTemplateArguments(
7283 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7284 NewTemplateArgs))
7285 return QualType();
7287 if (TL.getNestedNameSpecifierLoc()) {
7288 NewNestedNameSpec
7289 = getDerived().TransformNestedNameSpecifierLoc(
7290 TL.getNestedNameSpecifierLoc());
7291 if (!NewNestedNameSpec)
7292 return QualType();
7296 QualType Result = TL.getType();
7297 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7298 T->isDependentType() || T->isConstrained()) {
7299 // FIXME: Maybe don't rebuild if all template arguments are the same.
7300 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7301 NewArgList.reserve(NewTemplateArgs.size());
7302 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7303 NewArgList.push_back(ArgLoc.getArgument());
7304 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7305 NewArgList);
7306 if (Result.isNull())
7307 return QualType();
7310 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
7311 NewTL.setNameLoc(TL.getNameLoc());
7312 NewTL.setRParenLoc(TL.getRParenLoc());
7313 NewTL.setConceptReference(nullptr);
7315 if (T->isConstrained()) {
7316 DeclarationNameInfo DNI = DeclarationNameInfo(
7317 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7318 TL.getConceptNameLoc(),
7319 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7320 auto *CR = ConceptReference::Create(
7321 SemaRef.Context, NewNestedNameSpec, TL.getTemplateKWLoc(), DNI,
7322 TL.getFoundDecl(), TL.getTypePtr()->getTypeConstraintConcept(),
7323 ASTTemplateArgumentListInfo::Create(SemaRef.Context, NewTemplateArgs));
7324 NewTL.setConceptReference(CR);
7327 return Result;
7330 template <typename Derived>
7331 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7332 TypeLocBuilder &TLB,
7333 TemplateSpecializationTypeLoc TL,
7334 TemplateName Template) {
7335 TemplateArgumentListInfo NewTemplateArgs;
7336 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7337 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7338 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7339 ArgIterator;
7340 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7341 ArgIterator(TL, TL.getNumArgs()),
7342 NewTemplateArgs))
7343 return QualType();
7345 // This needs to be rebuilt if either the arguments changed, or if the
7346 // original template changed. If the template changed, and even if the
7347 // arguments didn't change, these arguments might not correspond to their
7348 // respective parameters, therefore needing conversions.
7349 QualType Result =
7350 getDerived().RebuildTemplateSpecializationType(Template,
7351 TL.getTemplateNameLoc(),
7352 NewTemplateArgs);
7354 if (!Result.isNull()) {
7355 // Specializations of template template parameters are represented as
7356 // TemplateSpecializationTypes, and substitution of type alias templates
7357 // within a dependent context can transform them into
7358 // DependentTemplateSpecializationTypes.
7359 if (isa<DependentTemplateSpecializationType>(Result)) {
7360 DependentTemplateSpecializationTypeLoc NewTL
7361 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7362 NewTL.setElaboratedKeywordLoc(SourceLocation());
7363 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
7364 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7365 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7366 NewTL.setLAngleLoc(TL.getLAngleLoc());
7367 NewTL.setRAngleLoc(TL.getRAngleLoc());
7368 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7369 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7370 return Result;
7373 TemplateSpecializationTypeLoc NewTL
7374 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7375 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7376 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7377 NewTL.setLAngleLoc(TL.getLAngleLoc());
7378 NewTL.setRAngleLoc(TL.getRAngleLoc());
7379 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7380 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7383 return Result;
7386 template <typename Derived>
7387 QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
7388 TypeLocBuilder &TLB,
7389 DependentTemplateSpecializationTypeLoc TL,
7390 TemplateName Template,
7391 CXXScopeSpec &SS) {
7392 TemplateArgumentListInfo NewTemplateArgs;
7393 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7394 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7395 typedef TemplateArgumentLocContainerIterator<
7396 DependentTemplateSpecializationTypeLoc> ArgIterator;
7397 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7398 ArgIterator(TL, TL.getNumArgs()),
7399 NewTemplateArgs))
7400 return QualType();
7402 // FIXME: maybe don't rebuild if all the template arguments are the same.
7404 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
7405 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
7406 TL.getTypePtr()->getKeyword(), DTN->getQualifier(),
7407 DTN->getIdentifier(), NewTemplateArgs.arguments());
7409 DependentTemplateSpecializationTypeLoc NewTL
7410 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7411 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7412 NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
7413 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7414 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7415 NewTL.setLAngleLoc(TL.getLAngleLoc());
7416 NewTL.setRAngleLoc(TL.getRAngleLoc());
7417 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7418 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7419 return Result;
7422 QualType Result
7423 = getDerived().RebuildTemplateSpecializationType(Template,
7424 TL.getTemplateNameLoc(),
7425 NewTemplateArgs);
7427 if (!Result.isNull()) {
7428 /// FIXME: Wrap this in an elaborated-type-specifier?
7429 TemplateSpecializationTypeLoc NewTL
7430 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7431 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7432 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7433 NewTL.setLAngleLoc(TL.getLAngleLoc());
7434 NewTL.setRAngleLoc(TL.getRAngleLoc());
7435 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7436 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7439 return Result;
7442 template<typename Derived>
7443 QualType
7444 TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
7445 ElaboratedTypeLoc TL) {
7446 const ElaboratedType *T = TL.getTypePtr();
7448 NestedNameSpecifierLoc QualifierLoc;
7449 // NOTE: the qualifier in an ElaboratedType is optional.
7450 if (TL.getQualifierLoc()) {
7451 QualifierLoc
7452 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7453 if (!QualifierLoc)
7454 return QualType();
7457 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7458 if (NamedT.isNull())
7459 return QualType();
7461 // C++0x [dcl.type.elab]p2:
7462 // If the identifier resolves to a typedef-name or the simple-template-id
7463 // resolves to an alias template specialization, the
7464 // elaborated-type-specifier is ill-formed.
7465 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7466 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7467 if (const TemplateSpecializationType *TST =
7468 NamedT->getAs<TemplateSpecializationType>()) {
7469 TemplateName Template = TST->getTemplateName();
7470 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7471 Template.getAsTemplateDecl())) {
7472 SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
7473 diag::err_tag_reference_non_tag)
7474 << TAT << Sema::NTK_TypeAliasTemplate
7475 << llvm::to_underlying(
7476 ElaboratedType::getTagTypeKindForKeyword(T->getKeyword()));
7477 SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
7482 QualType Result = TL.getType();
7483 if (getDerived().AlwaysRebuild() ||
7484 QualifierLoc != TL.getQualifierLoc() ||
7485 NamedT != T->getNamedType()) {
7486 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7487 T->getKeyword(),
7488 QualifierLoc, NamedT);
7489 if (Result.isNull())
7490 return QualType();
7493 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7494 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7495 NewTL.setQualifierLoc(QualifierLoc);
7496 return Result;
7499 template <typename Derived>
7500 QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7501 AttributedTypeLoc TL) {
7502 const AttributedType *oldType = TL.getTypePtr();
7503 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7504 if (modifiedType.isNull())
7505 return QualType();
7507 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7508 const Attr *oldAttr = TL.getAttr();
7509 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7510 if (oldAttr && !newAttr)
7511 return QualType();
7513 QualType result = TL.getType();
7515 // FIXME: dependent operand expressions?
7516 if (getDerived().AlwaysRebuild() ||
7517 modifiedType != oldType->getModifiedType()) {
7518 // If the equivalent type is equal to the modified type, we don't want to
7519 // transform it as well because:
7521 // 1. The transformation would yield the same result and is therefore
7522 // superfluous, and
7524 // 2. Transforming the same type twice can cause problems, e.g. if it
7525 // is a FunctionProtoType, we may end up instantiating the function
7526 // parameters twice, which causes an assertion since the parameters
7527 // are already bound to their counterparts in the template for this
7528 // instantiation.
7530 QualType equivalentType = modifiedType;
7531 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7532 TypeLocBuilder AuxiliaryTLB;
7533 AuxiliaryTLB.reserve(TL.getFullDataSize());
7534 equivalentType =
7535 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7536 if (equivalentType.isNull())
7537 return QualType();
7540 // Check whether we can add nullability; it is only represented as
7541 // type sugar, and therefore cannot be diagnosed in any other way.
7542 if (auto nullability = oldType->getImmediateNullability()) {
7543 if (!modifiedType->canHaveNullability()) {
7544 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
7545 : TL.getModifiedLoc().getBeginLoc()),
7546 diag::err_nullability_nonpointer)
7547 << DiagNullabilityKind(*nullability, false) << modifiedType;
7548 return QualType();
7552 result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
7553 modifiedType,
7554 equivalentType,
7555 TL.getAttr());
7558 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
7559 newTL.setAttr(newAttr);
7560 return result;
7563 template <typename Derived>
7564 QualType TreeTransform<Derived>::TransformCountAttributedType(
7565 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7566 const CountAttributedType *OldTy = TL.getTypePtr();
7567 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7568 if (InnerTy.isNull())
7569 return QualType();
7571 Expr *OldCount = TL.getCountExpr();
7572 Expr *NewCount = nullptr;
7573 if (OldCount) {
7574 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7575 if (CountResult.isInvalid())
7576 return QualType();
7577 NewCount = CountResult.get();
7580 QualType Result = TL.getType();
7581 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7582 OldCount != NewCount) {
7583 // Currently, CountAttributedType can only wrap incomplete array types.
7584 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7585 InnerTy, NewCount, OldTy->isCountInBytes(), OldTy->isOrNull());
7588 TLB.push<CountAttributedTypeLoc>(Result);
7589 return Result;
7592 template <typename Derived>
7593 QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7594 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7595 // The BTFTagAttributedType is available for C only.
7596 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7599 template <typename Derived>
7600 QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7601 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7603 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7605 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7606 if (WrappedTy.isNull())
7607 return QualType();
7609 QualType ContainedTy = QualType();
7610 QualType OldContainedTy = oldType->getContainedType();
7611 if (!OldContainedTy.isNull()) {
7612 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7613 if (!oldContainedTSI)
7614 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7615 OldContainedTy, SourceLocation());
7616 TypeSourceInfo *ContainedTSI = getDerived().TransformType(oldContainedTSI);
7617 if (!ContainedTSI)
7618 return QualType();
7619 ContainedTy = ContainedTSI->getType();
7622 QualType Result = TL.getType();
7623 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7624 ContainedTy != oldType->getContainedType()) {
7625 Result = SemaRef.Context.getHLSLAttributedResourceType(
7626 WrappedTy, ContainedTy, oldType->getAttrs());
7629 TLB.push<HLSLAttributedResourceTypeLoc>(Result);
7630 return Result;
7633 template<typename Derived>
7634 QualType
7635 TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7636 ParenTypeLoc TL) {
7637 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7638 if (Inner.isNull())
7639 return QualType();
7641 QualType Result = TL.getType();
7642 if (getDerived().AlwaysRebuild() ||
7643 Inner != TL.getInnerLoc().getType()) {
7644 Result = getDerived().RebuildParenType(Inner);
7645 if (Result.isNull())
7646 return QualType();
7649 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
7650 NewTL.setLParenLoc(TL.getLParenLoc());
7651 NewTL.setRParenLoc(TL.getRParenLoc());
7652 return Result;
7655 template <typename Derived>
7656 QualType
7657 TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7658 MacroQualifiedTypeLoc TL) {
7659 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7660 if (Inner.isNull())
7661 return QualType();
7663 QualType Result = TL.getType();
7664 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7665 Result =
7666 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7667 if (Result.isNull())
7668 return QualType();
7671 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
7672 NewTL.setExpansionLoc(TL.getExpansionLoc());
7673 return Result;
7676 template<typename Derived>
7677 QualType TreeTransform<Derived>::TransformDependentNameType(
7678 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7679 return TransformDependentNameType(TLB, TL, false);
7682 template<typename Derived>
7683 QualType TreeTransform<Derived>::TransformDependentNameType(
7684 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7685 const DependentNameType *T = TL.getTypePtr();
7687 NestedNameSpecifierLoc QualifierLoc
7688 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7689 if (!QualifierLoc)
7690 return QualType();
7692 QualType Result
7693 = getDerived().RebuildDependentNameType(T->getKeyword(),
7694 TL.getElaboratedKeywordLoc(),
7695 QualifierLoc,
7696 T->getIdentifier(),
7697 TL.getNameLoc(),
7698 DeducedTSTContext);
7699 if (Result.isNull())
7700 return QualType();
7702 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7703 QualType NamedT = ElabT->getNamedType();
7704 TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
7706 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7707 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7708 NewTL.setQualifierLoc(QualifierLoc);
7709 } else {
7710 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
7711 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7712 NewTL.setQualifierLoc(QualifierLoc);
7713 NewTL.setNameLoc(TL.getNameLoc());
7715 return Result;
7718 template<typename Derived>
7719 QualType TreeTransform<Derived>::
7720 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7721 DependentTemplateSpecializationTypeLoc TL) {
7722 NestedNameSpecifierLoc QualifierLoc;
7723 if (TL.getQualifierLoc()) {
7724 QualifierLoc
7725 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7726 if (!QualifierLoc)
7727 return QualType();
7730 return getDerived()
7731 .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
7734 template<typename Derived>
7735 QualType TreeTransform<Derived>::
7736 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7737 DependentTemplateSpecializationTypeLoc TL,
7738 NestedNameSpecifierLoc QualifierLoc) {
7739 const DependentTemplateSpecializationType *T = TL.getTypePtr();
7741 TemplateArgumentListInfo NewTemplateArgs;
7742 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7743 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7745 typedef TemplateArgumentLocContainerIterator<
7746 DependentTemplateSpecializationTypeLoc> ArgIterator;
7747 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7748 ArgIterator(TL, TL.getNumArgs()),
7749 NewTemplateArgs))
7750 return QualType();
7752 QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
7753 T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(),
7754 T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs,
7755 /*AllowInjectedClassName*/ false);
7756 if (Result.isNull())
7757 return QualType();
7759 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
7760 QualType NamedT = ElabT->getNamedType();
7762 // Copy information relevant to the template specialization.
7763 TemplateSpecializationTypeLoc NamedTL
7764 = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
7765 NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7766 NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7767 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7768 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7769 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7770 NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7772 // Copy information relevant to the elaborated type.
7773 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7774 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7775 NewTL.setQualifierLoc(QualifierLoc);
7776 } else if (isa<DependentTemplateSpecializationType>(Result)) {
7777 DependentTemplateSpecializationTypeLoc SpecTL
7778 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7779 SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7780 SpecTL.setQualifierLoc(QualifierLoc);
7781 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7782 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7783 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7784 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7785 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7786 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7787 } else {
7788 TemplateSpecializationTypeLoc SpecTL
7789 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7790 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7791 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7792 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7793 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7794 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7795 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7797 return Result;
7800 template<typename Derived>
7801 QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7802 PackExpansionTypeLoc TL) {
7803 QualType Pattern
7804 = getDerived().TransformType(TLB, TL.getPatternLoc());
7805 if (Pattern.isNull())
7806 return QualType();
7808 QualType Result = TL.getType();
7809 if (getDerived().AlwaysRebuild() ||
7810 Pattern != TL.getPatternLoc().getType()) {
7811 Result = getDerived().RebuildPackExpansionType(Pattern,
7812 TL.getPatternLoc().getSourceRange(),
7813 TL.getEllipsisLoc(),
7814 TL.getTypePtr()->getNumExpansions());
7815 if (Result.isNull())
7816 return QualType();
7819 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
7820 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7821 return Result;
7824 template<typename Derived>
7825 QualType
7826 TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7827 ObjCInterfaceTypeLoc TL) {
7828 // ObjCInterfaceType is never dependent.
7829 TLB.pushFullCopy(TL);
7830 return TL.getType();
7833 template<typename Derived>
7834 QualType
7835 TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7836 ObjCTypeParamTypeLoc TL) {
7837 const ObjCTypeParamType *T = TL.getTypePtr();
7838 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7839 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7840 if (!OTP)
7841 return QualType();
7843 QualType Result = TL.getType();
7844 if (getDerived().AlwaysRebuild() ||
7845 OTP != T->getDecl()) {
7846 Result = getDerived().RebuildObjCTypeParamType(
7847 OTP, TL.getProtocolLAngleLoc(),
7848 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7849 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7850 if (Result.isNull())
7851 return QualType();
7854 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
7855 if (TL.getNumProtocols()) {
7856 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7857 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7858 NewTL.setProtocolLoc(i, TL.getProtocolLoc(i));
7859 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7861 return Result;
7864 template<typename Derived>
7865 QualType
7866 TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7867 ObjCObjectTypeLoc TL) {
7868 // Transform base type.
7869 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7870 if (BaseType.isNull())
7871 return QualType();
7873 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7875 // Transform type arguments.
7876 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7877 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7878 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7879 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7880 QualType TypeArg = TypeArgInfo->getType();
7881 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7882 AnyChanged = true;
7884 // We have a pack expansion. Instantiate it.
7885 const auto *PackExpansion = PackExpansionLoc.getType()
7886 ->castAs<PackExpansionType>();
7887 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7888 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
7889 Unexpanded);
7890 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7892 // Determine whether the set of unexpanded parameter packs can
7893 // and should be expanded.
7894 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7895 bool Expand = false;
7896 bool RetainExpansion = false;
7897 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
7898 if (getDerived().TryExpandParameterPacks(
7899 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7900 Unexpanded, Expand, RetainExpansion, NumExpansions))
7901 return QualType();
7903 if (!Expand) {
7904 // We can't expand this pack expansion into separate arguments yet;
7905 // just substitute into the pattern and create a new pack expansion
7906 // type.
7907 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
7909 TypeLocBuilder TypeArgBuilder;
7910 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7911 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7912 PatternLoc);
7913 if (NewPatternType.isNull())
7914 return QualType();
7916 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7917 NewPatternType, NumExpansions);
7918 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);
7919 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7920 NewTypeArgInfos.push_back(
7921 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewExpansionType));
7922 continue;
7925 // Substitute into the pack expansion pattern for each slice of the
7926 // pack.
7927 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
7928 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
7930 TypeLocBuilder TypeArgBuilder;
7931 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7933 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
7934 PatternLoc);
7935 if (NewTypeArg.isNull())
7936 return QualType();
7938 NewTypeArgInfos.push_back(
7939 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7942 continue;
7945 TypeLocBuilder TypeArgBuilder;
7946 TypeArgBuilder.reserve(TypeArgLoc.getFullDataSize());
7947 QualType NewTypeArg =
7948 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
7949 if (NewTypeArg.isNull())
7950 return QualType();
7952 // If nothing changed, just keep the old TypeSourceInfo.
7953 if (NewTypeArg == TypeArg) {
7954 NewTypeArgInfos.push_back(TypeArgInfo);
7955 continue;
7958 NewTypeArgInfos.push_back(
7959 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7960 AnyChanged = true;
7963 QualType Result = TL.getType();
7964 if (getDerived().AlwaysRebuild() || AnyChanged) {
7965 // Rebuild the type.
7966 Result = getDerived().RebuildObjCObjectType(
7967 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
7968 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
7969 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7970 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7972 if (Result.isNull())
7973 return QualType();
7976 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);
7977 NewT.setHasBaseTypeAsWritten(true);
7978 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
7979 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
7980 NewT.setTypeArgTInfo(i, NewTypeArgInfos[i]);
7981 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
7982 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7983 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7984 NewT.setProtocolLoc(i, TL.getProtocolLoc(i));
7985 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7986 return Result;
7989 template<typename Derived>
7990 QualType
7991 TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
7992 ObjCObjectPointerTypeLoc TL) {
7993 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
7994 if (PointeeType.isNull())
7995 return QualType();
7997 QualType Result = TL.getType();
7998 if (getDerived().AlwaysRebuild() ||
7999 PointeeType != TL.getPointeeLoc().getType()) {
8000 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8001 TL.getStarLoc());
8002 if (Result.isNull())
8003 return QualType();
8006 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
8007 NewT.setStarLoc(TL.getStarLoc());
8008 return Result;
8011 //===----------------------------------------------------------------------===//
8012 // Statement transformation
8013 //===----------------------------------------------------------------------===//
8014 template<typename Derived>
8015 StmtResult
8016 TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8017 return S;
8020 template<typename Derived>
8021 StmtResult
8022 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8023 return getDerived().TransformCompoundStmt(S, false);
8026 template<typename Derived>
8027 StmtResult
8028 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8029 bool IsStmtExpr) {
8030 Sema::CompoundScopeRAII CompoundScope(getSema());
8031 Sema::FPFeaturesStateRAII FPSave(getSema());
8032 if (S->hasStoredFPFeatures())
8033 getSema().resetFPOptions(
8034 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8036 const Stmt *ExprResult = S->getStmtExprResult();
8037 bool SubStmtInvalid = false;
8038 bool SubStmtChanged = false;
8039 SmallVector<Stmt*, 8> Statements;
8040 for (auto *B : S->body()) {
8041 StmtResult Result = getDerived().TransformStmt(
8042 B, IsStmtExpr && B == ExprResult ? SDK_StmtExprResult : SDK_Discarded);
8044 if (Result.isInvalid()) {
8045 // Immediately fail if this was a DeclStmt, since it's very
8046 // likely that this will cause problems for future statements.
8047 if (isa<DeclStmt>(B))
8048 return StmtError();
8050 // Otherwise, just keep processing substatements and fail later.
8051 SubStmtInvalid = true;
8052 continue;
8055 SubStmtChanged = SubStmtChanged || Result.get() != B;
8056 Statements.push_back(Result.getAs<Stmt>());
8059 if (SubStmtInvalid)
8060 return StmtError();
8062 if (!getDerived().AlwaysRebuild() &&
8063 !SubStmtChanged)
8064 return S;
8066 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8067 Statements,
8068 S->getRBracLoc(),
8069 IsStmtExpr);
8072 template<typename Derived>
8073 StmtResult
8074 TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8075 ExprResult LHS, RHS;
8077 EnterExpressionEvaluationContext Unevaluated(
8078 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8080 // Transform the left-hand case value.
8081 LHS = getDerived().TransformExpr(S->getLHS());
8082 LHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), LHS);
8083 if (LHS.isInvalid())
8084 return StmtError();
8086 // Transform the right-hand case value (for the GNU case-range extension).
8087 RHS = getDerived().TransformExpr(S->getRHS());
8088 RHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), RHS);
8089 if (RHS.isInvalid())
8090 return StmtError();
8093 // Build the case statement.
8094 // Case statements are always rebuilt so that they will attached to their
8095 // transformed switch statement.
8096 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8097 LHS.get(),
8098 S->getEllipsisLoc(),
8099 RHS.get(),
8100 S->getColonLoc());
8101 if (Case.isInvalid())
8102 return StmtError();
8104 // Transform the statement following the case
8105 StmtResult SubStmt =
8106 getDerived().TransformStmt(S->getSubStmt());
8107 if (SubStmt.isInvalid())
8108 return StmtError();
8110 // Attach the body to the case statement
8111 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8114 template <typename Derived>
8115 StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8116 // Transform the statement following the default case
8117 StmtResult SubStmt =
8118 getDerived().TransformStmt(S->getSubStmt());
8119 if (SubStmt.isInvalid())
8120 return StmtError();
8122 // Default statements are always rebuilt
8123 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8124 SubStmt.get());
8127 template<typename Derived>
8128 StmtResult
8129 TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8130 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8131 if (SubStmt.isInvalid())
8132 return StmtError();
8134 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8135 S->getDecl());
8136 if (!LD)
8137 return StmtError();
8139 // If we're transforming "in-place" (we're not creating new local
8140 // declarations), assume we're replacing the old label statement
8141 // and clear out the reference to it.
8142 if (LD == S->getDecl())
8143 S->getDecl()->setStmt(nullptr);
8145 // FIXME: Pass the real colon location in.
8146 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8147 cast<LabelDecl>(LD), SourceLocation(),
8148 SubStmt.get());
8151 template <typename Derived>
8152 const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8153 if (!R)
8154 return R;
8156 switch (R->getKind()) {
8157 // Transform attributes by calling TransformXXXAttr.
8158 #define ATTR(X) \
8159 case attr::X: \
8160 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8161 #include "clang/Basic/AttrList.inc"
8163 return R;
8166 template <typename Derived>
8167 const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8168 const Stmt *InstS,
8169 const Attr *R) {
8170 if (!R)
8171 return R;
8173 switch (R->getKind()) {
8174 // Transform attributes by calling TransformStmtXXXAttr.
8175 #define ATTR(X) \
8176 case attr::X: \
8177 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8178 #include "clang/Basic/AttrList.inc"
8180 return TransformAttr(R);
8183 template <typename Derived>
8184 StmtResult
8185 TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8186 StmtDiscardKind SDK) {
8187 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8188 if (SubStmt.isInvalid())
8189 return StmtError();
8191 bool AttrsChanged = false;
8192 SmallVector<const Attr *, 1> Attrs;
8194 // Visit attributes and keep track if any are transformed.
8195 for (const auto *I : S->getAttrs()) {
8196 const Attr *R =
8197 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8198 AttrsChanged |= (I != R);
8199 if (R)
8200 Attrs.push_back(R);
8203 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8204 return S;
8206 // If transforming the attributes failed for all of the attributes in the
8207 // statement, don't make an AttributedStmt without attributes.
8208 if (Attrs.empty())
8209 return SubStmt;
8211 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8212 SubStmt.get());
8215 template<typename Derived>
8216 StmtResult
8217 TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8218 // Transform the initialization statement
8219 StmtResult Init = getDerived().TransformStmt(S->getInit());
8220 if (Init.isInvalid())
8221 return StmtError();
8223 Sema::ConditionResult Cond;
8224 if (!S->isConsteval()) {
8225 // Transform the condition
8226 Cond = getDerived().TransformCondition(
8227 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8228 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8229 : Sema::ConditionKind::Boolean);
8230 if (Cond.isInvalid())
8231 return StmtError();
8234 // If this is a constexpr if, determine which arm we should instantiate.
8235 std::optional<bool> ConstexprConditionValue;
8236 if (S->isConstexpr())
8237 ConstexprConditionValue = Cond.getKnownValue();
8239 // Transform the "then" branch.
8240 StmtResult Then;
8241 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8242 EnterExpressionEvaluationContext Ctx(
8243 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8244 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8245 S->isNonNegatedConsteval());
8247 Then = getDerived().TransformStmt(S->getThen());
8248 if (Then.isInvalid())
8249 return StmtError();
8250 } else {
8251 // Discarded branch is replaced with empty CompoundStmt so we can keep
8252 // proper source location for start and end of original branch, so
8253 // subsequent transformations like CoverageMapping work properly
8254 Then = new (getSema().Context)
8255 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8258 // Transform the "else" branch.
8259 StmtResult Else;
8260 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8261 EnterExpressionEvaluationContext Ctx(
8262 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8263 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8264 S->isNegatedConsteval());
8266 Else = getDerived().TransformStmt(S->getElse());
8267 if (Else.isInvalid())
8268 return StmtError();
8269 } else if (S->getElse() && ConstexprConditionValue &&
8270 *ConstexprConditionValue) {
8271 // Same thing here as with <then> branch, we are discarding it, we can't
8272 // replace it with NULL nor NullStmt as we need to keep for source location
8273 // range, for CoverageMapping
8274 Else = new (getSema().Context)
8275 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8278 if (!getDerived().AlwaysRebuild() &&
8279 Init.get() == S->getInit() &&
8280 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8281 Then.get() == S->getThen() &&
8282 Else.get() == S->getElse())
8283 return S;
8285 return getDerived().RebuildIfStmt(
8286 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8287 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8290 template<typename Derived>
8291 StmtResult
8292 TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8293 // Transform the initialization statement
8294 StmtResult Init = getDerived().TransformStmt(S->getInit());
8295 if (Init.isInvalid())
8296 return StmtError();
8298 // Transform the condition.
8299 Sema::ConditionResult Cond = getDerived().TransformCondition(
8300 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8301 Sema::ConditionKind::Switch);
8302 if (Cond.isInvalid())
8303 return StmtError();
8305 // Rebuild the switch statement.
8306 StmtResult Switch =
8307 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8308 Init.get(), Cond, S->getRParenLoc());
8309 if (Switch.isInvalid())
8310 return StmtError();
8312 // Transform the body of the switch statement.
8313 StmtResult Body = getDerived().TransformStmt(S->getBody());
8314 if (Body.isInvalid())
8315 return StmtError();
8317 // Complete the switch statement.
8318 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8319 Body.get());
8322 template<typename Derived>
8323 StmtResult
8324 TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8325 // Transform the condition
8326 Sema::ConditionResult Cond = getDerived().TransformCondition(
8327 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8328 Sema::ConditionKind::Boolean);
8329 if (Cond.isInvalid())
8330 return StmtError();
8332 // OpenACC Restricts a while-loop inside of certain construct/clause
8333 // combinations, so diagnose that here in OpenACC mode.
8334 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8335 SemaRef.OpenACC().ActOnWhileStmt(S->getBeginLoc());
8337 // Transform the body
8338 StmtResult Body = getDerived().TransformStmt(S->getBody());
8339 if (Body.isInvalid())
8340 return StmtError();
8342 if (!getDerived().AlwaysRebuild() &&
8343 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8344 Body.get() == S->getBody())
8345 return Owned(S);
8347 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8348 Cond, S->getRParenLoc(), Body.get());
8351 template<typename Derived>
8352 StmtResult
8353 TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8354 // OpenACC Restricts a do-loop inside of certain construct/clause
8355 // combinations, so diagnose that here in OpenACC mode.
8356 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8357 SemaRef.OpenACC().ActOnDoStmt(S->getBeginLoc());
8359 // Transform the body
8360 StmtResult Body = getDerived().TransformStmt(S->getBody());
8361 if (Body.isInvalid())
8362 return StmtError();
8364 // Transform the condition
8365 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8366 if (Cond.isInvalid())
8367 return StmtError();
8369 if (!getDerived().AlwaysRebuild() &&
8370 Cond.get() == S->getCond() &&
8371 Body.get() == S->getBody())
8372 return S;
8374 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8375 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8376 S->getRParenLoc());
8379 template<typename Derived>
8380 StmtResult
8381 TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8382 if (getSema().getLangOpts().OpenMP)
8383 getSema().OpenMP().startOpenMPLoop();
8385 // Transform the initialization statement
8386 StmtResult Init = getDerived().TransformStmt(S->getInit());
8387 if (Init.isInvalid())
8388 return StmtError();
8390 // In OpenMP loop region loop control variable must be captured and be
8391 // private. Perform analysis of first part (if any).
8392 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8393 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8394 Init.get());
8396 // Transform the condition
8397 Sema::ConditionResult Cond = getDerived().TransformCondition(
8398 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8399 Sema::ConditionKind::Boolean);
8400 if (Cond.isInvalid())
8401 return StmtError();
8403 // Transform the increment
8404 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8405 if (Inc.isInvalid())
8406 return StmtError();
8408 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8409 if (S->getInc() && !FullInc.get())
8410 return StmtError();
8412 // OpenACC Restricts a for-loop inside of certain construct/clause
8413 // combinations, so diagnose that here in OpenACC mode.
8414 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8415 SemaRef.OpenACC().ActOnForStmtBegin(
8416 S->getBeginLoc(), S->getInit(), Init.get(), S->getCond(),
8417 Cond.get().second, S->getInc(), Inc.get());
8419 // Transform the body
8420 StmtResult Body = getDerived().TransformStmt(S->getBody());
8421 if (Body.isInvalid())
8422 return StmtError();
8424 SemaRef.OpenACC().ActOnForStmtEnd(S->getBeginLoc(), Body);
8426 if (!getDerived().AlwaysRebuild() &&
8427 Init.get() == S->getInit() &&
8428 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8429 Inc.get() == S->getInc() &&
8430 Body.get() == S->getBody())
8431 return S;
8433 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8434 Init.get(), Cond, FullInc,
8435 S->getRParenLoc(), Body.get());
8438 template<typename Derived>
8439 StmtResult
8440 TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8441 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8442 S->getLabel());
8443 if (!LD)
8444 return StmtError();
8446 // Goto statements must always be rebuilt, to resolve the label.
8447 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8448 cast<LabelDecl>(LD));
8451 template<typename Derived>
8452 StmtResult
8453 TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8454 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8455 if (Target.isInvalid())
8456 return StmtError();
8457 Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());
8459 if (!getDerived().AlwaysRebuild() &&
8460 Target.get() == S->getTarget())
8461 return S;
8463 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8464 Target.get());
8467 template<typename Derived>
8468 StmtResult
8469 TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8470 return S;
8473 template<typename Derived>
8474 StmtResult
8475 TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8476 return S;
8479 template<typename Derived>
8480 StmtResult
8481 TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8482 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8483 /*NotCopyInit*/false);
8484 if (Result.isInvalid())
8485 return StmtError();
8487 // FIXME: We always rebuild the return statement because there is no way
8488 // to tell whether the return type of the function has changed.
8489 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8492 template<typename Derived>
8493 StmtResult
8494 TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8495 bool DeclChanged = false;
8496 SmallVector<Decl *, 4> Decls;
8497 LambdaScopeInfo *LSI = getSema().getCurLambda();
8498 for (auto *D : S->decls()) {
8499 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8500 if (!Transformed)
8501 return StmtError();
8503 if (Transformed != D)
8504 DeclChanged = true;
8506 if (LSI) {
8507 if (auto *TD = dyn_cast<TypeDecl>(Transformed))
8508 LSI->ContainsUnexpandedParameterPack |=
8509 getSema()
8510 .getASTContext()
8511 .getTypeDeclType(TD)
8512 .getSingleStepDesugaredType(getSema().getASTContext())
8513 ->containsUnexpandedParameterPack();
8515 if (auto *VD = dyn_cast<VarDecl>(Transformed))
8516 LSI->ContainsUnexpandedParameterPack |=
8517 VD->getType()->containsUnexpandedParameterPack();
8520 Decls.push_back(Transformed);
8523 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8524 return S;
8526 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8529 template<typename Derived>
8530 StmtResult
8531 TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8533 SmallVector<Expr*, 8> Constraints;
8534 SmallVector<Expr*, 8> Exprs;
8535 SmallVector<IdentifierInfo *, 4> Names;
8537 ExprResult AsmString;
8538 SmallVector<Expr*, 8> Clobbers;
8540 bool ExprsChanged = false;
8542 // Go through the outputs.
8543 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8544 Names.push_back(S->getOutputIdentifier(I));
8546 // No need to transform the constraint literal.
8547 Constraints.push_back(S->getOutputConstraintLiteral(I));
8549 // Transform the output expr.
8550 Expr *OutputExpr = S->getOutputExpr(I);
8551 ExprResult Result = getDerived().TransformExpr(OutputExpr);
8552 if (Result.isInvalid())
8553 return StmtError();
8555 ExprsChanged |= Result.get() != OutputExpr;
8557 Exprs.push_back(Result.get());
8560 // Go through the inputs.
8561 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8562 Names.push_back(S->getInputIdentifier(I));
8564 // No need to transform the constraint literal.
8565 Constraints.push_back(S->getInputConstraintLiteral(I));
8567 // Transform the input expr.
8568 Expr *InputExpr = S->getInputExpr(I);
8569 ExprResult Result = getDerived().TransformExpr(InputExpr);
8570 if (Result.isInvalid())
8571 return StmtError();
8573 ExprsChanged |= Result.get() != InputExpr;
8575 Exprs.push_back(Result.get());
8578 // Go through the Labels.
8579 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8580 Names.push_back(S->getLabelIdentifier(I));
8582 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(I));
8583 if (Result.isInvalid())
8584 return StmtError();
8585 ExprsChanged |= Result.get() != S->getLabelExpr(I);
8586 Exprs.push_back(Result.get());
8588 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8589 return S;
8591 // Go through the clobbers.
8592 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
8593 Clobbers.push_back(S->getClobberStringLiteral(I));
8595 // No need to transform the asm string literal.
8596 AsmString = S->getAsmString();
8597 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8598 S->isVolatile(), S->getNumOutputs(),
8599 S->getNumInputs(), Names.data(),
8600 Constraints, Exprs, AsmString.get(),
8601 Clobbers, S->getNumLabels(),
8602 S->getRParenLoc());
8605 template<typename Derived>
8606 StmtResult
8607 TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8608 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8610 bool HadError = false, HadChange = false;
8612 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8613 SmallVector<Expr*, 8> TransformedExprs;
8614 TransformedExprs.reserve(SrcExprs.size());
8615 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8616 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8617 if (!Result.isUsable()) {
8618 HadError = true;
8619 } else {
8620 HadChange |= (Result.get() != SrcExprs[i]);
8621 TransformedExprs.push_back(Result.get());
8625 if (HadError) return StmtError();
8626 if (!HadChange && !getDerived().AlwaysRebuild())
8627 return Owned(S);
8629 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8630 AsmToks, S->getAsmString(),
8631 S->getNumOutputs(), S->getNumInputs(),
8632 S->getAllConstraints(), S->getClobbers(),
8633 TransformedExprs, S->getEndLoc());
8636 // C++ Coroutines
8637 template<typename Derived>
8638 StmtResult
8639 TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8640 auto *ScopeInfo = SemaRef.getCurFunction();
8641 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
8642 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8643 ScopeInfo->NeedsCoroutineSuspends &&
8644 ScopeInfo->CoroutineSuspends.first == nullptr &&
8645 ScopeInfo->CoroutineSuspends.second == nullptr &&
8646 "expected clean scope info");
8648 // Set that we have (possibly-invalid) suspend points before we do anything
8649 // that may fail.
8650 ScopeInfo->setNeedsCoroutineSuspends(false);
8652 // We re-build the coroutine promise object (and the coroutine parameters its
8653 // type and constructor depend on) based on the types used in our current
8654 // function. We must do so, and set it on the current FunctionScopeInfo,
8655 // before attempting to transform the other parts of the coroutine body
8656 // statement, such as the implicit suspend statements (because those
8657 // statements reference the FunctionScopeInfo::CoroutinePromise).
8658 if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation()))
8659 return StmtError();
8660 auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());
8661 if (!Promise)
8662 return StmtError();
8663 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8664 ScopeInfo->CoroutinePromise = Promise;
8666 // Transform the implicit coroutine statements constructed using dependent
8667 // types during the previous parse: initial and final suspensions, the return
8668 // object, and others. We also transform the coroutine function's body.
8669 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8670 if (InitSuspend.isInvalid())
8671 return StmtError();
8672 StmtResult FinalSuspend =
8673 getDerived().TransformStmt(S->getFinalSuspendStmt());
8674 if (FinalSuspend.isInvalid() ||
8675 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get()))
8676 return StmtError();
8677 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
8678 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8680 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8681 if (BodyRes.isInvalid())
8682 return StmtError();
8684 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8685 if (Builder.isInvalid())
8686 return StmtError();
8688 Expr *ReturnObject = S->getReturnValueInit();
8689 assert(ReturnObject && "the return object is expected to be valid");
8690 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8691 /*NoCopyInit*/ false);
8692 if (Res.isInvalid())
8693 return StmtError();
8694 Builder.ReturnValue = Res.get();
8696 // If during the previous parse the coroutine still had a dependent promise
8697 // statement, we may need to build some implicit coroutine statements
8698 // (such as exception and fallthrough handlers) for the first time.
8699 if (S->hasDependentPromiseType()) {
8700 // We can only build these statements, however, if the current promise type
8701 // is not dependent.
8702 if (!Promise->getType()->isDependentType()) {
8703 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8704 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8705 "these nodes should not have been built yet");
8706 if (!Builder.buildDependentStatements())
8707 return StmtError();
8709 } else {
8710 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8711 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8712 if (Res.isInvalid())
8713 return StmtError();
8714 Builder.OnFallthrough = Res.get();
8717 if (auto *OnException = S->getExceptionHandler()) {
8718 StmtResult Res = getDerived().TransformStmt(OnException);
8719 if (Res.isInvalid())
8720 return StmtError();
8721 Builder.OnException = Res.get();
8724 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8725 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8726 if (Res.isInvalid())
8727 return StmtError();
8728 Builder.ReturnStmtOnAllocFailure = Res.get();
8731 // Transform any additional statements we may have already built
8732 assert(S->getAllocate() && S->getDeallocate() &&
8733 "allocation and deallocation calls must already be built");
8734 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8735 if (AllocRes.isInvalid())
8736 return StmtError();
8737 Builder.Allocate = AllocRes.get();
8739 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8740 if (DeallocRes.isInvalid())
8741 return StmtError();
8742 Builder.Deallocate = DeallocRes.get();
8744 if (auto *ResultDecl = S->getResultDecl()) {
8745 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8746 if (Res.isInvalid())
8747 return StmtError();
8748 Builder.ResultDecl = Res.get();
8751 if (auto *ReturnStmt = S->getReturnStmt()) {
8752 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8753 if (Res.isInvalid())
8754 return StmtError();
8755 Builder.ReturnStmt = Res.get();
8759 return getDerived().RebuildCoroutineBodyStmt(Builder);
8762 template<typename Derived>
8763 StmtResult
8764 TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8765 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8766 /*NotCopyInit*/false);
8767 if (Result.isInvalid())
8768 return StmtError();
8770 // Always rebuild; we don't know if this needs to be injected into a new
8771 // context or if the promise type has changed.
8772 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8773 S->isImplicit());
8776 template <typename Derived>
8777 ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8778 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8779 /*NotCopyInit*/ false);
8780 if (Operand.isInvalid())
8781 return ExprError();
8783 // Rebuild the common-expr from the operand rather than transforming it
8784 // separately.
8786 // FIXME: getCurScope() should not be used during template instantiation.
8787 // We should pick up the set of unqualified lookup results for operator
8788 // co_await during the initial parse.
8789 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8790 getSema().getCurScope(), E->getKeywordLoc());
8792 // Always rebuild; we don't know if this needs to be injected into a new
8793 // context or if the promise type has changed.
8794 return getDerived().RebuildCoawaitExpr(
8795 E->getKeywordLoc(), Operand.get(),
8796 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());
8799 template <typename Derived>
8800 ExprResult
8801 TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8802 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8803 /*NotCopyInit*/ false);
8804 if (OperandResult.isInvalid())
8805 return ExprError();
8807 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8808 E->getOperatorCoawaitLookup());
8810 if (LookupResult.isInvalid())
8811 return ExprError();
8813 // Always rebuild; we don't know if this needs to be injected into a new
8814 // context or if the promise type has changed.
8815 return getDerived().RebuildDependentCoawaitExpr(
8816 E->getKeywordLoc(), OperandResult.get(),
8817 cast<UnresolvedLookupExpr>(LookupResult.get()));
8820 template<typename Derived>
8821 ExprResult
8822 TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8823 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8824 /*NotCopyInit*/false);
8825 if (Result.isInvalid())
8826 return ExprError();
8828 // Always rebuild; we don't know if this needs to be injected into a new
8829 // context or if the promise type has changed.
8830 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8833 // Objective-C Statements.
8835 template<typename Derived>
8836 StmtResult
8837 TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8838 // Transform the body of the @try.
8839 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8840 if (TryBody.isInvalid())
8841 return StmtError();
8843 // Transform the @catch statements (if present).
8844 bool AnyCatchChanged = false;
8845 SmallVector<Stmt*, 8> CatchStmts;
8846 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8847 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8848 if (Catch.isInvalid())
8849 return StmtError();
8850 if (Catch.get() != S->getCatchStmt(I))
8851 AnyCatchChanged = true;
8852 CatchStmts.push_back(Catch.get());
8855 // Transform the @finally statement (if present).
8856 StmtResult Finally;
8857 if (S->getFinallyStmt()) {
8858 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8859 if (Finally.isInvalid())
8860 return StmtError();
8863 // If nothing changed, just retain this statement.
8864 if (!getDerived().AlwaysRebuild() &&
8865 TryBody.get() == S->getTryBody() &&
8866 !AnyCatchChanged &&
8867 Finally.get() == S->getFinallyStmt())
8868 return S;
8870 // Build a new statement.
8871 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8872 CatchStmts, Finally.get());
8875 template<typename Derived>
8876 StmtResult
8877 TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8878 // Transform the @catch parameter, if there is one.
8879 VarDecl *Var = nullptr;
8880 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8881 TypeSourceInfo *TSInfo = nullptr;
8882 if (FromVar->getTypeSourceInfo()) {
8883 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8884 if (!TSInfo)
8885 return StmtError();
8888 QualType T;
8889 if (TSInfo)
8890 T = TSInfo->getType();
8891 else {
8892 T = getDerived().TransformType(FromVar->getType());
8893 if (T.isNull())
8894 return StmtError();
8897 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8898 if (!Var)
8899 return StmtError();
8902 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8903 if (Body.isInvalid())
8904 return StmtError();
8906 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
8907 S->getRParenLoc(),
8908 Var, Body.get());
8911 template<typename Derived>
8912 StmtResult
8913 TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
8914 // Transform the body.
8915 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
8916 if (Body.isInvalid())
8917 return StmtError();
8919 // If nothing changed, just retain this statement.
8920 if (!getDerived().AlwaysRebuild() &&
8921 Body.get() == S->getFinallyBody())
8922 return S;
8924 // Build a new statement.
8925 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
8926 Body.get());
8929 template<typename Derived>
8930 StmtResult
8931 TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
8932 ExprResult Operand;
8933 if (S->getThrowExpr()) {
8934 Operand = getDerived().TransformExpr(S->getThrowExpr());
8935 if (Operand.isInvalid())
8936 return StmtError();
8939 if (!getDerived().AlwaysRebuild() &&
8940 Operand.get() == S->getThrowExpr())
8941 return S;
8943 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
8946 template<typename Derived>
8947 StmtResult
8948 TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
8949 ObjCAtSynchronizedStmt *S) {
8950 // Transform the object we are locking.
8951 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
8952 if (Object.isInvalid())
8953 return StmtError();
8954 Object =
8955 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
8956 Object.get());
8957 if (Object.isInvalid())
8958 return StmtError();
8960 // Transform the body.
8961 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
8962 if (Body.isInvalid())
8963 return StmtError();
8965 // If nothing change, just retain the current statement.
8966 if (!getDerived().AlwaysRebuild() &&
8967 Object.get() == S->getSynchExpr() &&
8968 Body.get() == S->getSynchBody())
8969 return S;
8971 // Build a new statement.
8972 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
8973 Object.get(), Body.get());
8976 template<typename Derived>
8977 StmtResult
8978 TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
8979 ObjCAutoreleasePoolStmt *S) {
8980 // Transform the body.
8981 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
8982 if (Body.isInvalid())
8983 return StmtError();
8985 // If nothing changed, just retain this statement.
8986 if (!getDerived().AlwaysRebuild() &&
8987 Body.get() == S->getSubStmt())
8988 return S;
8990 // Build a new statement.
8991 return getDerived().RebuildObjCAutoreleasePoolStmt(
8992 S->getAtLoc(), Body.get());
8995 template<typename Derived>
8996 StmtResult
8997 TreeTransform<Derived>::TransformObjCForCollectionStmt(
8998 ObjCForCollectionStmt *S) {
8999 // Transform the element statement.
9000 StmtResult Element =
9001 getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded);
9002 if (Element.isInvalid())
9003 return StmtError();
9005 // Transform the collection expression.
9006 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9007 if (Collection.isInvalid())
9008 return StmtError();
9010 // Transform the body.
9011 StmtResult Body = getDerived().TransformStmt(S->getBody());
9012 if (Body.isInvalid())
9013 return StmtError();
9015 // If nothing changed, just retain this statement.
9016 if (!getDerived().AlwaysRebuild() &&
9017 Element.get() == S->getElement() &&
9018 Collection.get() == S->getCollection() &&
9019 Body.get() == S->getBody())
9020 return S;
9022 // Build a new statement.
9023 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9024 Element.get(),
9025 Collection.get(),
9026 S->getRParenLoc(),
9027 Body.get());
9030 template <typename Derived>
9031 StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9032 // Transform the exception declaration, if any.
9033 VarDecl *Var = nullptr;
9034 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9035 TypeSourceInfo *T =
9036 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9037 if (!T)
9038 return StmtError();
9040 Var = getDerived().RebuildExceptionDecl(
9041 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9042 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9043 if (!Var || Var->isInvalidDecl())
9044 return StmtError();
9047 // Transform the actual exception handler.
9048 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9049 if (Handler.isInvalid())
9050 return StmtError();
9052 if (!getDerived().AlwaysRebuild() && !Var &&
9053 Handler.get() == S->getHandlerBlock())
9054 return S;
9056 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9059 template <typename Derived>
9060 StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9061 // Transform the try block itself.
9062 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9063 if (TryBlock.isInvalid())
9064 return StmtError();
9066 // Transform the handlers.
9067 bool HandlerChanged = false;
9068 SmallVector<Stmt *, 8> Handlers;
9069 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9070 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I));
9071 if (Handler.isInvalid())
9072 return StmtError();
9074 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
9075 Handlers.push_back(Handler.getAs<Stmt>());
9078 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9079 !HandlerChanged)
9080 return S;
9082 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9083 Handlers);
9086 template<typename Derived>
9087 StmtResult
9088 TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9089 EnterExpressionEvaluationContext ForRangeInitContext(
9090 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9091 /*LambdaContextDecl=*/nullptr,
9092 Sema::ExpressionEvaluationContextRecord::EK_Other,
9093 getSema().getLangOpts().CPlusPlus23);
9095 // P2718R0 - Lifetime extension in range-based for loops.
9096 if (getSema().getLangOpts().CPlusPlus23) {
9097 auto &LastRecord = getSema().currentEvaluationContext();
9098 LastRecord.InLifetimeExtendingContext = true;
9099 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9101 StmtResult Init =
9102 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9103 if (Init.isInvalid())
9104 return StmtError();
9106 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9107 if (Range.isInvalid())
9108 return StmtError();
9110 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9111 assert(getSema().getLangOpts().CPlusPlus23 ||
9112 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9113 auto ForRangeLifetimeExtendTemps =
9114 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9116 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9117 if (Begin.isInvalid())
9118 return StmtError();
9119 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9120 if (End.isInvalid())
9121 return StmtError();
9123 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9124 if (Cond.isInvalid())
9125 return StmtError();
9126 if (Cond.get())
9127 Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());
9128 if (Cond.isInvalid())
9129 return StmtError();
9130 if (Cond.get())
9131 Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());
9133 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9134 if (Inc.isInvalid())
9135 return StmtError();
9136 if (Inc.get())
9137 Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());
9139 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9140 if (LoopVar.isInvalid())
9141 return StmtError();
9143 StmtResult NewStmt = S;
9144 if (getDerived().AlwaysRebuild() ||
9145 Init.get() != S->getInit() ||
9146 Range.get() != S->getRangeStmt() ||
9147 Begin.get() != S->getBeginStmt() ||
9148 End.get() != S->getEndStmt() ||
9149 Cond.get() != S->getCond() ||
9150 Inc.get() != S->getInc() ||
9151 LoopVar.get() != S->getLoopVarStmt()) {
9152 NewStmt = getDerived().RebuildCXXForRangeStmt(
9153 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9154 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9155 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9156 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9157 // Might not have attached any initializer to the loop variable.
9158 getSema().ActOnInitializerError(
9159 cast<DeclStmt>(LoopVar.get())->getSingleDecl());
9160 return StmtError();
9164 // OpenACC Restricts a while-loop inside of certain construct/clause
9165 // combinations, so diagnose that here in OpenACC mode.
9166 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9167 SemaRef.OpenACC().ActOnRangeForStmtBegin(S->getBeginLoc(), S, NewStmt.get());
9169 StmtResult Body = getDerived().TransformStmt(S->getBody());
9170 if (Body.isInvalid())
9171 return StmtError();
9173 SemaRef.OpenACC().ActOnForStmtEnd(S->getBeginLoc(), Body);
9175 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9176 // it now so we have a new statement to attach the body to.
9177 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9178 NewStmt = getDerived().RebuildCXXForRangeStmt(
9179 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9180 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9181 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9182 if (NewStmt.isInvalid())
9183 return StmtError();
9186 if (NewStmt.get() == S)
9187 return S;
9189 return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
9192 template<typename Derived>
9193 StmtResult
9194 TreeTransform<Derived>::TransformMSDependentExistsStmt(
9195 MSDependentExistsStmt *S) {
9196 // Transform the nested-name-specifier, if any.
9197 NestedNameSpecifierLoc QualifierLoc;
9198 if (S->getQualifierLoc()) {
9199 QualifierLoc
9200 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9201 if (!QualifierLoc)
9202 return StmtError();
9205 // Transform the declaration name.
9206 DeclarationNameInfo NameInfo = S->getNameInfo();
9207 if (NameInfo.getName()) {
9208 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9209 if (!NameInfo.getName())
9210 return StmtError();
9213 // Check whether anything changed.
9214 if (!getDerived().AlwaysRebuild() &&
9215 QualifierLoc == S->getQualifierLoc() &&
9216 NameInfo.getName() == S->getNameInfo().getName())
9217 return S;
9219 // Determine whether this name exists, if we can.
9220 CXXScopeSpec SS;
9221 SS.Adopt(QualifierLoc);
9222 bool Dependent = false;
9223 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9224 case Sema::IER_Exists:
9225 if (S->isIfExists())
9226 break;
9228 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9230 case Sema::IER_DoesNotExist:
9231 if (S->isIfNotExists())
9232 break;
9234 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9236 case Sema::IER_Dependent:
9237 Dependent = true;
9238 break;
9240 case Sema::IER_Error:
9241 return StmtError();
9244 // We need to continue with the instantiation, so do so now.
9245 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9246 if (SubStmt.isInvalid())
9247 return StmtError();
9249 // If we have resolved the name, just transform to the substatement.
9250 if (!Dependent)
9251 return SubStmt;
9253 // The name is still dependent, so build a dependent expression again.
9254 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9255 S->isIfExists(),
9256 QualifierLoc,
9257 NameInfo,
9258 SubStmt.get());
9261 template<typename Derived>
9262 ExprResult
9263 TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9264 NestedNameSpecifierLoc QualifierLoc;
9265 if (E->getQualifierLoc()) {
9266 QualifierLoc
9267 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9268 if (!QualifierLoc)
9269 return ExprError();
9272 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9273 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9274 if (!PD)
9275 return ExprError();
9277 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9278 if (Base.isInvalid())
9279 return ExprError();
9281 return new (SemaRef.getASTContext())
9282 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9283 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9284 QualifierLoc, E->getMemberLoc());
9287 template <typename Derived>
9288 ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9289 MSPropertySubscriptExpr *E) {
9290 auto BaseRes = getDerived().TransformExpr(E->getBase());
9291 if (BaseRes.isInvalid())
9292 return ExprError();
9293 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9294 if (IdxRes.isInvalid())
9295 return ExprError();
9297 if (!getDerived().AlwaysRebuild() &&
9298 BaseRes.get() == E->getBase() &&
9299 IdxRes.get() == E->getIdx())
9300 return E;
9302 return getDerived().RebuildArraySubscriptExpr(
9303 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9306 template <typename Derived>
9307 StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9308 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9309 if (TryBlock.isInvalid())
9310 return StmtError();
9312 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9313 if (Handler.isInvalid())
9314 return StmtError();
9316 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9317 Handler.get() == S->getHandler())
9318 return S;
9320 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9321 TryBlock.get(), Handler.get());
9324 template <typename Derived>
9325 StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9326 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9327 if (Block.isInvalid())
9328 return StmtError();
9330 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9333 template <typename Derived>
9334 StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9335 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9336 if (FilterExpr.isInvalid())
9337 return StmtError();
9339 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9340 if (Block.isInvalid())
9341 return StmtError();
9343 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9344 Block.get());
9347 template <typename Derived>
9348 StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9349 if (isa<SEHFinallyStmt>(Handler))
9350 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
9351 else
9352 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
9355 template<typename Derived>
9356 StmtResult
9357 TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9358 return S;
9361 //===----------------------------------------------------------------------===//
9362 // OpenMP directive transformation
9363 //===----------------------------------------------------------------------===//
9365 template <typename Derived>
9366 StmtResult
9367 TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9368 // OMPCanonicalLoops are eliminated during transformation, since they will be
9369 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9370 // after transformation.
9371 return getDerived().TransformStmt(L->getLoopStmt());
9374 template <typename Derived>
9375 StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9376 OMPExecutableDirective *D) {
9378 // Transform the clauses
9379 llvm::SmallVector<OMPClause *, 16> TClauses;
9380 ArrayRef<OMPClause *> Clauses = D->clauses();
9381 TClauses.reserve(Clauses.size());
9382 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9383 I != E; ++I) {
9384 if (*I) {
9385 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9386 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9387 getDerived().getSema().OpenMP().EndOpenMPClause();
9388 if (Clause)
9389 TClauses.push_back(Clause);
9390 } else {
9391 TClauses.push_back(nullptr);
9394 StmtResult AssociatedStmt;
9395 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9396 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9397 D->getDirectiveKind(),
9398 /*CurScope=*/nullptr);
9399 StmtResult Body;
9401 Sema::CompoundScopeRAII CompoundScope(getSema());
9402 Stmt *CS;
9403 if (D->getDirectiveKind() == OMPD_atomic ||
9404 D->getDirectiveKind() == OMPD_critical ||
9405 D->getDirectiveKind() == OMPD_section ||
9406 D->getDirectiveKind() == OMPD_master)
9407 CS = D->getAssociatedStmt();
9408 else
9409 CS = D->getRawStmt();
9410 Body = getDerived().TransformStmt(CS);
9411 if (Body.isUsable() && isOpenMPLoopDirective(D->getDirectiveKind()) &&
9412 getSema().getLangOpts().OpenMPIRBuilder)
9413 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9415 AssociatedStmt =
9416 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9417 if (AssociatedStmt.isInvalid()) {
9418 return StmtError();
9421 if (TClauses.size() != Clauses.size()) {
9422 return StmtError();
9425 // Transform directive name for 'omp critical' directive.
9426 DeclarationNameInfo DirName;
9427 if (D->getDirectiveKind() == OMPD_critical) {
9428 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
9429 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9431 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9432 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9433 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();
9434 } else if (D->getDirectiveKind() == OMPD_cancel) {
9435 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();
9438 return getDerived().RebuildOMPExecutableDirective(
9439 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9440 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
9443 /// This is mostly the same as above, but allows 'informational' class
9444 /// directives when rebuilding the stmt. It still takes an
9445 /// OMPExecutableDirective-type argument because we're reusing that as the
9446 /// superclass for the 'assume' directive at present, instead of defining a
9447 /// mostly-identical OMPInformationalDirective parent class.
9448 template <typename Derived>
9449 StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
9450 OMPExecutableDirective *D) {
9452 // Transform the clauses
9453 llvm::SmallVector<OMPClause *, 16> TClauses;
9454 ArrayRef<OMPClause *> Clauses = D->clauses();
9455 TClauses.reserve(Clauses.size());
9456 for (OMPClause *C : Clauses) {
9457 if (C) {
9458 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
9459 OMPClause *Clause = getDerived().TransformOMPClause(C);
9460 getDerived().getSema().OpenMP().EndOpenMPClause();
9461 if (Clause)
9462 TClauses.push_back(Clause);
9463 } else {
9464 TClauses.push_back(nullptr);
9467 StmtResult AssociatedStmt;
9468 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9469 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9470 D->getDirectiveKind(),
9471 /*CurScope=*/nullptr);
9472 StmtResult Body;
9474 Sema::CompoundScopeRAII CompoundScope(getSema());
9475 assert(D->getDirectiveKind() == OMPD_assume &&
9476 "Unexpected informational directive");
9477 Stmt *CS = D->getAssociatedStmt();
9478 Body = getDerived().TransformStmt(CS);
9480 AssociatedStmt =
9481 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9482 if (AssociatedStmt.isInvalid())
9483 return StmtError();
9485 if (TClauses.size() != Clauses.size())
9486 return StmtError();
9488 DeclarationNameInfo DirName;
9490 return getDerived().RebuildOMPInformationalDirective(
9491 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
9492 D->getBeginLoc(), D->getEndLoc());
9495 template <typename Derived>
9496 StmtResult
9497 TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9498 // TODO: Fix This
9499 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)
9500 << getOpenMPDirectiveName(D->getDirectiveKind());
9501 return StmtError();
9504 template <typename Derived>
9505 StmtResult
9506 TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9507 DeclarationNameInfo DirName;
9508 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9509 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9510 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9511 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9512 return Res;
9515 template <typename Derived>
9516 StmtResult
9517 TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9518 DeclarationNameInfo DirName;
9519 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9520 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9521 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9522 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9523 return Res;
9526 template <typename Derived>
9527 StmtResult
9528 TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9529 DeclarationNameInfo DirName;
9530 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9531 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9532 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9533 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9534 return Res;
9537 template <typename Derived>
9538 StmtResult
9539 TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9540 DeclarationNameInfo DirName;
9541 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9542 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9543 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9544 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9545 return Res;
9548 template <typename Derived>
9549 StmtResult
9550 TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
9551 DeclarationNameInfo DirName;
9552 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9553 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9554 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9555 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9556 return Res;
9559 template <typename Derived>
9560 StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
9561 OMPInterchangeDirective *D) {
9562 DeclarationNameInfo DirName;
9563 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9564 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9565 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9566 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9567 return Res;
9570 template <typename Derived>
9571 StmtResult
9572 TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9573 DeclarationNameInfo DirName;
9574 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9575 OMPD_for, DirName, nullptr, D->getBeginLoc());
9576 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9577 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9578 return Res;
9581 template <typename Derived>
9582 StmtResult
9583 TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9584 DeclarationNameInfo DirName;
9585 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9586 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9587 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9588 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9589 return Res;
9592 template <typename Derived>
9593 StmtResult
9594 TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9595 DeclarationNameInfo DirName;
9596 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9597 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9598 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9599 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9600 return Res;
9603 template <typename Derived>
9604 StmtResult
9605 TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9606 DeclarationNameInfo DirName;
9607 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9608 OMPD_section, DirName, nullptr, D->getBeginLoc());
9609 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9610 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9611 return Res;
9614 template <typename Derived>
9615 StmtResult
9616 TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9617 DeclarationNameInfo DirName;
9618 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9619 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9620 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9621 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9622 return Res;
9625 template <typename Derived>
9626 StmtResult
9627 TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9628 DeclarationNameInfo DirName;
9629 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9630 OMPD_single, DirName, nullptr, D->getBeginLoc());
9631 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9632 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9633 return Res;
9636 template <typename Derived>
9637 StmtResult
9638 TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9639 DeclarationNameInfo DirName;
9640 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9641 OMPD_master, DirName, nullptr, D->getBeginLoc());
9642 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9643 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9644 return Res;
9647 template <typename Derived>
9648 StmtResult
9649 TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9650 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9651 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9652 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9653 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9654 return Res;
9657 template <typename Derived>
9658 StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9659 OMPParallelForDirective *D) {
9660 DeclarationNameInfo DirName;
9661 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9662 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9663 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9664 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9665 return Res;
9668 template <typename Derived>
9669 StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9670 OMPParallelForSimdDirective *D) {
9671 DeclarationNameInfo DirName;
9672 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9673 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9674 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9675 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9676 return Res;
9679 template <typename Derived>
9680 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9681 OMPParallelMasterDirective *D) {
9682 DeclarationNameInfo DirName;
9683 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9684 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
9685 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9686 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9687 return Res;
9690 template <typename Derived>
9691 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9692 OMPParallelMaskedDirective *D) {
9693 DeclarationNameInfo DirName;
9694 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9695 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
9696 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9697 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9698 return Res;
9701 template <typename Derived>
9702 StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9703 OMPParallelSectionsDirective *D) {
9704 DeclarationNameInfo DirName;
9705 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9706 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
9707 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9708 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9709 return Res;
9712 template <typename Derived>
9713 StmtResult
9714 TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9715 DeclarationNameInfo DirName;
9716 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9717 OMPD_task, DirName, nullptr, D->getBeginLoc());
9718 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9719 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9720 return Res;
9723 template <typename Derived>
9724 StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9725 OMPTaskyieldDirective *D) {
9726 DeclarationNameInfo DirName;
9727 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9728 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
9729 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9730 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9731 return Res;
9734 template <typename Derived>
9735 StmtResult
9736 TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9737 DeclarationNameInfo DirName;
9738 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9739 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
9740 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9741 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9742 return Res;
9745 template <typename Derived>
9746 StmtResult
9747 TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9748 DeclarationNameInfo DirName;
9749 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9750 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
9751 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9752 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9753 return Res;
9756 template <typename Derived>
9757 StmtResult
9758 TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
9759 DeclarationNameInfo DirName;
9760 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9761 OMPD_assume, DirName, nullptr, D->getBeginLoc());
9762 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
9763 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9764 return Res;
9767 template <typename Derived>
9768 StmtResult
9769 TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9770 DeclarationNameInfo DirName;
9771 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9772 OMPD_error, DirName, nullptr, D->getBeginLoc());
9773 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9774 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9775 return Res;
9778 template <typename Derived>
9779 StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9780 OMPTaskgroupDirective *D) {
9781 DeclarationNameInfo DirName;
9782 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9783 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
9784 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9785 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9786 return Res;
9789 template <typename Derived>
9790 StmtResult
9791 TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9792 DeclarationNameInfo DirName;
9793 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9794 OMPD_flush, DirName, nullptr, D->getBeginLoc());
9795 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9796 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9797 return Res;
9800 template <typename Derived>
9801 StmtResult
9802 TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9803 DeclarationNameInfo DirName;
9804 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9805 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
9806 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9807 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9808 return Res;
9811 template <typename Derived>
9812 StmtResult
9813 TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9814 DeclarationNameInfo DirName;
9815 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9816 OMPD_scan, DirName, nullptr, D->getBeginLoc());
9817 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9818 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9819 return Res;
9822 template <typename Derived>
9823 StmtResult
9824 TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9825 DeclarationNameInfo DirName;
9826 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9827 OMPD_ordered, DirName, nullptr, D->getBeginLoc());
9828 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9829 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9830 return Res;
9833 template <typename Derived>
9834 StmtResult
9835 TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9836 DeclarationNameInfo DirName;
9837 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9838 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
9839 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9840 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9841 return Res;
9844 template <typename Derived>
9845 StmtResult
9846 TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9847 DeclarationNameInfo DirName;
9848 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9849 OMPD_target, DirName, nullptr, D->getBeginLoc());
9850 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9851 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9852 return Res;
9855 template <typename Derived>
9856 StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9857 OMPTargetDataDirective *D) {
9858 DeclarationNameInfo DirName;
9859 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9860 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
9861 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9862 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9863 return Res;
9866 template <typename Derived>
9867 StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9868 OMPTargetEnterDataDirective *D) {
9869 DeclarationNameInfo DirName;
9870 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9871 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
9872 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9873 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9874 return Res;
9877 template <typename Derived>
9878 StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9879 OMPTargetExitDataDirective *D) {
9880 DeclarationNameInfo DirName;
9881 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9882 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
9883 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9884 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9885 return Res;
9888 template <typename Derived>
9889 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
9890 OMPTargetParallelDirective *D) {
9891 DeclarationNameInfo DirName;
9892 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9893 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
9894 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9895 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9896 return Res;
9899 template <typename Derived>
9900 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
9901 OMPTargetParallelForDirective *D) {
9902 DeclarationNameInfo DirName;
9903 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9904 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
9905 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9906 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9907 return Res;
9910 template <typename Derived>
9911 StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
9912 OMPTargetUpdateDirective *D) {
9913 DeclarationNameInfo DirName;
9914 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9915 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
9916 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9917 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9918 return Res;
9921 template <typename Derived>
9922 StmtResult
9923 TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
9924 DeclarationNameInfo DirName;
9925 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9926 OMPD_teams, DirName, nullptr, D->getBeginLoc());
9927 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9928 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9929 return Res;
9932 template <typename Derived>
9933 StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
9934 OMPCancellationPointDirective *D) {
9935 DeclarationNameInfo DirName;
9936 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9937 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
9938 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9939 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9940 return Res;
9943 template <typename Derived>
9944 StmtResult
9945 TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
9946 DeclarationNameInfo DirName;
9947 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9948 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
9949 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9950 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9951 return Res;
9954 template <typename Derived>
9955 StmtResult
9956 TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
9957 DeclarationNameInfo DirName;
9958 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9959 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
9960 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9961 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9962 return Res;
9965 template <typename Derived>
9966 StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
9967 OMPTaskLoopSimdDirective *D) {
9968 DeclarationNameInfo DirName;
9969 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9970 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9971 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9972 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9973 return Res;
9976 template <typename Derived>
9977 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
9978 OMPMasterTaskLoopDirective *D) {
9979 DeclarationNameInfo DirName;
9980 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9981 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
9982 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9983 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9984 return Res;
9987 template <typename Derived>
9988 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
9989 OMPMaskedTaskLoopDirective *D) {
9990 DeclarationNameInfo DirName;
9991 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9992 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9993 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9994 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9995 return Res;
9998 template <typename Derived>
9999 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10000 OMPMasterTaskLoopSimdDirective *D) {
10001 DeclarationNameInfo DirName;
10002 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10003 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10004 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10005 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10006 return Res;
10009 template <typename Derived>
10010 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10011 OMPMaskedTaskLoopSimdDirective *D) {
10012 DeclarationNameInfo DirName;
10013 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10014 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10015 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10016 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10017 return Res;
10020 template <typename Derived>
10021 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10022 OMPParallelMasterTaskLoopDirective *D) {
10023 DeclarationNameInfo DirName;
10024 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10025 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10026 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10027 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10028 return Res;
10031 template <typename Derived>
10032 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10033 OMPParallelMaskedTaskLoopDirective *D) {
10034 DeclarationNameInfo DirName;
10035 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10036 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10037 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10038 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10039 return Res;
10042 template <typename Derived>
10043 StmtResult
10044 TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10045 OMPParallelMasterTaskLoopSimdDirective *D) {
10046 DeclarationNameInfo DirName;
10047 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10048 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10049 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10050 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10051 return Res;
10054 template <typename Derived>
10055 StmtResult
10056 TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10057 OMPParallelMaskedTaskLoopSimdDirective *D) {
10058 DeclarationNameInfo DirName;
10059 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10060 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10061 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10062 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10063 return Res;
10066 template <typename Derived>
10067 StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10068 OMPDistributeDirective *D) {
10069 DeclarationNameInfo DirName;
10070 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10071 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10072 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10073 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10074 return Res;
10077 template <typename Derived>
10078 StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10079 OMPDistributeParallelForDirective *D) {
10080 DeclarationNameInfo DirName;
10081 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10082 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10083 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10084 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10085 return Res;
10088 template <typename Derived>
10089 StmtResult
10090 TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10091 OMPDistributeParallelForSimdDirective *D) {
10092 DeclarationNameInfo DirName;
10093 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10094 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10095 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10096 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10097 return Res;
10100 template <typename Derived>
10101 StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10102 OMPDistributeSimdDirective *D) {
10103 DeclarationNameInfo DirName;
10104 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10105 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10106 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10107 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10108 return Res;
10111 template <typename Derived>
10112 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10113 OMPTargetParallelForSimdDirective *D) {
10114 DeclarationNameInfo DirName;
10115 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10116 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10117 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10118 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10119 return Res;
10122 template <typename Derived>
10123 StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10124 OMPTargetSimdDirective *D) {
10125 DeclarationNameInfo DirName;
10126 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10127 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10128 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10129 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10130 return Res;
10133 template <typename Derived>
10134 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10135 OMPTeamsDistributeDirective *D) {
10136 DeclarationNameInfo DirName;
10137 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10138 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10139 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10140 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10141 return Res;
10144 template <typename Derived>
10145 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10146 OMPTeamsDistributeSimdDirective *D) {
10147 DeclarationNameInfo DirName;
10148 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10149 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10150 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10151 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10152 return Res;
10155 template <typename Derived>
10156 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10157 OMPTeamsDistributeParallelForSimdDirective *D) {
10158 DeclarationNameInfo DirName;
10159 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10160 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10161 D->getBeginLoc());
10162 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10163 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10164 return Res;
10167 template <typename Derived>
10168 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10169 OMPTeamsDistributeParallelForDirective *D) {
10170 DeclarationNameInfo DirName;
10171 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10172 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10173 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10174 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10175 return Res;
10178 template <typename Derived>
10179 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10180 OMPTargetTeamsDirective *D) {
10181 DeclarationNameInfo DirName;
10182 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10183 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10184 auto Res = getDerived().TransformOMPExecutableDirective(D);
10185 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10186 return Res;
10189 template <typename Derived>
10190 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10191 OMPTargetTeamsDistributeDirective *D) {
10192 DeclarationNameInfo DirName;
10193 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10194 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10195 auto Res = getDerived().TransformOMPExecutableDirective(D);
10196 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10197 return Res;
10200 template <typename Derived>
10201 StmtResult
10202 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10203 OMPTargetTeamsDistributeParallelForDirective *D) {
10204 DeclarationNameInfo DirName;
10205 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10206 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10207 D->getBeginLoc());
10208 auto Res = getDerived().TransformOMPExecutableDirective(D);
10209 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10210 return Res;
10213 template <typename Derived>
10214 StmtResult TreeTransform<Derived>::
10215 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10216 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10217 DeclarationNameInfo DirName;
10218 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10219 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10220 D->getBeginLoc());
10221 auto Res = getDerived().TransformOMPExecutableDirective(D);
10222 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10223 return Res;
10226 template <typename Derived>
10227 StmtResult
10228 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10229 OMPTargetTeamsDistributeSimdDirective *D) {
10230 DeclarationNameInfo DirName;
10231 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10232 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10233 auto Res = getDerived().TransformOMPExecutableDirective(D);
10234 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10235 return Res;
10238 template <typename Derived>
10239 StmtResult
10240 TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10241 DeclarationNameInfo DirName;
10242 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10243 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10244 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10245 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10246 return Res;
10249 template <typename Derived>
10250 StmtResult
10251 TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10252 DeclarationNameInfo DirName;
10253 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10254 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10255 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10256 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10257 return Res;
10260 template <typename Derived>
10261 StmtResult
10262 TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10263 DeclarationNameInfo DirName;
10264 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10265 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10266 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10267 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10268 return Res;
10271 template <typename Derived>
10272 StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10273 OMPGenericLoopDirective *D) {
10274 DeclarationNameInfo DirName;
10275 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10276 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10277 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10278 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10279 return Res;
10282 template <typename Derived>
10283 StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10284 OMPTeamsGenericLoopDirective *D) {
10285 DeclarationNameInfo DirName;
10286 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10287 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10288 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10289 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10290 return Res;
10293 template <typename Derived>
10294 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10295 OMPTargetTeamsGenericLoopDirective *D) {
10296 DeclarationNameInfo DirName;
10297 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10298 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10299 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10300 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10301 return Res;
10304 template <typename Derived>
10305 StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10306 OMPParallelGenericLoopDirective *D) {
10307 DeclarationNameInfo DirName;
10308 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10309 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10310 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10311 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10312 return Res;
10315 template <typename Derived>
10316 StmtResult
10317 TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10318 OMPTargetParallelGenericLoopDirective *D) {
10319 DeclarationNameInfo DirName;
10320 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10321 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10322 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10323 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10324 return Res;
10327 //===----------------------------------------------------------------------===//
10328 // OpenMP clause transformation
10329 //===----------------------------------------------------------------------===//
10330 template <typename Derived>
10331 OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10332 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10333 if (Cond.isInvalid())
10334 return nullptr;
10335 return getDerived().RebuildOMPIfClause(
10336 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10337 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10340 template <typename Derived>
10341 OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10342 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10343 if (Cond.isInvalid())
10344 return nullptr;
10345 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10346 C->getLParenLoc(), C->getEndLoc());
10349 template <typename Derived>
10350 OMPClause *
10351 TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10352 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10353 if (NumThreads.isInvalid())
10354 return nullptr;
10355 return getDerived().RebuildOMPNumThreadsClause(
10356 NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10359 template <typename Derived>
10360 OMPClause *
10361 TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10362 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10363 if (E.isInvalid())
10364 return nullptr;
10365 return getDerived().RebuildOMPSafelenClause(
10366 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10369 template <typename Derived>
10370 OMPClause *
10371 TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10372 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10373 if (E.isInvalid())
10374 return nullptr;
10375 return getDerived().RebuildOMPAllocatorClause(
10376 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10379 template <typename Derived>
10380 OMPClause *
10381 TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10382 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10383 if (E.isInvalid())
10384 return nullptr;
10385 return getDerived().RebuildOMPSimdlenClause(
10386 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10389 template <typename Derived>
10390 OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10391 SmallVector<Expr *, 4> TransformedSizes;
10392 TransformedSizes.reserve(C->getNumSizes());
10393 bool Changed = false;
10394 for (Expr *E : C->getSizesRefs()) {
10395 if (!E) {
10396 TransformedSizes.push_back(nullptr);
10397 continue;
10400 ExprResult T = getDerived().TransformExpr(E);
10401 if (T.isInvalid())
10402 return nullptr;
10403 if (E != T.get())
10404 Changed = true;
10405 TransformedSizes.push_back(T.get());
10408 if (!Changed && !getDerived().AlwaysRebuild())
10409 return C;
10410 return RebuildOMPSizesClause(TransformedSizes, C->getBeginLoc(),
10411 C->getLParenLoc(), C->getEndLoc());
10414 template <typename Derived>
10415 OMPClause *
10416 TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
10417 SmallVector<Expr *> TransformedArgs;
10418 TransformedArgs.reserve(C->getNumLoops());
10419 bool Changed = false;
10420 for (Expr *E : C->getArgsRefs()) {
10421 if (!E) {
10422 TransformedArgs.push_back(nullptr);
10423 continue;
10426 ExprResult T = getDerived().TransformExpr(E);
10427 if (T.isInvalid())
10428 return nullptr;
10429 if (E != T.get())
10430 Changed = true;
10431 TransformedArgs.push_back(T.get());
10434 if (!Changed && !getDerived().AlwaysRebuild())
10435 return C;
10436 return RebuildOMPPermutationClause(TransformedArgs, C->getBeginLoc(),
10437 C->getLParenLoc(), C->getEndLoc());
10440 template <typename Derived>
10441 OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10442 if (!getDerived().AlwaysRebuild())
10443 return C;
10444 return RebuildOMPFullClause(C->getBeginLoc(), C->getEndLoc());
10447 template <typename Derived>
10448 OMPClause *
10449 TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10450 ExprResult T = getDerived().TransformExpr(C->getFactor());
10451 if (T.isInvalid())
10452 return nullptr;
10453 Expr *Factor = T.get();
10454 bool Changed = Factor != C->getFactor();
10456 if (!Changed && !getDerived().AlwaysRebuild())
10457 return C;
10458 return RebuildOMPPartialClause(Factor, C->getBeginLoc(), C->getLParenLoc(),
10459 C->getEndLoc());
10462 template <typename Derived>
10463 OMPClause *
10464 TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10465 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10466 if (E.isInvalid())
10467 return nullptr;
10468 return getDerived().RebuildOMPCollapseClause(
10469 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10472 template <typename Derived>
10473 OMPClause *
10474 TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10475 return getDerived().RebuildOMPDefaultClause(
10476 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
10477 C->getLParenLoc(), C->getEndLoc());
10480 template <typename Derived>
10481 OMPClause *
10482 TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10483 return getDerived().RebuildOMPProcBindClause(
10484 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10485 C->getLParenLoc(), C->getEndLoc());
10488 template <typename Derived>
10489 OMPClause *
10490 TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10491 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10492 if (E.isInvalid())
10493 return nullptr;
10494 return getDerived().RebuildOMPScheduleClause(
10495 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10496 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10497 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10498 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10501 template <typename Derived>
10502 OMPClause *
10503 TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10504 ExprResult E;
10505 if (auto *Num = C->getNumForLoops()) {
10506 E = getDerived().TransformExpr(Num);
10507 if (E.isInvalid())
10508 return nullptr;
10510 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10511 C->getLParenLoc(), E.get());
10514 template <typename Derived>
10515 OMPClause *
10516 TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10517 ExprResult E;
10518 if (Expr *Evt = C->getEventHandler()) {
10519 E = getDerived().TransformExpr(Evt);
10520 if (E.isInvalid())
10521 return nullptr;
10523 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10524 C->getLParenLoc(), C->getEndLoc());
10527 template <typename Derived>
10528 OMPClause *
10529 TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10530 // No need to rebuild this clause, no template-dependent parameters.
10531 return C;
10534 template <typename Derived>
10535 OMPClause *
10536 TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10537 // No need to rebuild this clause, no template-dependent parameters.
10538 return C;
10541 template <typename Derived>
10542 OMPClause *
10543 TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10544 // No need to rebuild this clause, no template-dependent parameters.
10545 return C;
10548 template <typename Derived>
10549 OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10550 // No need to rebuild this clause, no template-dependent parameters.
10551 return C;
10554 template <typename Derived>
10555 OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10556 // No need to rebuild this clause, no template-dependent parameters.
10557 return C;
10560 template <typename Derived>
10561 OMPClause *
10562 TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10563 // No need to rebuild this clause, no template-dependent parameters.
10564 return C;
10567 template <typename Derived>
10568 OMPClause *
10569 TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10570 // No need to rebuild this clause, no template-dependent parameters.
10571 return C;
10574 template <typename Derived>
10575 OMPClause *
10576 TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10577 // No need to rebuild this clause, no template-dependent parameters.
10578 return C;
10581 template <typename Derived>
10582 OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10583 // No need to rebuild this clause, no template-dependent parameters.
10584 return C;
10587 template <typename Derived>
10588 OMPClause *
10589 TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
10590 return C;
10593 template <typename Derived>
10594 OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
10595 ExprResult E = getDerived().TransformExpr(C->getExpr());
10596 if (E.isInvalid())
10597 return nullptr;
10598 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
10599 C->getLParenLoc(), C->getEndLoc());
10602 template <typename Derived>
10603 OMPClause *
10604 TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
10605 return C;
10608 template <typename Derived>
10609 OMPClause *
10610 TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
10611 return C;
10613 template <typename Derived>
10614 OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
10615 OMPNoOpenMPRoutinesClause *C) {
10616 return C;
10618 template <typename Derived>
10619 OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
10620 OMPNoParallelismClause *C) {
10621 return C;
10624 template <typename Derived>
10625 OMPClause *
10626 TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10627 // No need to rebuild this clause, no template-dependent parameters.
10628 return C;
10631 template <typename Derived>
10632 OMPClause *
10633 TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10634 // No need to rebuild this clause, no template-dependent parameters.
10635 return C;
10638 template <typename Derived>
10639 OMPClause *
10640 TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10641 // No need to rebuild this clause, no template-dependent parameters.
10642 return C;
10645 template <typename Derived>
10646 OMPClause *
10647 TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10648 // No need to rebuild this clause, no template-dependent parameters.
10649 return C;
10652 template <typename Derived>
10653 OMPClause *
10654 TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10655 // No need to rebuild this clause, no template-dependent parameters.
10656 return C;
10659 template <typename Derived>
10660 OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10661 // No need to rebuild this clause, no template-dependent parameters.
10662 return C;
10665 template <typename Derived>
10666 OMPClause *
10667 TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10668 // No need to rebuild this clause, no template-dependent parameters.
10669 return C;
10672 template <typename Derived>
10673 OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10674 // No need to rebuild this clause, no template-dependent parameters.
10675 return C;
10678 template <typename Derived>
10679 OMPClause *
10680 TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10681 // No need to rebuild this clause, no template-dependent parameters.
10682 return C;
10685 template <typename Derived>
10686 OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10687 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10688 if (IVR.isInvalid())
10689 return nullptr;
10691 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10692 InteropInfo.PreferTypes.reserve(C->varlist_size() - 1);
10693 for (Expr *E : llvm::drop_begin(C->varlist())) {
10694 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
10695 if (ER.isInvalid())
10696 return nullptr;
10697 InteropInfo.PreferTypes.push_back(ER.get());
10699 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10700 C->getBeginLoc(), C->getLParenLoc(),
10701 C->getVarLoc(), C->getEndLoc());
10704 template <typename Derived>
10705 OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10706 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10707 if (ER.isInvalid())
10708 return nullptr;
10709 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10710 C->getLParenLoc(), C->getVarLoc(),
10711 C->getEndLoc());
10714 template <typename Derived>
10715 OMPClause *
10716 TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10717 ExprResult ER;
10718 if (Expr *IV = C->getInteropVar()) {
10719 ER = getDerived().TransformExpr(IV);
10720 if (ER.isInvalid())
10721 return nullptr;
10723 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10724 C->getLParenLoc(), C->getVarLoc(),
10725 C->getEndLoc());
10728 template <typename Derived>
10729 OMPClause *
10730 TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10731 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10732 if (Cond.isInvalid())
10733 return nullptr;
10734 return getDerived().RebuildOMPNovariantsClause(
10735 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10738 template <typename Derived>
10739 OMPClause *
10740 TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
10741 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10742 if (Cond.isInvalid())
10743 return nullptr;
10744 return getDerived().RebuildOMPNocontextClause(
10745 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10748 template <typename Derived>
10749 OMPClause *
10750 TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
10751 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
10752 if (ThreadID.isInvalid())
10753 return nullptr;
10754 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10755 C->getLParenLoc(), C->getEndLoc());
10758 template <typename Derived>
10759 OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10760 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10761 if (E.isInvalid())
10762 return nullptr;
10763 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10764 C->getLParenLoc(), C->getEndLoc());
10767 template <typename Derived>
10768 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10769 OMPUnifiedAddressClause *C) {
10770 llvm_unreachable("unified_address clause cannot appear in dependent context");
10773 template <typename Derived>
10774 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10775 OMPUnifiedSharedMemoryClause *C) {
10776 llvm_unreachable(
10777 "unified_shared_memory clause cannot appear in dependent context");
10780 template <typename Derived>
10781 OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10782 OMPReverseOffloadClause *C) {
10783 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10786 template <typename Derived>
10787 OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10788 OMPDynamicAllocatorsClause *C) {
10789 llvm_unreachable(
10790 "dynamic_allocators clause cannot appear in dependent context");
10793 template <typename Derived>
10794 OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10795 OMPAtomicDefaultMemOrderClause *C) {
10796 llvm_unreachable(
10797 "atomic_default_mem_order clause cannot appear in dependent context");
10800 template <typename Derived>
10801 OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10802 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10803 C->getBeginLoc(), C->getLParenLoc(),
10804 C->getEndLoc());
10807 template <typename Derived>
10808 OMPClause *
10809 TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10810 return getDerived().RebuildOMPSeverityClause(
10811 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10812 C->getLParenLoc(), C->getEndLoc());
10815 template <typename Derived>
10816 OMPClause *
10817 TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10818 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10819 if (E.isInvalid())
10820 return nullptr;
10821 return getDerived().RebuildOMPMessageClause(
10822 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10823 C->getEndLoc());
10826 template <typename Derived>
10827 OMPClause *
10828 TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10829 llvm::SmallVector<Expr *, 16> Vars;
10830 Vars.reserve(C->varlist_size());
10831 for (auto *VE : C->varlist()) {
10832 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10833 if (EVar.isInvalid())
10834 return nullptr;
10835 Vars.push_back(EVar.get());
10837 return getDerived().RebuildOMPPrivateClause(
10838 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10841 template <typename Derived>
10842 OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10843 OMPFirstprivateClause *C) {
10844 llvm::SmallVector<Expr *, 16> Vars;
10845 Vars.reserve(C->varlist_size());
10846 for (auto *VE : C->varlist()) {
10847 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10848 if (EVar.isInvalid())
10849 return nullptr;
10850 Vars.push_back(EVar.get());
10852 return getDerived().RebuildOMPFirstprivateClause(
10853 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10856 template <typename Derived>
10857 OMPClause *
10858 TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10859 llvm::SmallVector<Expr *, 16> Vars;
10860 Vars.reserve(C->varlist_size());
10861 for (auto *VE : C->varlist()) {
10862 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10863 if (EVar.isInvalid())
10864 return nullptr;
10865 Vars.push_back(EVar.get());
10867 return getDerived().RebuildOMPLastprivateClause(
10868 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10869 C->getLParenLoc(), C->getEndLoc());
10872 template <typename Derived>
10873 OMPClause *
10874 TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
10875 llvm::SmallVector<Expr *, 16> Vars;
10876 Vars.reserve(C->varlist_size());
10877 for (auto *VE : C->varlist()) {
10878 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10879 if (EVar.isInvalid())
10880 return nullptr;
10881 Vars.push_back(EVar.get());
10883 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
10884 C->getLParenLoc(), C->getEndLoc());
10887 template <typename Derived>
10888 OMPClause *
10889 TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
10890 llvm::SmallVector<Expr *, 16> Vars;
10891 Vars.reserve(C->varlist_size());
10892 for (auto *VE : C->varlist()) {
10893 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10894 if (EVar.isInvalid())
10895 return nullptr;
10896 Vars.push_back(EVar.get());
10898 CXXScopeSpec ReductionIdScopeSpec;
10899 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10901 DeclarationNameInfo NameInfo = C->getNameInfo();
10902 if (NameInfo.getName()) {
10903 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10904 if (!NameInfo.getName())
10905 return nullptr;
10907 // Build a list of all UDR decls with the same names ranged by the Scopes.
10908 // The Scope boundary is a duplication of the previous decl.
10909 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10910 for (auto *E : C->reduction_ops()) {
10911 // Transform all the decls.
10912 if (E) {
10913 auto *ULE = cast<UnresolvedLookupExpr>(E);
10914 UnresolvedSet<8> Decls;
10915 for (auto *D : ULE->decls()) {
10916 NamedDecl *InstD =
10917 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10918 Decls.addDecl(InstD, InstD->getAccess());
10920 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10921 SemaRef.Context, /*NamingClass=*/nullptr,
10922 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10923 /*ADL=*/true, Decls.begin(), Decls.end(),
10924 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
10925 } else
10926 UnresolvedReductions.push_back(nullptr);
10928 return getDerived().RebuildOMPReductionClause(
10929 Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(),
10930 C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
10931 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10934 template <typename Derived>
10935 OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
10936 OMPTaskReductionClause *C) {
10937 llvm::SmallVector<Expr *, 16> Vars;
10938 Vars.reserve(C->varlist_size());
10939 for (auto *VE : C->varlist()) {
10940 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10941 if (EVar.isInvalid())
10942 return nullptr;
10943 Vars.push_back(EVar.get());
10945 CXXScopeSpec ReductionIdScopeSpec;
10946 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10948 DeclarationNameInfo NameInfo = C->getNameInfo();
10949 if (NameInfo.getName()) {
10950 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10951 if (!NameInfo.getName())
10952 return nullptr;
10954 // Build a list of all UDR decls with the same names ranged by the Scopes.
10955 // The Scope boundary is a duplication of the previous decl.
10956 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10957 for (auto *E : C->reduction_ops()) {
10958 // Transform all the decls.
10959 if (E) {
10960 auto *ULE = cast<UnresolvedLookupExpr>(E);
10961 UnresolvedSet<8> Decls;
10962 for (auto *D : ULE->decls()) {
10963 NamedDecl *InstD =
10964 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10965 Decls.addDecl(InstD, InstD->getAccess());
10967 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10968 SemaRef.Context, /*NamingClass=*/nullptr,
10969 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10970 /*ADL=*/true, Decls.begin(), Decls.end(),
10971 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
10972 } else
10973 UnresolvedReductions.push_back(nullptr);
10975 return getDerived().RebuildOMPTaskReductionClause(
10976 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10977 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10980 template <typename Derived>
10981 OMPClause *
10982 TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
10983 llvm::SmallVector<Expr *, 16> Vars;
10984 Vars.reserve(C->varlist_size());
10985 for (auto *VE : C->varlist()) {
10986 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10987 if (EVar.isInvalid())
10988 return nullptr;
10989 Vars.push_back(EVar.get());
10991 CXXScopeSpec ReductionIdScopeSpec;
10992 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10994 DeclarationNameInfo NameInfo = C->getNameInfo();
10995 if (NameInfo.getName()) {
10996 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10997 if (!NameInfo.getName())
10998 return nullptr;
11000 // Build a list of all UDR decls with the same names ranged by the Scopes.
11001 // The Scope boundary is a duplication of the previous decl.
11002 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11003 for (auto *E : C->reduction_ops()) {
11004 // Transform all the decls.
11005 if (E) {
11006 auto *ULE = cast<UnresolvedLookupExpr>(E);
11007 UnresolvedSet<8> Decls;
11008 for (auto *D : ULE->decls()) {
11009 NamedDecl *InstD =
11010 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11011 Decls.addDecl(InstD, InstD->getAccess());
11013 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
11014 SemaRef.Context, /*NamingClass=*/nullptr,
11015 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
11016 /*ADL=*/true, Decls.begin(), Decls.end(),
11017 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11018 } else
11019 UnresolvedReductions.push_back(nullptr);
11021 return getDerived().RebuildOMPInReductionClause(
11022 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11023 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11026 template <typename Derived>
11027 OMPClause *
11028 TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11029 llvm::SmallVector<Expr *, 16> Vars;
11030 Vars.reserve(C->varlist_size());
11031 for (auto *VE : C->varlist()) {
11032 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11033 if (EVar.isInvalid())
11034 return nullptr;
11035 Vars.push_back(EVar.get());
11037 ExprResult Step = getDerived().TransformExpr(C->getStep());
11038 if (Step.isInvalid())
11039 return nullptr;
11040 return getDerived().RebuildOMPLinearClause(
11041 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11042 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11043 C->getEndLoc());
11046 template <typename Derived>
11047 OMPClause *
11048 TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11049 llvm::SmallVector<Expr *, 16> Vars;
11050 Vars.reserve(C->varlist_size());
11051 for (auto *VE : C->varlist()) {
11052 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11053 if (EVar.isInvalid())
11054 return nullptr;
11055 Vars.push_back(EVar.get());
11057 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11058 if (Alignment.isInvalid())
11059 return nullptr;
11060 return getDerived().RebuildOMPAlignedClause(
11061 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11062 C->getColonLoc(), C->getEndLoc());
11065 template <typename Derived>
11066 OMPClause *
11067 TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11068 llvm::SmallVector<Expr *, 16> Vars;
11069 Vars.reserve(C->varlist_size());
11070 for (auto *VE : C->varlist()) {
11071 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11072 if (EVar.isInvalid())
11073 return nullptr;
11074 Vars.push_back(EVar.get());
11076 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11077 C->getLParenLoc(), C->getEndLoc());
11080 template <typename Derived>
11081 OMPClause *
11082 TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11083 llvm::SmallVector<Expr *, 16> Vars;
11084 Vars.reserve(C->varlist_size());
11085 for (auto *VE : C->varlist()) {
11086 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11087 if (EVar.isInvalid())
11088 return nullptr;
11089 Vars.push_back(EVar.get());
11091 return getDerived().RebuildOMPCopyprivateClause(
11092 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11095 template <typename Derived>
11096 OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11097 llvm::SmallVector<Expr *, 16> Vars;
11098 Vars.reserve(C->varlist_size());
11099 for (auto *VE : C->varlist()) {
11100 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11101 if (EVar.isInvalid())
11102 return nullptr;
11103 Vars.push_back(EVar.get());
11105 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11106 C->getLParenLoc(), C->getEndLoc());
11109 template <typename Derived>
11110 OMPClause *
11111 TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11112 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11113 if (E.isInvalid())
11114 return nullptr;
11115 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11116 C->getLParenLoc(), C->getEndLoc());
11119 template <typename Derived>
11120 OMPClause *
11121 TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11122 llvm::SmallVector<Expr *, 16> Vars;
11123 Expr *DepModifier = C->getModifier();
11124 if (DepModifier) {
11125 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11126 if (DepModRes.isInvalid())
11127 return nullptr;
11128 DepModifier = DepModRes.get();
11130 Vars.reserve(C->varlist_size());
11131 for (auto *VE : C->varlist()) {
11132 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11133 if (EVar.isInvalid())
11134 return nullptr;
11135 Vars.push_back(EVar.get());
11137 return getDerived().RebuildOMPDependClause(
11138 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11139 C->getOmpAllMemoryLoc()},
11140 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11143 template <typename Derived>
11144 OMPClause *
11145 TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11146 ExprResult E = getDerived().TransformExpr(C->getDevice());
11147 if (E.isInvalid())
11148 return nullptr;
11149 return getDerived().RebuildOMPDeviceClause(
11150 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11151 C->getModifierLoc(), C->getEndLoc());
11154 template <typename Derived, class T>
11155 bool transformOMPMappableExprListClause(
11156 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11157 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11158 DeclarationNameInfo &MapperIdInfo,
11159 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11160 // Transform expressions in the list.
11161 Vars.reserve(C->varlist_size());
11162 for (auto *VE : C->varlist()) {
11163 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11164 if (EVar.isInvalid())
11165 return true;
11166 Vars.push_back(EVar.get());
11168 // Transform mapper scope specifier and identifier.
11169 NestedNameSpecifierLoc QualifierLoc;
11170 if (C->getMapperQualifierLoc()) {
11171 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11172 C->getMapperQualifierLoc());
11173 if (!QualifierLoc)
11174 return true;
11176 MapperIdScopeSpec.Adopt(QualifierLoc);
11177 MapperIdInfo = C->getMapperIdInfo();
11178 if (MapperIdInfo.getName()) {
11179 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11180 if (!MapperIdInfo.getName())
11181 return true;
11183 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11184 // the previous user-defined mapper lookup in dependent environment.
11185 for (auto *E : C->mapperlists()) {
11186 // Transform all the decls.
11187 if (E) {
11188 auto *ULE = cast<UnresolvedLookupExpr>(E);
11189 UnresolvedSet<8> Decls;
11190 for (auto *D : ULE->decls()) {
11191 NamedDecl *InstD =
11192 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11193 Decls.addDecl(InstD, InstD->getAccess());
11195 UnresolvedMappers.push_back(UnresolvedLookupExpr::Create(
11196 TT.getSema().Context, /*NamingClass=*/nullptr,
11197 MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
11198 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11199 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11200 } else {
11201 UnresolvedMappers.push_back(nullptr);
11204 return false;
11207 template <typename Derived>
11208 OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11209 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11210 llvm::SmallVector<Expr *, 16> Vars;
11211 Expr *IteratorModifier = C->getIteratorModifier();
11212 if (IteratorModifier) {
11213 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11214 if (MapModRes.isInvalid())
11215 return nullptr;
11216 IteratorModifier = MapModRes.get();
11218 CXXScopeSpec MapperIdScopeSpec;
11219 DeclarationNameInfo MapperIdInfo;
11220 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11221 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11222 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11223 return nullptr;
11224 return getDerived().RebuildOMPMapClause(
11225 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11226 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11227 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11230 template <typename Derived>
11231 OMPClause *
11232 TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11233 Expr *Allocator = C->getAllocator();
11234 if (Allocator) {
11235 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11236 if (AllocatorRes.isInvalid())
11237 return nullptr;
11238 Allocator = AllocatorRes.get();
11240 Expr *Alignment = C->getAlignment();
11241 if (Alignment) {
11242 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
11243 if (AlignmentRes.isInvalid())
11244 return nullptr;
11245 Alignment = AlignmentRes.get();
11247 llvm::SmallVector<Expr *, 16> Vars;
11248 Vars.reserve(C->varlist_size());
11249 for (auto *VE : C->varlist()) {
11250 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11251 if (EVar.isInvalid())
11252 return nullptr;
11253 Vars.push_back(EVar.get());
11255 return getDerived().RebuildOMPAllocateClause(
11256 Allocator, Alignment, C->getFirstAllocateModifier(),
11257 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
11258 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
11259 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11262 template <typename Derived>
11263 OMPClause *
11264 TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11265 llvm::SmallVector<Expr *, 3> Vars;
11266 Vars.reserve(C->varlist_size());
11267 for (auto *VE : C->varlist()) {
11268 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11269 if (EVar.isInvalid())
11270 return nullptr;
11271 Vars.push_back(EVar.get());
11273 return getDerived().RebuildOMPNumTeamsClause(
11274 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11277 template <typename Derived>
11278 OMPClause *
11279 TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
11280 llvm::SmallVector<Expr *, 3> Vars;
11281 Vars.reserve(C->varlist_size());
11282 for (auto *VE : C->varlist()) {
11283 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11284 if (EVar.isInvalid())
11285 return nullptr;
11286 Vars.push_back(EVar.get());
11288 return getDerived().RebuildOMPThreadLimitClause(
11289 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11292 template <typename Derived>
11293 OMPClause *
11294 TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
11295 ExprResult E = getDerived().TransformExpr(C->getPriority());
11296 if (E.isInvalid())
11297 return nullptr;
11298 return getDerived().RebuildOMPPriorityClause(
11299 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11302 template <typename Derived>
11303 OMPClause *
11304 TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
11305 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
11306 if (E.isInvalid())
11307 return nullptr;
11308 return getDerived().RebuildOMPGrainsizeClause(
11309 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11310 C->getModifierLoc(), C->getEndLoc());
11313 template <typename Derived>
11314 OMPClause *
11315 TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
11316 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
11317 if (E.isInvalid())
11318 return nullptr;
11319 return getDerived().RebuildOMPNumTasksClause(
11320 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11321 C->getModifierLoc(), C->getEndLoc());
11324 template <typename Derived>
11325 OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
11326 ExprResult E = getDerived().TransformExpr(C->getHint());
11327 if (E.isInvalid())
11328 return nullptr;
11329 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
11330 C->getLParenLoc(), C->getEndLoc());
11333 template <typename Derived>
11334 OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
11335 OMPDistScheduleClause *C) {
11336 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11337 if (E.isInvalid())
11338 return nullptr;
11339 return getDerived().RebuildOMPDistScheduleClause(
11340 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11341 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11344 template <typename Derived>
11345 OMPClause *
11346 TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
11347 // Rebuild Defaultmap Clause since we need to invoke the checking of
11348 // defaultmap(none:variable-category) after template initialization.
11349 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
11350 C->getDefaultmapKind(),
11351 C->getBeginLoc(),
11352 C->getLParenLoc(),
11353 C->getDefaultmapModifierLoc(),
11354 C->getDefaultmapKindLoc(),
11355 C->getEndLoc());
11358 template <typename Derived>
11359 OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
11360 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11361 llvm::SmallVector<Expr *, 16> Vars;
11362 CXXScopeSpec MapperIdScopeSpec;
11363 DeclarationNameInfo MapperIdInfo;
11364 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11365 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
11366 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11367 return nullptr;
11368 return getDerived().RebuildOMPToClause(
11369 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11370 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11373 template <typename Derived>
11374 OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
11375 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11376 llvm::SmallVector<Expr *, 16> Vars;
11377 CXXScopeSpec MapperIdScopeSpec;
11378 DeclarationNameInfo MapperIdInfo;
11379 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11380 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
11381 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11382 return nullptr;
11383 return getDerived().RebuildOMPFromClause(
11384 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11385 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11388 template <typename Derived>
11389 OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
11390 OMPUseDevicePtrClause *C) {
11391 llvm::SmallVector<Expr *, 16> Vars;
11392 Vars.reserve(C->varlist_size());
11393 for (auto *VE : C->varlist()) {
11394 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11395 if (EVar.isInvalid())
11396 return nullptr;
11397 Vars.push_back(EVar.get());
11399 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11400 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
11403 template <typename Derived>
11404 OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11405 OMPUseDeviceAddrClause *C) {
11406 llvm::SmallVector<Expr *, 16> Vars;
11407 Vars.reserve(C->varlist_size());
11408 for (auto *VE : C->varlist()) {
11409 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11410 if (EVar.isInvalid())
11411 return nullptr;
11412 Vars.push_back(EVar.get());
11414 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11415 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11418 template <typename Derived>
11419 OMPClause *
11420 TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11421 llvm::SmallVector<Expr *, 16> Vars;
11422 Vars.reserve(C->varlist_size());
11423 for (auto *VE : C->varlist()) {
11424 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11425 if (EVar.isInvalid())
11426 return nullptr;
11427 Vars.push_back(EVar.get());
11429 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11430 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
11433 template <typename Derived>
11434 OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
11435 OMPHasDeviceAddrClause *C) {
11436 llvm::SmallVector<Expr *, 16> Vars;
11437 Vars.reserve(C->varlist_size());
11438 for (auto *VE : C->varlist()) {
11439 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11440 if (EVar.isInvalid())
11441 return nullptr;
11442 Vars.push_back(EVar.get());
11444 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11445 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
11448 template <typename Derived>
11449 OMPClause *
11450 TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
11451 llvm::SmallVector<Expr *, 16> Vars;
11452 Vars.reserve(C->varlist_size());
11453 for (auto *VE : C->varlist()) {
11454 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11455 if (EVar.isInvalid())
11456 return nullptr;
11457 Vars.push_back(EVar.get());
11459 return getDerived().RebuildOMPNontemporalClause(
11460 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11463 template <typename Derived>
11464 OMPClause *
11465 TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
11466 llvm::SmallVector<Expr *, 16> Vars;
11467 Vars.reserve(C->varlist_size());
11468 for (auto *VE : C->varlist()) {
11469 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11470 if (EVar.isInvalid())
11471 return nullptr;
11472 Vars.push_back(EVar.get());
11474 return getDerived().RebuildOMPInclusiveClause(
11475 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11478 template <typename Derived>
11479 OMPClause *
11480 TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
11481 llvm::SmallVector<Expr *, 16> Vars;
11482 Vars.reserve(C->varlist_size());
11483 for (auto *VE : C->varlist()) {
11484 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11485 if (EVar.isInvalid())
11486 return nullptr;
11487 Vars.push_back(EVar.get());
11489 return getDerived().RebuildOMPExclusiveClause(
11490 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11493 template <typename Derived>
11494 OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11495 OMPUsesAllocatorsClause *C) {
11496 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
11497 Data.reserve(C->getNumberOfAllocators());
11498 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11499 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11500 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11501 if (Allocator.isInvalid())
11502 continue;
11503 ExprResult AllocatorTraits;
11504 if (Expr *AT = D.AllocatorTraits) {
11505 AllocatorTraits = getDerived().TransformExpr(AT);
11506 if (AllocatorTraits.isInvalid())
11507 continue;
11509 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11510 NewD.Allocator = Allocator.get();
11511 NewD.AllocatorTraits = AllocatorTraits.get();
11512 NewD.LParenLoc = D.LParenLoc;
11513 NewD.RParenLoc = D.RParenLoc;
11515 return getDerived().RebuildOMPUsesAllocatorsClause(
11516 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11519 template <typename Derived>
11520 OMPClause *
11521 TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11522 SmallVector<Expr *, 4> Locators;
11523 Locators.reserve(C->varlist_size());
11524 ExprResult ModifierRes;
11525 if (Expr *Modifier = C->getModifier()) {
11526 ModifierRes = getDerived().TransformExpr(Modifier);
11527 if (ModifierRes.isInvalid())
11528 return nullptr;
11530 for (Expr *E : C->varlist()) {
11531 ExprResult Locator = getDerived().TransformExpr(E);
11532 if (Locator.isInvalid())
11533 continue;
11534 Locators.push_back(Locator.get());
11536 return getDerived().RebuildOMPAffinityClause(
11537 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11538 ModifierRes.get(), Locators);
11541 template <typename Derived>
11542 OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11543 return getDerived().RebuildOMPOrderClause(
11544 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11545 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11548 template <typename Derived>
11549 OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11550 return getDerived().RebuildOMPBindClause(
11551 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11552 C->getLParenLoc(), C->getEndLoc());
11555 template <typename Derived>
11556 OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11557 OMPXDynCGroupMemClause *C) {
11558 ExprResult Size = getDerived().TransformExpr(C->getSize());
11559 if (Size.isInvalid())
11560 return nullptr;
11561 return getDerived().RebuildOMPXDynCGroupMemClause(
11562 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11565 template <typename Derived>
11566 OMPClause *
11567 TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11568 llvm::SmallVector<Expr *, 16> Vars;
11569 Vars.reserve(C->varlist_size());
11570 for (auto *VE : C->varlist()) {
11571 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11572 if (EVar.isInvalid())
11573 return nullptr;
11574 Vars.push_back(EVar.get());
11576 return getDerived().RebuildOMPDoacrossClause(
11577 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11578 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11581 template <typename Derived>
11582 OMPClause *
11583 TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11584 SmallVector<const Attr *> NewAttrs;
11585 for (auto *A : C->getAttrs())
11586 NewAttrs.push_back(getDerived().TransformAttr(A));
11587 return getDerived().RebuildOMPXAttributeClause(
11588 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11591 template <typename Derived>
11592 OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11593 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11596 //===----------------------------------------------------------------------===//
11597 // OpenACC transformation
11598 //===----------------------------------------------------------------------===//
11599 namespace {
11600 template <typename Derived>
11601 class OpenACCClauseTransform final
11602 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11603 TreeTransform<Derived> &Self;
11604 ArrayRef<const OpenACCClause *> ExistingClauses;
11605 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11606 OpenACCClause *NewClause = nullptr;
11608 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11609 llvm::SmallVector<Expr *> InstantiatedVarList;
11610 for (Expr *CurVar : VarList) {
11611 ExprResult Res = Self.TransformExpr(CurVar);
11613 if (!Res.isUsable())
11614 continue;
11616 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getClauseKind(),
11617 Res.get());
11619 if (Res.isUsable())
11620 InstantiatedVarList.push_back(Res.get());
11623 return InstantiatedVarList;
11626 public:
11627 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11628 ArrayRef<const OpenACCClause *> ExistingClauses,
11629 SemaOpenACC::OpenACCParsedClause &PC)
11630 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
11632 OpenACCClause *CreatedClause() const { return NewClause; }
11634 #define VISIT_CLAUSE(CLAUSE_NAME) \
11635 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11636 #include "clang/Basic/OpenACCClauses.def"
11639 template <typename Derived>
11640 void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11641 const OpenACCDefaultClause &C) {
11642 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11644 NewClause = OpenACCDefaultClause::Create(
11645 Self.getSema().getASTContext(), ParsedClause.getDefaultClauseKind(),
11646 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11647 ParsedClause.getEndLoc());
11650 template <typename Derived>
11651 void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11652 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11653 assert(Cond && "If constructed with invalid Condition");
11654 Sema::ConditionResult Res = Self.TransformCondition(
11655 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11657 if (Res.isInvalid() || !Res.get().second)
11658 return;
11660 ParsedClause.setConditionDetails(Res.get().second);
11662 NewClause = OpenACCIfClause::Create(
11663 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11664 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11665 ParsedClause.getEndLoc());
11668 template <typename Derived>
11669 void OpenACCClauseTransform<Derived>::VisitSelfClause(
11670 const OpenACCSelfClause &C) {
11672 // If this is an 'update' 'self' clause, this is actually a var list instead.
11673 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
11674 llvm::SmallVector<Expr *> InstantiatedVarList;
11675 for (Expr *CurVar : C.getVarList()) {
11676 ExprResult Res = Self.TransformExpr(CurVar);
11678 if (!Res.isUsable())
11679 continue;
11681 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getClauseKind(),
11682 Res.get());
11684 if (Res.isUsable())
11685 InstantiatedVarList.push_back(Res.get());
11688 ParsedClause.setVarListDetails(InstantiatedVarList,
11689 /*IsReadOnly=*/false, /*IsZero=*/false);
11691 NewClause = OpenACCSelfClause::Create(
11692 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11693 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11694 ParsedClause.getEndLoc());
11695 } else {
11697 if (C.hasConditionExpr()) {
11698 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11699 Sema::ConditionResult Res =
11700 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
11701 Sema::ConditionKind::Boolean);
11703 if (Res.isInvalid() || !Res.get().second)
11704 return;
11706 ParsedClause.setConditionDetails(Res.get().second);
11709 NewClause = OpenACCSelfClause::Create(
11710 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11711 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11712 ParsedClause.getEndLoc());
11716 template <typename Derived>
11717 void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
11718 const OpenACCNumGangsClause &C) {
11719 llvm::SmallVector<Expr *> InstantiatedIntExprs;
11721 for (Expr *CurIntExpr : C.getIntExprs()) {
11722 ExprResult Res = Self.TransformExpr(CurIntExpr);
11724 if (!Res.isUsable())
11725 return;
11727 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11728 C.getClauseKind(),
11729 C.getBeginLoc(), Res.get());
11730 if (!Res.isUsable())
11731 return;
11733 InstantiatedIntExprs.push_back(Res.get());
11736 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
11737 NewClause = OpenACCNumGangsClause::Create(
11738 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11739 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs(),
11740 ParsedClause.getEndLoc());
11743 template <typename Derived>
11744 void OpenACCClauseTransform<Derived>::VisitPrivateClause(
11745 const OpenACCPrivateClause &C) {
11746 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11747 /*IsReadOnly=*/false, /*IsZero=*/false);
11749 NewClause = OpenACCPrivateClause::Create(
11750 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11751 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11752 ParsedClause.getEndLoc());
11755 template <typename Derived>
11756 void OpenACCClauseTransform<Derived>::VisitHostClause(
11757 const OpenACCHostClause &C) {
11758 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11759 /*IsReadOnly=*/false, /*IsZero=*/false);
11761 NewClause = OpenACCHostClause::Create(
11762 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11763 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11764 ParsedClause.getEndLoc());
11767 template <typename Derived>
11768 void OpenACCClauseTransform<Derived>::VisitDeviceClause(
11769 const OpenACCDeviceClause &C) {
11770 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11771 /*IsReadOnly=*/false, /*IsZero=*/false);
11773 NewClause = OpenACCDeviceClause::Create(
11774 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11775 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11776 ParsedClause.getEndLoc());
11779 template <typename Derived>
11780 void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
11781 const OpenACCFirstPrivateClause &C) {
11782 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11783 /*IsReadOnly=*/false, /*IsZero=*/false);
11785 NewClause = OpenACCFirstPrivateClause::Create(
11786 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11787 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11788 ParsedClause.getEndLoc());
11791 template <typename Derived>
11792 void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
11793 const OpenACCNoCreateClause &C) {
11794 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11795 /*IsReadOnly=*/false, /*IsZero=*/false);
11797 NewClause = OpenACCNoCreateClause::Create(
11798 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11799 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11800 ParsedClause.getEndLoc());
11803 template <typename Derived>
11804 void OpenACCClauseTransform<Derived>::VisitPresentClause(
11805 const OpenACCPresentClause &C) {
11806 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11807 /*IsReadOnly=*/false, /*IsZero=*/false);
11809 NewClause = OpenACCPresentClause::Create(
11810 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11811 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11812 ParsedClause.getEndLoc());
11815 template <typename Derived>
11816 void OpenACCClauseTransform<Derived>::VisitCopyClause(
11817 const OpenACCCopyClause &C) {
11818 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11819 /*IsReadOnly=*/false, /*IsZero=*/false);
11821 NewClause = OpenACCCopyClause::Create(
11822 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11823 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11824 ParsedClause.getVarList(), ParsedClause.getEndLoc());
11827 template <typename Derived>
11828 void OpenACCClauseTransform<Derived>::VisitCopyInClause(
11829 const OpenACCCopyInClause &C) {
11830 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()), C.isReadOnly(),
11831 /*IsZero=*/false);
11833 NewClause = OpenACCCopyInClause::Create(
11834 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11835 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11836 ParsedClause.isReadOnly(), ParsedClause.getVarList(),
11837 ParsedClause.getEndLoc());
11840 template <typename Derived>
11841 void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
11842 const OpenACCCopyOutClause &C) {
11843 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11844 /*IsReadOnly=*/false, C.isZero());
11846 NewClause = OpenACCCopyOutClause::Create(
11847 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11848 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11849 ParsedClause.isZero(), ParsedClause.getVarList(),
11850 ParsedClause.getEndLoc());
11853 template <typename Derived>
11854 void OpenACCClauseTransform<Derived>::VisitCreateClause(
11855 const OpenACCCreateClause &C) {
11856 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11857 /*IsReadOnly=*/false, C.isZero());
11859 NewClause = OpenACCCreateClause::Create(
11860 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11861 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11862 ParsedClause.isZero(), ParsedClause.getVarList(),
11863 ParsedClause.getEndLoc());
11865 template <typename Derived>
11866 void OpenACCClauseTransform<Derived>::VisitAttachClause(
11867 const OpenACCAttachClause &C) {
11868 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
11870 // Ensure each var is a pointer type.
11871 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
11872 return Self.getSema().OpenACC().CheckVarIsPointerType(
11873 OpenACCClauseKind::Attach, E);
11874 }), VarList.end());
11876 ParsedClause.setVarListDetails(VarList,
11877 /*IsReadOnly=*/false, /*IsZero=*/false);
11878 NewClause = OpenACCAttachClause::Create(
11879 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11880 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11881 ParsedClause.getEndLoc());
11884 template <typename Derived>
11885 void OpenACCClauseTransform<Derived>::VisitDetachClause(
11886 const OpenACCDetachClause &C) {
11887 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
11889 // Ensure each var is a pointer type.
11890 VarList.erase(
11891 std::remove_if(VarList.begin(), VarList.end(),
11892 [&](Expr *E) {
11893 return Self.getSema().OpenACC().CheckVarIsPointerType(
11894 OpenACCClauseKind::Detach, E);
11896 VarList.end());
11898 ParsedClause.setVarListDetails(VarList,
11899 /*IsReadOnly=*/false, /*IsZero=*/false);
11900 NewClause = OpenACCDetachClause::Create(
11901 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11902 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11903 ParsedClause.getEndLoc());
11906 template <typename Derived>
11907 void OpenACCClauseTransform<Derived>::VisitDeleteClause(
11908 const OpenACCDeleteClause &C) {
11909 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11910 /*IsReadOnly=*/false, /*IsZero=*/false);
11911 NewClause = OpenACCDeleteClause::Create(
11912 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11913 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11914 ParsedClause.getEndLoc());
11917 template <typename Derived>
11918 void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
11919 const OpenACCUseDeviceClause &C) {
11920 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11921 /*IsReadOnly=*/false, /*IsZero=*/false);
11922 NewClause = OpenACCUseDeviceClause::Create(
11923 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11924 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11925 ParsedClause.getEndLoc());
11928 template <typename Derived>
11929 void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
11930 const OpenACCDevicePtrClause &C) {
11931 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
11933 // Ensure each var is a pointer type.
11934 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
11935 return Self.getSema().OpenACC().CheckVarIsPointerType(
11936 OpenACCClauseKind::DevicePtr, E);
11937 }), VarList.end());
11939 ParsedClause.setVarListDetails(VarList,
11940 /*IsReadOnly=*/false, /*IsZero=*/false);
11941 NewClause = OpenACCDevicePtrClause::Create(
11942 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11943 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11944 ParsedClause.getEndLoc());
11947 template <typename Derived>
11948 void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
11949 const OpenACCNumWorkersClause &C) {
11950 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11951 assert(IntExpr && "num_workers clause constructed with invalid int expr");
11953 ExprResult Res = Self.TransformExpr(IntExpr);
11954 if (!Res.isUsable())
11955 return;
11957 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11958 C.getClauseKind(),
11959 C.getBeginLoc(), Res.get());
11960 if (!Res.isUsable())
11961 return;
11963 ParsedClause.setIntExprDetails(Res.get());
11964 NewClause = OpenACCNumWorkersClause::Create(
11965 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11966 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
11967 ParsedClause.getEndLoc());
11970 template <typename Derived>
11971 void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
11972 const OpenACCDeviceNumClause &C) {
11973 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11974 assert(IntExpr && "device_num clause constructed with invalid int expr");
11976 ExprResult Res = Self.TransformExpr(IntExpr);
11977 if (!Res.isUsable())
11978 return;
11980 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11981 C.getClauseKind(),
11982 C.getBeginLoc(), Res.get());
11983 if (!Res.isUsable())
11984 return;
11986 ParsedClause.setIntExprDetails(Res.get());
11987 NewClause = OpenACCDeviceNumClause::Create(
11988 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11989 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
11990 ParsedClause.getEndLoc());
11993 template <typename Derived>
11994 void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
11995 const OpenACCDefaultAsyncClause &C) {
11996 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11997 assert(IntExpr && "default_async clause constructed with invalid int expr");
11999 ExprResult Res = Self.TransformExpr(IntExpr);
12000 if (!Res.isUsable())
12001 return;
12003 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12004 C.getClauseKind(),
12005 C.getBeginLoc(), Res.get());
12006 if (!Res.isUsable())
12007 return;
12009 ParsedClause.setIntExprDetails(Res.get());
12010 NewClause = OpenACCDefaultAsyncClause::Create(
12011 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12012 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
12013 ParsedClause.getEndLoc());
12016 template <typename Derived>
12017 void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12018 const OpenACCVectorLengthClause &C) {
12019 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12020 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12022 ExprResult Res = Self.TransformExpr(IntExpr);
12023 if (!Res.isUsable())
12024 return;
12026 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12027 C.getClauseKind(),
12028 C.getBeginLoc(), Res.get());
12029 if (!Res.isUsable())
12030 return;
12032 ParsedClause.setIntExprDetails(Res.get());
12033 NewClause = OpenACCVectorLengthClause::Create(
12034 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12035 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
12036 ParsedClause.getEndLoc());
12039 template <typename Derived>
12040 void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12041 const OpenACCAsyncClause &C) {
12042 if (C.hasIntExpr()) {
12043 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12044 if (!Res.isUsable())
12045 return;
12047 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12048 C.getClauseKind(),
12049 C.getBeginLoc(), Res.get());
12050 if (!Res.isUsable())
12051 return;
12052 ParsedClause.setIntExprDetails(Res.get());
12055 NewClause = OpenACCAsyncClause::Create(
12056 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12057 ParsedClause.getLParenLoc(),
12058 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12059 : nullptr,
12060 ParsedClause.getEndLoc());
12063 template <typename Derived>
12064 void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12065 const OpenACCWorkerClause &C) {
12066 if (C.hasIntExpr()) {
12067 // restrictions on this expression are all "does it exist in certain
12068 // situations" that are not possible to be dependent, so the only check we
12069 // have is that it transforms, and is an int expression.
12070 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12071 if (!Res.isUsable())
12072 return;
12074 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12075 C.getClauseKind(),
12076 C.getBeginLoc(), Res.get());
12077 if (!Res.isUsable())
12078 return;
12079 ParsedClause.setIntExprDetails(Res.get());
12082 NewClause = OpenACCWorkerClause::Create(
12083 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12084 ParsedClause.getLParenLoc(),
12085 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12086 : nullptr,
12087 ParsedClause.getEndLoc());
12090 template <typename Derived>
12091 void OpenACCClauseTransform<Derived>::VisitVectorClause(
12092 const OpenACCVectorClause &C) {
12093 if (C.hasIntExpr()) {
12094 // restrictions on this expression are all "does it exist in certain
12095 // situations" that are not possible to be dependent, so the only check we
12096 // have is that it transforms, and is an int expression.
12097 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12098 if (!Res.isUsable())
12099 return;
12101 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12102 C.getClauseKind(),
12103 C.getBeginLoc(), Res.get());
12104 if (!Res.isUsable())
12105 return;
12106 ParsedClause.setIntExprDetails(Res.get());
12109 NewClause = OpenACCVectorClause::Create(
12110 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12111 ParsedClause.getLParenLoc(),
12112 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12113 : nullptr,
12114 ParsedClause.getEndLoc());
12117 template <typename Derived>
12118 void OpenACCClauseTransform<Derived>::VisitWaitClause(
12119 const OpenACCWaitClause &C) {
12120 if (!C.getLParenLoc().isInvalid()) {
12121 Expr *DevNumExpr = nullptr;
12122 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
12124 // Instantiate devnum expr if it exists.
12125 if (C.getDevNumExpr()) {
12126 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
12127 if (!Res.isUsable())
12128 return;
12129 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12130 C.getClauseKind(),
12131 C.getBeginLoc(), Res.get());
12132 if (!Res.isUsable())
12133 return;
12135 DevNumExpr = Res.get();
12138 // Instantiate queue ids.
12139 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
12140 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
12141 if (!Res.isUsable())
12142 return;
12143 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12144 C.getClauseKind(),
12145 C.getBeginLoc(), Res.get());
12146 if (!Res.isUsable())
12147 return;
12149 InstantiatedQueueIdExprs.push_back(Res.get());
12152 ParsedClause.setWaitDetails(DevNumExpr, C.getQueuesLoc(),
12153 std::move(InstantiatedQueueIdExprs));
12156 NewClause = OpenACCWaitClause::Create(
12157 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12158 ParsedClause.getLParenLoc(), ParsedClause.getDevNumExpr(),
12159 ParsedClause.getQueuesLoc(), ParsedClause.getQueueIdExprs(),
12160 ParsedClause.getEndLoc());
12163 template <typename Derived>
12164 void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
12165 const OpenACCDeviceTypeClause &C) {
12166 // Nothing to transform here, just create a new version of 'C'.
12167 NewClause = OpenACCDeviceTypeClause::Create(
12168 Self.getSema().getASTContext(), C.getClauseKind(),
12169 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12170 C.getArchitectures(), ParsedClause.getEndLoc());
12173 template <typename Derived>
12174 void OpenACCClauseTransform<Derived>::VisitAutoClause(
12175 const OpenACCAutoClause &C) {
12176 // Nothing to do, so just create a new node.
12177 NewClause = OpenACCAutoClause::Create(Self.getSema().getASTContext(),
12178 ParsedClause.getBeginLoc(),
12179 ParsedClause.getEndLoc());
12182 template <typename Derived>
12183 void OpenACCClauseTransform<Derived>::VisitIndependentClause(
12184 const OpenACCIndependentClause &C) {
12185 NewClause = OpenACCIndependentClause::Create(Self.getSema().getASTContext(),
12186 ParsedClause.getBeginLoc(),
12187 ParsedClause.getEndLoc());
12190 template <typename Derived>
12191 void OpenACCClauseTransform<Derived>::VisitSeqClause(
12192 const OpenACCSeqClause &C) {
12193 NewClause = OpenACCSeqClause::Create(Self.getSema().getASTContext(),
12194 ParsedClause.getBeginLoc(),
12195 ParsedClause.getEndLoc());
12197 template <typename Derived>
12198 void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
12199 const OpenACCFinalizeClause &C) {
12200 NewClause = OpenACCFinalizeClause::Create(Self.getSema().getASTContext(),
12201 ParsedClause.getBeginLoc(),
12202 ParsedClause.getEndLoc());
12205 template <typename Derived>
12206 void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
12207 const OpenACCIfPresentClause &C) {
12208 NewClause = OpenACCIfPresentClause::Create(Self.getSema().getASTContext(),
12209 ParsedClause.getBeginLoc(),
12210 ParsedClause.getEndLoc());
12213 template <typename Derived>
12214 void OpenACCClauseTransform<Derived>::VisitReductionClause(
12215 const OpenACCReductionClause &C) {
12216 SmallVector<Expr *> TransformedVars = VisitVarList(C.getVarList());
12217 SmallVector<Expr *> ValidVars;
12219 for (Expr *Var : TransformedVars) {
12220 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
12221 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
12222 if (Res.isUsable())
12223 ValidVars.push_back(Res.get());
12226 NewClause = Self.getSema().OpenACC().CheckReductionClause(
12227 ExistingClauses, ParsedClause.getDirectiveKind(),
12228 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12229 C.getReductionOp(), ValidVars, ParsedClause.getEndLoc());
12232 template <typename Derived>
12233 void OpenACCClauseTransform<Derived>::VisitCollapseClause(
12234 const OpenACCCollapseClause &C) {
12235 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
12236 assert(LoopCount && "collapse clause constructed with invalid loop count");
12238 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
12240 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
12241 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12242 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
12244 NewLoopCount =
12245 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
12247 if (!NewLoopCount.isUsable())
12248 return;
12250 ParsedClause.setCollapseDetails(C.hasForce(), NewLoopCount.get());
12251 NewClause = OpenACCCollapseClause::Create(
12252 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12253 ParsedClause.getLParenLoc(), ParsedClause.isForce(),
12254 ParsedClause.getLoopCount(), ParsedClause.getEndLoc());
12257 template <typename Derived>
12258 void OpenACCClauseTransform<Derived>::VisitTileClause(
12259 const OpenACCTileClause &C) {
12261 llvm::SmallVector<Expr *> TransformedExprs;
12263 for (Expr *E : C.getSizeExprs()) {
12264 ExprResult NewSizeExpr = Self.TransformExpr(E);
12266 if (!NewSizeExpr.isUsable())
12267 return;
12269 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
12270 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12271 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
12273 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
12275 if (!NewSizeExpr.isUsable())
12276 return;
12277 TransformedExprs.push_back(NewSizeExpr.get());
12280 ParsedClause.setIntExprDetails(TransformedExprs);
12281 NewClause = OpenACCTileClause::Create(
12282 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12283 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs(),
12284 ParsedClause.getEndLoc());
12286 template <typename Derived>
12287 void OpenACCClauseTransform<Derived>::VisitGangClause(
12288 const OpenACCGangClause &C) {
12289 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
12290 llvm::SmallVector<Expr *> TransformedIntExprs;
12292 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
12293 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
12294 if (!ER.isUsable())
12295 continue;
12297 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
12298 ParsedClause.getDirectiveKind(),
12299 C.getExpr(I).first, ER.get());
12300 if (!ER.isUsable())
12301 continue;
12302 TransformedGangKinds.push_back(C.getExpr(I).first);
12303 TransformedIntExprs.push_back(ER.get());
12306 NewClause = Self.getSema().OpenACC().CheckGangClause(
12307 ParsedClause.getDirectiveKind(), ExistingClauses,
12308 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12309 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
12311 } // namespace
12312 template <typename Derived>
12313 OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
12314 ArrayRef<const OpenACCClause *> ExistingClauses,
12315 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
12317 SemaOpenACC::OpenACCParsedClause ParsedClause(
12318 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
12319 ParsedClause.setEndLoc(OldClause->getEndLoc());
12321 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(OldClause))
12322 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
12324 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
12325 ParsedClause};
12326 Transform.Visit(OldClause);
12328 return Transform.CreatedClause();
12331 template <typename Derived>
12332 llvm::SmallVector<OpenACCClause *>
12333 TreeTransform<Derived>::TransformOpenACCClauseList(
12334 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
12335 llvm::SmallVector<OpenACCClause *> TransformedClauses;
12336 for (const auto *Clause : OldClauses) {
12337 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
12338 TransformedClauses, DirKind, Clause))
12339 TransformedClauses.push_back(TransformedClause);
12341 return TransformedClauses;
12344 template <typename Derived>
12345 StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
12346 OpenACCComputeConstruct *C) {
12347 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12349 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12350 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12351 C->clauses());
12353 if (getSema().OpenACC().ActOnStartStmtDirective(
12354 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12355 return StmtError();
12357 // Transform Structured Block.
12358 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12359 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12360 C->clauses(), TransformedClauses);
12361 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12362 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12363 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12365 return getDerived().RebuildOpenACCComputeConstruct(
12366 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12367 C->getEndLoc(), TransformedClauses, StrBlock);
12370 template <typename Derived>
12371 StmtResult
12372 TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
12374 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12376 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12377 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12378 C->clauses());
12380 if (getSema().OpenACC().ActOnStartStmtDirective(
12381 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12382 return StmtError();
12384 // Transform Loop.
12385 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12386 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12387 C->clauses(), TransformedClauses);
12388 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12389 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12390 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12392 return getDerived().RebuildOpenACCLoopConstruct(
12393 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12394 TransformedClauses, Loop);
12397 template <typename Derived>
12398 StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
12399 OpenACCCombinedConstruct *C) {
12400 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12402 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12403 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12404 C->clauses());
12406 if (getSema().OpenACC().ActOnStartStmtDirective(
12407 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12408 return StmtError();
12410 // Transform Loop.
12411 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12412 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12413 C->clauses(), TransformedClauses);
12414 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12415 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12416 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12418 return getDerived().RebuildOpenACCCombinedConstruct(
12419 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12420 C->getEndLoc(), TransformedClauses, Loop);
12423 template <typename Derived>
12424 StmtResult
12425 TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
12426 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12428 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12429 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12430 C->clauses());
12431 if (getSema().OpenACC().ActOnStartStmtDirective(
12432 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12433 return StmtError();
12435 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12436 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12437 C->clauses(), TransformedClauses);
12438 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12439 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12440 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12442 return getDerived().RebuildOpenACCDataConstruct(
12443 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12444 TransformedClauses, StrBlock);
12447 template <typename Derived>
12448 StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
12449 OpenACCEnterDataConstruct *C) {
12450 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12452 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12453 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12454 C->clauses());
12455 if (getSema().OpenACC().ActOnStartStmtDirective(
12456 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12457 return StmtError();
12459 return getDerived().RebuildOpenACCEnterDataConstruct(
12460 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12461 TransformedClauses);
12464 template <typename Derived>
12465 StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
12466 OpenACCExitDataConstruct *C) {
12467 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12469 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12470 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12471 C->clauses());
12472 if (getSema().OpenACC().ActOnStartStmtDirective(
12473 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12474 return StmtError();
12476 return getDerived().RebuildOpenACCExitDataConstruct(
12477 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12478 TransformedClauses);
12481 template <typename Derived>
12482 StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
12483 OpenACCHostDataConstruct *C) {
12484 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12486 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12487 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12488 C->clauses());
12489 if (getSema().OpenACC().ActOnStartStmtDirective(
12490 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12491 return StmtError();
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);
12500 return getDerived().RebuildOpenACCHostDataConstruct(
12501 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12502 TransformedClauses, StrBlock);
12505 template <typename Derived>
12506 StmtResult
12507 TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
12508 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12510 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12511 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12512 C->clauses());
12513 if (getSema().OpenACC().ActOnStartStmtDirective(
12514 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12515 return StmtError();
12517 return getDerived().RebuildOpenACCInitConstruct(
12518 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12519 TransformedClauses);
12522 template <typename Derived>
12523 StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
12524 OpenACCShutdownConstruct *C) {
12525 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12527 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12528 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12529 C->clauses());
12530 if (getSema().OpenACC().ActOnStartStmtDirective(
12531 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12532 return StmtError();
12534 return getDerived().RebuildOpenACCShutdownConstruct(
12535 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12536 TransformedClauses);
12538 template <typename Derived>
12539 StmtResult
12540 TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
12541 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12543 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12544 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12545 C->clauses());
12546 if (getSema().OpenACC().ActOnStartStmtDirective(
12547 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12548 return StmtError();
12550 return getDerived().RebuildOpenACCSetConstruct(
12551 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12552 TransformedClauses);
12555 template <typename Derived>
12556 StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
12557 OpenACCUpdateConstruct *C) {
12558 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12560 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12561 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12562 C->clauses());
12563 if (getSema().OpenACC().ActOnStartStmtDirective(
12564 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12565 return StmtError();
12567 return getDerived().RebuildOpenACCUpdateConstruct(
12568 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12569 TransformedClauses);
12572 template <typename Derived>
12573 StmtResult
12574 TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
12575 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12577 ExprResult DevNumExpr;
12578 if (C->hasDevNumExpr()) {
12579 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
12581 if (DevNumExpr.isUsable())
12582 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
12583 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
12584 C->getBeginLoc(), DevNumExpr.get());
12587 llvm::SmallVector<Expr *> QueueIdExprs;
12589 for (Expr *QE : C->getQueueIdExprs()) {
12590 assert(QE && "Null queue id expr?");
12591 ExprResult NewEQ = getDerived().TransformExpr(QE);
12593 if (!NewEQ.isUsable())
12594 break;
12595 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
12596 OpenACCClauseKind::Invalid,
12597 C->getBeginLoc(), NewEQ.get());
12598 if (NewEQ.isUsable())
12599 QueueIdExprs.push_back(NewEQ.get());
12602 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12603 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12604 C->clauses());
12606 if (getSema().OpenACC().ActOnStartStmtDirective(
12607 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12608 return StmtError();
12610 return getDerived().RebuildOpenACCWaitConstruct(
12611 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12612 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
12613 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
12616 template <typename Derived>
12617 ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
12618 OpenACCAsteriskSizeExpr *E) {
12619 if (getDerived().AlwaysRebuild())
12620 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
12621 // Nothing can ever change, so there is never anything to transform.
12622 return E;
12625 //===----------------------------------------------------------------------===//
12626 // Expression transformation
12627 //===----------------------------------------------------------------------===//
12628 template<typename Derived>
12629 ExprResult
12630 TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
12631 return TransformExpr(E->getSubExpr());
12634 template <typename Derived>
12635 ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
12636 SYCLUniqueStableNameExpr *E) {
12637 if (!E->isTypeDependent())
12638 return E;
12640 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
12642 if (!NewT)
12643 return ExprError();
12645 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
12646 return E;
12648 return getDerived().RebuildSYCLUniqueStableNameExpr(
12649 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
12652 template<typename Derived>
12653 ExprResult
12654 TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
12655 if (!E->isTypeDependent())
12656 return E;
12658 return getDerived().RebuildPredefinedExpr(E->getLocation(),
12659 E->getIdentKind());
12662 template<typename Derived>
12663 ExprResult
12664 TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
12665 NestedNameSpecifierLoc QualifierLoc;
12666 if (E->getQualifierLoc()) {
12667 QualifierLoc
12668 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
12669 if (!QualifierLoc)
12670 return ExprError();
12673 ValueDecl *ND
12674 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
12675 E->getDecl()));
12676 if (!ND)
12677 return ExprError();
12679 NamedDecl *Found = ND;
12680 if (E->getFoundDecl() != E->getDecl()) {
12681 Found = cast_or_null<NamedDecl>(
12682 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
12683 if (!Found)
12684 return ExprError();
12687 DeclarationNameInfo NameInfo = E->getNameInfo();
12688 if (NameInfo.getName()) {
12689 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
12690 if (!NameInfo.getName())
12691 return ExprError();
12694 if (!getDerived().AlwaysRebuild() &&
12695 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
12696 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
12697 Found == E->getFoundDecl() &&
12698 NameInfo.getName() == E->getDecl()->getDeclName() &&
12699 !E->hasExplicitTemplateArgs()) {
12701 // Mark it referenced in the new context regardless.
12702 // FIXME: this is a bit instantiation-specific.
12703 SemaRef.MarkDeclRefReferenced(E);
12705 return E;
12708 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
12709 if (E->hasExplicitTemplateArgs()) {
12710 TemplateArgs = &TransArgs;
12711 TransArgs.setLAngleLoc(E->getLAngleLoc());
12712 TransArgs.setRAngleLoc(E->getRAngleLoc());
12713 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
12714 E->getNumTemplateArgs(),
12715 TransArgs))
12716 return ExprError();
12719 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
12720 Found, TemplateArgs);
12723 template<typename Derived>
12724 ExprResult
12725 TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
12726 return E;
12729 template <typename Derived>
12730 ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
12731 FixedPointLiteral *E) {
12732 return E;
12735 template<typename Derived>
12736 ExprResult
12737 TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
12738 return E;
12741 template<typename Derived>
12742 ExprResult
12743 TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
12744 return E;
12747 template<typename Derived>
12748 ExprResult
12749 TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
12750 return E;
12753 template<typename Derived>
12754 ExprResult
12755 TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
12756 return E;
12759 template<typename Derived>
12760 ExprResult
12761 TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
12762 return getDerived().TransformCallExpr(E);
12765 template<typename Derived>
12766 ExprResult
12767 TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
12768 ExprResult ControllingExpr;
12769 TypeSourceInfo *ControllingType = nullptr;
12770 if (E->isExprPredicate())
12771 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
12772 else
12773 ControllingType = getDerived().TransformType(E->getControllingType());
12775 if (ControllingExpr.isInvalid() && !ControllingType)
12776 return ExprError();
12778 SmallVector<Expr *, 4> AssocExprs;
12779 SmallVector<TypeSourceInfo *, 4> AssocTypes;
12780 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
12781 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
12782 if (TSI) {
12783 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
12784 if (!AssocType)
12785 return ExprError();
12786 AssocTypes.push_back(AssocType);
12787 } else {
12788 AssocTypes.push_back(nullptr);
12791 ExprResult AssocExpr =
12792 getDerived().TransformExpr(Assoc.getAssociationExpr());
12793 if (AssocExpr.isInvalid())
12794 return ExprError();
12795 AssocExprs.push_back(AssocExpr.get());
12798 if (!ControllingType)
12799 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
12800 E->getDefaultLoc(),
12801 E->getRParenLoc(),
12802 ControllingExpr.get(),
12803 AssocTypes,
12804 AssocExprs);
12805 return getDerived().RebuildGenericSelectionExpr(
12806 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
12807 ControllingType, AssocTypes, AssocExprs);
12810 template<typename Derived>
12811 ExprResult
12812 TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
12813 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12814 if (SubExpr.isInvalid())
12815 return ExprError();
12817 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
12818 return E;
12820 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
12821 E->getRParen());
12824 /// The operand of a unary address-of operator has special rules: it's
12825 /// allowed to refer to a non-static member of a class even if there's no 'this'
12826 /// object available.
12827 template<typename Derived>
12828 ExprResult
12829 TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
12830 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
12831 return getDerived().TransformDependentScopeDeclRefExpr(
12832 DRE, /*IsAddressOfOperand=*/true, nullptr);
12833 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E))
12834 return getDerived().TransformUnresolvedLookupExpr(
12835 ULE, /*IsAddressOfOperand=*/true);
12836 else
12837 return getDerived().TransformExpr(E);
12840 template<typename Derived>
12841 ExprResult
12842 TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
12843 ExprResult SubExpr;
12844 if (E->getOpcode() == UO_AddrOf)
12845 SubExpr = TransformAddressOfOperand(E->getSubExpr());
12846 else
12847 SubExpr = TransformExpr(E->getSubExpr());
12848 if (SubExpr.isInvalid())
12849 return ExprError();
12851 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
12852 return E;
12854 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
12855 E->getOpcode(),
12856 SubExpr.get());
12859 template<typename Derived>
12860 ExprResult
12861 TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
12862 // Transform the type.
12863 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
12864 if (!Type)
12865 return ExprError();
12867 // Transform all of the components into components similar to what the
12868 // parser uses.
12869 // FIXME: It would be slightly more efficient in the non-dependent case to
12870 // just map FieldDecls, rather than requiring the rebuilder to look for
12871 // the fields again. However, __builtin_offsetof is rare enough in
12872 // template code that we don't care.
12873 bool ExprChanged = false;
12874 typedef Sema::OffsetOfComponent Component;
12875 SmallVector<Component, 4> Components;
12876 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
12877 const OffsetOfNode &ON = E->getComponent(I);
12878 Component Comp;
12879 Comp.isBrackets = true;
12880 Comp.LocStart = ON.getSourceRange().getBegin();
12881 Comp.LocEnd = ON.getSourceRange().getEnd();
12882 switch (ON.getKind()) {
12883 case OffsetOfNode::Array: {
12884 Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
12885 ExprResult Index = getDerived().TransformExpr(FromIndex);
12886 if (Index.isInvalid())
12887 return ExprError();
12889 ExprChanged = ExprChanged || Index.get() != FromIndex;
12890 Comp.isBrackets = true;
12891 Comp.U.E = Index.get();
12892 break;
12895 case OffsetOfNode::Field:
12896 case OffsetOfNode::Identifier:
12897 Comp.isBrackets = false;
12898 Comp.U.IdentInfo = ON.getFieldName();
12899 if (!Comp.U.IdentInfo)
12900 continue;
12902 break;
12904 case OffsetOfNode::Base:
12905 // Will be recomputed during the rebuild.
12906 continue;
12909 Components.push_back(Comp);
12912 // If nothing changed, retain the existing expression.
12913 if (!getDerived().AlwaysRebuild() &&
12914 Type == E->getTypeSourceInfo() &&
12915 !ExprChanged)
12916 return E;
12918 // Build a new offsetof expression.
12919 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
12920 Components, E->getRParenLoc());
12923 template<typename Derived>
12924 ExprResult
12925 TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
12926 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
12927 "opaque value expression requires transformation");
12928 return E;
12931 template<typename Derived>
12932 ExprResult
12933 TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
12934 return E;
12937 template <typename Derived>
12938 ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
12939 llvm::SmallVector<Expr *, 8> Children;
12940 bool Changed = false;
12941 for (Expr *C : E->subExpressions()) {
12942 ExprResult NewC = getDerived().TransformExpr(C);
12943 if (NewC.isInvalid())
12944 return ExprError();
12945 Children.push_back(NewC.get());
12947 Changed |= NewC.get() != C;
12949 if (!getDerived().AlwaysRebuild() && !Changed)
12950 return E;
12951 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
12952 Children, E->getType());
12955 template<typename Derived>
12956 ExprResult
12957 TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
12958 // Rebuild the syntactic form. The original syntactic form has
12959 // opaque-value expressions in it, so strip those away and rebuild
12960 // the result. This is a really awful way of doing this, but the
12961 // better solution (rebuilding the semantic expressions and
12962 // rebinding OVEs as necessary) doesn't work; we'd need
12963 // TreeTransform to not strip away implicit conversions.
12964 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
12965 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
12966 if (result.isInvalid()) return ExprError();
12968 // If that gives us a pseudo-object result back, the pseudo-object
12969 // expression must have been an lvalue-to-rvalue conversion which we
12970 // should reapply.
12971 if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
12972 result = SemaRef.PseudoObject().checkRValue(result.get());
12974 return result;
12977 template<typename Derived>
12978 ExprResult
12979 TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
12980 UnaryExprOrTypeTraitExpr *E) {
12981 if (E->isArgumentType()) {
12982 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
12984 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
12985 if (!NewT)
12986 return ExprError();
12988 if (!getDerived().AlwaysRebuild() && OldT == NewT)
12989 return E;
12991 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
12992 E->getKind(),
12993 E->getSourceRange());
12996 // C++0x [expr.sizeof]p1:
12997 // The operand is either an expression, which is an unevaluated operand
12998 // [...]
12999 EnterExpressionEvaluationContext Unevaluated(
13000 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13001 Sema::ReuseLambdaContextDecl);
13003 // Try to recover if we have something like sizeof(T::X) where X is a type.
13004 // Notably, there must be *exactly* one set of parens if X is a type.
13005 TypeSourceInfo *RecoveryTSI = nullptr;
13006 ExprResult SubExpr;
13007 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
13008 if (auto *DRE =
13009 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
13010 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
13011 PE, DRE, false, &RecoveryTSI);
13012 else
13013 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
13015 if (RecoveryTSI) {
13016 return getDerived().RebuildUnaryExprOrTypeTrait(
13017 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
13018 } else if (SubExpr.isInvalid())
13019 return ExprError();
13021 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
13022 return E;
13024 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
13025 E->getOperatorLoc(),
13026 E->getKind(),
13027 E->getSourceRange());
13030 template<typename Derived>
13031 ExprResult
13032 TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
13033 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13034 if (LHS.isInvalid())
13035 return ExprError();
13037 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13038 if (RHS.isInvalid())
13039 return ExprError();
13042 if (!getDerived().AlwaysRebuild() &&
13043 LHS.get() == E->getLHS() &&
13044 RHS.get() == E->getRHS())
13045 return E;
13047 return getDerived().RebuildArraySubscriptExpr(
13048 LHS.get(),
13049 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
13052 template <typename Derived>
13053 ExprResult
13054 TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
13055 ExprResult Base = getDerived().TransformExpr(E->getBase());
13056 if (Base.isInvalid())
13057 return ExprError();
13059 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13060 if (RowIdx.isInvalid())
13061 return ExprError();
13063 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
13064 if (ColumnIdx.isInvalid())
13065 return ExprError();
13067 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13068 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
13069 return E;
13071 return getDerived().RebuildMatrixSubscriptExpr(
13072 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
13075 template <typename Derived>
13076 ExprResult
13077 TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
13078 ExprResult Base = getDerived().TransformExpr(E->getBase());
13079 if (Base.isInvalid())
13080 return ExprError();
13082 ExprResult LowerBound;
13083 if (E->getLowerBound()) {
13084 LowerBound = getDerived().TransformExpr(E->getLowerBound());
13085 if (LowerBound.isInvalid())
13086 return ExprError();
13089 ExprResult Length;
13090 if (E->getLength()) {
13091 Length = getDerived().TransformExpr(E->getLength());
13092 if (Length.isInvalid())
13093 return ExprError();
13096 ExprResult Stride;
13097 if (E->isOMPArraySection()) {
13098 if (Expr *Str = E->getStride()) {
13099 Stride = getDerived().TransformExpr(Str);
13100 if (Stride.isInvalid())
13101 return ExprError();
13105 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13106 LowerBound.get() == E->getLowerBound() &&
13107 Length.get() == E->getLength() &&
13108 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
13109 return E;
13111 return getDerived().RebuildArraySectionExpr(
13112 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
13113 LowerBound.get(), E->getColonLocFirst(),
13114 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
13115 Length.get(), Stride.get(), E->getRBracketLoc());
13118 template <typename Derived>
13119 ExprResult
13120 TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
13121 ExprResult Base = getDerived().TransformExpr(E->getBase());
13122 if (Base.isInvalid())
13123 return ExprError();
13125 SmallVector<Expr *, 4> Dims;
13126 bool ErrorFound = false;
13127 for (Expr *Dim : E->getDimensions()) {
13128 ExprResult DimRes = getDerived().TransformExpr(Dim);
13129 if (DimRes.isInvalid()) {
13130 ErrorFound = true;
13131 continue;
13133 Dims.push_back(DimRes.get());
13136 if (ErrorFound)
13137 return ExprError();
13138 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
13139 E->getRParenLoc(), Dims,
13140 E->getBracketsRanges());
13143 template <typename Derived>
13144 ExprResult
13145 TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
13146 unsigned NumIterators = E->numOfIterators();
13147 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
13149 bool ErrorFound = false;
13150 bool NeedToRebuild = getDerived().AlwaysRebuild();
13151 for (unsigned I = 0; I < NumIterators; ++I) {
13152 auto *D = cast<VarDecl>(E->getIteratorDecl(I));
13153 Data[I].DeclIdent = D->getIdentifier();
13154 Data[I].DeclIdentLoc = D->getLocation();
13155 if (D->getLocation() == D->getBeginLoc()) {
13156 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
13157 "Implicit type must be int.");
13158 } else {
13159 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
13160 QualType DeclTy = getDerived().TransformType(D->getType());
13161 Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI);
13163 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
13164 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
13165 ExprResult End = getDerived().TransformExpr(Range.End);
13166 ExprResult Step = getDerived().TransformExpr(Range.Step);
13167 ErrorFound = ErrorFound ||
13168 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
13169 !Data[I].Type.get().isNull())) ||
13170 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
13171 if (ErrorFound)
13172 continue;
13173 Data[I].Range.Begin = Begin.get();
13174 Data[I].Range.End = End.get();
13175 Data[I].Range.Step = Step.get();
13176 Data[I].AssignLoc = E->getAssignLoc(I);
13177 Data[I].ColonLoc = E->getColonLoc(I);
13178 Data[I].SecColonLoc = E->getSecondColonLoc(I);
13179 NeedToRebuild =
13180 NeedToRebuild ||
13181 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
13182 D->getType().getTypePtrOrNull()) ||
13183 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
13184 Range.Step != Data[I].Range.Step;
13186 if (ErrorFound)
13187 return ExprError();
13188 if (!NeedToRebuild)
13189 return E;
13191 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
13192 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
13193 if (!Res.isUsable())
13194 return Res;
13195 auto *IE = cast<OMPIteratorExpr>(Res.get());
13196 for (unsigned I = 0; I < NumIterators; ++I)
13197 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
13198 IE->getIteratorDecl(I));
13199 return Res;
13202 template<typename Derived>
13203 ExprResult
13204 TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
13205 // Transform the callee.
13206 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13207 if (Callee.isInvalid())
13208 return ExprError();
13210 // Transform arguments.
13211 bool ArgChanged = false;
13212 SmallVector<Expr*, 8> Args;
13213 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13214 &ArgChanged))
13215 return ExprError();
13217 if (!getDerived().AlwaysRebuild() &&
13218 Callee.get() == E->getCallee() &&
13219 !ArgChanged)
13220 return SemaRef.MaybeBindToTemporary(E);
13222 // FIXME: Wrong source location information for the '('.
13223 SourceLocation FakeLParenLoc
13224 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13226 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13227 if (E->hasStoredFPFeatures()) {
13228 FPOptionsOverride NewOverrides = E->getFPFeatures();
13229 getSema().CurFPFeatures =
13230 NewOverrides.applyOverrides(getSema().getLangOpts());
13231 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13234 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13235 Args,
13236 E->getRParenLoc());
13239 template<typename Derived>
13240 ExprResult
13241 TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
13242 ExprResult Base = getDerived().TransformExpr(E->getBase());
13243 if (Base.isInvalid())
13244 return ExprError();
13246 NestedNameSpecifierLoc QualifierLoc;
13247 if (E->hasQualifier()) {
13248 QualifierLoc
13249 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13251 if (!QualifierLoc)
13252 return ExprError();
13254 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13256 ValueDecl *Member
13257 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
13258 E->getMemberDecl()));
13259 if (!Member)
13260 return ExprError();
13262 NamedDecl *FoundDecl = E->getFoundDecl();
13263 if (FoundDecl == E->getMemberDecl()) {
13264 FoundDecl = Member;
13265 } else {
13266 FoundDecl = cast_or_null<NamedDecl>(
13267 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
13268 if (!FoundDecl)
13269 return ExprError();
13272 if (!getDerived().AlwaysRebuild() &&
13273 Base.get() == E->getBase() &&
13274 QualifierLoc == E->getQualifierLoc() &&
13275 Member == E->getMemberDecl() &&
13276 FoundDecl == E->getFoundDecl() &&
13277 !E->hasExplicitTemplateArgs()) {
13279 // Skip for member expression of (this->f), rebuilt thisi->f is needed
13280 // for Openmp where the field need to be privatizized in the case.
13281 if (!(isa<CXXThisExpr>(E->getBase()) &&
13282 getSema().OpenMP().isOpenMPRebuildMemberExpr(
13283 cast<ValueDecl>(Member)))) {
13284 // Mark it referenced in the new context regardless.
13285 // FIXME: this is a bit instantiation-specific.
13286 SemaRef.MarkMemberReferenced(E);
13287 return E;
13291 TemplateArgumentListInfo TransArgs;
13292 if (E->hasExplicitTemplateArgs()) {
13293 TransArgs.setLAngleLoc(E->getLAngleLoc());
13294 TransArgs.setRAngleLoc(E->getRAngleLoc());
13295 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13296 E->getNumTemplateArgs(),
13297 TransArgs))
13298 return ExprError();
13301 // FIXME: Bogus source location for the operator
13302 SourceLocation FakeOperatorLoc =
13303 SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
13305 // FIXME: to do this check properly, we will need to preserve the
13306 // first-qualifier-in-scope here, just in case we had a dependent
13307 // base (and therefore couldn't do the check) and a
13308 // nested-name-qualifier (and therefore could do the lookup).
13309 NamedDecl *FirstQualifierInScope = nullptr;
13310 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
13311 if (MemberNameInfo.getName()) {
13312 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
13313 if (!MemberNameInfo.getName())
13314 return ExprError();
13317 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
13318 E->isArrow(),
13319 QualifierLoc,
13320 TemplateKWLoc,
13321 MemberNameInfo,
13322 Member,
13323 FoundDecl,
13324 (E->hasExplicitTemplateArgs()
13325 ? &TransArgs : nullptr),
13326 FirstQualifierInScope);
13329 template<typename Derived>
13330 ExprResult
13331 TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
13332 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13333 if (LHS.isInvalid())
13334 return ExprError();
13336 ExprResult RHS =
13337 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
13338 if (RHS.isInvalid())
13339 return ExprError();
13341 if (!getDerived().AlwaysRebuild() &&
13342 LHS.get() == E->getLHS() &&
13343 RHS.get() == E->getRHS())
13344 return E;
13346 if (E->isCompoundAssignmentOp())
13347 // FPFeatures has already been established from trailing storage
13348 return getDerived().RebuildBinaryOperator(
13349 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
13350 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13351 FPOptionsOverride NewOverrides(E->getFPFeatures());
13352 getSema().CurFPFeatures =
13353 NewOverrides.applyOverrides(getSema().getLangOpts());
13354 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13355 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
13356 LHS.get(), RHS.get());
13359 template <typename Derived>
13360 ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
13361 CXXRewrittenBinaryOperator *E) {
13362 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
13364 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
13365 if (LHS.isInvalid())
13366 return ExprError();
13368 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
13369 if (RHS.isInvalid())
13370 return ExprError();
13372 // Extract the already-resolved callee declarations so that we can restrict
13373 // ourselves to using them as the unqualified lookup results when rebuilding.
13374 UnresolvedSet<2> UnqualLookups;
13375 bool ChangedAnyLookups = false;
13376 Expr *PossibleBinOps[] = {E->getSemanticForm(),
13377 const_cast<Expr *>(Decomp.InnerBinOp)};
13378 for (Expr *PossibleBinOp : PossibleBinOps) {
13379 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());
13380 if (!Op)
13381 continue;
13382 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());
13383 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))
13384 continue;
13386 // Transform the callee in case we built a call to a local extern
13387 // declaration.
13388 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
13389 E->getOperatorLoc(), Callee->getFoundDecl()));
13390 if (!Found)
13391 return ExprError();
13392 if (Found != Callee->getFoundDecl())
13393 ChangedAnyLookups = true;
13394 UnqualLookups.addDecl(Found);
13397 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
13398 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
13399 // Mark all functions used in the rewrite as referenced. Note that when
13400 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
13401 // function calls, and/or there might be a user-defined conversion sequence
13402 // applied to the operands of the <.
13403 // FIXME: this is a bit instantiation-specific.
13404 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
13405 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);
13406 return E;
13409 return getDerived().RebuildCXXRewrittenBinaryOperator(
13410 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
13413 template<typename Derived>
13414 ExprResult
13415 TreeTransform<Derived>::TransformCompoundAssignOperator(
13416 CompoundAssignOperator *E) {
13417 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13418 FPOptionsOverride NewOverrides(E->getFPFeatures());
13419 getSema().CurFPFeatures =
13420 NewOverrides.applyOverrides(getSema().getLangOpts());
13421 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13422 return getDerived().TransformBinaryOperator(E);
13425 template<typename Derived>
13426 ExprResult TreeTransform<Derived>::
13427 TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
13428 // Just rebuild the common and RHS expressions and see whether we
13429 // get any changes.
13431 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
13432 if (commonExpr.isInvalid())
13433 return ExprError();
13435 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
13436 if (rhs.isInvalid())
13437 return ExprError();
13439 if (!getDerived().AlwaysRebuild() &&
13440 commonExpr.get() == e->getCommon() &&
13441 rhs.get() == e->getFalseExpr())
13442 return e;
13444 return getDerived().RebuildConditionalOperator(commonExpr.get(),
13445 e->getQuestionLoc(),
13446 nullptr,
13447 e->getColonLoc(),
13448 rhs.get());
13451 template<typename Derived>
13452 ExprResult
13453 TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
13454 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13455 if (Cond.isInvalid())
13456 return ExprError();
13458 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13459 if (LHS.isInvalid())
13460 return ExprError();
13462 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13463 if (RHS.isInvalid())
13464 return ExprError();
13466 if (!getDerived().AlwaysRebuild() &&
13467 Cond.get() == E->getCond() &&
13468 LHS.get() == E->getLHS() &&
13469 RHS.get() == E->getRHS())
13470 return E;
13472 return getDerived().RebuildConditionalOperator(Cond.get(),
13473 E->getQuestionLoc(),
13474 LHS.get(),
13475 E->getColonLoc(),
13476 RHS.get());
13479 template<typename Derived>
13480 ExprResult
13481 TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
13482 // Implicit casts are eliminated during transformation, since they
13483 // will be recomputed by semantic analysis after transformation.
13484 return getDerived().TransformExpr(E->getSubExprAsWritten());
13487 template<typename Derived>
13488 ExprResult
13489 TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
13490 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13491 if (!Type)
13492 return ExprError();
13494 ExprResult SubExpr
13495 = getDerived().TransformExpr(E->getSubExprAsWritten());
13496 if (SubExpr.isInvalid())
13497 return ExprError();
13499 if (!getDerived().AlwaysRebuild() &&
13500 Type == E->getTypeInfoAsWritten() &&
13501 SubExpr.get() == E->getSubExpr())
13502 return E;
13504 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
13505 Type,
13506 E->getRParenLoc(),
13507 SubExpr.get());
13510 template<typename Derived>
13511 ExprResult
13512 TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
13513 TypeSourceInfo *OldT = E->getTypeSourceInfo();
13514 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13515 if (!NewT)
13516 return ExprError();
13518 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
13519 if (Init.isInvalid())
13520 return ExprError();
13522 if (!getDerived().AlwaysRebuild() &&
13523 OldT == NewT &&
13524 Init.get() == E->getInitializer())
13525 return SemaRef.MaybeBindToTemporary(E);
13527 // Note: the expression type doesn't necessarily match the
13528 // type-as-written, but that's okay, because it should always be
13529 // derivable from the initializer.
13531 return getDerived().RebuildCompoundLiteralExpr(
13532 E->getLParenLoc(), NewT,
13533 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
13536 template<typename Derived>
13537 ExprResult
13538 TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
13539 ExprResult Base = getDerived().TransformExpr(E->getBase());
13540 if (Base.isInvalid())
13541 return ExprError();
13543 if (!getDerived().AlwaysRebuild() &&
13544 Base.get() == E->getBase())
13545 return E;
13547 // FIXME: Bad source location
13548 SourceLocation FakeOperatorLoc =
13549 SemaRef.getLocForEndOfToken(E->getBase()->getEndLoc());
13550 return getDerived().RebuildExtVectorElementExpr(
13551 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
13552 E->getAccessor());
13555 template<typename Derived>
13556 ExprResult
13557 TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
13558 if (InitListExpr *Syntactic = E->getSyntacticForm())
13559 E = Syntactic;
13561 bool InitChanged = false;
13563 EnterExpressionEvaluationContext Context(
13564 getSema(), EnterExpressionEvaluationContext::InitList);
13566 SmallVector<Expr*, 4> Inits;
13567 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
13568 Inits, &InitChanged))
13569 return ExprError();
13571 if (!getDerived().AlwaysRebuild() && !InitChanged) {
13572 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
13573 // in some cases. We can't reuse it in general, because the syntactic and
13574 // semantic forms are linked, and we can't know that semantic form will
13575 // match even if the syntactic form does.
13578 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
13579 E->getRBraceLoc());
13582 template<typename Derived>
13583 ExprResult
13584 TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
13585 Designation Desig;
13587 // transform the initializer value
13588 ExprResult Init = getDerived().TransformExpr(E->getInit());
13589 if (Init.isInvalid())
13590 return ExprError();
13592 // transform the designators.
13593 SmallVector<Expr*, 4> ArrayExprs;
13594 bool ExprChanged = false;
13595 for (const DesignatedInitExpr::Designator &D : E->designators()) {
13596 if (D.isFieldDesignator()) {
13597 if (D.getFieldDecl()) {
13598 FieldDecl *Field = cast_or_null<FieldDecl>(
13599 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
13600 if (Field != D.getFieldDecl())
13601 // Rebuild the expression when the transformed FieldDecl is
13602 // different to the already assigned FieldDecl.
13603 ExprChanged = true;
13604 if (Field->isAnonymousStructOrUnion())
13605 continue;
13606 } else {
13607 // Ensure that the designator expression is rebuilt when there isn't
13608 // a resolved FieldDecl in the designator as we don't want to assign
13609 // a FieldDecl to a pattern designator that will be instantiated again.
13610 ExprChanged = true;
13612 Desig.AddDesignator(Designator::CreateFieldDesignator(
13613 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
13614 continue;
13617 if (D.isArrayDesignator()) {
13618 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
13619 if (Index.isInvalid())
13620 return ExprError();
13622 Desig.AddDesignator(
13623 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
13625 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
13626 ArrayExprs.push_back(Index.get());
13627 continue;
13630 assert(D.isArrayRangeDesignator() && "New kind of designator?");
13631 ExprResult Start
13632 = getDerived().TransformExpr(E->getArrayRangeStart(D));
13633 if (Start.isInvalid())
13634 return ExprError();
13636 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
13637 if (End.isInvalid())
13638 return ExprError();
13640 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
13641 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
13643 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
13644 End.get() != E->getArrayRangeEnd(D);
13646 ArrayExprs.push_back(Start.get());
13647 ArrayExprs.push_back(End.get());
13650 if (!getDerived().AlwaysRebuild() &&
13651 Init.get() == E->getInit() &&
13652 !ExprChanged)
13653 return E;
13655 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
13656 E->getEqualOrColonLoc(),
13657 E->usesGNUSyntax(), Init.get());
13660 // Seems that if TransformInitListExpr() only works on the syntactic form of an
13661 // InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
13662 template<typename Derived>
13663 ExprResult
13664 TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
13665 DesignatedInitUpdateExpr *E) {
13666 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
13667 "initializer");
13668 return ExprError();
13671 template<typename Derived>
13672 ExprResult
13673 TreeTransform<Derived>::TransformNoInitExpr(
13674 NoInitExpr *E) {
13675 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
13676 return ExprError();
13679 template<typename Derived>
13680 ExprResult
13681 TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
13682 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
13683 return ExprError();
13686 template<typename Derived>
13687 ExprResult
13688 TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
13689 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
13690 return ExprError();
13693 template<typename Derived>
13694 ExprResult
13695 TreeTransform<Derived>::TransformImplicitValueInitExpr(
13696 ImplicitValueInitExpr *E) {
13697 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
13699 // FIXME: Will we ever have proper type location here? Will we actually
13700 // need to transform the type?
13701 QualType T = getDerived().TransformType(E->getType());
13702 if (T.isNull())
13703 return ExprError();
13705 if (!getDerived().AlwaysRebuild() &&
13706 T == E->getType())
13707 return E;
13709 return getDerived().RebuildImplicitValueInitExpr(T);
13712 template<typename Derived>
13713 ExprResult
13714 TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
13715 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
13716 if (!TInfo)
13717 return ExprError();
13719 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13720 if (SubExpr.isInvalid())
13721 return ExprError();
13723 if (!getDerived().AlwaysRebuild() &&
13724 TInfo == E->getWrittenTypeInfo() &&
13725 SubExpr.get() == E->getSubExpr())
13726 return E;
13728 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
13729 TInfo, E->getRParenLoc());
13732 template<typename Derived>
13733 ExprResult
13734 TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
13735 bool ArgumentChanged = false;
13736 SmallVector<Expr*, 4> Inits;
13737 if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits,
13738 &ArgumentChanged))
13739 return ExprError();
13741 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
13742 Inits,
13743 E->getRParenLoc());
13746 /// Transform an address-of-label expression.
13748 /// By default, the transformation of an address-of-label expression always
13749 /// rebuilds the expression, so that the label identifier can be resolved to
13750 /// the corresponding label statement by semantic analysis.
13751 template<typename Derived>
13752 ExprResult
13753 TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
13754 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
13755 E->getLabel());
13756 if (!LD)
13757 return ExprError();
13759 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
13760 cast<LabelDecl>(LD));
13763 template<typename Derived>
13764 ExprResult
13765 TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
13766 SemaRef.ActOnStartStmtExpr();
13767 StmtResult SubStmt
13768 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
13769 if (SubStmt.isInvalid()) {
13770 SemaRef.ActOnStmtExprError();
13771 return ExprError();
13774 unsigned OldDepth = E->getTemplateDepth();
13775 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
13777 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
13778 SubStmt.get() == E->getSubStmt()) {
13779 // Calling this an 'error' is unintuitive, but it does the right thing.
13780 SemaRef.ActOnStmtExprError();
13781 return SemaRef.MaybeBindToTemporary(E);
13784 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
13785 E->getRParenLoc(), NewDepth);
13788 template<typename Derived>
13789 ExprResult
13790 TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
13791 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13792 if (Cond.isInvalid())
13793 return ExprError();
13795 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13796 if (LHS.isInvalid())
13797 return ExprError();
13799 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13800 if (RHS.isInvalid())
13801 return ExprError();
13803 if (!getDerived().AlwaysRebuild() &&
13804 Cond.get() == E->getCond() &&
13805 LHS.get() == E->getLHS() &&
13806 RHS.get() == E->getRHS())
13807 return E;
13809 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
13810 Cond.get(), LHS.get(), RHS.get(),
13811 E->getRParenLoc());
13814 template<typename Derived>
13815 ExprResult
13816 TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
13817 return E;
13820 template<typename Derived>
13821 ExprResult
13822 TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
13823 switch (E->getOperator()) {
13824 case OO_New:
13825 case OO_Delete:
13826 case OO_Array_New:
13827 case OO_Array_Delete:
13828 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
13830 case OO_Subscript:
13831 case OO_Call: {
13832 // This is a call to an object's operator().
13833 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
13835 // Transform the object itself.
13836 ExprResult Object = getDerived().TransformExpr(E->getArg(0));
13837 if (Object.isInvalid())
13838 return ExprError();
13840 // FIXME: Poor location information
13841 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
13842 static_cast<Expr *>(Object.get())->getEndLoc());
13844 // Transform the call arguments.
13845 SmallVector<Expr*, 8> Args;
13846 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
13847 Args))
13848 return ExprError();
13850 if (E->getOperator() == OO_Subscript)
13851 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
13852 Args, E->getEndLoc());
13854 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
13855 E->getEndLoc());
13858 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
13859 case OO_##Name: \
13860 break;
13862 #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
13863 #include "clang/Basic/OperatorKinds.def"
13865 case OO_Conditional:
13866 llvm_unreachable("conditional operator is not actually overloadable");
13868 case OO_None:
13869 case NUM_OVERLOADED_OPERATORS:
13870 llvm_unreachable("not an overloaded operator?");
13873 ExprResult First;
13874 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
13875 First = getDerived().TransformAddressOfOperand(E->getArg(0));
13876 else
13877 First = getDerived().TransformExpr(E->getArg(0));
13878 if (First.isInvalid())
13879 return ExprError();
13881 ExprResult Second;
13882 if (E->getNumArgs() == 2) {
13883 Second =
13884 getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);
13885 if (Second.isInvalid())
13886 return ExprError();
13889 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13890 FPOptionsOverride NewOverrides(E->getFPFeatures());
13891 getSema().CurFPFeatures =
13892 NewOverrides.applyOverrides(getSema().getLangOpts());
13893 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13895 Expr *Callee = E->getCallee();
13896 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
13897 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
13898 Sema::LookupOrdinaryName);
13899 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
13900 return ExprError();
13902 return getDerived().RebuildCXXOperatorCallExpr(
13903 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
13904 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
13907 UnresolvedSet<1> Functions;
13908 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
13909 Callee = ICE->getSubExprAsWritten();
13910 NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();
13911 ValueDecl *VD = cast_or_null<ValueDecl>(
13912 getDerived().TransformDecl(DR->getLocation(), DR));
13913 if (!VD)
13914 return ExprError();
13916 if (!isa<CXXMethodDecl>(VD))
13917 Functions.addDecl(VD);
13919 return getDerived().RebuildCXXOperatorCallExpr(
13920 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
13921 /*RequiresADL=*/false, Functions, First.get(), Second.get());
13924 template<typename Derived>
13925 ExprResult
13926 TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
13927 return getDerived().TransformCallExpr(E);
13930 template <typename Derived>
13931 ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
13932 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(E->getIdentKind()) &&
13933 getSema().CurContext != E->getParentContext();
13935 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
13936 return E;
13938 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
13939 E->getBeginLoc(), E->getEndLoc(),
13940 getSema().CurContext);
13943 template <typename Derived>
13944 ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
13945 return E;
13948 template<typename Derived>
13949 ExprResult
13950 TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
13951 // Transform the callee.
13952 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13953 if (Callee.isInvalid())
13954 return ExprError();
13956 // Transform exec config.
13957 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
13958 if (EC.isInvalid())
13959 return ExprError();
13961 // Transform arguments.
13962 bool ArgChanged = false;
13963 SmallVector<Expr*, 8> Args;
13964 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13965 &ArgChanged))
13966 return ExprError();
13968 if (!getDerived().AlwaysRebuild() &&
13969 Callee.get() == E->getCallee() &&
13970 !ArgChanged)
13971 return SemaRef.MaybeBindToTemporary(E);
13973 // FIXME: Wrong source location information for the '('.
13974 SourceLocation FakeLParenLoc
13975 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13976 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13977 Args,
13978 E->getRParenLoc(), EC.get());
13981 template<typename Derived>
13982 ExprResult
13983 TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
13984 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13985 if (!Type)
13986 return ExprError();
13988 ExprResult SubExpr
13989 = getDerived().TransformExpr(E->getSubExprAsWritten());
13990 if (SubExpr.isInvalid())
13991 return ExprError();
13993 if (!getDerived().AlwaysRebuild() &&
13994 Type == E->getTypeInfoAsWritten() &&
13995 SubExpr.get() == E->getSubExpr())
13996 return E;
13997 return getDerived().RebuildCXXNamedCastExpr(
13998 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
13999 Type, E->getAngleBrackets().getEnd(),
14000 // FIXME. this should be '(' location
14001 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
14004 template<typename Derived>
14005 ExprResult
14006 TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
14007 TypeSourceInfo *TSI =
14008 getDerived().TransformType(BCE->getTypeInfoAsWritten());
14009 if (!TSI)
14010 return ExprError();
14012 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
14013 if (Sub.isInvalid())
14014 return ExprError();
14016 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
14017 Sub.get(), BCE->getEndLoc());
14020 template<typename Derived>
14021 ExprResult
14022 TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
14023 return getDerived().TransformCXXNamedCastExpr(E);
14026 template<typename Derived>
14027 ExprResult
14028 TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
14029 return getDerived().TransformCXXNamedCastExpr(E);
14032 template<typename Derived>
14033 ExprResult
14034 TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
14035 CXXReinterpretCastExpr *E) {
14036 return getDerived().TransformCXXNamedCastExpr(E);
14039 template<typename Derived>
14040 ExprResult
14041 TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
14042 return getDerived().TransformCXXNamedCastExpr(E);
14045 template<typename Derived>
14046 ExprResult
14047 TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
14048 return getDerived().TransformCXXNamedCastExpr(E);
14051 template<typename Derived>
14052 ExprResult
14053 TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
14054 CXXFunctionalCastExpr *E) {
14055 TypeSourceInfo *Type =
14056 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
14057 if (!Type)
14058 return ExprError();
14060 ExprResult SubExpr
14061 = getDerived().TransformExpr(E->getSubExprAsWritten());
14062 if (SubExpr.isInvalid())
14063 return ExprError();
14065 if (!getDerived().AlwaysRebuild() &&
14066 Type == E->getTypeInfoAsWritten() &&
14067 SubExpr.get() == E->getSubExpr())
14068 return E;
14070 return getDerived().RebuildCXXFunctionalCastExpr(Type,
14071 E->getLParenLoc(),
14072 SubExpr.get(),
14073 E->getRParenLoc(),
14074 E->isListInitialization());
14077 template<typename Derived>
14078 ExprResult
14079 TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
14080 if (E->isTypeOperand()) {
14081 TypeSourceInfo *TInfo
14082 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14083 if (!TInfo)
14084 return ExprError();
14086 if (!getDerived().AlwaysRebuild() &&
14087 TInfo == E->getTypeOperandSourceInfo())
14088 return E;
14090 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14091 TInfo, E->getEndLoc());
14094 // Typeid's operand is an unevaluated context, unless it's a polymorphic
14095 // type. We must not unilaterally enter unevaluated context here, as then
14096 // semantic processing can re-transform an already transformed operand.
14097 Expr *Op = E->getExprOperand();
14098 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
14099 if (E->isGLValue())
14100 if (auto *RecordT = Op->getType()->getAs<RecordType>())
14101 if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
14102 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
14104 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
14105 Sema::ReuseLambdaContextDecl);
14107 ExprResult SubExpr = getDerived().TransformExpr(Op);
14108 if (SubExpr.isInvalid())
14109 return ExprError();
14111 if (!getDerived().AlwaysRebuild() &&
14112 SubExpr.get() == E->getExprOperand())
14113 return E;
14115 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14116 SubExpr.get(), E->getEndLoc());
14119 template<typename Derived>
14120 ExprResult
14121 TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
14122 if (E->isTypeOperand()) {
14123 TypeSourceInfo *TInfo
14124 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14125 if (!TInfo)
14126 return ExprError();
14128 if (!getDerived().AlwaysRebuild() &&
14129 TInfo == E->getTypeOperandSourceInfo())
14130 return E;
14132 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14133 TInfo, E->getEndLoc());
14136 EnterExpressionEvaluationContext Unevaluated(
14137 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14139 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
14140 if (SubExpr.isInvalid())
14141 return ExprError();
14143 if (!getDerived().AlwaysRebuild() &&
14144 SubExpr.get() == E->getExprOperand())
14145 return E;
14147 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14148 SubExpr.get(), E->getEndLoc());
14151 template<typename Derived>
14152 ExprResult
14153 TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
14154 return E;
14157 template<typename Derived>
14158 ExprResult
14159 TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
14160 CXXNullPtrLiteralExpr *E) {
14161 return E;
14164 template<typename Derived>
14165 ExprResult
14166 TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
14168 // In lambdas, the qualifiers of the type depends of where in
14169 // the call operator `this` appear, and we do not have a good way to
14170 // rebuild this information, so we transform the type.
14172 // In other contexts, the type of `this` may be overrided
14173 // for type deduction, so we need to recompute it.
14175 // Always recompute the type if we're in the body of a lambda, and
14176 // 'this' is dependent on a lambda's explicit object parameter.
14177 QualType T = [&]() {
14178 auto &S = getSema();
14179 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
14180 return S.getCurrentThisType();
14181 if (S.getCurLambda())
14182 return getDerived().TransformType(E->getType());
14183 return S.getCurrentThisType();
14184 }();
14186 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
14187 // Mark it referenced in the new context regardless.
14188 // FIXME: this is a bit instantiation-specific.
14189 getSema().MarkThisReferenced(E);
14190 return E;
14193 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
14196 template<typename Derived>
14197 ExprResult
14198 TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
14199 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14200 if (SubExpr.isInvalid())
14201 return ExprError();
14203 if (!getDerived().AlwaysRebuild() &&
14204 SubExpr.get() == E->getSubExpr())
14205 return E;
14207 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
14208 E->isThrownVariableInScope());
14211 template<typename Derived>
14212 ExprResult
14213 TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
14214 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
14215 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
14216 if (!Param)
14217 return ExprError();
14219 ExprResult InitRes;
14220 if (E->hasRewrittenInit()) {
14221 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
14222 if (InitRes.isInvalid())
14223 return ExprError();
14226 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
14227 E->getUsedContext() == SemaRef.CurContext &&
14228 InitRes.get() == E->getRewrittenExpr())
14229 return E;
14231 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
14232 InitRes.get());
14235 template<typename Derived>
14236 ExprResult
14237 TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
14238 FieldDecl *Field = cast_or_null<FieldDecl>(
14239 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
14240 if (!Field)
14241 return ExprError();
14243 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
14244 E->getUsedContext() == SemaRef.CurContext)
14245 return E;
14247 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
14250 template<typename Derived>
14251 ExprResult
14252 TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
14253 CXXScalarValueInitExpr *E) {
14254 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
14255 if (!T)
14256 return ExprError();
14258 if (!getDerived().AlwaysRebuild() &&
14259 T == E->getTypeSourceInfo())
14260 return E;
14262 return getDerived().RebuildCXXScalarValueInitExpr(T,
14263 /*FIXME:*/T->getTypeLoc().getEndLoc(),
14264 E->getRParenLoc());
14267 template<typename Derived>
14268 ExprResult
14269 TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
14270 // Transform the type that we're allocating
14271 TypeSourceInfo *AllocTypeInfo =
14272 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
14273 if (!AllocTypeInfo)
14274 return ExprError();
14276 // Transform the size of the array we're allocating (if any).
14277 std::optional<Expr *> ArraySize;
14278 if (E->isArray()) {
14279 ExprResult NewArraySize;
14280 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
14281 NewArraySize = getDerived().TransformExpr(*OldArraySize);
14282 if (NewArraySize.isInvalid())
14283 return ExprError();
14285 ArraySize = NewArraySize.get();
14288 // Transform the placement arguments (if any).
14289 bool ArgumentChanged = false;
14290 SmallVector<Expr*, 8> PlacementArgs;
14291 if (getDerived().TransformExprs(E->getPlacementArgs(),
14292 E->getNumPlacementArgs(), true,
14293 PlacementArgs, &ArgumentChanged))
14294 return ExprError();
14296 // Transform the initializer (if any).
14297 Expr *OldInit = E->getInitializer();
14298 ExprResult NewInit;
14299 if (OldInit)
14300 NewInit = getDerived().TransformInitializer(OldInit, true);
14301 if (NewInit.isInvalid())
14302 return ExprError();
14304 // Transform new operator and delete operator.
14305 FunctionDecl *OperatorNew = nullptr;
14306 if (E->getOperatorNew()) {
14307 OperatorNew = cast_or_null<FunctionDecl>(
14308 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
14309 if (!OperatorNew)
14310 return ExprError();
14313 FunctionDecl *OperatorDelete = nullptr;
14314 if (E->getOperatorDelete()) {
14315 OperatorDelete = cast_or_null<FunctionDecl>(
14316 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14317 if (!OperatorDelete)
14318 return ExprError();
14321 if (!getDerived().AlwaysRebuild() &&
14322 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
14323 ArraySize == E->getArraySize() &&
14324 NewInit.get() == OldInit &&
14325 OperatorNew == E->getOperatorNew() &&
14326 OperatorDelete == E->getOperatorDelete() &&
14327 !ArgumentChanged) {
14328 // Mark any declarations we need as referenced.
14329 // FIXME: instantiation-specific.
14330 if (OperatorNew)
14331 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorNew);
14332 if (OperatorDelete)
14333 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
14335 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
14336 QualType ElementType
14337 = SemaRef.Context.getBaseElementType(E->getAllocatedType());
14338 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
14339 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
14340 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
14341 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor);
14346 return E;
14349 QualType AllocType = AllocTypeInfo->getType();
14350 if (!ArraySize) {
14351 // If no array size was specified, but the new expression was
14352 // instantiated with an array type (e.g., "new T" where T is
14353 // instantiated with "int[4]"), extract the outer bound from the
14354 // array type as our array size. We do this with constant and
14355 // dependently-sized array types.
14356 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);
14357 if (!ArrayT) {
14358 // Do nothing
14359 } else if (const ConstantArrayType *ConsArrayT
14360 = dyn_cast<ConstantArrayType>(ArrayT)) {
14361 ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),
14362 SemaRef.Context.getSizeType(),
14363 /*FIXME:*/ E->getBeginLoc());
14364 AllocType = ConsArrayT->getElementType();
14365 } else if (const DependentSizedArrayType *DepArrayT
14366 = dyn_cast<DependentSizedArrayType>(ArrayT)) {
14367 if (DepArrayT->getSizeExpr()) {
14368 ArraySize = DepArrayT->getSizeExpr();
14369 AllocType = DepArrayT->getElementType();
14374 return getDerived().RebuildCXXNewExpr(
14375 E->getBeginLoc(), E->isGlobalNew(),
14376 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
14377 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
14378 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
14381 template<typename Derived>
14382 ExprResult
14383 TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
14384 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
14385 if (Operand.isInvalid())
14386 return ExprError();
14388 // Transform the delete operator, if known.
14389 FunctionDecl *OperatorDelete = nullptr;
14390 if (E->getOperatorDelete()) {
14391 OperatorDelete = cast_or_null<FunctionDecl>(
14392 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14393 if (!OperatorDelete)
14394 return ExprError();
14397 if (!getDerived().AlwaysRebuild() &&
14398 Operand.get() == E->getArgument() &&
14399 OperatorDelete == E->getOperatorDelete()) {
14400 // Mark any declarations we need as referenced.
14401 // FIXME: instantiation-specific.
14402 if (OperatorDelete)
14403 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
14405 if (!E->getArgument()->isTypeDependent()) {
14406 QualType Destroyed = SemaRef.Context.getBaseElementType(
14407 E->getDestroyedType());
14408 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
14409 CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
14410 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
14411 SemaRef.LookupDestructor(Record));
14415 return E;
14418 return getDerived().RebuildCXXDeleteExpr(
14419 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
14422 template<typename Derived>
14423 ExprResult
14424 TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
14425 CXXPseudoDestructorExpr *E) {
14426 ExprResult Base = getDerived().TransformExpr(E->getBase());
14427 if (Base.isInvalid())
14428 return ExprError();
14430 ParsedType ObjectTypePtr;
14431 bool MayBePseudoDestructor = false;
14432 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
14433 E->getOperatorLoc(),
14434 E->isArrow()? tok::arrow : tok::period,
14435 ObjectTypePtr,
14436 MayBePseudoDestructor);
14437 if (Base.isInvalid())
14438 return ExprError();
14440 QualType ObjectType = ObjectTypePtr.get();
14441 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
14442 if (QualifierLoc) {
14443 QualifierLoc
14444 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
14445 if (!QualifierLoc)
14446 return ExprError();
14448 CXXScopeSpec SS;
14449 SS.Adopt(QualifierLoc);
14451 PseudoDestructorTypeStorage Destroyed;
14452 if (E->getDestroyedTypeInfo()) {
14453 TypeSourceInfo *DestroyedTypeInfo
14454 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
14455 ObjectType, nullptr, SS);
14456 if (!DestroyedTypeInfo)
14457 return ExprError();
14458 Destroyed = DestroyedTypeInfo;
14459 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
14460 // We aren't likely to be able to resolve the identifier down to a type
14461 // now anyway, so just retain the identifier.
14462 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
14463 E->getDestroyedTypeLoc());
14464 } else {
14465 // Look for a destructor known with the given name.
14466 ParsedType T = SemaRef.getDestructorName(
14467 *E->getDestroyedTypeIdentifier(), E->getDestroyedTypeLoc(),
14468 /*Scope=*/nullptr, SS, ObjectTypePtr, false);
14469 if (!T)
14470 return ExprError();
14472 Destroyed
14473 = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),
14474 E->getDestroyedTypeLoc());
14477 TypeSourceInfo *ScopeTypeInfo = nullptr;
14478 if (E->getScopeTypeInfo()) {
14479 CXXScopeSpec EmptySS;
14480 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
14481 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
14482 if (!ScopeTypeInfo)
14483 return ExprError();
14486 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
14487 E->getOperatorLoc(),
14488 E->isArrow(),
14490 ScopeTypeInfo,
14491 E->getColonColonLoc(),
14492 E->getTildeLoc(),
14493 Destroyed);
14496 template <typename Derived>
14497 bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
14498 bool RequiresADL,
14499 LookupResult &R) {
14500 // Transform all the decls.
14501 bool AllEmptyPacks = true;
14502 for (auto *OldD : Old->decls()) {
14503 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
14504 if (!InstD) {
14505 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
14506 // This can happen because of dependent hiding.
14507 if (isa<UsingShadowDecl>(OldD))
14508 continue;
14509 else {
14510 R.clear();
14511 return true;
14515 // Expand using pack declarations.
14516 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
14517 ArrayRef<NamedDecl*> Decls = SingleDecl;
14518 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
14519 Decls = UPD->expansions();
14521 // Expand using declarations.
14522 for (auto *D : Decls) {
14523 if (auto *UD = dyn_cast<UsingDecl>(D)) {
14524 for (auto *SD : UD->shadows())
14525 R.addDecl(SD);
14526 } else {
14527 R.addDecl(D);
14531 AllEmptyPacks &= Decls.empty();
14534 // C++ [temp.res]/8.4.2:
14535 // The program is ill-formed, no diagnostic required, if [...] lookup for
14536 // a name in the template definition found a using-declaration, but the
14537 // lookup in the corresponding scope in the instantiation odoes not find
14538 // any declarations because the using-declaration was a pack expansion and
14539 // the corresponding pack is empty
14540 if (AllEmptyPacks && !RequiresADL) {
14541 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
14542 << isa<UnresolvedMemberExpr>(Old) << Old->getName();
14543 return true;
14546 // Resolve a kind, but don't do any further analysis. If it's
14547 // ambiguous, the callee needs to deal with it.
14548 R.resolveKind();
14550 if (Old->hasTemplateKeyword() && !R.empty()) {
14551 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
14552 getSema().FilterAcceptableTemplateNames(R,
14553 /*AllowFunctionTemplates=*/true,
14554 /*AllowDependent=*/true);
14555 if (R.empty()) {
14556 // If a 'template' keyword was used, a lookup that finds only non-template
14557 // names is an error.
14558 getSema().Diag(R.getNameLoc(),
14559 diag::err_template_kw_refers_to_non_template)
14560 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
14561 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
14562 getSema().Diag(FoundDecl->getLocation(),
14563 diag::note_template_kw_refers_to_non_template)
14564 << R.getLookupName();
14565 return true;
14569 return false;
14572 template <typename Derived>
14573 ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
14574 UnresolvedLookupExpr *Old) {
14575 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
14578 template <typename Derived>
14579 ExprResult
14580 TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
14581 bool IsAddressOfOperand) {
14582 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
14583 Sema::LookupOrdinaryName);
14585 // Transform the declaration set.
14586 if (TransformOverloadExprDecls(Old, Old->requiresADL(), R))
14587 return ExprError();
14589 // Rebuild the nested-name qualifier, if present.
14590 CXXScopeSpec SS;
14591 if (Old->getQualifierLoc()) {
14592 NestedNameSpecifierLoc QualifierLoc
14593 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
14594 if (!QualifierLoc)
14595 return ExprError();
14597 SS.Adopt(QualifierLoc);
14600 if (Old->getNamingClass()) {
14601 CXXRecordDecl *NamingClass
14602 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
14603 Old->getNameLoc(),
14604 Old->getNamingClass()));
14605 if (!NamingClass) {
14606 R.clear();
14607 return ExprError();
14610 R.setNamingClass(NamingClass);
14613 // Rebuild the template arguments, if any.
14614 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
14615 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
14616 if (Old->hasExplicitTemplateArgs() &&
14617 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14618 Old->getNumTemplateArgs(),
14619 TransArgs)) {
14620 R.clear();
14621 return ExprError();
14624 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
14625 // a non-static data member is named in an unevaluated operand, or when
14626 // a member is named in a dependent class scope function template explicit
14627 // specialization that is neither declared static nor with an explicit object
14628 // parameter.
14629 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
14630 return SemaRef.BuildPossibleImplicitMemberExpr(
14631 SS, TemplateKWLoc, R,
14632 Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
14633 /*S=*/nullptr);
14635 // If we have neither explicit template arguments, nor the template keyword,
14636 // it's a normal declaration name or member reference.
14637 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
14638 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
14640 // If we have template arguments, then rebuild the template-id expression.
14641 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
14642 Old->requiresADL(), &TransArgs);
14645 template<typename Derived>
14646 ExprResult
14647 TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
14648 bool ArgChanged = false;
14649 SmallVector<TypeSourceInfo *, 4> Args;
14650 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
14651 TypeSourceInfo *From = E->getArg(I);
14652 TypeLoc FromTL = From->getTypeLoc();
14653 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
14654 TypeLocBuilder TLB;
14655 TLB.reserve(FromTL.getFullDataSize());
14656 QualType To = getDerived().TransformType(TLB, FromTL);
14657 if (To.isNull())
14658 return ExprError();
14660 if (To == From->getType())
14661 Args.push_back(From);
14662 else {
14663 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14664 ArgChanged = true;
14666 continue;
14669 ArgChanged = true;
14671 // We have a pack expansion. Instantiate it.
14672 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
14673 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
14674 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14675 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
14677 // Determine whether the set of unexpanded parameter packs can and should
14678 // be expanded.
14679 bool Expand = true;
14680 bool RetainExpansion = false;
14681 std::optional<unsigned> OrigNumExpansions =
14682 ExpansionTL.getTypePtr()->getNumExpansions();
14683 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14684 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
14685 PatternTL.getSourceRange(),
14686 Unexpanded,
14687 Expand, RetainExpansion,
14688 NumExpansions))
14689 return ExprError();
14691 if (!Expand) {
14692 // The transform has determined that we should perform a simple
14693 // transformation on the pack expansion, producing another pack
14694 // expansion.
14695 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14697 TypeLocBuilder TLB;
14698 TLB.reserve(From->getTypeLoc().getFullDataSize());
14700 QualType To = getDerived().TransformType(TLB, PatternTL);
14701 if (To.isNull())
14702 return ExprError();
14704 To = getDerived().RebuildPackExpansionType(To,
14705 PatternTL.getSourceRange(),
14706 ExpansionTL.getEllipsisLoc(),
14707 NumExpansions);
14708 if (To.isNull())
14709 return ExprError();
14711 PackExpansionTypeLoc ToExpansionTL
14712 = TLB.push<PackExpansionTypeLoc>(To);
14713 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14714 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14715 continue;
14718 // Expand the pack expansion by substituting for each argument in the
14719 // pack(s).
14720 for (unsigned I = 0; I != *NumExpansions; ++I) {
14721 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
14722 TypeLocBuilder TLB;
14723 TLB.reserve(PatternTL.getFullDataSize());
14724 QualType To = getDerived().TransformType(TLB, PatternTL);
14725 if (To.isNull())
14726 return ExprError();
14728 if (To->containsUnexpandedParameterPack()) {
14729 To = getDerived().RebuildPackExpansionType(To,
14730 PatternTL.getSourceRange(),
14731 ExpansionTL.getEllipsisLoc(),
14732 NumExpansions);
14733 if (To.isNull())
14734 return ExprError();
14736 PackExpansionTypeLoc ToExpansionTL
14737 = TLB.push<PackExpansionTypeLoc>(To);
14738 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14741 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14744 if (!RetainExpansion)
14745 continue;
14747 // If we're supposed to retain a pack expansion, do so by temporarily
14748 // forgetting the partially-substituted parameter pack.
14749 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14751 TypeLocBuilder TLB;
14752 TLB.reserve(From->getTypeLoc().getFullDataSize());
14754 QualType To = getDerived().TransformType(TLB, PatternTL);
14755 if (To.isNull())
14756 return ExprError();
14758 To = getDerived().RebuildPackExpansionType(To,
14759 PatternTL.getSourceRange(),
14760 ExpansionTL.getEllipsisLoc(),
14761 NumExpansions);
14762 if (To.isNull())
14763 return ExprError();
14765 PackExpansionTypeLoc ToExpansionTL
14766 = TLB.push<PackExpansionTypeLoc>(To);
14767 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14768 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14771 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14772 return E;
14774 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
14775 E->getEndLoc());
14778 template<typename Derived>
14779 ExprResult
14780 TreeTransform<Derived>::TransformConceptSpecializationExpr(
14781 ConceptSpecializationExpr *E) {
14782 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
14783 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
14784 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14785 Old->NumTemplateArgs, TransArgs))
14786 return ExprError();
14788 return getDerived().RebuildConceptSpecializationExpr(
14789 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
14790 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
14791 &TransArgs);
14794 template<typename Derived>
14795 ExprResult
14796 TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
14797 SmallVector<ParmVarDecl*, 4> TransParams;
14798 SmallVector<QualType, 4> TransParamTypes;
14799 Sema::ExtParameterInfoBuilder ExtParamInfos;
14801 // C++2a [expr.prim.req]p2
14802 // Expressions appearing within a requirement-body are unevaluated operands.
14803 EnterExpressionEvaluationContext Ctx(
14804 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
14805 Sema::ReuseLambdaContextDecl);
14807 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
14808 getSema().Context, getSema().CurContext,
14809 E->getBody()->getBeginLoc());
14811 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
14813 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
14814 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
14815 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
14817 for (ParmVarDecl *Param : TransParams)
14818 if (Param)
14819 Param->setDeclContext(Body);
14821 // On failure to transform, TransformRequiresTypeParams returns an expression
14822 // in the event that the transformation of the type params failed in some way.
14823 // It is expected that this will result in a 'not satisfied' Requires clause
14824 // when instantiating.
14825 if (!TypeParamResult.isUnset())
14826 return TypeParamResult;
14828 SmallVector<concepts::Requirement *, 4> TransReqs;
14829 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
14830 TransReqs))
14831 return ExprError();
14833 for (concepts::Requirement *Req : TransReqs) {
14834 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
14835 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
14836 ER->getReturnTypeRequirement()
14837 .getTypeConstraintTemplateParameterList()->getParam(0)
14838 ->setDeclContext(Body);
14843 return getDerived().RebuildRequiresExpr(
14844 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
14845 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
14848 template<typename Derived>
14849 bool TreeTransform<Derived>::TransformRequiresExprRequirements(
14850 ArrayRef<concepts::Requirement *> Reqs,
14851 SmallVectorImpl<concepts::Requirement *> &Transformed) {
14852 for (concepts::Requirement *Req : Reqs) {
14853 concepts::Requirement *TransReq = nullptr;
14854 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
14855 TransReq = getDerived().TransformTypeRequirement(TypeReq);
14856 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
14857 TransReq = getDerived().TransformExprRequirement(ExprReq);
14858 else
14859 TransReq = getDerived().TransformNestedRequirement(
14860 cast<concepts::NestedRequirement>(Req));
14861 if (!TransReq)
14862 return true;
14863 Transformed.push_back(TransReq);
14865 return false;
14868 template<typename Derived>
14869 concepts::TypeRequirement *
14870 TreeTransform<Derived>::TransformTypeRequirement(
14871 concepts::TypeRequirement *Req) {
14872 if (Req->isSubstitutionFailure()) {
14873 if (getDerived().AlwaysRebuild())
14874 return getDerived().RebuildTypeRequirement(
14875 Req->getSubstitutionDiagnostic());
14876 return Req;
14878 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
14879 if (!TransType)
14880 return nullptr;
14881 return getDerived().RebuildTypeRequirement(TransType);
14884 template<typename Derived>
14885 concepts::ExprRequirement *
14886 TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
14887 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
14888 if (Req->isExprSubstitutionFailure())
14889 TransExpr = Req->getExprSubstitutionDiagnostic();
14890 else {
14891 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
14892 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
14893 TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
14894 if (TransExprRes.isInvalid())
14895 return nullptr;
14896 TransExpr = TransExprRes.get();
14899 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
14900 const auto &RetReq = Req->getReturnTypeRequirement();
14901 if (RetReq.isEmpty())
14902 TransRetReq.emplace();
14903 else if (RetReq.isSubstitutionFailure())
14904 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
14905 else if (RetReq.isTypeConstraint()) {
14906 TemplateParameterList *OrigTPL =
14907 RetReq.getTypeConstraintTemplateParameterList();
14908 TemplateParameterList *TPL =
14909 getDerived().TransformTemplateParameterList(OrigTPL);
14910 if (!TPL)
14911 return nullptr;
14912 TransRetReq.emplace(TPL);
14914 assert(TransRetReq && "All code paths leading here must set TransRetReq");
14915 if (Expr *E = dyn_cast<Expr *>(TransExpr))
14916 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
14917 Req->getNoexceptLoc(),
14918 std::move(*TransRetReq));
14919 return getDerived().RebuildExprRequirement(
14920 cast<concepts::Requirement::SubstitutionDiagnostic *>(TransExpr),
14921 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
14924 template<typename Derived>
14925 concepts::NestedRequirement *
14926 TreeTransform<Derived>::TransformNestedRequirement(
14927 concepts::NestedRequirement *Req) {
14928 if (Req->hasInvalidConstraint()) {
14929 if (getDerived().AlwaysRebuild())
14930 return getDerived().RebuildNestedRequirement(
14931 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
14932 return Req;
14934 ExprResult TransConstraint =
14935 getDerived().TransformExpr(Req->getConstraintExpr());
14936 if (TransConstraint.isInvalid())
14937 return nullptr;
14938 return getDerived().RebuildNestedRequirement(TransConstraint.get());
14941 template<typename Derived>
14942 ExprResult
14943 TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
14944 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
14945 if (!T)
14946 return ExprError();
14948 if (!getDerived().AlwaysRebuild() &&
14949 T == E->getQueriedTypeSourceInfo())
14950 return E;
14952 ExprResult SubExpr;
14954 EnterExpressionEvaluationContext Unevaluated(
14955 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14956 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
14957 if (SubExpr.isInvalid())
14958 return ExprError();
14961 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
14962 SubExpr.get(), E->getEndLoc());
14965 template<typename Derived>
14966 ExprResult
14967 TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
14968 ExprResult SubExpr;
14970 EnterExpressionEvaluationContext Unevaluated(
14971 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14972 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
14973 if (SubExpr.isInvalid())
14974 return ExprError();
14976 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
14977 return E;
14980 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
14981 SubExpr.get(), E->getEndLoc());
14984 template <typename Derived>
14985 ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
14986 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
14987 TypeSourceInfo **RecoveryTSI) {
14988 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
14989 DRE, AddrTaken, RecoveryTSI);
14991 // Propagate both errors and recovered types, which return ExprEmpty.
14992 if (!NewDRE.isUsable())
14993 return NewDRE;
14995 // We got an expr, wrap it up in parens.
14996 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
14997 return PE;
14998 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
14999 PE->getRParen());
15002 template <typename Derived>
15003 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15004 DependentScopeDeclRefExpr *E) {
15005 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
15006 nullptr);
15009 template <typename Derived>
15010 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15011 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
15012 TypeSourceInfo **RecoveryTSI) {
15013 assert(E->getQualifierLoc());
15014 NestedNameSpecifierLoc QualifierLoc =
15015 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
15016 if (!QualifierLoc)
15017 return ExprError();
15018 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15020 // TODO: If this is a conversion-function-id, verify that the
15021 // destination type name (if present) resolves the same way after
15022 // instantiation as it did in the local scope.
15024 DeclarationNameInfo NameInfo =
15025 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
15026 if (!NameInfo.getName())
15027 return ExprError();
15029 if (!E->hasExplicitTemplateArgs()) {
15030 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
15031 // Note: it is sufficient to compare the Name component of NameInfo:
15032 // if name has not changed, DNLoc has not changed either.
15033 NameInfo.getName() == E->getDeclName())
15034 return E;
15036 return getDerived().RebuildDependentScopeDeclRefExpr(
15037 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
15038 IsAddressOfOperand, RecoveryTSI);
15041 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15042 if (getDerived().TransformTemplateArguments(
15043 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
15044 return ExprError();
15046 return getDerived().RebuildDependentScopeDeclRefExpr(
15047 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
15048 RecoveryTSI);
15051 template<typename Derived>
15052 ExprResult
15053 TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
15054 // CXXConstructExprs other than for list-initialization and
15055 // CXXTemporaryObjectExpr are always implicit, so when we have
15056 // a 1-argument construction we just transform that argument.
15057 if (getDerived().AllowSkippingCXXConstructExpr() &&
15058 ((E->getNumArgs() == 1 ||
15059 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) &&
15060 (!getDerived().DropCallArgument(E->getArg(0))) &&
15061 !E->isListInitialization()))
15062 return getDerived().TransformInitializer(E->getArg(0),
15063 /*DirectInit*/ false);
15065 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
15067 QualType T = getDerived().TransformType(E->getType());
15068 if (T.isNull())
15069 return ExprError();
15071 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15072 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15073 if (!Constructor)
15074 return ExprError();
15076 bool ArgumentChanged = false;
15077 SmallVector<Expr*, 8> Args;
15079 EnterExpressionEvaluationContext Context(
15080 getSema(), EnterExpressionEvaluationContext::InitList,
15081 E->isListInitialization());
15082 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15083 &ArgumentChanged))
15084 return ExprError();
15087 if (!getDerived().AlwaysRebuild() &&
15088 T == E->getType() &&
15089 Constructor == E->getConstructor() &&
15090 !ArgumentChanged) {
15091 // Mark the constructor as referenced.
15092 // FIXME: Instantiation-specific
15093 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
15094 return E;
15097 return getDerived().RebuildCXXConstructExpr(
15098 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
15099 E->hadMultipleCandidates(), E->isListInitialization(),
15100 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
15101 E->getConstructionKind(), E->getParenOrBraceRange());
15104 template<typename Derived>
15105 ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
15106 CXXInheritedCtorInitExpr *E) {
15107 QualType T = getDerived().TransformType(E->getType());
15108 if (T.isNull())
15109 return ExprError();
15111 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15112 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15113 if (!Constructor)
15114 return ExprError();
15116 if (!getDerived().AlwaysRebuild() &&
15117 T == E->getType() &&
15118 Constructor == E->getConstructor()) {
15119 // Mark the constructor as referenced.
15120 // FIXME: Instantiation-specific
15121 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
15122 return E;
15125 return getDerived().RebuildCXXInheritedCtorInitExpr(
15126 T, E->getLocation(), Constructor,
15127 E->constructsVBase(), E->inheritedFromVBase());
15130 /// Transform a C++ temporary-binding expression.
15132 /// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
15133 /// transform the subexpression and return that.
15134 template<typename Derived>
15135 ExprResult
15136 TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
15137 if (auto *Dtor = E->getTemporary()->getDestructor())
15138 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
15139 const_cast<CXXDestructorDecl *>(Dtor));
15140 return getDerived().TransformExpr(E->getSubExpr());
15143 /// Transform a C++ expression that contains cleanups that should
15144 /// be run after the expression is evaluated.
15146 /// Since ExprWithCleanups nodes are implicitly generated, we
15147 /// just transform the subexpression and return that.
15148 template<typename Derived>
15149 ExprResult
15150 TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
15151 return getDerived().TransformExpr(E->getSubExpr());
15154 template<typename Derived>
15155 ExprResult
15156 TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
15157 CXXTemporaryObjectExpr *E) {
15158 TypeSourceInfo *T =
15159 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15160 if (!T)
15161 return ExprError();
15163 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15164 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15165 if (!Constructor)
15166 return ExprError();
15168 bool ArgumentChanged = false;
15169 SmallVector<Expr*, 8> Args;
15170 Args.reserve(E->getNumArgs());
15172 EnterExpressionEvaluationContext Context(
15173 getSema(), EnterExpressionEvaluationContext::InitList,
15174 E->isListInitialization());
15175 if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15176 &ArgumentChanged))
15177 return ExprError();
15179 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
15180 ExprResult Res = RebuildInitList(E->getBeginLoc(), Args, E->getEndLoc());
15181 if (Res.isInvalid())
15182 return ExprError();
15183 Args = {Res.get()};
15187 if (!getDerived().AlwaysRebuild() &&
15188 T == E->getTypeSourceInfo() &&
15189 Constructor == E->getConstructor() &&
15190 !ArgumentChanged) {
15191 // FIXME: Instantiation-specific
15192 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
15193 return SemaRef.MaybeBindToTemporary(E);
15196 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
15197 return getDerived().RebuildCXXTemporaryObjectExpr(
15198 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
15201 template<typename Derived>
15202 ExprResult
15203 TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
15204 // Transform any init-capture expressions before entering the scope of the
15205 // lambda body, because they are not semantically within that scope.
15206 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
15207 struct TransformedInitCapture {
15208 // The location of the ... if the result is retaining a pack expansion.
15209 SourceLocation EllipsisLoc;
15210 // Zero or more expansions of the init-capture.
15211 SmallVector<InitCaptureInfoTy, 4> Expansions;
15213 SmallVector<TransformedInitCapture, 4> InitCaptures;
15214 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
15215 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15216 CEnd = E->capture_end();
15217 C != CEnd; ++C) {
15218 if (!E->isInitCapture(C))
15219 continue;
15221 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
15222 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
15224 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
15225 std::optional<unsigned> NumExpansions) {
15226 ExprResult NewExprInitResult = getDerived().TransformInitializer(
15227 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
15229 if (NewExprInitResult.isInvalid()) {
15230 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
15231 return;
15233 Expr *NewExprInit = NewExprInitResult.get();
15235 QualType NewInitCaptureType =
15236 getSema().buildLambdaInitCaptureInitialization(
15237 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
15238 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
15239 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=
15240 VarDecl::CInit,
15241 NewExprInit);
15242 Result.Expansions.push_back(
15243 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
15246 // If this is an init-capture pack, consider expanding the pack now.
15247 if (OldVD->isParameterPack()) {
15248 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
15249 ->getTypeLoc()
15250 .castAs<PackExpansionTypeLoc>();
15251 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15252 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
15254 // Determine whether the set of unexpanded parameter packs can and should
15255 // be expanded.
15256 bool Expand = true;
15257 bool RetainExpansion = false;
15258 std::optional<unsigned> OrigNumExpansions =
15259 ExpansionTL.getTypePtr()->getNumExpansions();
15260 std::optional<unsigned> NumExpansions = OrigNumExpansions;
15261 if (getDerived().TryExpandParameterPacks(
15262 ExpansionTL.getEllipsisLoc(),
15263 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
15264 RetainExpansion, NumExpansions))
15265 return ExprError();
15266 assert(!RetainExpansion && "Should not need to retain expansion after a "
15267 "capture since it cannot be extended");
15268 if (Expand) {
15269 for (unsigned I = 0; I != *NumExpansions; ++I) {
15270 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
15271 SubstInitCapture(SourceLocation(), std::nullopt);
15273 } else {
15274 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
15275 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
15277 } else {
15278 SubstInitCapture(SourceLocation(), std::nullopt);
15282 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
15283 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
15285 // Create the local class that will describe the lambda.
15287 // FIXME: DependencyKind below is wrong when substituting inside a templated
15288 // context that isn't a DeclContext (such as a variable template), or when
15289 // substituting an unevaluated lambda inside of a function's parameter's type
15290 // - as parameter types are not instantiated from within a function's DC. We
15291 // use evaluation contexts to distinguish the function parameter case.
15292 CXXRecordDecl::LambdaDependencyKind DependencyKind =
15293 CXXRecordDecl::LDK_Unknown;
15294 DeclContext *DC = getSema().CurContext;
15295 // A RequiresExprBodyDecl is not interesting for dependencies.
15296 // For the following case,
15298 // template <typename>
15299 // concept C = requires { [] {}; };
15301 // template <class F>
15302 // struct Widget;
15304 // template <C F>
15305 // struct Widget<F> {};
15307 // While we are substituting Widget<F>, the parent of DC would be
15308 // the template specialization itself. Thus, the lambda expression
15309 // will be deemed as dependent even if there are no dependent template
15310 // arguments.
15311 // (A ClassTemplateSpecializationDecl is always a dependent context.)
15312 while (DC->isRequiresExprBody())
15313 DC = DC->getParent();
15314 if ((getSema().isUnevaluatedContext() ||
15315 getSema().isConstantEvaluatedContext()) &&
15316 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
15317 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
15319 CXXRecordDecl *OldClass = E->getLambdaClass();
15320 CXXRecordDecl *Class = getSema().createLambdaClosureType(
15321 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
15322 E->getCaptureDefault());
15323 getDerived().transformedLocalDecl(OldClass, {Class});
15325 CXXMethodDecl *NewCallOperator =
15326 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
15328 // Enter the scope of the lambda.
15329 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
15330 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
15331 E->hasExplicitParameters(), E->isMutable());
15333 // Introduce the context of the call operator.
15334 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
15335 /*NewThisContext*/false);
15337 bool Invalid = false;
15339 // Transform captures.
15340 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15341 CEnd = E->capture_end();
15342 C != CEnd; ++C) {
15343 // When we hit the first implicit capture, tell Sema that we've finished
15344 // the list of explicit captures.
15345 if (C->isImplicit())
15346 break;
15348 // Capturing 'this' is trivial.
15349 if (C->capturesThis()) {
15350 // If this is a lambda that is part of a default member initialiser
15351 // and which we're instantiating outside the class that 'this' is
15352 // supposed to refer to, adjust the type of 'this' accordingly.
15354 // Otherwise, leave the type of 'this' as-is.
15355 Sema::CXXThisScopeRAII ThisScope(
15356 getSema(),
15357 dyn_cast_if_present<CXXRecordDecl>(
15358 getSema().getFunctionLevelDeclContext()),
15359 Qualifiers());
15360 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15361 /*BuildAndDiagnose*/ true, nullptr,
15362 C->getCaptureKind() == LCK_StarThis);
15363 continue;
15365 // Captured expression will be recaptured during captured variables
15366 // rebuilding.
15367 if (C->capturesVLAType())
15368 continue;
15370 // Rebuild init-captures, including the implied field declaration.
15371 if (E->isInitCapture(C)) {
15372 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
15374 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
15375 llvm::SmallVector<Decl*, 4> NewVDs;
15377 for (InitCaptureInfoTy &Info : NewC.Expansions) {
15378 ExprResult Init = Info.first;
15379 QualType InitQualType = Info.second;
15380 if (Init.isInvalid() || InitQualType.isNull()) {
15381 Invalid = true;
15382 break;
15384 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
15385 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
15386 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
15387 getSema().CurContext);
15388 if (!NewVD) {
15389 Invalid = true;
15390 break;
15392 NewVDs.push_back(NewVD);
15393 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
15394 // Cases we want to tackle:
15395 // ([C(Pack)] {}, ...)
15396 // But rule out cases e.g.
15397 // [...C = Pack()] {}
15398 if (NewC.EllipsisLoc.isInvalid())
15399 LSI->ContainsUnexpandedParameterPack |=
15400 Init.get()->containsUnexpandedParameterPack();
15403 if (Invalid)
15404 break;
15406 getDerived().transformedLocalDecl(OldVD, NewVDs);
15407 continue;
15410 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15412 // Determine the capture kind for Sema.
15413 Sema::TryCaptureKind Kind
15414 = C->isImplicit()? Sema::TryCapture_Implicit
15415 : C->getCaptureKind() == LCK_ByCopy
15416 ? Sema::TryCapture_ExplicitByVal
15417 : Sema::TryCapture_ExplicitByRef;
15418 SourceLocation EllipsisLoc;
15419 if (C->isPackExpansion()) {
15420 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
15421 bool ShouldExpand = false;
15422 bool RetainExpansion = false;
15423 std::optional<unsigned> NumExpansions;
15424 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
15425 C->getLocation(),
15426 Unexpanded,
15427 ShouldExpand, RetainExpansion,
15428 NumExpansions)) {
15429 Invalid = true;
15430 continue;
15433 if (ShouldExpand) {
15434 // The transform has determined that we should perform an expansion;
15435 // transform and capture each of the arguments.
15436 // expansion of the pattern. Do so.
15437 auto *Pack = cast<ValueDecl>(C->getCapturedVar());
15438 for (unsigned I = 0; I != *NumExpansions; ++I) {
15439 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
15440 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
15441 getDerived().TransformDecl(C->getLocation(), Pack));
15442 if (!CapturedVar) {
15443 Invalid = true;
15444 continue;
15447 // Capture the transformed variable.
15448 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
15451 // FIXME: Retain a pack expansion if RetainExpansion is true.
15453 continue;
15456 EllipsisLoc = C->getEllipsisLoc();
15459 // Transform the captured variable.
15460 auto *CapturedVar = cast_or_null<ValueDecl>(
15461 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15462 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
15463 Invalid = true;
15464 continue;
15467 // This is not an init-capture; however it contains an unexpanded pack e.g.
15468 // ([Pack] {}(), ...)
15469 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
15470 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
15472 // Capture the transformed variable.
15473 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
15474 EllipsisLoc);
15476 getSema().finishLambdaExplicitCaptures(LSI);
15478 // Transform the template parameters, and add them to the current
15479 // instantiation scope. The null case is handled correctly.
15480 auto TPL = getDerived().TransformTemplateParameterList(
15481 E->getTemplateParameterList());
15482 LSI->GLTemplateParameterList = TPL;
15483 if (TPL) {
15484 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
15485 TPL);
15486 LSI->ContainsUnexpandedParameterPack |=
15487 TPL->containsUnexpandedParameterPack();
15490 TypeLocBuilder NewCallOpTLBuilder;
15491 TypeLoc OldCallOpTypeLoc =
15492 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
15493 QualType NewCallOpType =
15494 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
15495 if (NewCallOpType.isNull())
15496 return ExprError();
15497 LSI->ContainsUnexpandedParameterPack |=
15498 NewCallOpType->containsUnexpandedParameterPack();
15499 TypeSourceInfo *NewCallOpTSI =
15500 NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
15502 // The type may be an AttributedType or some other kind of sugar;
15503 // get the actual underlying FunctionProtoType.
15504 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
15505 assert(FPTL && "Not a FunctionProtoType?");
15507 getSema().CompleteLambdaCallOperator(
15508 NewCallOperator, E->getCallOperator()->getLocation(),
15509 E->getCallOperator()->getInnerLocStart(),
15510 E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
15511 E->getCallOperator()->getConstexprKind(),
15512 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
15513 E->hasExplicitResultType());
15515 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
15516 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
15519 // Number the lambda for linkage purposes if necessary.
15520 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
15522 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
15523 if (getDerived().ReplacingOriginal()) {
15524 Numbering = OldClass->getLambdaNumbering();
15527 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
15530 // FIXME: Sema's lambda-building mechanism expects us to push an expression
15531 // evaluation context even if we're not transforming the function body.
15532 getSema().PushExpressionEvaluationContext(
15533 E->getCallOperator()->isConsteval() ?
15534 Sema::ExpressionEvaluationContext::ImmediateFunctionContext :
15535 Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
15536 getSema().currentEvaluationContext().InImmediateEscalatingFunctionContext =
15537 getSema().getLangOpts().CPlusPlus20 &&
15538 E->getCallOperator()->isImmediateEscalating();
15540 Sema::CodeSynthesisContext C;
15541 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
15542 C.PointOfInstantiation = E->getBody()->getBeginLoc();
15543 getSema().pushCodeSynthesisContext(C);
15545 // Instantiate the body of the lambda expression.
15546 StmtResult Body =
15547 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
15549 getSema().popCodeSynthesisContext();
15551 // ActOnLambda* will pop the function scope for us.
15552 FuncScopeCleanup.disable();
15554 if (Body.isInvalid()) {
15555 SavedContext.pop();
15556 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
15557 /*IsInstantiation=*/true);
15558 return ExprError();
15561 // Copy the LSI before ActOnFinishFunctionBody removes it.
15562 // FIXME: This is dumb. Store the lambda information somewhere that outlives
15563 // the call operator.
15564 auto LSICopy = *LSI;
15565 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
15566 /*IsInstantiation*/ true);
15567 SavedContext.pop();
15569 // Recompute the dependency of the lambda so that we can defer the lambda call
15570 // construction until after we have all the necessary template arguments. For
15571 // example, given
15573 // template <class> struct S {
15574 // template <class U>
15575 // using Type = decltype([](U){}(42.0));
15576 // };
15577 // void foo() {
15578 // using T = S<int>::Type<float>;
15579 // ^~~~~~
15580 // }
15582 // We would end up here from instantiating S<int> when ensuring its
15583 // completeness. That would transform the lambda call expression regardless of
15584 // the absence of the corresponding argument for U.
15586 // Going ahead with unsubstituted type U makes things worse: we would soon
15587 // compare the argument type (which is float) against the parameter U
15588 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
15589 // error suggesting unmatched types 'U' and 'float'!
15591 // That said, everything will be fine if we defer that semantic checking.
15592 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
15593 // dependent. Since the CallExpr's dependency boils down to the lambda's
15594 // dependency in this case, we can harness that by recomputing the dependency
15595 // from the instantiation arguments.
15597 // FIXME: Creating the type of a lambda requires us to have a dependency
15598 // value, which happens before its substitution. We update its dependency
15599 // *after* the substitution in case we can't decide the dependency
15600 // so early, e.g. because we want to see if any of the *substituted*
15601 // parameters are dependent.
15602 DependencyKind = getDerived().ComputeLambdaDependency(&LSICopy);
15603 Class->setLambdaDependencyKind(DependencyKind);
15604 // Clean up the type cache created previously. Then, we re-create a type for
15605 // such Decl with the new DependencyKind.
15606 Class->setTypeForDecl(nullptr);
15607 getSema().Context.getTypeDeclType(Class);
15609 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
15610 Body.get()->getEndLoc(), &LSICopy);
15613 template<typename Derived>
15614 StmtResult
15615 TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
15616 return TransformStmt(S);
15619 template<typename Derived>
15620 StmtResult
15621 TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
15622 // Transform captures.
15623 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15624 CEnd = E->capture_end();
15625 C != CEnd; ++C) {
15626 // When we hit the first implicit capture, tell Sema that we've finished
15627 // the list of explicit captures.
15628 if (!C->isImplicit())
15629 continue;
15631 // Capturing 'this' is trivial.
15632 if (C->capturesThis()) {
15633 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15634 /*BuildAndDiagnose*/ true, nullptr,
15635 C->getCaptureKind() == LCK_StarThis);
15636 continue;
15638 // Captured expression will be recaptured during captured variables
15639 // rebuilding.
15640 if (C->capturesVLAType())
15641 continue;
15643 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15644 assert(!E->isInitCapture(C) && "implicit init-capture?");
15646 // Transform the captured variable.
15647 VarDecl *CapturedVar = cast_or_null<VarDecl>(
15648 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15649 if (!CapturedVar || CapturedVar->isInvalidDecl())
15650 return StmtError();
15652 // Capture the transformed variable.
15653 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
15656 return S;
15659 template<typename Derived>
15660 ExprResult
15661 TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
15662 CXXUnresolvedConstructExpr *E) {
15663 TypeSourceInfo *T =
15664 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15665 if (!T)
15666 return ExprError();
15668 bool ArgumentChanged = false;
15669 SmallVector<Expr*, 8> Args;
15670 Args.reserve(E->getNumArgs());
15672 EnterExpressionEvaluationContext Context(
15673 getSema(), EnterExpressionEvaluationContext::InitList,
15674 E->isListInitialization());
15675 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
15676 &ArgumentChanged))
15677 return ExprError();
15680 if (!getDerived().AlwaysRebuild() &&
15681 T == E->getTypeSourceInfo() &&
15682 !ArgumentChanged)
15683 return E;
15685 // FIXME: we're faking the locations of the commas
15686 return getDerived().RebuildCXXUnresolvedConstructExpr(
15687 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
15690 template<typename Derived>
15691 ExprResult
15692 TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
15693 CXXDependentScopeMemberExpr *E) {
15694 // Transform the base of the expression.
15695 ExprResult Base((Expr*) nullptr);
15696 Expr *OldBase;
15697 QualType BaseType;
15698 QualType ObjectType;
15699 if (!E->isImplicitAccess()) {
15700 OldBase = E->getBase();
15701 Base = getDerived().TransformExpr(OldBase);
15702 if (Base.isInvalid())
15703 return ExprError();
15705 // Start the member reference and compute the object's type.
15706 ParsedType ObjectTy;
15707 bool MayBePseudoDestructor = false;
15708 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
15709 E->getOperatorLoc(),
15710 E->isArrow()? tok::arrow : tok::period,
15711 ObjectTy,
15712 MayBePseudoDestructor);
15713 if (Base.isInvalid())
15714 return ExprError();
15716 ObjectType = ObjectTy.get();
15717 BaseType = ((Expr*) Base.get())->getType();
15718 } else {
15719 OldBase = nullptr;
15720 BaseType = getDerived().TransformType(E->getBaseType());
15721 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
15724 // Transform the first part of the nested-name-specifier that qualifies
15725 // the member name.
15726 NamedDecl *FirstQualifierInScope
15727 = getDerived().TransformFirstQualifierInScope(
15728 E->getFirstQualifierFoundInScope(),
15729 E->getQualifierLoc().getBeginLoc());
15731 NestedNameSpecifierLoc QualifierLoc;
15732 if (E->getQualifier()) {
15733 QualifierLoc
15734 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
15735 ObjectType,
15736 FirstQualifierInScope);
15737 if (!QualifierLoc)
15738 return ExprError();
15741 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15743 // TODO: If this is a conversion-function-id, verify that the
15744 // destination type name (if present) resolves the same way after
15745 // instantiation as it did in the local scope.
15747 DeclarationNameInfo NameInfo
15748 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
15749 if (!NameInfo.getName())
15750 return ExprError();
15752 if (!E->hasExplicitTemplateArgs()) {
15753 // This is a reference to a member without an explicitly-specified
15754 // template argument list. Optimize for this common case.
15755 if (!getDerived().AlwaysRebuild() &&
15756 Base.get() == OldBase &&
15757 BaseType == E->getBaseType() &&
15758 QualifierLoc == E->getQualifierLoc() &&
15759 NameInfo.getName() == E->getMember() &&
15760 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
15761 return E;
15763 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15764 BaseType,
15765 E->isArrow(),
15766 E->getOperatorLoc(),
15767 QualifierLoc,
15768 TemplateKWLoc,
15769 FirstQualifierInScope,
15770 NameInfo,
15771 /*TemplateArgs*/nullptr);
15774 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15775 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
15776 E->getNumTemplateArgs(),
15777 TransArgs))
15778 return ExprError();
15780 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15781 BaseType,
15782 E->isArrow(),
15783 E->getOperatorLoc(),
15784 QualifierLoc,
15785 TemplateKWLoc,
15786 FirstQualifierInScope,
15787 NameInfo,
15788 &TransArgs);
15791 template <typename Derived>
15792 ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
15793 UnresolvedMemberExpr *Old) {
15794 // Transform the base of the expression.
15795 ExprResult Base((Expr *)nullptr);
15796 QualType BaseType;
15797 if (!Old->isImplicitAccess()) {
15798 Base = getDerived().TransformExpr(Old->getBase());
15799 if (Base.isInvalid())
15800 return ExprError();
15801 Base =
15802 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
15803 if (Base.isInvalid())
15804 return ExprError();
15805 BaseType = Base.get()->getType();
15806 } else {
15807 BaseType = getDerived().TransformType(Old->getBaseType());
15810 NestedNameSpecifierLoc QualifierLoc;
15811 if (Old->getQualifierLoc()) {
15812 QualifierLoc =
15813 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
15814 if (!QualifierLoc)
15815 return ExprError();
15818 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
15820 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
15822 // Transform the declaration set.
15823 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ false, R))
15824 return ExprError();
15826 // Determine the naming class.
15827 if (Old->getNamingClass()) {
15828 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
15829 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
15830 if (!NamingClass)
15831 return ExprError();
15833 R.setNamingClass(NamingClass);
15836 TemplateArgumentListInfo TransArgs;
15837 if (Old->hasExplicitTemplateArgs()) {
15838 TransArgs.setLAngleLoc(Old->getLAngleLoc());
15839 TransArgs.setRAngleLoc(Old->getRAngleLoc());
15840 if (getDerived().TransformTemplateArguments(
15841 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
15842 return ExprError();
15845 // FIXME: to do this check properly, we will need to preserve the
15846 // first-qualifier-in-scope here, just in case we had a dependent
15847 // base (and therefore couldn't do the check) and a
15848 // nested-name-qualifier (and therefore could do the lookup).
15849 NamedDecl *FirstQualifierInScope = nullptr;
15851 return getDerived().RebuildUnresolvedMemberExpr(
15852 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
15853 TemplateKWLoc, FirstQualifierInScope, R,
15854 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
15857 template<typename Derived>
15858 ExprResult
15859 TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
15860 EnterExpressionEvaluationContext Unevaluated(
15861 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15862 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
15863 if (SubExpr.isInvalid())
15864 return ExprError();
15866 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
15867 return E;
15869 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
15872 template<typename Derived>
15873 ExprResult
15874 TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
15875 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
15876 if (Pattern.isInvalid())
15877 return ExprError();
15879 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
15880 return E;
15882 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
15883 E->getNumExpansions());
15886 template<typename Derived>
15887 ExprResult
15888 TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
15889 // If E is not value-dependent, then nothing will change when we transform it.
15890 // Note: This is an instantiation-centric view.
15891 if (!E->isValueDependent())
15892 return E;
15894 EnterExpressionEvaluationContext Unevaluated(
15895 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
15897 ArrayRef<TemplateArgument> PackArgs;
15898 TemplateArgument ArgStorage;
15900 // Find the argument list to transform.
15901 if (E->isPartiallySubstituted()) {
15902 PackArgs = E->getPartialArguments();
15903 } else if (E->isValueDependent()) {
15904 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
15905 bool ShouldExpand = false;
15906 bool RetainExpansion = false;
15907 std::optional<unsigned> NumExpansions;
15908 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
15909 Unexpanded,
15910 ShouldExpand, RetainExpansion,
15911 NumExpansions))
15912 return ExprError();
15914 // If we need to expand the pack, build a template argument from it and
15915 // expand that.
15916 if (ShouldExpand) {
15917 auto *Pack = E->getPack();
15918 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) {
15919 ArgStorage = getSema().Context.getPackExpansionType(
15920 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
15921 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {
15922 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
15923 } else {
15924 auto *VD = cast<ValueDecl>(Pack);
15925 ExprResult DRE = getSema().BuildDeclRefExpr(
15926 VD, VD->getType().getNonLValueExprType(getSema().Context),
15927 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
15928 E->getPackLoc());
15929 if (DRE.isInvalid())
15930 return ExprError();
15931 ArgStorage = new (getSema().Context)
15932 PackExpansionExpr(getSema().Context.DependentTy, DRE.get(),
15933 E->getPackLoc(), std::nullopt);
15935 PackArgs = ArgStorage;
15939 // If we're not expanding the pack, just transform the decl.
15940 if (!PackArgs.size()) {
15941 auto *Pack = cast_or_null<NamedDecl>(
15942 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
15943 if (!Pack)
15944 return ExprError();
15945 return getDerived().RebuildSizeOfPackExpr(
15946 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
15947 std::nullopt, {});
15950 // Try to compute the result without performing a partial substitution.
15951 std::optional<unsigned> Result = 0;
15952 for (const TemplateArgument &Arg : PackArgs) {
15953 if (!Arg.isPackExpansion()) {
15954 Result = *Result + 1;
15955 continue;
15958 TemplateArgumentLoc ArgLoc;
15959 InventTemplateArgumentLoc(Arg, ArgLoc);
15961 // Find the pattern of the pack expansion.
15962 SourceLocation Ellipsis;
15963 std::optional<unsigned> OrigNumExpansions;
15964 TemplateArgumentLoc Pattern =
15965 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
15966 OrigNumExpansions);
15968 // Substitute under the pack expansion. Do not expand the pack (yet).
15969 TemplateArgumentLoc OutPattern;
15970 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15971 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
15972 /*Uneval*/ true))
15973 return true;
15975 // See if we can determine the number of arguments from the result.
15976 std::optional<unsigned> NumExpansions =
15977 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
15978 if (!NumExpansions) {
15979 // No: we must be in an alias template expansion, and we're going to need
15980 // to actually expand the packs.
15981 Result = std::nullopt;
15982 break;
15985 Result = *Result + *NumExpansions;
15988 // Common case: we could determine the number of expansions without
15989 // substituting.
15990 if (Result)
15991 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
15992 E->getPackLoc(),
15993 E->getRParenLoc(), *Result, {});
15995 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
15996 E->getPackLoc());
15998 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
15999 typedef TemplateArgumentLocInventIterator<
16000 Derived, const TemplateArgument*> PackLocIterator;
16001 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
16002 PackLocIterator(*this, PackArgs.end()),
16003 TransformedPackArgs, /*Uneval*/true))
16004 return ExprError();
16007 // Check whether we managed to fully-expand the pack.
16008 // FIXME: Is it possible for us to do so and not hit the early exit path?
16009 SmallVector<TemplateArgument, 8> Args;
16010 bool PartialSubstitution = false;
16011 for (auto &Loc : TransformedPackArgs.arguments()) {
16012 Args.push_back(Loc.getArgument());
16013 if (Loc.getArgument().isPackExpansion())
16014 PartialSubstitution = true;
16017 if (PartialSubstitution)
16018 return getDerived().RebuildSizeOfPackExpr(
16019 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16020 std::nullopt, Args);
16022 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
16023 E->getPackLoc(), E->getRParenLoc(),
16024 Args.size(), {});
16027 template <typename Derived>
16028 ExprResult
16029 TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
16030 if (!E->isValueDependent())
16031 return E;
16033 // Transform the index
16034 ExprResult IndexExpr;
16036 EnterExpressionEvaluationContext ConstantContext(
16037 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
16038 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
16039 if (IndexExpr.isInvalid())
16040 return ExprError();
16043 SmallVector<Expr *, 5> ExpandedExprs;
16044 bool FullySubstituted = true;
16045 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
16046 Expr *Pattern = E->getPackIdExpression();
16047 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16048 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
16049 Unexpanded);
16050 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16052 // Determine whether the set of unexpanded parameter packs can and should
16053 // be expanded.
16054 bool ShouldExpand = true;
16055 bool RetainExpansion = false;
16056 std::optional<unsigned> OrigNumExpansions;
16057 std::optional<unsigned> NumExpansions = OrigNumExpansions;
16058 if (getDerived().TryExpandParameterPacks(
16059 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16060 ShouldExpand, RetainExpansion, NumExpansions))
16061 return true;
16062 if (!ShouldExpand) {
16063 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
16064 ExprResult Pack = getDerived().TransformExpr(Pattern);
16065 if (Pack.isInvalid())
16066 return ExprError();
16067 return getDerived().RebuildPackIndexingExpr(
16068 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
16069 {}, /*FullySubstituted=*/false);
16071 for (unsigned I = 0; I != *NumExpansions; ++I) {
16072 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
16073 ExprResult Out = getDerived().TransformExpr(Pattern);
16074 if (Out.isInvalid())
16075 return true;
16076 if (Out.get()->containsUnexpandedParameterPack()) {
16077 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16078 OrigNumExpansions);
16079 if (Out.isInvalid())
16080 return true;
16081 FullySubstituted = false;
16083 ExpandedExprs.push_back(Out.get());
16085 // If we're supposed to retain a pack expansion, do so by temporarily
16086 // forgetting the partially-substituted parameter pack.
16087 if (RetainExpansion) {
16088 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16090 ExprResult Out = getDerived().TransformExpr(Pattern);
16091 if (Out.isInvalid())
16092 return true;
16094 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16095 OrigNumExpansions);
16096 if (Out.isInvalid())
16097 return true;
16098 FullySubstituted = false;
16099 ExpandedExprs.push_back(Out.get());
16101 } else if (!E->expandsToEmptyPack()) {
16102 if (getDerived().TransformExprs(E->getExpressions().data(),
16103 E->getExpressions().size(), false,
16104 ExpandedExprs))
16105 return ExprError();
16108 return getDerived().RebuildPackIndexingExpr(
16109 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
16110 IndexExpr.get(), ExpandedExprs, FullySubstituted);
16113 template<typename Derived>
16114 ExprResult
16115 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
16116 SubstNonTypeTemplateParmPackExpr *E) {
16117 // Default behavior is to do nothing with this transformation.
16118 return E;
16121 template<typename Derived>
16122 ExprResult
16123 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
16124 SubstNonTypeTemplateParmExpr *E) {
16125 // Default behavior is to do nothing with this transformation.
16126 return E;
16129 template<typename Derived>
16130 ExprResult
16131 TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
16132 // Default behavior is to do nothing with this transformation.
16133 return E;
16136 template <typename Derived>
16137 ExprResult TreeTransform<Derived>::TransformResolvedUnexpandedPackExpr(
16138 ResolvedUnexpandedPackExpr *E) {
16139 bool ArgumentChanged = false;
16140 SmallVector<Expr *, 12> NewExprs;
16141 if (TransformExprs(E->getExprs().begin(), E->getNumExprs(),
16142 /*IsCall=*/false, NewExprs, &ArgumentChanged))
16143 return ExprError();
16145 if (!AlwaysRebuild() && !ArgumentChanged)
16146 return E;
16148 // NOTE: The type is just a superficial PackExpansionType
16149 // that needs no substitution.
16150 return RebuildResolvedUnexpandedPackExpr(E->getBeginLoc(), E->getType(),
16151 NewExprs);
16154 template<typename Derived>
16155 ExprResult
16156 TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
16157 MaterializeTemporaryExpr *E) {
16158 return getDerived().TransformExpr(E->getSubExpr());
16161 template<typename Derived>
16162 ExprResult
16163 TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
16164 UnresolvedLookupExpr *Callee = nullptr;
16165 if (Expr *OldCallee = E->getCallee()) {
16166 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
16167 if (CalleeResult.isInvalid())
16168 return ExprError();
16169 Callee = cast<UnresolvedLookupExpr>(CalleeResult.get());
16172 Expr *Pattern = E->getPattern();
16174 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16175 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
16176 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16178 // Determine whether the set of unexpanded parameter packs can and should
16179 // be expanded.
16180 bool Expand = true;
16181 bool RetainExpansion = false;
16182 std::optional<unsigned> OrigNumExpansions = E->getNumExpansions(),
16183 NumExpansions = OrigNumExpansions;
16184 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
16185 Pattern->getSourceRange(),
16186 Unexpanded,
16187 Expand, RetainExpansion,
16188 NumExpansions))
16189 return true;
16191 if (!Expand) {
16192 // Do not expand any packs here, just transform and rebuild a fold
16193 // expression.
16194 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
16196 ExprResult LHS =
16197 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
16198 if (LHS.isInvalid())
16199 return true;
16201 ExprResult RHS =
16202 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
16203 if (RHS.isInvalid())
16204 return true;
16206 if (!getDerived().AlwaysRebuild() &&
16207 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
16208 return E;
16210 return getDerived().RebuildCXXFoldExpr(
16211 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
16212 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
16215 // Formally a fold expression expands to nested parenthesized expressions.
16216 // Enforce this limit to avoid creating trees so deep we can't safely traverse
16217 // them.
16218 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) {
16219 SemaRef.Diag(E->getEllipsisLoc(),
16220 clang::diag::err_fold_expression_limit_exceeded)
16221 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
16222 << E->getSourceRange();
16223 SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);
16224 return ExprError();
16227 // The transform has determined that we should perform an elementwise
16228 // expansion of the pattern. Do so.
16229 ExprResult Result = getDerived().TransformExpr(E->getInit());
16230 if (Result.isInvalid())
16231 return true;
16232 bool LeftFold = E->isLeftFold();
16234 // If we're retaining an expansion for a right fold, it is the innermost
16235 // component and takes the init (if any).
16236 if (!LeftFold && RetainExpansion) {
16237 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16239 ExprResult Out = getDerived().TransformExpr(Pattern);
16240 if (Out.isInvalid())
16241 return true;
16243 Result = getDerived().RebuildCXXFoldExpr(
16244 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
16245 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
16246 if (Result.isInvalid())
16247 return true;
16250 for (unsigned I = 0; I != *NumExpansions; ++I) {
16251 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(
16252 getSema(), LeftFold ? I : *NumExpansions - I - 1);
16253 ExprResult Out = getDerived().TransformExpr(Pattern);
16254 if (Out.isInvalid())
16255 return true;
16257 if (Out.get()->containsUnexpandedParameterPack()) {
16258 // We still have a pack; retain a pack expansion for this slice.
16259 Result = getDerived().RebuildCXXFoldExpr(
16260 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
16261 E->getOperator(), E->getEllipsisLoc(),
16262 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
16263 OrigNumExpansions);
16264 } else if (Result.isUsable()) {
16265 // We've got down to a single element; build a binary operator.
16266 Expr *LHS = LeftFold ? Result.get() : Out.get();
16267 Expr *RHS = LeftFold ? Out.get() : Result.get();
16268 if (Callee) {
16269 UnresolvedSet<16> Functions;
16270 Functions.append(Callee->decls_begin(), Callee->decls_end());
16271 Result = getDerived().RebuildCXXOperatorCallExpr(
16272 BinaryOperator::getOverloadedOperator(E->getOperator()),
16273 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
16274 Functions, LHS, RHS);
16275 } else {
16276 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
16277 E->getOperator(), LHS, RHS);
16279 } else
16280 Result = Out;
16282 if (Result.isInvalid())
16283 return true;
16286 // If we're retaining an expansion for a left fold, it is the outermost
16287 // component and takes the complete expansion so far as its init (if any).
16288 if (LeftFold && RetainExpansion) {
16289 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16291 ExprResult Out = getDerived().TransformExpr(Pattern);
16292 if (Out.isInvalid())
16293 return true;
16295 Result = getDerived().RebuildCXXFoldExpr(
16296 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
16297 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
16298 if (Result.isInvalid())
16299 return true;
16302 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Result.get()))
16303 PE->setIsProducedByFoldExpansion();
16305 // If we had no init and an empty pack, and we're not retaining an expansion,
16306 // then produce a fallback value or error.
16307 if (Result.isUnset())
16308 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
16309 E->getOperator());
16310 return Result;
16313 template <typename Derived>
16314 ExprResult
16315 TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
16316 SmallVector<Expr *, 4> TransformedInits;
16317 ArrayRef<Expr *> InitExprs = E->getInitExprs();
16318 if (TransformExprs(InitExprs.data(), InitExprs.size(), true,
16319 TransformedInits))
16320 return ExprError();
16322 return getDerived().RebuildParenListExpr(E->getBeginLoc(), TransformedInits,
16323 E->getEndLoc());
16326 template<typename Derived>
16327 ExprResult
16328 TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
16329 CXXStdInitializerListExpr *E) {
16330 return getDerived().TransformExpr(E->getSubExpr());
16333 template<typename Derived>
16334 ExprResult
16335 TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
16336 return SemaRef.MaybeBindToTemporary(E);
16339 template<typename Derived>
16340 ExprResult
16341 TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
16342 return E;
16345 template<typename Derived>
16346 ExprResult
16347 TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
16348 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
16349 if (SubExpr.isInvalid())
16350 return ExprError();
16352 if (!getDerived().AlwaysRebuild() &&
16353 SubExpr.get() == E->getSubExpr())
16354 return E;
16356 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
16359 template<typename Derived>
16360 ExprResult
16361 TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
16362 // Transform each of the elements.
16363 SmallVector<Expr *, 8> Elements;
16364 bool ArgChanged = false;
16365 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
16366 /*IsCall=*/false, Elements, &ArgChanged))
16367 return ExprError();
16369 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16370 return SemaRef.MaybeBindToTemporary(E);
16372 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
16373 Elements.data(),
16374 Elements.size());
16377 template<typename Derived>
16378 ExprResult
16379 TreeTransform<Derived>::TransformObjCDictionaryLiteral(
16380 ObjCDictionaryLiteral *E) {
16381 // Transform each of the elements.
16382 SmallVector<ObjCDictionaryElement, 8> Elements;
16383 bool ArgChanged = false;
16384 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
16385 ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);
16387 if (OrigElement.isPackExpansion()) {
16388 // This key/value element is a pack expansion.
16389 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16390 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
16391 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
16392 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16394 // Determine whether the set of unexpanded parameter packs can
16395 // and should be expanded.
16396 bool Expand = true;
16397 bool RetainExpansion = false;
16398 std::optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
16399 std::optional<unsigned> NumExpansions = OrigNumExpansions;
16400 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
16401 OrigElement.Value->getEndLoc());
16402 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
16403 PatternRange, Unexpanded, Expand,
16404 RetainExpansion, NumExpansions))
16405 return ExprError();
16407 if (!Expand) {
16408 // The transform has determined that we should perform a simple
16409 // transformation on the pack expansion, producing another pack
16410 // expansion.
16411 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
16412 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16413 if (Key.isInvalid())
16414 return ExprError();
16416 if (Key.get() != OrigElement.Key)
16417 ArgChanged = true;
16419 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16420 if (Value.isInvalid())
16421 return ExprError();
16423 if (Value.get() != OrigElement.Value)
16424 ArgChanged = true;
16426 ObjCDictionaryElement Expansion = {
16427 Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions
16429 Elements.push_back(Expansion);
16430 continue;
16433 // Record right away that the argument was changed. This needs
16434 // to happen even if the array expands to nothing.
16435 ArgChanged = true;
16437 // The transform has determined that we should perform an elementwise
16438 // expansion of the pattern. Do so.
16439 for (unsigned I = 0; I != *NumExpansions; ++I) {
16440 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
16441 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16442 if (Key.isInvalid())
16443 return ExprError();
16445 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16446 if (Value.isInvalid())
16447 return ExprError();
16449 ObjCDictionaryElement Element = {
16450 Key.get(), Value.get(), SourceLocation(), NumExpansions
16453 // If any unexpanded parameter packs remain, we still have a
16454 // pack expansion.
16455 // FIXME: Can this really happen?
16456 if (Key.get()->containsUnexpandedParameterPack() ||
16457 Value.get()->containsUnexpandedParameterPack())
16458 Element.EllipsisLoc = OrigElement.EllipsisLoc;
16460 Elements.push_back(Element);
16463 // FIXME: Retain a pack expansion if RetainExpansion is true.
16465 // We've finished with this pack expansion.
16466 continue;
16469 // Transform and check key.
16470 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16471 if (Key.isInvalid())
16472 return ExprError();
16474 if (Key.get() != OrigElement.Key)
16475 ArgChanged = true;
16477 // Transform and check value.
16478 ExprResult Value
16479 = getDerived().TransformExpr(OrigElement.Value);
16480 if (Value.isInvalid())
16481 return ExprError();
16483 if (Value.get() != OrigElement.Value)
16484 ArgChanged = true;
16486 ObjCDictionaryElement Element = {Key.get(), Value.get(), SourceLocation(),
16487 std::nullopt};
16488 Elements.push_back(Element);
16491 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16492 return SemaRef.MaybeBindToTemporary(E);
16494 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
16495 Elements);
16498 template<typename Derived>
16499 ExprResult
16500 TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
16501 TypeSourceInfo *EncodedTypeInfo
16502 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
16503 if (!EncodedTypeInfo)
16504 return ExprError();
16506 if (!getDerived().AlwaysRebuild() &&
16507 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
16508 return E;
16510 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
16511 EncodedTypeInfo,
16512 E->getRParenLoc());
16515 template<typename Derived>
16516 ExprResult TreeTransform<Derived>::
16517 TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
16518 // This is a kind of implicit conversion, and it needs to get dropped
16519 // and recomputed for the same general reasons that ImplicitCastExprs
16520 // do, as well a more specific one: this expression is only valid when
16521 // it appears *immediately* as an argument expression.
16522 return getDerived().TransformExpr(E->getSubExpr());
16525 template<typename Derived>
16526 ExprResult TreeTransform<Derived>::
16527 TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
16528 TypeSourceInfo *TSInfo
16529 = getDerived().TransformType(E->getTypeInfoAsWritten());
16530 if (!TSInfo)
16531 return ExprError();
16533 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
16534 if (Result.isInvalid())
16535 return ExprError();
16537 if (!getDerived().AlwaysRebuild() &&
16538 TSInfo == E->getTypeInfoAsWritten() &&
16539 Result.get() == E->getSubExpr())
16540 return E;
16542 return SemaRef.ObjC().BuildObjCBridgedCast(
16543 E->getLParenLoc(), E->getBridgeKind(), E->getBridgeKeywordLoc(), TSInfo,
16544 Result.get());
16547 template <typename Derived>
16548 ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
16549 ObjCAvailabilityCheckExpr *E) {
16550 return E;
16553 template<typename Derived>
16554 ExprResult
16555 TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
16556 // Transform arguments.
16557 bool ArgChanged = false;
16558 SmallVector<Expr*, 8> Args;
16559 Args.reserve(E->getNumArgs());
16560 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
16561 &ArgChanged))
16562 return ExprError();
16564 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
16565 // Class message: transform the receiver type.
16566 TypeSourceInfo *ReceiverTypeInfo
16567 = getDerived().TransformType(E->getClassReceiverTypeInfo());
16568 if (!ReceiverTypeInfo)
16569 return ExprError();
16571 // If nothing changed, just retain the existing message send.
16572 if (!getDerived().AlwaysRebuild() &&
16573 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
16574 return SemaRef.MaybeBindToTemporary(E);
16576 // Build a new class message send.
16577 SmallVector<SourceLocation, 16> SelLocs;
16578 E->getSelectorLocs(SelLocs);
16579 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
16580 E->getSelector(),
16581 SelLocs,
16582 E->getMethodDecl(),
16583 E->getLeftLoc(),
16584 Args,
16585 E->getRightLoc());
16587 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
16588 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
16589 if (!E->getMethodDecl())
16590 return ExprError();
16592 // Build a new class message send to 'super'.
16593 SmallVector<SourceLocation, 16> SelLocs;
16594 E->getSelectorLocs(SelLocs);
16595 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
16596 E->getSelector(),
16597 SelLocs,
16598 E->getReceiverType(),
16599 E->getMethodDecl(),
16600 E->getLeftLoc(),
16601 Args,
16602 E->getRightLoc());
16605 // Instance message: transform the receiver
16606 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
16607 "Only class and instance messages may be instantiated");
16608 ExprResult Receiver
16609 = getDerived().TransformExpr(E->getInstanceReceiver());
16610 if (Receiver.isInvalid())
16611 return ExprError();
16613 // If nothing changed, just retain the existing message send.
16614 if (!getDerived().AlwaysRebuild() &&
16615 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
16616 return SemaRef.MaybeBindToTemporary(E);
16618 // Build a new instance message send.
16619 SmallVector<SourceLocation, 16> SelLocs;
16620 E->getSelectorLocs(SelLocs);
16621 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
16622 E->getSelector(),
16623 SelLocs,
16624 E->getMethodDecl(),
16625 E->getLeftLoc(),
16626 Args,
16627 E->getRightLoc());
16630 template<typename Derived>
16631 ExprResult
16632 TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
16633 return E;
16636 template<typename Derived>
16637 ExprResult
16638 TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
16639 return E;
16642 template<typename Derived>
16643 ExprResult
16644 TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
16645 // Transform the base expression.
16646 ExprResult Base = getDerived().TransformExpr(E->getBase());
16647 if (Base.isInvalid())
16648 return ExprError();
16650 // We don't need to transform the ivar; it will never change.
16652 // If nothing changed, just retain the existing expression.
16653 if (!getDerived().AlwaysRebuild() &&
16654 Base.get() == E->getBase())
16655 return E;
16657 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
16658 E->getLocation(),
16659 E->isArrow(), E->isFreeIvar());
16662 template<typename Derived>
16663 ExprResult
16664 TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
16665 // 'super' and types never change. Property never changes. Just
16666 // retain the existing expression.
16667 if (!E->isObjectReceiver())
16668 return E;
16670 // Transform the base expression.
16671 ExprResult Base = getDerived().TransformExpr(E->getBase());
16672 if (Base.isInvalid())
16673 return ExprError();
16675 // We don't need to transform the property; it will never change.
16677 // If nothing changed, just retain the existing expression.
16678 if (!getDerived().AlwaysRebuild() &&
16679 Base.get() == E->getBase())
16680 return E;
16682 if (E->isExplicitProperty())
16683 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
16684 E->getExplicitProperty(),
16685 E->getLocation());
16687 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
16688 SemaRef.Context.PseudoObjectTy,
16689 E->getImplicitPropertyGetter(),
16690 E->getImplicitPropertySetter(),
16691 E->getLocation());
16694 template<typename Derived>
16695 ExprResult
16696 TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
16697 // Transform the base expression.
16698 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
16699 if (Base.isInvalid())
16700 return ExprError();
16702 // Transform the key expression.
16703 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
16704 if (Key.isInvalid())
16705 return ExprError();
16707 // If nothing changed, just retain the existing expression.
16708 if (!getDerived().AlwaysRebuild() &&
16709 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
16710 return E;
16712 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
16713 Base.get(), Key.get(),
16714 E->getAtIndexMethodDecl(),
16715 E->setAtIndexMethodDecl());
16718 template<typename Derived>
16719 ExprResult
16720 TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
16721 // Transform the base expression.
16722 ExprResult Base = getDerived().TransformExpr(E->getBase());
16723 if (Base.isInvalid())
16724 return ExprError();
16726 // If nothing changed, just retain the existing expression.
16727 if (!getDerived().AlwaysRebuild() &&
16728 Base.get() == E->getBase())
16729 return E;
16731 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
16732 E->getOpLoc(),
16733 E->isArrow());
16736 template<typename Derived>
16737 ExprResult
16738 TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
16739 bool ArgumentChanged = false;
16740 SmallVector<Expr*, 8> SubExprs;
16741 SubExprs.reserve(E->getNumSubExprs());
16742 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
16743 SubExprs, &ArgumentChanged))
16744 return ExprError();
16746 if (!getDerived().AlwaysRebuild() &&
16747 !ArgumentChanged)
16748 return E;
16750 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
16751 SubExprs,
16752 E->getRParenLoc());
16755 template<typename Derived>
16756 ExprResult
16757 TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
16758 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
16759 if (SrcExpr.isInvalid())
16760 return ExprError();
16762 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
16763 if (!Type)
16764 return ExprError();
16766 if (!getDerived().AlwaysRebuild() &&
16767 Type == E->getTypeSourceInfo() &&
16768 SrcExpr.get() == E->getSrcExpr())
16769 return E;
16771 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
16772 SrcExpr.get(), Type,
16773 E->getRParenLoc());
16776 template<typename Derived>
16777 ExprResult
16778 TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
16779 BlockDecl *oldBlock = E->getBlockDecl();
16781 SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr);
16782 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
16784 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
16785 blockScope->TheDecl->setBlockMissingReturnType(
16786 oldBlock->blockMissingReturnType());
16788 SmallVector<ParmVarDecl*, 4> params;
16789 SmallVector<QualType, 4> paramTypes;
16791 const FunctionProtoType *exprFunctionType = E->getFunctionType();
16793 // Parameter substitution.
16794 Sema::ExtParameterInfoBuilder extParamInfos;
16795 if (getDerived().TransformFunctionTypeParams(
16796 E->getCaretLocation(), oldBlock->parameters(), nullptr,
16797 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
16798 extParamInfos)) {
16799 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
16800 return ExprError();
16803 QualType exprResultType =
16804 getDerived().TransformType(exprFunctionType->getReturnType());
16806 auto epi = exprFunctionType->getExtProtoInfo();
16807 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size());
16809 QualType functionType =
16810 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
16811 blockScope->FunctionType = functionType;
16813 // Set the parameters on the block decl.
16814 if (!params.empty())
16815 blockScope->TheDecl->setParams(params);
16817 if (!oldBlock->blockMissingReturnType()) {
16818 blockScope->HasImplicitReturnType = false;
16819 blockScope->ReturnType = exprResultType;
16822 // Transform the body
16823 StmtResult body = getDerived().TransformStmt(E->getBody());
16824 if (body.isInvalid()) {
16825 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
16826 return ExprError();
16829 #ifndef NDEBUG
16830 // In builds with assertions, make sure that we captured everything we
16831 // captured before.
16832 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
16833 for (const auto &I : oldBlock->captures()) {
16834 VarDecl *oldCapture = I.getVariable();
16836 // Ignore parameter packs.
16837 if (oldCapture->isParameterPack())
16838 continue;
16840 VarDecl *newCapture =
16841 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
16842 oldCapture));
16843 assert(blockScope->CaptureMap.count(newCapture));
16846 // The this pointer may not be captured by the instantiated block, even when
16847 // it's captured by the original block, if the expression causing the
16848 // capture is in the discarded branch of a constexpr if statement.
16849 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
16850 "this pointer isn't captured in the old block");
16852 #endif
16854 return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(),
16855 /*Scope=*/nullptr);
16858 template<typename Derived>
16859 ExprResult
16860 TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
16861 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
16862 if (SrcExpr.isInvalid())
16863 return ExprError();
16865 QualType Type = getDerived().TransformType(E->getType());
16867 return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(),
16868 E->getRParenLoc());
16871 template<typename Derived>
16872 ExprResult
16873 TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
16874 bool ArgumentChanged = false;
16875 SmallVector<Expr*, 8> SubExprs;
16876 SubExprs.reserve(E->getNumSubExprs());
16877 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
16878 SubExprs, &ArgumentChanged))
16879 return ExprError();
16881 if (!getDerived().AlwaysRebuild() &&
16882 !ArgumentChanged)
16883 return E;
16885 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
16886 E->getOp(), E->getRParenLoc());
16889 //===----------------------------------------------------------------------===//
16890 // Type reconstruction
16891 //===----------------------------------------------------------------------===//
16893 template<typename Derived>
16894 QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
16895 SourceLocation Star) {
16896 return SemaRef.BuildPointerType(PointeeType, Star,
16897 getDerived().getBaseEntity());
16900 template<typename Derived>
16901 QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
16902 SourceLocation Star) {
16903 return SemaRef.BuildBlockPointerType(PointeeType, Star,
16904 getDerived().getBaseEntity());
16907 template<typename Derived>
16908 QualType
16909 TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
16910 bool WrittenAsLValue,
16911 SourceLocation Sigil) {
16912 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue,
16913 Sigil, getDerived().getBaseEntity());
16916 template<typename Derived>
16917 QualType
16918 TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
16919 QualType ClassType,
16920 SourceLocation Sigil) {
16921 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil,
16922 getDerived().getBaseEntity());
16925 template<typename Derived>
16926 QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
16927 const ObjCTypeParamDecl *Decl,
16928 SourceLocation ProtocolLAngleLoc,
16929 ArrayRef<ObjCProtocolDecl *> Protocols,
16930 ArrayRef<SourceLocation> ProtocolLocs,
16931 SourceLocation ProtocolRAngleLoc) {
16932 return SemaRef.ObjC().BuildObjCTypeParamType(
16933 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
16934 /*FailOnError=*/true);
16937 template<typename Derived>
16938 QualType TreeTransform<Derived>::RebuildObjCObjectType(
16939 QualType BaseType,
16940 SourceLocation Loc,
16941 SourceLocation TypeArgsLAngleLoc,
16942 ArrayRef<TypeSourceInfo *> TypeArgs,
16943 SourceLocation TypeArgsRAngleLoc,
16944 SourceLocation ProtocolLAngleLoc,
16945 ArrayRef<ObjCProtocolDecl *> Protocols,
16946 ArrayRef<SourceLocation> ProtocolLocs,
16947 SourceLocation ProtocolRAngleLoc) {
16948 return SemaRef.ObjC().BuildObjCObjectType(
16949 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
16950 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
16951 /*FailOnError=*/true,
16952 /*Rebuilding=*/true);
16955 template<typename Derived>
16956 QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
16957 QualType PointeeType,
16958 SourceLocation Star) {
16959 return SemaRef.Context.getObjCObjectPointerType(PointeeType);
16962 template <typename Derived>
16963 QualType TreeTransform<Derived>::RebuildArrayType(
16964 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
16965 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
16966 if (SizeExpr || !Size)
16967 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
16968 IndexTypeQuals, BracketsRange,
16969 getDerived().getBaseEntity());
16971 QualType Types[] = {
16972 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
16973 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
16974 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
16976 QualType SizeType;
16977 for (const auto &T : Types)
16978 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
16979 SizeType = T;
16980 break;
16983 // Note that we can return a VariableArrayType here in the case where
16984 // the element type was a dependent VariableArrayType.
16985 IntegerLiteral *ArraySize
16986 = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType,
16987 /*FIXME*/BracketsRange.getBegin());
16988 return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize,
16989 IndexTypeQuals, BracketsRange,
16990 getDerived().getBaseEntity());
16993 template <typename Derived>
16994 QualType TreeTransform<Derived>::RebuildConstantArrayType(
16995 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
16996 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
16997 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
16998 IndexTypeQuals, BracketsRange);
17001 template <typename Derived>
17002 QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
17003 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
17004 SourceRange BracketsRange) {
17005 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
17006 IndexTypeQuals, BracketsRange);
17009 template <typename Derived>
17010 QualType TreeTransform<Derived>::RebuildVariableArrayType(
17011 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17012 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17013 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17014 SizeExpr,
17015 IndexTypeQuals, BracketsRange);
17018 template <typename Derived>
17019 QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
17020 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17021 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17022 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17023 SizeExpr,
17024 IndexTypeQuals, BracketsRange);
17027 template <typename Derived>
17028 QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
17029 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
17030 return SemaRef.BuildAddressSpaceAttr(PointeeType, AddrSpaceExpr,
17031 AttributeLoc);
17034 template <typename Derived>
17035 QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
17036 unsigned NumElements,
17037 VectorKind VecKind) {
17038 // FIXME: semantic checking!
17039 return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);
17042 template <typename Derived>
17043 QualType TreeTransform<Derived>::RebuildDependentVectorType(
17044 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
17045 VectorKind VecKind) {
17046 return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc);
17049 template<typename Derived>
17050 QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
17051 unsigned NumElements,
17052 SourceLocation AttributeLoc) {
17053 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
17054 NumElements, true);
17055 IntegerLiteral *VectorSize
17056 = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
17057 AttributeLoc);
17058 return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
17061 template<typename Derived>
17062 QualType
17063 TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
17064 Expr *SizeExpr,
17065 SourceLocation AttributeLoc) {
17066 return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
17069 template <typename Derived>
17070 QualType TreeTransform<Derived>::RebuildConstantMatrixType(
17071 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
17072 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
17073 NumColumns);
17076 template <typename Derived>
17077 QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
17078 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
17079 SourceLocation AttributeLoc) {
17080 return SemaRef.BuildMatrixType(ElementType, RowExpr, ColumnExpr,
17081 AttributeLoc);
17084 template <typename Derived>
17085 QualType TreeTransform<Derived>::RebuildFunctionProtoType(
17086 QualType T, MutableArrayRef<QualType> ParamTypes,
17087 const FunctionProtoType::ExtProtoInfo &EPI) {
17088 return SemaRef.BuildFunctionType(T, ParamTypes,
17089 getDerived().getBaseLocation(),
17090 getDerived().getBaseEntity(),
17091 EPI);
17094 template<typename Derived>
17095 QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
17096 return SemaRef.Context.getFunctionNoProtoType(T);
17099 template<typename Derived>
17100 QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
17101 Decl *D) {
17102 assert(D && "no decl found");
17103 if (D->isInvalidDecl()) return QualType();
17105 // FIXME: Doesn't account for ObjCInterfaceDecl!
17106 if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
17107 // A valid resolved using typename pack expansion decl can have multiple
17108 // UsingDecls, but they must each have exactly one type, and it must be
17109 // the same type in every case. But we must have at least one expansion!
17110 if (UPD->expansions().empty()) {
17111 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
17112 << UPD->isCXXClassMember() << UPD;
17113 return QualType();
17116 // We might still have some unresolved types. Try to pick a resolved type
17117 // if we can. The final instantiation will check that the remaining
17118 // unresolved types instantiate to the type we pick.
17119 QualType FallbackT;
17120 QualType T;
17121 for (auto *E : UPD->expansions()) {
17122 QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
17123 if (ThisT.isNull())
17124 continue;
17125 else if (ThisT->getAs<UnresolvedUsingType>())
17126 FallbackT = ThisT;
17127 else if (T.isNull())
17128 T = ThisT;
17129 else
17130 assert(getSema().Context.hasSameType(ThisT, T) &&
17131 "mismatched resolved types in using pack expansion");
17133 return T.isNull() ? FallbackT : T;
17134 } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
17135 assert(Using->hasTypename() &&
17136 "UnresolvedUsingTypenameDecl transformed to non-typename using");
17138 // A valid resolved using typename decl points to exactly one type decl.
17139 assert(++Using->shadow_begin() == Using->shadow_end());
17141 UsingShadowDecl *Shadow = *Using->shadow_begin();
17142 if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), Loc))
17143 return QualType();
17144 return SemaRef.Context.getUsingType(
17145 Shadow, SemaRef.Context.getTypeDeclType(
17146 cast<TypeDecl>(Shadow->getTargetDecl())));
17147 } else {
17148 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
17149 "UnresolvedUsingTypenameDecl transformed to non-using decl");
17150 return SemaRef.Context.getTypeDeclType(
17151 cast<UnresolvedUsingTypenameDecl>(D));
17155 template <typename Derived>
17156 QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
17157 TypeOfKind Kind) {
17158 return SemaRef.BuildTypeofExprType(E, Kind);
17161 template<typename Derived>
17162 QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
17163 TypeOfKind Kind) {
17164 return SemaRef.Context.getTypeOfType(Underlying, Kind);
17167 template <typename Derived>
17168 QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
17169 return SemaRef.BuildDecltypeType(E);
17172 template <typename Derived>
17173 QualType TreeTransform<Derived>::RebuildPackIndexingType(
17174 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
17175 SourceLocation EllipsisLoc, bool FullySubstituted,
17176 ArrayRef<QualType> Expansions) {
17177 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
17178 FullySubstituted, Expansions);
17181 template<typename Derived>
17182 QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
17183 UnaryTransformType::UTTKind UKind,
17184 SourceLocation Loc) {
17185 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
17188 template<typename Derived>
17189 QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
17190 TemplateName Template,
17191 SourceLocation TemplateNameLoc,
17192 TemplateArgumentListInfo &TemplateArgs) {
17193 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
17196 template<typename Derived>
17197 QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
17198 SourceLocation KWLoc) {
17199 return SemaRef.BuildAtomicType(ValueType, KWLoc);
17202 template<typename Derived>
17203 QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
17204 SourceLocation KWLoc,
17205 bool isReadPipe) {
17206 return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc)
17207 : SemaRef.BuildWritePipeType(ValueType, KWLoc);
17210 template <typename Derived>
17211 QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
17212 unsigned NumBits,
17213 SourceLocation Loc) {
17214 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
17215 NumBits, true);
17216 IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,
17217 SemaRef.Context.IntTy, Loc);
17218 return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc);
17221 template <typename Derived>
17222 QualType TreeTransform<Derived>::RebuildDependentBitIntType(
17223 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
17224 return SemaRef.BuildBitIntType(IsUnsigned, NumBitsExpr, Loc);
17227 template<typename Derived>
17228 TemplateName
17229 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17230 bool TemplateKW,
17231 TemplateDecl *Template) {
17232 return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW,
17233 TemplateName(Template));
17236 template<typename Derived>
17237 TemplateName
17238 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17239 SourceLocation TemplateKWLoc,
17240 const IdentifierInfo &Name,
17241 SourceLocation NameLoc,
17242 QualType ObjectType,
17243 NamedDecl *FirstQualifierInScope,
17244 bool AllowInjectedClassName) {
17245 UnqualifiedId TemplateName;
17246 TemplateName.setIdentifier(&Name, NameLoc);
17247 Sema::TemplateTy Template;
17248 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
17249 TemplateName, ParsedType::make(ObjectType),
17250 /*EnteringContext=*/false, Template,
17251 AllowInjectedClassName);
17252 return Template.get();
17255 template<typename Derived>
17256 TemplateName
17257 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17258 SourceLocation TemplateKWLoc,
17259 OverloadedOperatorKind Operator,
17260 SourceLocation NameLoc,
17261 QualType ObjectType,
17262 bool AllowInjectedClassName) {
17263 UnqualifiedId Name;
17264 // FIXME: Bogus location information.
17265 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
17266 Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);
17267 Sema::TemplateTy Template;
17268 getSema().ActOnTemplateName(
17269 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(ObjectType),
17270 /*EnteringContext=*/false, Template, AllowInjectedClassName);
17271 return Template.get();
17274 template <typename Derived>
17275 ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
17276 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
17277 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
17278 Expr *Second) {
17279 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
17281 if (First->getObjectKind() == OK_ObjCProperty) {
17282 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
17283 if (BinaryOperator::isAssignmentOp(Opc))
17284 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/nullptr, OpLoc,
17285 Opc, First, Second);
17286 ExprResult Result = SemaRef.CheckPlaceholderExpr(First);
17287 if (Result.isInvalid())
17288 return ExprError();
17289 First = Result.get();
17292 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
17293 ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
17294 if (Result.isInvalid())
17295 return ExprError();
17296 Second = Result.get();
17299 // Determine whether this should be a builtin operation.
17300 if (Op == OO_Subscript) {
17301 if (!First->getType()->isOverloadableType() &&
17302 !Second->getType()->isOverloadableType())
17303 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
17304 OpLoc);
17305 } else if (Op == OO_Arrow) {
17306 // It is possible that the type refers to a RecoveryExpr created earlier
17307 // in the tree transformation.
17308 if (First->getType()->isDependentType())
17309 return ExprError();
17310 // -> is never a builtin operation.
17311 return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);
17312 } else if (Second == nullptr || isPostIncDec) {
17313 if (!First->getType()->isOverloadableType() ||
17314 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
17315 // The argument is not of overloadable type, or this is an expression
17316 // of the form &Class::member, so try to create a built-in unary
17317 // operation.
17318 UnaryOperatorKind Opc
17319 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
17321 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
17323 } else {
17324 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
17325 !First->getType()->isOverloadableType() &&
17326 !Second->getType()->isOverloadableType()) {
17327 // Neither of the arguments is type-dependent or has an overloadable
17328 // type, so try to create a built-in binary operation.
17329 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
17330 ExprResult Result
17331 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
17332 if (Result.isInvalid())
17333 return ExprError();
17335 return Result;
17339 // Create the overloaded operator invocation for unary operators.
17340 if (!Second || isPostIncDec) {
17341 UnaryOperatorKind Opc
17342 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
17343 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First,
17344 RequiresADL);
17347 // Create the overloaded operator invocation for binary operators.
17348 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
17349 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions,
17350 First, Second, RequiresADL);
17351 if (Result.isInvalid())
17352 return ExprError();
17354 return Result;
17357 template<typename Derived>
17358 ExprResult
17359 TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
17360 SourceLocation OperatorLoc,
17361 bool isArrow,
17362 CXXScopeSpec &SS,
17363 TypeSourceInfo *ScopeType,
17364 SourceLocation CCLoc,
17365 SourceLocation TildeLoc,
17366 PseudoDestructorTypeStorage Destroyed) {
17367 QualType BaseType = Base->getType();
17368 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
17369 (!isArrow && !BaseType->getAs<RecordType>()) ||
17370 (isArrow && BaseType->getAs<PointerType>() &&
17371 !BaseType->castAs<PointerType>()->getPointeeType()
17372 ->template getAs<RecordType>())){
17373 // This pseudo-destructor expression is still a pseudo-destructor.
17374 return SemaRef.BuildPseudoDestructorExpr(
17375 Base, OperatorLoc, isArrow ? tok::arrow : tok::period, SS, ScopeType,
17376 CCLoc, TildeLoc, Destroyed);
17379 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
17380 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
17381 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
17382 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
17383 NameInfo.setNamedTypeInfo(DestroyedType);
17385 // The scope type is now known to be a valid nested name specifier
17386 // component. Tack it on to the end of the nested name specifier.
17387 if (ScopeType) {
17388 if (!ScopeType->getType()->getAs<TagType>()) {
17389 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
17390 diag::err_expected_class_or_namespace)
17391 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
17392 return ExprError();
17394 SS.Extend(SemaRef.Context, SourceLocation(), ScopeType->getTypeLoc(),
17395 CCLoc);
17398 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
17399 return getSema().BuildMemberReferenceExpr(Base, BaseType,
17400 OperatorLoc, isArrow,
17401 SS, TemplateKWLoc,
17402 /*FIXME: FirstQualifier*/ nullptr,
17403 NameInfo,
17404 /*TemplateArgs*/ nullptr,
17405 /*S*/nullptr);
17408 template<typename Derived>
17409 StmtResult
17410 TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
17411 SourceLocation Loc = S->getBeginLoc();
17412 CapturedDecl *CD = S->getCapturedDecl();
17413 unsigned NumParams = CD->getNumParams();
17414 unsigned ContextParamPos = CD->getContextParamPosition();
17415 SmallVector<Sema::CapturedParamNameType, 4> Params;
17416 for (unsigned I = 0; I < NumParams; ++I) {
17417 if (I != ContextParamPos) {
17418 Params.push_back(
17419 std::make_pair(
17420 CD->getParam(I)->getName(),
17421 getDerived().TransformType(CD->getParam(I)->getType())));
17422 } else {
17423 Params.push_back(std::make_pair(StringRef(), QualType()));
17426 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
17427 S->getCapturedRegionKind(), Params);
17428 StmtResult Body;
17430 Sema::CompoundScopeRAII CompoundScope(getSema());
17431 Body = getDerived().TransformStmt(S->getCapturedStmt());
17434 if (Body.isInvalid()) {
17435 getSema().ActOnCapturedRegionError();
17436 return StmtError();
17439 return getSema().ActOnCapturedRegionEnd(Body.get());
17442 template <typename Derived>
17443 StmtResult
17444 TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
17445 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
17446 // function definition or instantiation of a function template specialization
17447 // and will therefore never appear in a dependent context.
17448 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
17449 "context");
17452 template <typename Derived>
17453 ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
17454 // We can transform the base expression and allow argument resolution to fill
17455 // in the rest.
17456 return getDerived().TransformExpr(E->getArgLValue());
17459 } // end namespace clang
17461 #endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H