[OpenACC] Enable 'attach' clause for combined constructs
[llvm-project.git] / clang / lib / Sema / TreeTransform.h
blob3a8f2d95f329b85968983b2d1970d4ec3644b2d3
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/Basic/DiagnosticParse.h"
33 #include "clang/Basic/OpenMPKinds.h"
34 #include "clang/Sema/Designator.h"
35 #include "clang/Sema/EnterExpressionEvaluationContext.h"
36 #include "clang/Sema/Lookup.h"
37 #include "clang/Sema/Ownership.h"
38 #include "clang/Sema/ParsedTemplate.h"
39 #include "clang/Sema/ScopeInfo.h"
40 #include "clang/Sema/SemaDiagnostic.h"
41 #include "clang/Sema/SemaInternal.h"
42 #include "clang/Sema/SemaObjC.h"
43 #include "clang/Sema/SemaOpenACC.h"
44 #include "clang/Sema/SemaOpenMP.h"
45 #include "clang/Sema/SemaPseudoObject.h"
46 #include "clang/Sema/SemaSYCL.h"
47 #include "llvm/ADT/ArrayRef.h"
48 #include "llvm/Support/ErrorHandling.h"
49 #include <algorithm>
50 #include <optional>
52 using namespace llvm::omp;
54 namespace clang {
55 using namespace sema;
57 /// A semantic tree transformation that allows one to transform one
58 /// abstract syntax tree into another.
59 ///
60 /// A new tree transformation is defined by creating a new subclass \c X of
61 /// \c TreeTransform<X> and then overriding certain operations to provide
62 /// behavior specific to that transformation. For example, template
63 /// instantiation is implemented as a tree transformation where the
64 /// transformation of TemplateTypeParmType nodes involves substituting the
65 /// template arguments for their corresponding template parameters; a similar
66 /// transformation is performed for non-type template parameters and
67 /// template template parameters.
68 ///
69 /// This tree-transformation template uses static polymorphism to allow
70 /// subclasses to customize any of its operations. Thus, a subclass can
71 /// override any of the transformation or rebuild operators by providing an
72 /// operation with the same signature as the default implementation. The
73 /// overriding function should not be virtual.
74 ///
75 /// Semantic tree transformations are split into two stages, either of which
76 /// can be replaced by a subclass. The "transform" step transforms an AST node
77 /// or the parts of an AST node using the various transformation functions,
78 /// then passes the pieces on to the "rebuild" step, which constructs a new AST
79 /// node of the appropriate kind from the pieces. The default transformation
80 /// routines recursively transform the operands to composite AST nodes (e.g.,
81 /// the pointee type of a PointerType node) and, if any of those operand nodes
82 /// were changed by the transformation, invokes the rebuild operation to create
83 /// a new AST node.
84 ///
85 /// Subclasses can customize the transformation at various levels. The
86 /// most coarse-grained transformations involve replacing TransformType(),
87 /// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
88 /// TransformTemplateName(), or TransformTemplateArgument() with entirely
89 /// new implementations.
90 ///
91 /// For more fine-grained transformations, subclasses can replace any of the
92 /// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
93 /// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
94 /// replacing TransformTemplateTypeParmType() allows template instantiation
95 /// to substitute template arguments for their corresponding template
96 /// parameters. Additionally, subclasses can override the \c RebuildXXX
97 /// functions to control how AST nodes are rebuilt when their operands change.
98 /// By default, \c TreeTransform will invoke semantic analysis to rebuild
99 /// AST nodes. However, certain other tree transformations (e.g, cloning) may
100 /// be able to use more efficient rebuild steps.
102 /// There are a handful of other functions that can be overridden, allowing one
103 /// to avoid traversing nodes that don't need any transformation
104 /// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
105 /// operands have not changed (\c AlwaysRebuild()), and customize the
106 /// default locations and entity names used for type-checking
107 /// (\c getBaseLocation(), \c getBaseEntity()).
108 template<typename Derived>
109 class TreeTransform {
110 /// Private RAII object that helps us forget and then re-remember
111 /// the template argument corresponding to a partially-substituted parameter
112 /// pack.
113 class ForgetPartiallySubstitutedPackRAII {
114 Derived &Self;
115 TemplateArgument Old;
116 // Set the pack expansion index to -1 to avoid pack substitution and
117 // indicate that parameter packs should be instantiated as themselves.
118 Sema::ArgumentPackSubstitutionIndexRAII ResetPackSubstIndex;
120 public:
121 ForgetPartiallySubstitutedPackRAII(Derived &Self)
122 : Self(Self), ResetPackSubstIndex(Self.getSema(), -1) {
123 Old = Self.ForgetPartiallySubstitutedPack();
126 ~ForgetPartiallySubstitutedPackRAII() {
127 Self.RememberPartiallySubstitutedPack(Old);
131 protected:
132 Sema &SemaRef;
134 /// The set of local declarations that have been transformed, for
135 /// cases where we are forced to build new declarations within the transformer
136 /// rather than in the subclass (e.g., lambda closure types).
137 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
139 public:
140 /// Initializes a new tree transformer.
141 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
143 /// Retrieves a reference to the derived class.
144 Derived &getDerived() { return static_cast<Derived&>(*this); }
146 /// Retrieves a reference to the derived class.
147 const Derived &getDerived() const {
148 return static_cast<const Derived&>(*this);
151 static inline ExprResult Owned(Expr *E) { return E; }
152 static inline StmtResult Owned(Stmt *S) { return S; }
154 /// Retrieves a reference to the semantic analysis object used for
155 /// this tree transform.
156 Sema &getSema() const { return SemaRef; }
158 /// Whether the transformation should always rebuild AST nodes, even
159 /// if none of the children have changed.
161 /// Subclasses may override this function to specify when the transformation
162 /// should rebuild all AST nodes.
164 /// We must always rebuild all AST nodes when performing variadic template
165 /// pack expansion, in order to avoid violating the AST invariant that each
166 /// statement node appears at most once in its containing declaration.
167 bool AlwaysRebuild() { return SemaRef.ArgumentPackSubstitutionIndex != -1; }
169 /// Whether the transformation is forming an expression or statement that
170 /// replaces the original. In this case, we'll reuse mangling numbers from
171 /// existing lambdas.
172 bool ReplacingOriginal() { return false; }
174 /// Wether CXXConstructExpr can be skipped when they are implicit.
175 /// They will be reconstructed when used if needed.
176 /// This is useful when the user that cause rebuilding of the
177 /// CXXConstructExpr is outside of the expression at which the TreeTransform
178 /// started.
179 bool AllowSkippingCXXConstructExpr() { return true; }
181 /// Returns the location of the entity being transformed, if that
182 /// information was not available elsewhere in the AST.
184 /// By default, returns no source-location information. Subclasses can
185 /// provide an alternative implementation that provides better location
186 /// information.
187 SourceLocation getBaseLocation() { return SourceLocation(); }
189 /// Returns the name of the entity being transformed, if that
190 /// information was not available elsewhere in the AST.
192 /// By default, returns an empty name. Subclasses can provide an alternative
193 /// implementation with a more precise name.
194 DeclarationName getBaseEntity() { return DeclarationName(); }
196 /// Sets the "base" location and entity when that
197 /// information is known based on another transformation.
199 /// By default, the source location and entity are ignored. Subclasses can
200 /// override this function to provide a customized implementation.
201 void setBase(SourceLocation Loc, DeclarationName Entity) { }
203 /// RAII object that temporarily sets the base location and entity
204 /// used for reporting diagnostics in types.
205 class TemporaryBase {
206 TreeTransform &Self;
207 SourceLocation OldLocation;
208 DeclarationName OldEntity;
210 public:
211 TemporaryBase(TreeTransform &Self, SourceLocation Location,
212 DeclarationName Entity) : Self(Self) {
213 OldLocation = Self.getDerived().getBaseLocation();
214 OldEntity = Self.getDerived().getBaseEntity();
216 if (Location.isValid())
217 Self.getDerived().setBase(Location, Entity);
220 ~TemporaryBase() {
221 Self.getDerived().setBase(OldLocation, OldEntity);
225 /// Determine whether the given type \p T has already been
226 /// transformed.
228 /// Subclasses can provide an alternative implementation of this routine
229 /// to short-circuit evaluation when it is known that a given type will
230 /// not change. For example, template instantiation need not traverse
231 /// non-dependent types.
232 bool AlreadyTransformed(QualType T) {
233 return T.isNull();
236 /// Transform a template parameter depth level.
238 /// During a transformation that transforms template parameters, this maps
239 /// an old template parameter depth to a new depth.
240 unsigned TransformTemplateDepth(unsigned Depth) {
241 return Depth;
244 /// Determine whether the given call argument should be dropped, e.g.,
245 /// because it is a default argument.
247 /// Subclasses can provide an alternative implementation of this routine to
248 /// determine which kinds of call arguments get dropped. By default,
249 /// CXXDefaultArgument nodes are dropped (prior to transformation).
250 bool DropCallArgument(Expr *E) {
251 return E->isDefaultArgument();
254 /// Determine whether we should expand a pack expansion with the
255 /// given set of parameter packs into separate arguments by repeatedly
256 /// transforming the pattern.
258 /// By default, the transformer never tries to expand pack expansions.
259 /// Subclasses can override this routine to provide different behavior.
261 /// \param EllipsisLoc The location of the ellipsis that identifies the
262 /// pack expansion.
264 /// \param PatternRange The source range that covers the entire pattern of
265 /// the pack expansion.
267 /// \param Unexpanded The set of unexpanded parameter packs within the
268 /// pattern.
270 /// \param ShouldExpand Will be set to \c true if the transformer should
271 /// expand the corresponding pack expansions into separate arguments. When
272 /// set, \c NumExpansions must also be set.
274 /// \param RetainExpansion Whether the caller should add an unexpanded
275 /// pack expansion after all of the expanded arguments. This is used
276 /// when extending explicitly-specified template argument packs per
277 /// C++0x [temp.arg.explicit]p9.
279 /// \param NumExpansions The number of separate arguments that will be in
280 /// the expanded form of the corresponding pack expansion. This is both an
281 /// input and an output parameter, which can be set by the caller if the
282 /// number of expansions is known a priori (e.g., due to a prior substitution)
283 /// and will be set by the callee when the number of expansions is known.
284 /// The callee must set this value when \c ShouldExpand is \c true; it may
285 /// set this value in other cases.
287 /// \returns true if an error occurred (e.g., because the parameter packs
288 /// are to be instantiated with arguments of different lengths), false
289 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
290 /// must be set.
291 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
292 SourceRange PatternRange,
293 ArrayRef<UnexpandedParameterPack> Unexpanded,
294 bool &ShouldExpand, bool &RetainExpansion,
295 std::optional<unsigned> &NumExpansions) {
296 ShouldExpand = false;
297 return false;
300 /// "Forget" about the partially-substituted pack template argument,
301 /// when performing an instantiation that must preserve the parameter pack
302 /// use.
304 /// This routine is meant to be overridden by the template instantiator.
305 TemplateArgument ForgetPartiallySubstitutedPack() {
306 return TemplateArgument();
309 /// "Remember" the partially-substituted pack template argument
310 /// after performing an instantiation that must preserve the parameter pack
311 /// use.
313 /// This routine is meant to be overridden by the template instantiator.
314 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
316 /// Note to the derived class when a function parameter pack is
317 /// being expanded.
318 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
320 /// Transforms the given type into another type.
322 /// By default, this routine transforms a type by creating a
323 /// TypeSourceInfo for it and delegating to the appropriate
324 /// function. This is expensive, but we don't mind, because
325 /// this method is deprecated anyway; all users should be
326 /// switched to storing TypeSourceInfos.
328 /// \returns the transformed type.
329 QualType TransformType(QualType T);
331 /// Transforms the given type-with-location into a new
332 /// type-with-location.
334 /// By default, this routine transforms a type by delegating to the
335 /// appropriate TransformXXXType to build a new type. Subclasses
336 /// may override this function (to take over all type
337 /// transformations) or some set of the TransformXXXType functions
338 /// to alter the transformation.
339 TypeSourceInfo *TransformType(TypeSourceInfo *DI);
341 /// Transform the given type-with-location into a new
342 /// type, collecting location information in the given builder
343 /// as necessary.
345 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
347 /// Transform a type that is permitted to produce a
348 /// DeducedTemplateSpecializationType.
350 /// This is used in the (relatively rare) contexts where it is acceptable
351 /// for transformation to produce a class template type with deduced
352 /// template arguments.
353 /// @{
354 QualType TransformTypeWithDeducedTST(QualType T);
355 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *DI);
356 /// @}
358 /// The reason why the value of a statement is not discarded, if any.
359 enum StmtDiscardKind {
360 SDK_Discarded,
361 SDK_NotDiscarded,
362 SDK_StmtExprResult,
365 /// Transform the given statement.
367 /// By default, this routine transforms a statement by delegating to the
368 /// appropriate TransformXXXStmt function to transform a specific kind of
369 /// statement or the TransformExpr() function to transform an expression.
370 /// Subclasses may override this function to transform statements using some
371 /// other mechanism.
373 /// \returns the transformed statement.
374 StmtResult TransformStmt(Stmt *S, StmtDiscardKind SDK = SDK_Discarded);
376 /// Transform the given statement.
378 /// By default, this routine transforms a statement by delegating to the
379 /// appropriate TransformOMPXXXClause function to transform a specific kind
380 /// of clause. Subclasses may override this function to transform statements
381 /// using some other mechanism.
383 /// \returns the transformed OpenMP clause.
384 OMPClause *TransformOMPClause(OMPClause *S);
386 /// Transform the given attribute.
388 /// By default, this routine transforms a statement by delegating to the
389 /// appropriate TransformXXXAttr function to transform a specific kind
390 /// of attribute. Subclasses may override this function to transform
391 /// attributed statements/types using some other mechanism.
393 /// \returns the transformed attribute
394 const Attr *TransformAttr(const Attr *S);
396 // Transform the given statement attribute.
398 // Delegates to the appropriate TransformXXXAttr function to transform a
399 // specific kind of statement attribute. Unlike the non-statement taking
400 // version of this, this implements all attributes, not just pragmas.
401 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
402 const Attr *A);
404 // Transform the specified attribute.
406 // Subclasses should override the transformation of attributes with a pragma
407 // spelling to transform expressions stored within the attribute.
409 // \returns the transformed attribute.
410 #define ATTR(X) \
411 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
412 #include "clang/Basic/AttrList.inc"
414 // Transform the specified attribute.
416 // Subclasses should override the transformation of attributes to do
417 // transformation and checking of statement attributes. By default, this
418 // delegates to the non-statement taking version.
420 // \returns the transformed attribute.
421 #define ATTR(X) \
422 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
423 const X##Attr *A) { \
424 return getDerived().Transform##X##Attr(A); \
426 #include "clang/Basic/AttrList.inc"
428 /// Transform the given expression.
430 /// By default, this routine transforms an expression by delegating to the
431 /// appropriate TransformXXXExpr function to build a new expression.
432 /// Subclasses may override this function to transform expressions using some
433 /// other mechanism.
435 /// \returns the transformed expression.
436 ExprResult TransformExpr(Expr *E);
438 /// Transform the given initializer.
440 /// By default, this routine transforms an initializer by stripping off the
441 /// semantic nodes added by initialization, then passing the result to
442 /// TransformExpr or TransformExprs.
444 /// \returns the transformed initializer.
445 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
447 /// Transform the given list of expressions.
449 /// This routine transforms a list of expressions by invoking
450 /// \c TransformExpr() for each subexpression. However, it also provides
451 /// support for variadic templates by expanding any pack expansions (if the
452 /// derived class permits such expansion) along the way. When pack expansions
453 /// are present, the number of outputs may not equal the number of inputs.
455 /// \param Inputs The set of expressions to be transformed.
457 /// \param NumInputs The number of expressions in \c Inputs.
459 /// \param IsCall If \c true, then this transform is being performed on
460 /// function-call arguments, and any arguments that should be dropped, will
461 /// be.
463 /// \param Outputs The transformed input expressions will be added to this
464 /// vector.
466 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
467 /// due to transformation.
469 /// \returns true if an error occurred, false otherwise.
470 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
471 SmallVectorImpl<Expr *> &Outputs,
472 bool *ArgChanged = nullptr);
474 /// Transform the given declaration, which is referenced from a type
475 /// or expression.
477 /// By default, acts as the identity function on declarations, unless the
478 /// transformer has had to transform the declaration itself. Subclasses
479 /// may override this function to provide alternate behavior.
480 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
481 llvm::DenseMap<Decl *, Decl *>::iterator Known
482 = TransformedLocalDecls.find(D);
483 if (Known != TransformedLocalDecls.end())
484 return Known->second;
486 return D;
489 /// Transform the specified condition.
491 /// By default, this transforms the variable and expression and rebuilds
492 /// the condition.
493 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
494 Expr *Expr,
495 Sema::ConditionKind Kind);
497 /// Transform the attributes associated with the given declaration and
498 /// place them on the new declaration.
500 /// By default, this operation does nothing. Subclasses may override this
501 /// behavior to transform attributes.
502 void transformAttrs(Decl *Old, Decl *New) { }
504 /// Note that a local declaration has been transformed by this
505 /// transformer.
507 /// Local declarations are typically transformed via a call to
508 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
509 /// the transformer itself has to transform the declarations. This routine
510 /// can be overridden by a subclass that keeps track of such mappings.
511 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
512 assert(New.size() == 1 &&
513 "must override transformedLocalDecl if performing pack expansion");
514 TransformedLocalDecls[Old] = New.front();
517 /// Transform the definition of the given declaration.
519 /// By default, invokes TransformDecl() to transform the declaration.
520 /// Subclasses may override this function to provide alternate behavior.
521 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
522 return getDerived().TransformDecl(Loc, D);
525 /// Transform the given declaration, which was the first part of a
526 /// nested-name-specifier in a member access expression.
528 /// This specific declaration transformation only applies to the first
529 /// identifier in a nested-name-specifier of a member access expression, e.g.,
530 /// the \c T in \c x->T::member
532 /// By default, invokes TransformDecl() to transform the declaration.
533 /// Subclasses may override this function to provide alternate behavior.
534 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
535 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
538 /// Transform the set of declarations in an OverloadExpr.
539 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
540 LookupResult &R);
542 /// Transform the given nested-name-specifier with source-location
543 /// information.
545 /// By default, transforms all of the types and declarations within the
546 /// nested-name-specifier. Subclasses may override this function to provide
547 /// alternate behavior.
548 NestedNameSpecifierLoc
549 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
550 QualType ObjectType = QualType(),
551 NamedDecl *FirstQualifierInScope = nullptr);
553 /// Transform the given declaration name.
555 /// By default, transforms the types of conversion function, constructor,
556 /// and destructor names and then (if needed) rebuilds the declaration name.
557 /// Identifiers and selectors are returned unmodified. Subclasses may
558 /// override this function to provide alternate behavior.
559 DeclarationNameInfo
560 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
562 bool TransformRequiresExprRequirements(
563 ArrayRef<concepts::Requirement *> Reqs,
564 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
565 concepts::TypeRequirement *
566 TransformTypeRequirement(concepts::TypeRequirement *Req);
567 concepts::ExprRequirement *
568 TransformExprRequirement(concepts::ExprRequirement *Req);
569 concepts::NestedRequirement *
570 TransformNestedRequirement(concepts::NestedRequirement *Req);
572 /// Transform the given template name.
574 /// \param SS The nested-name-specifier that qualifies the template
575 /// name. This nested-name-specifier must already have been transformed.
577 /// \param Name The template name to transform.
579 /// \param NameLoc The source location of the template name.
581 /// \param ObjectType If we're translating a template name within a member
582 /// access expression, this is the type of the object whose member template
583 /// is being referenced.
585 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
586 /// also refers to a name within the current (lexical) scope, this is the
587 /// declaration it refers to.
589 /// By default, transforms the template name by transforming the declarations
590 /// and nested-name-specifiers that occur within the template name.
591 /// Subclasses may override this function to provide alternate behavior.
592 TemplateName
593 TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
594 SourceLocation NameLoc,
595 QualType ObjectType = QualType(),
596 NamedDecl *FirstQualifierInScope = nullptr,
597 bool AllowInjectedClassName = false);
599 /// Transform the given template argument.
601 /// By default, this operation transforms the type, expression, or
602 /// declaration stored within the template argument and constructs a
603 /// new template argument from the transformed result. Subclasses may
604 /// override this function to provide alternate behavior.
606 /// Returns true if there was an error.
607 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
608 TemplateArgumentLoc &Output,
609 bool Uneval = false);
611 /// Transform the given set of template arguments.
613 /// By default, this operation transforms all of the template arguments
614 /// in the input set using \c TransformTemplateArgument(), and appends
615 /// the transformed arguments to the output list.
617 /// Note that this overload of \c TransformTemplateArguments() is merely
618 /// a convenience function. Subclasses that wish to override this behavior
619 /// should override the iterator-based member template version.
621 /// \param Inputs The set of template arguments to be transformed.
623 /// \param NumInputs The number of template arguments in \p Inputs.
625 /// \param Outputs The set of transformed template arguments output by this
626 /// routine.
628 /// Returns true if an error occurred.
629 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
630 unsigned NumInputs,
631 TemplateArgumentListInfo &Outputs,
632 bool Uneval = false) {
633 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
634 Uneval);
637 /// Transform the given set of template arguments.
639 /// By default, this operation transforms all of the template arguments
640 /// in the input set using \c TransformTemplateArgument(), and appends
641 /// the transformed arguments to the output list.
643 /// \param First An iterator to the first template argument.
645 /// \param Last An iterator one step past the last template argument.
647 /// \param Outputs The set of transformed template arguments output by this
648 /// routine.
650 /// Returns true if an error occurred.
651 template<typename InputIterator>
652 bool TransformTemplateArguments(InputIterator First,
653 InputIterator Last,
654 TemplateArgumentListInfo &Outputs,
655 bool Uneval = false);
657 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
658 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
659 TemplateArgumentLoc &ArgLoc);
661 /// Fakes up a TypeSourceInfo for a type.
662 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
663 return SemaRef.Context.getTrivialTypeSourceInfo(T,
664 getDerived().getBaseLocation());
667 #define ABSTRACT_TYPELOC(CLASS, PARENT)
668 #define TYPELOC(CLASS, PARENT) \
669 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
670 #include "clang/AST/TypeLocNodes.def"
672 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
673 TemplateTypeParmTypeLoc TL,
674 bool SuppressObjCLifetime);
675 QualType
676 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
677 SubstTemplateTypeParmPackTypeLoc TL,
678 bool SuppressObjCLifetime);
680 template<typename Fn>
681 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
682 FunctionProtoTypeLoc TL,
683 CXXRecordDecl *ThisContext,
684 Qualifiers ThisTypeQuals,
685 Fn TransformExceptionSpec);
687 bool TransformExceptionSpec(SourceLocation Loc,
688 FunctionProtoType::ExceptionSpecInfo &ESI,
689 SmallVectorImpl<QualType> &Exceptions,
690 bool &Changed);
692 StmtResult TransformSEHHandler(Stmt *Handler);
694 QualType
695 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
696 TemplateSpecializationTypeLoc TL,
697 TemplateName Template);
699 QualType
700 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
701 DependentTemplateSpecializationTypeLoc TL,
702 TemplateName Template,
703 CXXScopeSpec &SS);
705 QualType TransformDependentTemplateSpecializationType(
706 TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
707 NestedNameSpecifierLoc QualifierLoc);
709 /// Transforms the parameters of a function type into the
710 /// given vectors.
712 /// The result vectors should be kept in sync; null entries in the
713 /// variables vector are acceptable.
715 /// LastParamTransformed, if non-null, will be set to the index of the last
716 /// parameter on which transfromation was started. In the event of an error,
717 /// this will contain the parameter which failed to instantiate.
719 /// Return true on error.
720 bool TransformFunctionTypeParams(
721 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
722 const QualType *ParamTypes,
723 const FunctionProtoType::ExtParameterInfo *ParamInfos,
724 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
725 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
727 bool TransformFunctionTypeParams(
728 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
729 const QualType *ParamTypes,
730 const FunctionProtoType::ExtParameterInfo *ParamInfos,
731 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
732 Sema::ExtParameterInfoBuilder &PInfos) {
733 return getDerived().TransformFunctionTypeParams(
734 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
737 /// Transforms the parameters of a requires expresison into the given vectors.
739 /// The result vectors should be kept in sync; null entries in the
740 /// variables vector are acceptable.
742 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
743 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
744 /// which are cases where transformation shouldn't continue.
745 ExprResult TransformRequiresTypeParams(
746 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
747 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
748 SmallVectorImpl<QualType> &PTypes,
749 SmallVectorImpl<ParmVarDecl *> &TransParams,
750 Sema::ExtParameterInfoBuilder &PInfos) {
751 if (getDerived().TransformFunctionTypeParams(
752 KWLoc, Params, /*ParamTypes=*/nullptr,
753 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
754 return ExprError();
756 return ExprResult{};
759 /// Transforms a single function-type parameter. Return null
760 /// on error.
762 /// \param indexAdjustment - A number to add to the parameter's
763 /// scope index; can be negative
764 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
765 int indexAdjustment,
766 std::optional<unsigned> NumExpansions,
767 bool ExpectParameterPack);
769 /// Transform the body of a lambda-expression.
770 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
771 /// Alternative implementation of TransformLambdaBody that skips transforming
772 /// the body.
773 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
775 CXXRecordDecl::LambdaDependencyKind
776 ComputeLambdaDependency(LambdaScopeInfo *LSI) {
777 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
778 LSI->Lambda->getLambdaDependencyKind());
781 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
783 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
784 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
786 TemplateParameterList *TransformTemplateParameterList(
787 TemplateParameterList *TPL) {
788 return TPL;
791 ExprResult TransformAddressOfOperand(Expr *E);
793 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
794 bool IsAddressOfOperand,
795 TypeSourceInfo **RecoveryTSI);
797 ExprResult TransformParenDependentScopeDeclRefExpr(
798 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
799 TypeSourceInfo **RecoveryTSI);
801 ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,
802 bool IsAddressOfOperand);
804 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
806 StmtResult TransformOMPInformationalDirective(OMPExecutableDirective *S);
808 // FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
809 // amount of stack usage with clang.
810 #define STMT(Node, Parent) \
811 LLVM_ATTRIBUTE_NOINLINE \
812 StmtResult Transform##Node(Node *S);
813 #define VALUESTMT(Node, Parent) \
814 LLVM_ATTRIBUTE_NOINLINE \
815 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
816 #define EXPR(Node, Parent) \
817 LLVM_ATTRIBUTE_NOINLINE \
818 ExprResult Transform##Node(Node *E);
819 #define ABSTRACT_STMT(Stmt)
820 #include "clang/AST/StmtNodes.inc"
822 #define GEN_CLANG_CLAUSE_CLASS
823 #define CLAUSE_CLASS(Enum, Str, Class) \
824 LLVM_ATTRIBUTE_NOINLINE \
825 OMPClause *Transform##Class(Class *S);
826 #include "llvm/Frontend/OpenMP/OMP.inc"
828 /// Build a new qualified type given its unqualified type and type location.
830 /// By default, this routine adds type qualifiers only to types that can
831 /// have qualifiers, and silently suppresses those qualifiers that are not
832 /// permitted. Subclasses may override this routine to provide different
833 /// behavior.
834 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
836 /// Build a new pointer type given its pointee type.
838 /// By default, performs semantic analysis when building the pointer type.
839 /// Subclasses may override this routine to provide different behavior.
840 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
842 /// Build a new block pointer type given its pointee type.
844 /// By default, performs semantic analysis when building the block pointer
845 /// type. Subclasses may override this routine to provide different behavior.
846 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
848 /// Build a new reference type given the type it references.
850 /// By default, performs semantic analysis when building the
851 /// reference type. Subclasses may override this routine to provide
852 /// different behavior.
854 /// \param LValue whether the type was written with an lvalue sigil
855 /// or an rvalue sigil.
856 QualType RebuildReferenceType(QualType ReferentType,
857 bool LValue,
858 SourceLocation Sigil);
860 /// Build a new member pointer type given the pointee type and the
861 /// class type it refers into.
863 /// By default, performs semantic analysis when building the member pointer
864 /// type. Subclasses may override this routine to provide different behavior.
865 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
866 SourceLocation Sigil);
868 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
869 SourceLocation ProtocolLAngleLoc,
870 ArrayRef<ObjCProtocolDecl *> Protocols,
871 ArrayRef<SourceLocation> ProtocolLocs,
872 SourceLocation ProtocolRAngleLoc);
874 /// Build an Objective-C object type.
876 /// By default, performs semantic analysis when building the object type.
877 /// Subclasses may override this routine to provide different behavior.
878 QualType RebuildObjCObjectType(QualType BaseType,
879 SourceLocation Loc,
880 SourceLocation TypeArgsLAngleLoc,
881 ArrayRef<TypeSourceInfo *> TypeArgs,
882 SourceLocation TypeArgsRAngleLoc,
883 SourceLocation ProtocolLAngleLoc,
884 ArrayRef<ObjCProtocolDecl *> Protocols,
885 ArrayRef<SourceLocation> ProtocolLocs,
886 SourceLocation ProtocolRAngleLoc);
888 /// Build a new Objective-C object pointer type given the pointee type.
890 /// By default, directly builds the pointer type, with no additional semantic
891 /// analysis.
892 QualType RebuildObjCObjectPointerType(QualType PointeeType,
893 SourceLocation Star);
895 /// Build a new array type given the element type, size
896 /// modifier, size of the array (if known), size expression, and index type
897 /// qualifiers.
899 /// By default, performs semantic analysis when building the array type.
900 /// Subclasses may override this routine to provide different behavior.
901 /// Also by default, all of the other Rebuild*Array
902 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
903 const llvm::APInt *Size, Expr *SizeExpr,
904 unsigned IndexTypeQuals, SourceRange BracketsRange);
906 /// Build a new constant array type given the element type, size
907 /// modifier, (known) size of the array, and index type qualifiers.
909 /// By default, performs semantic analysis when building the array type.
910 /// Subclasses may override this routine to provide different behavior.
911 QualType RebuildConstantArrayType(QualType ElementType,
912 ArraySizeModifier SizeMod,
913 const llvm::APInt &Size, Expr *SizeExpr,
914 unsigned IndexTypeQuals,
915 SourceRange BracketsRange);
917 /// Build a new incomplete array type given the element type, size
918 /// modifier, and index type qualifiers.
920 /// By default, performs semantic analysis when building the array type.
921 /// Subclasses may override this routine to provide different behavior.
922 QualType RebuildIncompleteArrayType(QualType ElementType,
923 ArraySizeModifier SizeMod,
924 unsigned IndexTypeQuals,
925 SourceRange BracketsRange);
927 /// Build a new variable-length array type given the element type,
928 /// size modifier, size expression, and index type qualifiers.
930 /// By default, performs semantic analysis when building the array type.
931 /// Subclasses may override this routine to provide different behavior.
932 QualType RebuildVariableArrayType(QualType ElementType,
933 ArraySizeModifier SizeMod, Expr *SizeExpr,
934 unsigned IndexTypeQuals,
935 SourceRange BracketsRange);
937 /// Build a new dependent-sized array type given the element type,
938 /// size modifier, size expression, and index type qualifiers.
940 /// By default, performs semantic analysis when building the array type.
941 /// Subclasses may override this routine to provide different behavior.
942 QualType RebuildDependentSizedArrayType(QualType ElementType,
943 ArraySizeModifier SizeMod,
944 Expr *SizeExpr,
945 unsigned IndexTypeQuals,
946 SourceRange BracketsRange);
948 /// Build a new vector type given the element type and
949 /// number of elements.
951 /// By default, performs semantic analysis when building the vector type.
952 /// Subclasses may override this routine to provide different behavior.
953 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
954 VectorKind VecKind);
956 /// Build a new potentially dependently-sized extended vector type
957 /// given the element type and number of elements.
959 /// By default, performs semantic analysis when building the vector type.
960 /// Subclasses may override this routine to provide different behavior.
961 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
962 SourceLocation AttributeLoc, VectorKind);
964 /// Build a new extended vector type given the element type and
965 /// number of elements.
967 /// By default, performs semantic analysis when building the vector type.
968 /// Subclasses may override this routine to provide different behavior.
969 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
970 SourceLocation AttributeLoc);
972 /// Build a new potentially dependently-sized extended vector type
973 /// given the element type and number of elements.
975 /// By default, performs semantic analysis when building the vector type.
976 /// Subclasses may override this routine to provide different behavior.
977 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
978 Expr *SizeExpr,
979 SourceLocation AttributeLoc);
981 /// Build a new matrix type given the element type and dimensions.
982 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
983 unsigned NumColumns);
985 /// Build a new matrix type given the type and dependently-defined
986 /// dimensions.
987 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
988 Expr *ColumnExpr,
989 SourceLocation AttributeLoc);
991 /// Build a new DependentAddressSpaceType or return the pointee
992 /// type variable with the correct address space (retrieved from
993 /// AddrSpaceExpr) applied to it. The former will be returned in cases
994 /// where the address space remains dependent.
996 /// By default, performs semantic analysis when building the type with address
997 /// space applied. Subclasses may override this routine to provide different
998 /// behavior.
999 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
1000 Expr *AddrSpaceExpr,
1001 SourceLocation AttributeLoc);
1003 /// Build a new function type.
1005 /// By default, performs semantic analysis when building the function type.
1006 /// Subclasses may override this routine to provide different behavior.
1007 QualType RebuildFunctionProtoType(QualType T,
1008 MutableArrayRef<QualType> ParamTypes,
1009 const FunctionProtoType::ExtProtoInfo &EPI);
1011 /// Build a new unprototyped function type.
1012 QualType RebuildFunctionNoProtoType(QualType ResultType);
1014 /// Rebuild an unresolved typename type, given the decl that
1015 /// the UnresolvedUsingTypenameDecl was transformed to.
1016 QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D);
1018 /// Build a new type found via an alias.
1019 QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying) {
1020 return SemaRef.Context.getUsingType(Found, Underlying);
1023 /// Build a new typedef type.
1024 QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
1025 return SemaRef.Context.getTypeDeclType(Typedef);
1028 /// Build a new MacroDefined type.
1029 QualType RebuildMacroQualifiedType(QualType T,
1030 const IdentifierInfo *MacroII) {
1031 return SemaRef.Context.getMacroQualifiedType(T, MacroII);
1034 /// Build a new class/struct/union type.
1035 QualType RebuildRecordType(RecordDecl *Record) {
1036 return SemaRef.Context.getTypeDeclType(Record);
1039 /// Build a new Enum type.
1040 QualType RebuildEnumType(EnumDecl *Enum) {
1041 return SemaRef.Context.getTypeDeclType(Enum);
1044 /// Build a new typeof(expr) type.
1046 /// By default, performs semantic analysis when building the typeof type.
1047 /// Subclasses may override this routine to provide different behavior.
1048 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1049 TypeOfKind Kind);
1051 /// Build a new typeof(type) type.
1053 /// By default, builds a new TypeOfType with the given underlying type.
1054 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1056 /// Build a new unary transform type.
1057 QualType RebuildUnaryTransformType(QualType BaseType,
1058 UnaryTransformType::UTTKind UKind,
1059 SourceLocation Loc);
1061 /// Build a new C++11 decltype type.
1063 /// By default, performs semantic analysis when building the decltype type.
1064 /// Subclasses may override this routine to provide different behavior.
1065 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1067 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1068 SourceLocation Loc,
1069 SourceLocation EllipsisLoc,
1070 bool FullySubstituted,
1071 ArrayRef<QualType> Expansions = {});
1073 /// Build a new C++11 auto type.
1075 /// By default, builds a new AutoType with the given deduced type.
1076 QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword,
1077 ConceptDecl *TypeConstraintConcept,
1078 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1079 // Note, IsDependent is always false here: we implicitly convert an 'auto'
1080 // which has been deduced to a dependent type into an undeduced 'auto', so
1081 // that we'll retry deduction after the transformation.
1082 return SemaRef.Context.getAutoType(Deduced, Keyword,
1083 /*IsDependent*/ false, /*IsPack=*/false,
1084 TypeConstraintConcept,
1085 TypeConstraintArgs);
1088 /// By default, builds a new DeducedTemplateSpecializationType with the given
1089 /// deduced type.
1090 QualType RebuildDeducedTemplateSpecializationType(TemplateName Template,
1091 QualType Deduced) {
1092 return SemaRef.Context.getDeducedTemplateSpecializationType(
1093 Template, Deduced, /*IsDependent*/ false);
1096 /// Build a new template specialization type.
1098 /// By default, performs semantic analysis when building the template
1099 /// specialization type. Subclasses may override this routine to provide
1100 /// different behavior.
1101 QualType RebuildTemplateSpecializationType(TemplateName Template,
1102 SourceLocation TemplateLoc,
1103 TemplateArgumentListInfo &Args);
1105 /// Build a new parenthesized type.
1107 /// By default, builds a new ParenType type from the inner type.
1108 /// Subclasses may override this routine to provide different behavior.
1109 QualType RebuildParenType(QualType InnerType) {
1110 return SemaRef.BuildParenType(InnerType);
1113 /// Build a new qualified name type.
1115 /// By default, builds a new ElaboratedType type from the keyword,
1116 /// the nested-name-specifier and the named type.
1117 /// Subclasses may override this routine to provide different behavior.
1118 QualType RebuildElaboratedType(SourceLocation KeywordLoc,
1119 ElaboratedTypeKeyword Keyword,
1120 NestedNameSpecifierLoc QualifierLoc,
1121 QualType Named) {
1122 return SemaRef.Context.getElaboratedType(Keyword,
1123 QualifierLoc.getNestedNameSpecifier(),
1124 Named);
1127 /// Build a new typename type that refers to a template-id.
1129 /// By default, builds a new DependentNameType type from the
1130 /// nested-name-specifier and the given type. Subclasses may override
1131 /// this routine to provide different behavior.
1132 QualType RebuildDependentTemplateSpecializationType(
1133 ElaboratedTypeKeyword Keyword,
1134 NestedNameSpecifierLoc QualifierLoc,
1135 SourceLocation TemplateKWLoc,
1136 const IdentifierInfo *Name,
1137 SourceLocation NameLoc,
1138 TemplateArgumentListInfo &Args,
1139 bool AllowInjectedClassName) {
1140 // Rebuild the template name.
1141 // TODO: avoid TemplateName abstraction
1142 CXXScopeSpec SS;
1143 SS.Adopt(QualifierLoc);
1144 TemplateName InstName = getDerived().RebuildTemplateName(
1145 SS, TemplateKWLoc, *Name, NameLoc, QualType(), nullptr,
1146 AllowInjectedClassName);
1148 if (InstName.isNull())
1149 return QualType();
1151 // If it's still dependent, make a dependent specialization.
1152 if (InstName.getAsDependentTemplateName())
1153 return SemaRef.Context.getDependentTemplateSpecializationType(
1154 Keyword, QualifierLoc.getNestedNameSpecifier(), Name,
1155 Args.arguments());
1157 // Otherwise, make an elaborated type wrapping a non-dependent
1158 // specialization.
1159 QualType T =
1160 getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
1161 if (T.isNull())
1162 return QualType();
1163 return SemaRef.Context.getElaboratedType(
1164 Keyword, QualifierLoc.getNestedNameSpecifier(), T);
1167 /// Build a new typename type that refers to an identifier.
1169 /// By default, performs semantic analysis when building the typename type
1170 /// (or elaborated type). Subclasses may override this routine to provide
1171 /// different behavior.
1172 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1173 SourceLocation KeywordLoc,
1174 NestedNameSpecifierLoc QualifierLoc,
1175 const IdentifierInfo *Id,
1176 SourceLocation IdLoc,
1177 bool DeducedTSTContext) {
1178 CXXScopeSpec SS;
1179 SS.Adopt(QualifierLoc);
1181 if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
1182 // If the name is still dependent, just build a new dependent name type.
1183 if (!SemaRef.computeDeclContext(SS))
1184 return SemaRef.Context.getDependentNameType(Keyword,
1185 QualifierLoc.getNestedNameSpecifier(),
1186 Id);
1189 if (Keyword == ElaboratedTypeKeyword::None ||
1190 Keyword == ElaboratedTypeKeyword::Typename) {
1191 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1192 *Id, IdLoc, DeducedTSTContext);
1195 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1197 // We had a dependent elaborated-type-specifier that has been transformed
1198 // into a non-dependent elaborated-type-specifier. Find the tag we're
1199 // referring to.
1200 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1201 DeclContext *DC = SemaRef.computeDeclContext(SS, false);
1202 if (!DC)
1203 return QualType();
1205 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1206 return QualType();
1208 TagDecl *Tag = nullptr;
1209 SemaRef.LookupQualifiedName(Result, DC);
1210 switch (Result.getResultKind()) {
1211 case LookupResult::NotFound:
1212 case LookupResult::NotFoundInCurrentInstantiation:
1213 break;
1215 case LookupResult::Found:
1216 Tag = Result.getAsSingle<TagDecl>();
1217 break;
1219 case LookupResult::FoundOverloaded:
1220 case LookupResult::FoundUnresolvedValue:
1221 llvm_unreachable("Tag lookup cannot find non-tags");
1223 case LookupResult::Ambiguous:
1224 // Let the LookupResult structure handle ambiguities.
1225 return QualType();
1228 if (!Tag) {
1229 // Check where the name exists but isn't a tag type and use that to emit
1230 // better diagnostics.
1231 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1232 SemaRef.LookupQualifiedName(Result, DC);
1233 switch (Result.getResultKind()) {
1234 case LookupResult::Found:
1235 case LookupResult::FoundOverloaded:
1236 case LookupResult::FoundUnresolvedValue: {
1237 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1238 Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind);
1239 SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag)
1240 << SomeDecl << NTK << llvm::to_underlying(Kind);
1241 SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
1242 break;
1244 default:
1245 SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
1246 << llvm::to_underlying(Kind) << Id << DC
1247 << QualifierLoc.getSourceRange();
1248 break;
1250 return QualType();
1253 if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false,
1254 IdLoc, Id)) {
1255 SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
1256 SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
1257 return QualType();
1260 // Build the elaborated-type-specifier type.
1261 QualType T = SemaRef.Context.getTypeDeclType(Tag);
1262 return SemaRef.Context.getElaboratedType(Keyword,
1263 QualifierLoc.getNestedNameSpecifier(),
1267 /// Build a new pack expansion type.
1269 /// By default, builds a new PackExpansionType type from the given pattern.
1270 /// Subclasses may override this routine to provide different behavior.
1271 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1272 SourceLocation EllipsisLoc,
1273 std::optional<unsigned> NumExpansions) {
1274 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1275 NumExpansions);
1278 /// Build a new atomic type given its value type.
1280 /// By default, performs semantic analysis when building the atomic type.
1281 /// Subclasses may override this routine to provide different behavior.
1282 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1284 /// Build a new pipe type given its value type.
1285 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1286 bool isReadPipe);
1288 /// Build a bit-precise int given its value type.
1289 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1290 SourceLocation Loc);
1292 /// Build a dependent bit-precise int given its value type.
1293 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1294 SourceLocation Loc);
1296 /// Build a new template name given a nested name specifier, a flag
1297 /// indicating whether the "template" keyword was provided, and the template
1298 /// that the template name refers to.
1300 /// By default, builds the new template name directly. Subclasses may override
1301 /// this routine to provide different behavior.
1302 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1303 bool TemplateKW,
1304 TemplateDecl *Template);
1306 /// Build a new template name given a nested name specifier and the
1307 /// name that is referred to as a template.
1309 /// By default, performs semantic analysis to determine whether the name can
1310 /// be resolved to a specific template, then builds the appropriate kind of
1311 /// template name. Subclasses may override this routine to provide different
1312 /// behavior.
1313 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1314 SourceLocation TemplateKWLoc,
1315 const IdentifierInfo &Name,
1316 SourceLocation NameLoc, QualType ObjectType,
1317 NamedDecl *FirstQualifierInScope,
1318 bool AllowInjectedClassName);
1320 /// Build a new template name given a nested name specifier and the
1321 /// overloaded operator name that is referred to as a template.
1323 /// By default, performs semantic analysis to determine whether the name can
1324 /// be resolved to a specific template, then builds the appropriate kind of
1325 /// template name. Subclasses may override this routine to provide different
1326 /// behavior.
1327 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1328 SourceLocation TemplateKWLoc,
1329 OverloadedOperatorKind Operator,
1330 SourceLocation NameLoc, QualType ObjectType,
1331 bool AllowInjectedClassName);
1333 /// Build a new template name given a template template parameter pack
1334 /// and the
1336 /// By default, performs semantic analysis to determine whether the name can
1337 /// be resolved to a specific template, then builds the appropriate kind of
1338 /// template name. Subclasses may override this routine to provide different
1339 /// behavior.
1340 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1341 Decl *AssociatedDecl, unsigned Index,
1342 bool Final) {
1343 return getSema().Context.getSubstTemplateTemplateParmPack(
1344 ArgPack, AssociatedDecl, Index, Final);
1347 /// Build a new compound statement.
1349 /// By default, performs semantic analysis to build the new statement.
1350 /// Subclasses may override this routine to provide different behavior.
1351 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1352 MultiStmtArg Statements,
1353 SourceLocation RBraceLoc,
1354 bool IsStmtExpr) {
1355 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1356 IsStmtExpr);
1359 /// Build a new case statement.
1361 /// By default, performs semantic analysis to build the new statement.
1362 /// Subclasses may override this routine to provide different behavior.
1363 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1364 Expr *LHS,
1365 SourceLocation EllipsisLoc,
1366 Expr *RHS,
1367 SourceLocation ColonLoc) {
1368 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1369 ColonLoc);
1372 /// Attach the body to a new case statement.
1374 /// By default, performs semantic analysis to build the new statement.
1375 /// Subclasses may override this routine to provide different behavior.
1376 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1377 getSema().ActOnCaseStmtBody(S, Body);
1378 return S;
1381 /// Build a new default statement.
1383 /// By default, performs semantic analysis to build the new statement.
1384 /// Subclasses may override this routine to provide different behavior.
1385 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1386 SourceLocation ColonLoc,
1387 Stmt *SubStmt) {
1388 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1389 /*CurScope=*/nullptr);
1392 /// Build a new label statement.
1394 /// By default, performs semantic analysis to build the new statement.
1395 /// Subclasses may override this routine to provide different behavior.
1396 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1397 SourceLocation ColonLoc, Stmt *SubStmt) {
1398 return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt);
1401 /// Build a new attributed statement.
1403 /// By default, performs semantic analysis to build the new statement.
1404 /// Subclasses may override this routine to provide different behavior.
1405 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1406 ArrayRef<const Attr *> Attrs,
1407 Stmt *SubStmt) {
1408 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1409 return StmtError();
1410 return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt);
1413 /// Build a new "if" statement.
1415 /// By default, performs semantic analysis to build the new statement.
1416 /// Subclasses may override this routine to provide different behavior.
1417 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1418 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1419 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1420 SourceLocation ElseLoc, Stmt *Else) {
1421 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1422 Then, ElseLoc, Else);
1425 /// Start building a new switch statement.
1427 /// By default, performs semantic analysis to build the new statement.
1428 /// Subclasses may override this routine to provide different behavior.
1429 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1430 SourceLocation LParenLoc, Stmt *Init,
1431 Sema::ConditionResult Cond,
1432 SourceLocation RParenLoc) {
1433 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1434 RParenLoc);
1437 /// Attach the body to the switch statement.
1439 /// By default, performs semantic analysis to build the new statement.
1440 /// Subclasses may override this routine to provide different behavior.
1441 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1442 Stmt *Switch, Stmt *Body) {
1443 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1446 /// Build a new while statement.
1448 /// By default, performs semantic analysis to build the new statement.
1449 /// Subclasses may override this routine to provide different behavior.
1450 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1451 Sema::ConditionResult Cond,
1452 SourceLocation RParenLoc, Stmt *Body) {
1453 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1456 /// Build a new do-while statement.
1458 /// By default, performs semantic analysis to build the new statement.
1459 /// Subclasses may override this routine to provide different behavior.
1460 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1461 SourceLocation WhileLoc, SourceLocation LParenLoc,
1462 Expr *Cond, SourceLocation RParenLoc) {
1463 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1464 Cond, RParenLoc);
1467 /// Build a new for statement.
1469 /// By default, performs semantic analysis to build the new statement.
1470 /// Subclasses may override this routine to provide different behavior.
1471 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1472 Stmt *Init, Sema::ConditionResult Cond,
1473 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1474 Stmt *Body) {
1475 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1476 Inc, RParenLoc, Body);
1479 /// Build a new goto statement.
1481 /// By default, performs semantic analysis to build the new statement.
1482 /// Subclasses may override this routine to provide different behavior.
1483 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1484 LabelDecl *Label) {
1485 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1488 /// Build a new indirect goto statement.
1490 /// By default, performs semantic analysis to build the new statement.
1491 /// Subclasses may override this routine to provide different behavior.
1492 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1493 SourceLocation StarLoc,
1494 Expr *Target) {
1495 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1498 /// Build a new return statement.
1500 /// By default, performs semantic analysis to build the new statement.
1501 /// Subclasses may override this routine to provide different behavior.
1502 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1503 return getSema().BuildReturnStmt(ReturnLoc, Result);
1506 /// Build a new declaration statement.
1508 /// By default, performs semantic analysis to build the new statement.
1509 /// Subclasses may override this routine to provide different behavior.
1510 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1511 SourceLocation StartLoc, SourceLocation EndLoc) {
1512 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1513 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1516 /// Build a new inline asm statement.
1518 /// By default, performs semantic analysis to build the new statement.
1519 /// Subclasses may override this routine to provide different behavior.
1520 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1521 bool IsVolatile, unsigned NumOutputs,
1522 unsigned NumInputs, IdentifierInfo **Names,
1523 MultiExprArg Constraints, MultiExprArg Exprs,
1524 Expr *AsmString, MultiExprArg Clobbers,
1525 unsigned NumLabels,
1526 SourceLocation RParenLoc) {
1527 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1528 NumInputs, Names, Constraints, Exprs,
1529 AsmString, Clobbers, NumLabels, RParenLoc);
1532 /// Build a new MS style inline asm statement.
1534 /// By default, performs semantic analysis to build the new statement.
1535 /// Subclasses may override this routine to provide different behavior.
1536 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1537 ArrayRef<Token> AsmToks,
1538 StringRef AsmString,
1539 unsigned NumOutputs, unsigned NumInputs,
1540 ArrayRef<StringRef> Constraints,
1541 ArrayRef<StringRef> Clobbers,
1542 ArrayRef<Expr*> Exprs,
1543 SourceLocation EndLoc) {
1544 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1545 NumOutputs, NumInputs,
1546 Constraints, Clobbers, Exprs, EndLoc);
1549 /// Build a new co_return statement.
1551 /// By default, performs semantic analysis to build the new statement.
1552 /// Subclasses may override this routine to provide different behavior.
1553 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1554 bool IsImplicit) {
1555 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1558 /// Build a new co_await expression.
1560 /// By default, performs semantic analysis to build the new expression.
1561 /// Subclasses may override this routine to provide different behavior.
1562 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1563 UnresolvedLookupExpr *OpCoawaitLookup,
1564 bool IsImplicit) {
1565 // This function rebuilds a coawait-expr given its operator.
1566 // For an explicit coawait-expr, the rebuild involves the full set
1567 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1568 // including calling await_transform().
1569 // For an implicit coawait-expr, we need to rebuild the "operator
1570 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1571 // This mirrors how the implicit CoawaitExpr is originally created
1572 // in Sema::ActOnCoroutineBodyStart().
1573 if (IsImplicit) {
1574 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1575 CoawaitLoc, Operand, OpCoawaitLookup);
1576 if (Suspend.isInvalid())
1577 return ExprError();
1578 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1579 Suspend.get(), true);
1582 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1583 OpCoawaitLookup);
1586 /// Build a new co_await expression.
1588 /// By default, performs semantic analysis to build the new expression.
1589 /// Subclasses may override this routine to provide different behavior.
1590 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1591 Expr *Result,
1592 UnresolvedLookupExpr *Lookup) {
1593 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1596 /// Build a new co_yield expression.
1598 /// By default, performs semantic analysis to build the new expression.
1599 /// Subclasses may override this routine to provide different behavior.
1600 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1601 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1604 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1605 return getSema().BuildCoroutineBodyStmt(Args);
1608 /// Build a new Objective-C \@try statement.
1610 /// By default, performs semantic analysis to build the new statement.
1611 /// Subclasses may override this routine to provide different behavior.
1612 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1613 Stmt *TryBody,
1614 MultiStmtArg CatchStmts,
1615 Stmt *Finally) {
1616 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1617 Finally);
1620 /// Rebuild an Objective-C exception declaration.
1622 /// By default, performs semantic analysis to build the new declaration.
1623 /// Subclasses may override this routine to provide different behavior.
1624 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1625 TypeSourceInfo *TInfo, QualType T) {
1626 return getSema().ObjC().BuildObjCExceptionDecl(
1627 TInfo, T, ExceptionDecl->getInnerLocStart(),
1628 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1631 /// Build a new Objective-C \@catch statement.
1633 /// By default, performs semantic analysis to build the new statement.
1634 /// Subclasses may override this routine to provide different behavior.
1635 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1636 SourceLocation RParenLoc,
1637 VarDecl *Var,
1638 Stmt *Body) {
1639 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1642 /// Build a new Objective-C \@finally statement.
1644 /// By default, performs semantic analysis to build the new statement.
1645 /// Subclasses may override this routine to provide different behavior.
1646 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1647 Stmt *Body) {
1648 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1651 /// Build a new Objective-C \@throw statement.
1653 /// By default, performs semantic analysis to build the new statement.
1654 /// Subclasses may override this routine to provide different behavior.
1655 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1656 Expr *Operand) {
1657 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1660 /// Build a new OpenMP Canonical loop.
1662 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1663 /// OMPCanonicalLoop.
1664 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1665 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1668 /// Build a new OpenMP executable directive.
1670 /// By default, performs semantic analysis to build the new statement.
1671 /// Subclasses may override this routine to provide different behavior.
1672 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
1673 DeclarationNameInfo DirName,
1674 OpenMPDirectiveKind CancelRegion,
1675 ArrayRef<OMPClause *> Clauses,
1676 Stmt *AStmt, SourceLocation StartLoc,
1677 SourceLocation EndLoc) {
1679 return getSema().OpenMP().ActOnOpenMPExecutableDirective(
1680 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1683 /// Build a new OpenMP informational directive.
1684 StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,
1685 DeclarationNameInfo DirName,
1686 ArrayRef<OMPClause *> Clauses,
1687 Stmt *AStmt,
1688 SourceLocation StartLoc,
1689 SourceLocation EndLoc) {
1691 return getSema().OpenMP().ActOnOpenMPInformationalDirective(
1692 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1695 /// Build a new OpenMP 'if' clause.
1697 /// By default, performs semantic analysis to build the new OpenMP clause.
1698 /// Subclasses may override this routine to provide different behavior.
1699 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1700 Expr *Condition, SourceLocation StartLoc,
1701 SourceLocation LParenLoc,
1702 SourceLocation NameModifierLoc,
1703 SourceLocation ColonLoc,
1704 SourceLocation EndLoc) {
1705 return getSema().OpenMP().ActOnOpenMPIfClause(
1706 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1707 EndLoc);
1710 /// Build a new OpenMP 'final' clause.
1712 /// By default, performs semantic analysis to build the new OpenMP clause.
1713 /// Subclasses may override this routine to provide different behavior.
1714 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1715 SourceLocation LParenLoc,
1716 SourceLocation EndLoc) {
1717 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1718 LParenLoc, EndLoc);
1721 /// Build a new OpenMP 'num_threads' clause.
1723 /// By default, performs semantic analysis to build the new OpenMP clause.
1724 /// Subclasses may override this routine to provide different behavior.
1725 OMPClause *RebuildOMPNumThreadsClause(Expr *NumThreads,
1726 SourceLocation StartLoc,
1727 SourceLocation LParenLoc,
1728 SourceLocation EndLoc) {
1729 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc,
1730 LParenLoc, EndLoc);
1733 /// Build a new OpenMP 'safelen' clause.
1735 /// By default, performs semantic analysis to build the new OpenMP clause.
1736 /// Subclasses may override this routine to provide different behavior.
1737 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1738 SourceLocation LParenLoc,
1739 SourceLocation EndLoc) {
1740 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1741 EndLoc);
1744 /// Build a new OpenMP 'simdlen' clause.
1746 /// By default, performs semantic analysis to build the new OpenMP clause.
1747 /// Subclasses may override this routine to provide different behavior.
1748 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1749 SourceLocation LParenLoc,
1750 SourceLocation EndLoc) {
1751 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1752 EndLoc);
1755 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1756 SourceLocation StartLoc,
1757 SourceLocation LParenLoc,
1758 SourceLocation EndLoc) {
1759 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1760 EndLoc);
1763 /// Build a new OpenMP 'permutation' clause.
1764 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,
1765 SourceLocation StartLoc,
1766 SourceLocation LParenLoc,
1767 SourceLocation EndLoc) {
1768 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1769 LParenLoc, EndLoc);
1772 /// Build a new OpenMP 'full' clause.
1773 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1774 SourceLocation EndLoc) {
1775 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1778 /// Build a new OpenMP 'partial' clause.
1779 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1780 SourceLocation LParenLoc,
1781 SourceLocation EndLoc) {
1782 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1783 LParenLoc, EndLoc);
1786 /// Build a new OpenMP 'allocator' clause.
1788 /// By default, performs semantic analysis to build the new OpenMP clause.
1789 /// Subclasses may override this routine to provide different behavior.
1790 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1791 SourceLocation LParenLoc,
1792 SourceLocation EndLoc) {
1793 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1794 EndLoc);
1797 /// Build a new OpenMP 'collapse' clause.
1799 /// By default, performs semantic analysis to build the new OpenMP clause.
1800 /// Subclasses may override this routine to provide different behavior.
1801 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1802 SourceLocation LParenLoc,
1803 SourceLocation EndLoc) {
1804 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1805 LParenLoc, EndLoc);
1808 /// Build a new OpenMP 'default' clause.
1810 /// By default, performs semantic analysis to build the new OpenMP clause.
1811 /// Subclasses may override this routine to provide different behavior.
1812 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1813 SourceLocation StartLoc,
1814 SourceLocation LParenLoc,
1815 SourceLocation EndLoc) {
1816 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1817 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1820 /// Build a new OpenMP 'proc_bind' clause.
1822 /// By default, performs semantic analysis to build the new OpenMP clause.
1823 /// Subclasses may override this routine to provide different behavior.
1824 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1825 SourceLocation KindKwLoc,
1826 SourceLocation StartLoc,
1827 SourceLocation LParenLoc,
1828 SourceLocation EndLoc) {
1829 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1830 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1833 /// Build a new OpenMP 'schedule' clause.
1835 /// By default, performs semantic analysis to build the new OpenMP clause.
1836 /// Subclasses may override this routine to provide different behavior.
1837 OMPClause *RebuildOMPScheduleClause(
1838 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1839 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1840 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1841 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1842 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1843 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1844 CommaLoc, EndLoc);
1847 /// Build a new OpenMP 'ordered' clause.
1849 /// By default, performs semantic analysis to build the new OpenMP clause.
1850 /// Subclasses may override this routine to provide different behavior.
1851 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1852 SourceLocation EndLoc,
1853 SourceLocation LParenLoc, Expr *Num) {
1854 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1855 LParenLoc, Num);
1858 /// Build a new OpenMP 'private' clause.
1860 /// By default, performs semantic analysis to build the new OpenMP clause.
1861 /// Subclasses may override this routine to provide different behavior.
1862 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1863 SourceLocation StartLoc,
1864 SourceLocation LParenLoc,
1865 SourceLocation EndLoc) {
1866 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1867 LParenLoc, EndLoc);
1870 /// Build a new OpenMP 'firstprivate' clause.
1872 /// By default, performs semantic analysis to build the new OpenMP clause.
1873 /// Subclasses may override this routine to provide different behavior.
1874 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1875 SourceLocation StartLoc,
1876 SourceLocation LParenLoc,
1877 SourceLocation EndLoc) {
1878 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1879 LParenLoc, EndLoc);
1882 /// Build a new OpenMP 'lastprivate' clause.
1884 /// By default, performs semantic analysis to build the new OpenMP clause.
1885 /// Subclasses may override this routine to provide different behavior.
1886 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1887 OpenMPLastprivateModifier LPKind,
1888 SourceLocation LPKindLoc,
1889 SourceLocation ColonLoc,
1890 SourceLocation StartLoc,
1891 SourceLocation LParenLoc,
1892 SourceLocation EndLoc) {
1893 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1894 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1897 /// Build a new OpenMP 'shared' clause.
1899 /// By default, performs semantic analysis to build the new OpenMP clause.
1900 /// Subclasses may override this routine to provide different behavior.
1901 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1902 SourceLocation StartLoc,
1903 SourceLocation LParenLoc,
1904 SourceLocation EndLoc) {
1905 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1906 LParenLoc, EndLoc);
1909 /// Build a new OpenMP 'reduction' clause.
1911 /// By default, performs semantic analysis to build the new statement.
1912 /// Subclasses may override this routine to provide different behavior.
1913 OMPClause *RebuildOMPReductionClause(
1914 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1915 SourceLocation StartLoc, SourceLocation LParenLoc,
1916 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1917 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1918 const DeclarationNameInfo &ReductionId,
1919 ArrayRef<Expr *> UnresolvedReductions) {
1920 return getSema().OpenMP().ActOnOpenMPReductionClause(
1921 VarList, Modifier, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
1922 ReductionIdScopeSpec, ReductionId, UnresolvedReductions);
1925 /// Build a new OpenMP 'task_reduction' clause.
1927 /// By default, performs semantic analysis to build the new statement.
1928 /// Subclasses may override this routine to provide different behavior.
1929 OMPClause *RebuildOMPTaskReductionClause(
1930 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1931 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1932 CXXScopeSpec &ReductionIdScopeSpec,
1933 const DeclarationNameInfo &ReductionId,
1934 ArrayRef<Expr *> UnresolvedReductions) {
1935 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
1936 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1937 ReductionId, UnresolvedReductions);
1940 /// Build a new OpenMP 'in_reduction' clause.
1942 /// By default, performs semantic analysis to build the new statement.
1943 /// Subclasses may override this routine to provide different behavior.
1944 OMPClause *
1945 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1946 SourceLocation LParenLoc, SourceLocation ColonLoc,
1947 SourceLocation EndLoc,
1948 CXXScopeSpec &ReductionIdScopeSpec,
1949 const DeclarationNameInfo &ReductionId,
1950 ArrayRef<Expr *> UnresolvedReductions) {
1951 return getSema().OpenMP().ActOnOpenMPInReductionClause(
1952 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1953 ReductionId, UnresolvedReductions);
1956 /// Build a new OpenMP 'linear' clause.
1958 /// By default, performs semantic analysis to build the new OpenMP clause.
1959 /// Subclasses may override this routine to provide different behavior.
1960 OMPClause *RebuildOMPLinearClause(
1961 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1962 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1963 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1964 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
1965 return getSema().OpenMP().ActOnOpenMPLinearClause(
1966 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
1967 StepModifierLoc, EndLoc);
1970 /// Build a new OpenMP 'aligned' clause.
1972 /// By default, performs semantic analysis to build the new OpenMP clause.
1973 /// Subclasses may override this routine to provide different behavior.
1974 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
1975 SourceLocation StartLoc,
1976 SourceLocation LParenLoc,
1977 SourceLocation ColonLoc,
1978 SourceLocation EndLoc) {
1979 return getSema().OpenMP().ActOnOpenMPAlignedClause(
1980 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
1983 /// Build a new OpenMP 'copyin' clause.
1985 /// By default, performs semantic analysis to build the new OpenMP clause.
1986 /// Subclasses may override this routine to provide different behavior.
1987 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
1988 SourceLocation StartLoc,
1989 SourceLocation LParenLoc,
1990 SourceLocation EndLoc) {
1991 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
1992 LParenLoc, EndLoc);
1995 /// Build a new OpenMP 'copyprivate' clause.
1997 /// By default, performs semantic analysis to build the new OpenMP clause.
1998 /// Subclasses may override this routine to provide different behavior.
1999 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
2000 SourceLocation StartLoc,
2001 SourceLocation LParenLoc,
2002 SourceLocation EndLoc) {
2003 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
2004 LParenLoc, EndLoc);
2007 /// Build a new OpenMP 'flush' pseudo clause.
2009 /// By default, performs semantic analysis to build the new OpenMP clause.
2010 /// Subclasses may override this routine to provide different behavior.
2011 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
2012 SourceLocation StartLoc,
2013 SourceLocation LParenLoc,
2014 SourceLocation EndLoc) {
2015 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2016 LParenLoc, EndLoc);
2019 /// Build a new OpenMP 'depobj' pseudo clause.
2021 /// By default, performs semantic analysis to build the new OpenMP clause.
2022 /// Subclasses may override this routine to provide different behavior.
2023 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2024 SourceLocation LParenLoc,
2025 SourceLocation EndLoc) {
2026 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2027 LParenLoc, EndLoc);
2030 /// Build a new OpenMP 'depend' pseudo clause.
2032 /// By default, performs semantic analysis to build the new OpenMP clause.
2033 /// Subclasses may override this routine to provide different behavior.
2034 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2035 Expr *DepModifier, ArrayRef<Expr *> VarList,
2036 SourceLocation StartLoc,
2037 SourceLocation LParenLoc,
2038 SourceLocation EndLoc) {
2039 return getSema().OpenMP().ActOnOpenMPDependClause(
2040 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2043 /// Build a new OpenMP 'device' clause.
2045 /// By default, performs semantic analysis to build the new statement.
2046 /// Subclasses may override this routine to provide different behavior.
2047 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2048 Expr *Device, SourceLocation StartLoc,
2049 SourceLocation LParenLoc,
2050 SourceLocation ModifierLoc,
2051 SourceLocation EndLoc) {
2052 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2053 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2056 /// Build a new OpenMP 'map' clause.
2058 /// By default, performs semantic analysis to build the new OpenMP clause.
2059 /// Subclasses may override this routine to provide different behavior.
2060 OMPClause *RebuildOMPMapClause(
2061 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2062 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2063 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2064 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2065 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2066 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2067 return getSema().OpenMP().ActOnOpenMPMapClause(
2068 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2069 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2070 ColonLoc, VarList, Locs,
2071 /*NoDiagnose=*/false, UnresolvedMappers);
2074 /// Build a new OpenMP 'allocate' clause.
2076 /// By default, performs semantic analysis to build the new OpenMP clause.
2077 /// Subclasses may override this routine to provide different behavior.
2078 OMPClause *RebuildOMPAllocateClause(Expr *Allocate,
2079 OpenMPAllocateClauseModifier ACModifier,
2080 ArrayRef<Expr *> VarList,
2081 SourceLocation StartLoc,
2082 SourceLocation LParenLoc,
2083 SourceLocation ColonLoc,
2084 SourceLocation EndLoc) {
2085 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2086 Allocate, ACModifier, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2089 /// Build a new OpenMP 'num_teams' clause.
2091 /// By default, performs semantic analysis to build the new statement.
2092 /// Subclasses may override this routine to provide different behavior.
2093 OMPClause *RebuildOMPNumTeamsClause(ArrayRef<Expr *> VarList,
2094 SourceLocation StartLoc,
2095 SourceLocation LParenLoc,
2096 SourceLocation EndLoc) {
2097 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(VarList, StartLoc,
2098 LParenLoc, EndLoc);
2101 /// Build a new OpenMP 'thread_limit' clause.
2103 /// By default, performs semantic analysis to build the new statement.
2104 /// Subclasses may override this routine to provide different behavior.
2105 OMPClause *RebuildOMPThreadLimitClause(ArrayRef<Expr *> VarList,
2106 SourceLocation StartLoc,
2107 SourceLocation LParenLoc,
2108 SourceLocation EndLoc) {
2109 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(VarList, StartLoc,
2110 LParenLoc, EndLoc);
2113 /// Build a new OpenMP 'priority' clause.
2115 /// By default, performs semantic analysis to build the new statement.
2116 /// Subclasses may override this routine to provide different behavior.
2117 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2118 SourceLocation LParenLoc,
2119 SourceLocation EndLoc) {
2120 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2121 LParenLoc, EndLoc);
2124 /// Build a new OpenMP 'grainsize' clause.
2126 /// By default, performs semantic analysis to build the new statement.
2127 /// Subclasses may override this routine to provide different behavior.
2128 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2129 Expr *Device, SourceLocation StartLoc,
2130 SourceLocation LParenLoc,
2131 SourceLocation ModifierLoc,
2132 SourceLocation EndLoc) {
2133 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2134 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2137 /// Build a new OpenMP 'num_tasks' clause.
2139 /// By default, performs semantic analysis to build the new statement.
2140 /// Subclasses may override this routine to provide different behavior.
2141 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2142 Expr *NumTasks, SourceLocation StartLoc,
2143 SourceLocation LParenLoc,
2144 SourceLocation ModifierLoc,
2145 SourceLocation EndLoc) {
2146 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2147 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2150 /// Build a new OpenMP 'hint' clause.
2152 /// By default, performs semantic analysis to build the new statement.
2153 /// Subclasses may override this routine to provide different behavior.
2154 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2155 SourceLocation LParenLoc,
2156 SourceLocation EndLoc) {
2157 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2158 EndLoc);
2161 /// Build a new OpenMP 'detach' clause.
2163 /// By default, performs semantic analysis to build the new statement.
2164 /// Subclasses may override this routine to provide different behavior.
2165 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2166 SourceLocation LParenLoc,
2167 SourceLocation EndLoc) {
2168 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2169 EndLoc);
2172 /// Build a new OpenMP 'dist_schedule' clause.
2174 /// By default, performs semantic analysis to build the new OpenMP clause.
2175 /// Subclasses may override this routine to provide different behavior.
2176 OMPClause *
2177 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2178 Expr *ChunkSize, SourceLocation StartLoc,
2179 SourceLocation LParenLoc, SourceLocation KindLoc,
2180 SourceLocation CommaLoc, SourceLocation EndLoc) {
2181 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2182 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2185 /// Build a new OpenMP 'to' clause.
2187 /// By default, performs semantic analysis to build the new statement.
2188 /// Subclasses may override this routine to provide different behavior.
2189 OMPClause *
2190 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2191 ArrayRef<SourceLocation> MotionModifiersLoc,
2192 CXXScopeSpec &MapperIdScopeSpec,
2193 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2194 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2195 ArrayRef<Expr *> UnresolvedMappers) {
2196 return getSema().OpenMP().ActOnOpenMPToClause(
2197 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2198 ColonLoc, VarList, Locs, UnresolvedMappers);
2201 /// Build a new OpenMP 'from' clause.
2203 /// By default, performs semantic analysis to build the new statement.
2204 /// Subclasses may override this routine to provide different behavior.
2205 OMPClause *
2206 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2207 ArrayRef<SourceLocation> MotionModifiersLoc,
2208 CXXScopeSpec &MapperIdScopeSpec,
2209 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2210 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2211 ArrayRef<Expr *> UnresolvedMappers) {
2212 return getSema().OpenMP().ActOnOpenMPFromClause(
2213 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2214 ColonLoc, VarList, Locs, UnresolvedMappers);
2217 /// Build a new OpenMP 'use_device_ptr' clause.
2219 /// By default, performs semantic analysis to build the new OpenMP clause.
2220 /// Subclasses may override this routine to provide different behavior.
2221 OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
2222 const OMPVarListLocTy &Locs) {
2223 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2226 /// Build a new OpenMP 'use_device_addr' clause.
2228 /// By default, performs semantic analysis to build the new OpenMP clause.
2229 /// Subclasses may override this routine to provide different behavior.
2230 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2231 const OMPVarListLocTy &Locs) {
2232 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2235 /// Build a new OpenMP 'is_device_ptr' clause.
2237 /// By default, performs semantic analysis to build the new OpenMP clause.
2238 /// Subclasses may override this routine to provide different behavior.
2239 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2240 const OMPVarListLocTy &Locs) {
2241 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2244 /// Build a new OpenMP 'has_device_addr' clause.
2246 /// By default, performs semantic analysis to build the new OpenMP clause.
2247 /// Subclasses may override this routine to provide different behavior.
2248 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2249 const OMPVarListLocTy &Locs) {
2250 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2253 /// Build a new OpenMP 'defaultmap' clause.
2255 /// By default, performs semantic analysis to build the new OpenMP clause.
2256 /// Subclasses may override this routine to provide different behavior.
2257 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2258 OpenMPDefaultmapClauseKind Kind,
2259 SourceLocation StartLoc,
2260 SourceLocation LParenLoc,
2261 SourceLocation MLoc,
2262 SourceLocation KindLoc,
2263 SourceLocation EndLoc) {
2264 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2265 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2268 /// Build a new OpenMP 'nontemporal' clause.
2270 /// By default, performs semantic analysis to build the new OpenMP clause.
2271 /// Subclasses may override this routine to provide different behavior.
2272 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2273 SourceLocation StartLoc,
2274 SourceLocation LParenLoc,
2275 SourceLocation EndLoc) {
2276 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2277 LParenLoc, EndLoc);
2280 /// Build a new OpenMP 'inclusive' clause.
2282 /// By default, performs semantic analysis to build the new OpenMP clause.
2283 /// Subclasses may override this routine to provide different behavior.
2284 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2285 SourceLocation StartLoc,
2286 SourceLocation LParenLoc,
2287 SourceLocation EndLoc) {
2288 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2289 LParenLoc, EndLoc);
2292 /// Build a new OpenMP 'exclusive' clause.
2294 /// By default, performs semantic analysis to build the new OpenMP clause.
2295 /// Subclasses may override this routine to provide different behavior.
2296 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2297 SourceLocation StartLoc,
2298 SourceLocation LParenLoc,
2299 SourceLocation EndLoc) {
2300 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2301 LParenLoc, EndLoc);
2304 /// Build a new OpenMP 'uses_allocators' clause.
2306 /// By default, performs semantic analysis to build the new OpenMP clause.
2307 /// Subclasses may override this routine to provide different behavior.
2308 OMPClause *RebuildOMPUsesAllocatorsClause(
2309 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2310 SourceLocation LParenLoc, SourceLocation EndLoc) {
2311 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2312 StartLoc, LParenLoc, EndLoc, Data);
2315 /// Build a new OpenMP 'affinity' clause.
2317 /// By default, performs semantic analysis to build the new OpenMP clause.
2318 /// Subclasses may override this routine to provide different behavior.
2319 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2320 SourceLocation LParenLoc,
2321 SourceLocation ColonLoc,
2322 SourceLocation EndLoc, Expr *Modifier,
2323 ArrayRef<Expr *> Locators) {
2324 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2325 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2328 /// Build a new OpenMP 'order' clause.
2330 /// By default, performs semantic analysis to build the new OpenMP clause.
2331 /// Subclasses may override this routine to provide different behavior.
2332 OMPClause *RebuildOMPOrderClause(
2333 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2334 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2335 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2336 return getSema().OpenMP().ActOnOpenMPOrderClause(
2337 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2340 /// Build a new OpenMP 'init' clause.
2342 /// By default, performs semantic analysis to build the new OpenMP clause.
2343 /// Subclasses may override this routine to provide different behavior.
2344 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2345 SourceLocation StartLoc,
2346 SourceLocation LParenLoc,
2347 SourceLocation VarLoc,
2348 SourceLocation EndLoc) {
2349 return getSema().OpenMP().ActOnOpenMPInitClause(
2350 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2353 /// Build a new OpenMP 'use' clause.
2355 /// By default, performs semantic analysis to build the new OpenMP clause.
2356 /// Subclasses may override this routine to provide different behavior.
2357 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2358 SourceLocation LParenLoc,
2359 SourceLocation VarLoc, SourceLocation EndLoc) {
2360 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2361 LParenLoc, VarLoc, EndLoc);
2364 /// Build a new OpenMP 'destroy' clause.
2366 /// By default, performs semantic analysis to build the new OpenMP clause.
2367 /// Subclasses may override this routine to provide different behavior.
2368 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2369 SourceLocation LParenLoc,
2370 SourceLocation VarLoc,
2371 SourceLocation EndLoc) {
2372 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2373 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2376 /// Build a new OpenMP 'novariants' clause.
2378 /// By default, performs semantic analysis to build the new OpenMP clause.
2379 /// Subclasses may override this routine to provide different behavior.
2380 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2381 SourceLocation StartLoc,
2382 SourceLocation LParenLoc,
2383 SourceLocation EndLoc) {
2384 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2385 LParenLoc, EndLoc);
2388 /// Build a new OpenMP 'nocontext' clause.
2390 /// By default, performs semantic analysis to build the new OpenMP clause.
2391 /// Subclasses may override this routine to provide different behavior.
2392 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2393 SourceLocation LParenLoc,
2394 SourceLocation EndLoc) {
2395 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2396 LParenLoc, EndLoc);
2399 /// Build a new OpenMP 'filter' clause.
2401 /// By default, performs semantic analysis to build the new OpenMP clause.
2402 /// Subclasses may override this routine to provide different behavior.
2403 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2404 SourceLocation LParenLoc,
2405 SourceLocation EndLoc) {
2406 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2407 LParenLoc, EndLoc);
2410 /// Build a new OpenMP 'bind' clause.
2412 /// By default, performs semantic analysis to build the new OpenMP clause.
2413 /// Subclasses may override this routine to provide different behavior.
2414 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2415 SourceLocation KindLoc,
2416 SourceLocation StartLoc,
2417 SourceLocation LParenLoc,
2418 SourceLocation EndLoc) {
2419 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2420 LParenLoc, EndLoc);
2423 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2425 /// By default, performs semantic analysis to build the new OpenMP clause.
2426 /// Subclasses may override this routine to provide different behavior.
2427 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2428 SourceLocation LParenLoc,
2429 SourceLocation EndLoc) {
2430 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2431 LParenLoc, EndLoc);
2434 /// Build a new OpenMP 'ompx_attribute' clause.
2436 /// By default, performs semantic analysis to build the new OpenMP clause.
2437 /// Subclasses may override this routine to provide different behavior.
2438 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2439 SourceLocation StartLoc,
2440 SourceLocation LParenLoc,
2441 SourceLocation EndLoc) {
2442 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2443 LParenLoc, EndLoc);
2446 /// Build a new OpenMP 'ompx_bare' clause.
2448 /// By default, performs semantic analysis to build the new OpenMP clause.
2449 /// Subclasses may override this routine to provide different behavior.
2450 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2451 SourceLocation EndLoc) {
2452 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2455 /// Build a new OpenMP 'align' clause.
2457 /// By default, performs semantic analysis to build the new OpenMP clause.
2458 /// Subclasses may override this routine to provide different behavior.
2459 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2460 SourceLocation LParenLoc,
2461 SourceLocation EndLoc) {
2462 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2463 EndLoc);
2466 /// Build a new OpenMP 'at' clause.
2468 /// By default, performs semantic analysis to build the new OpenMP clause.
2469 /// Subclasses may override this routine to provide different behavior.
2470 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2471 SourceLocation StartLoc,
2472 SourceLocation LParenLoc,
2473 SourceLocation EndLoc) {
2474 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2475 LParenLoc, EndLoc);
2478 /// Build a new OpenMP 'severity' clause.
2480 /// By default, performs semantic analysis to build the new OpenMP clause.
2481 /// Subclasses may override this routine to provide different behavior.
2482 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2483 SourceLocation KwLoc,
2484 SourceLocation StartLoc,
2485 SourceLocation LParenLoc,
2486 SourceLocation EndLoc) {
2487 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2488 LParenLoc, EndLoc);
2491 /// Build a new OpenMP 'message' clause.
2493 /// By default, performs semantic analysis to build the new OpenMP clause.
2494 /// Subclasses may override this routine to provide different behavior.
2495 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2496 SourceLocation LParenLoc,
2497 SourceLocation EndLoc) {
2498 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2499 EndLoc);
2502 /// Build a new OpenMP 'doacross' clause.
2504 /// By default, performs semantic analysis to build the new OpenMP clause.
2505 /// Subclasses may override this routine to provide different behavior.
2506 OMPClause *
2507 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2508 SourceLocation DepLoc, SourceLocation ColonLoc,
2509 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2510 SourceLocation LParenLoc, SourceLocation EndLoc) {
2511 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2512 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2515 /// Build a new OpenMP 'holds' clause.
2516 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,
2517 SourceLocation LParenLoc,
2518 SourceLocation EndLoc) {
2519 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2520 EndLoc);
2523 /// Rebuild the operand to an Objective-C \@synchronized statement.
2525 /// By default, performs semantic analysis to build the new statement.
2526 /// Subclasses may override this routine to provide different behavior.
2527 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2528 Expr *object) {
2529 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2532 /// Build a new Objective-C \@synchronized statement.
2534 /// By default, performs semantic analysis to build the new statement.
2535 /// Subclasses may override this routine to provide different behavior.
2536 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2537 Expr *Object, Stmt *Body) {
2538 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2541 /// Build a new Objective-C \@autoreleasepool statement.
2543 /// By default, performs semantic analysis to build the new statement.
2544 /// Subclasses may override this routine to provide different behavior.
2545 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2546 Stmt *Body) {
2547 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2550 /// Build a new Objective-C fast enumeration statement.
2552 /// By default, performs semantic analysis to build the new statement.
2553 /// Subclasses may override this routine to provide different behavior.
2554 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2555 Stmt *Element,
2556 Expr *Collection,
2557 SourceLocation RParenLoc,
2558 Stmt *Body) {
2559 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2560 ForLoc, Element, Collection, RParenLoc);
2561 if (ForEachStmt.isInvalid())
2562 return StmtError();
2564 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2565 Body);
2568 /// Build a new C++ exception declaration.
2570 /// By default, performs semantic analysis to build the new decaration.
2571 /// Subclasses may override this routine to provide different behavior.
2572 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2573 TypeSourceInfo *Declarator,
2574 SourceLocation StartLoc,
2575 SourceLocation IdLoc,
2576 IdentifierInfo *Id) {
2577 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2578 StartLoc, IdLoc, Id);
2579 if (Var)
2580 getSema().CurContext->addDecl(Var);
2581 return Var;
2584 /// Build a new C++ catch statement.
2586 /// By default, performs semantic analysis to build the new statement.
2587 /// Subclasses may override this routine to provide different behavior.
2588 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2589 VarDecl *ExceptionDecl,
2590 Stmt *Handler) {
2591 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2592 Handler));
2595 /// Build a new C++ try statement.
2597 /// By default, performs semantic analysis to build the new statement.
2598 /// Subclasses may override this routine to provide different behavior.
2599 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2600 ArrayRef<Stmt *> Handlers) {
2601 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2604 /// Build a new C++0x range-based for statement.
2606 /// By default, performs semantic analysis to build the new statement.
2607 /// Subclasses may override this routine to provide different behavior.
2608 StmtResult RebuildCXXForRangeStmt(
2609 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2610 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2611 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2612 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2613 // If we've just learned that the range is actually an Objective-C
2614 // collection, treat this as an Objective-C fast enumeration loop.
2615 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
2616 if (RangeStmt->isSingleDecl()) {
2617 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
2618 if (RangeVar->isInvalidDecl())
2619 return StmtError();
2621 Expr *RangeExpr = RangeVar->getInit();
2622 if (!RangeExpr->isTypeDependent() &&
2623 RangeExpr->getType()->isObjCObjectPointerType()) {
2624 // FIXME: Support init-statements in Objective-C++20 ranged for
2625 // statement.
2626 if (Init) {
2627 return SemaRef.Diag(Init->getBeginLoc(),
2628 diag::err_objc_for_range_init_stmt)
2629 << Init->getSourceRange();
2631 return getSema().ObjC().ActOnObjCForCollectionStmt(
2632 ForLoc, LoopVar, RangeExpr, RParenLoc);
2638 return getSema().BuildCXXForRangeStmt(
2639 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2640 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2643 /// Build a new C++0x range-based for statement.
2645 /// By default, performs semantic analysis to build the new statement.
2646 /// Subclasses may override this routine to provide different behavior.
2647 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2648 bool IsIfExists,
2649 NestedNameSpecifierLoc QualifierLoc,
2650 DeclarationNameInfo NameInfo,
2651 Stmt *Nested) {
2652 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2653 QualifierLoc, NameInfo, Nested);
2656 /// Attach body to a C++0x range-based for statement.
2658 /// By default, performs semantic analysis to finish the new statement.
2659 /// Subclasses may override this routine to provide different behavior.
2660 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2661 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2664 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2665 Stmt *TryBlock, Stmt *Handler) {
2666 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2669 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2670 Stmt *Block) {
2671 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2674 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2675 return SEHFinallyStmt::Create(getSema().getASTContext(), Loc, Block);
2678 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2679 SourceLocation LParen,
2680 SourceLocation RParen,
2681 TypeSourceInfo *TSI) {
2682 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2683 TSI);
2686 /// Build a new predefined expression.
2688 /// By default, performs semantic analysis to build the new expression.
2689 /// Subclasses may override this routine to provide different behavior.
2690 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2691 return getSema().BuildPredefinedExpr(Loc, IK);
2694 /// Build a new expression that references a declaration.
2696 /// By default, performs semantic analysis to build the new expression.
2697 /// Subclasses may override this routine to provide different behavior.
2698 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2699 LookupResult &R,
2700 bool RequiresADL) {
2701 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2705 /// Build a new expression that references a declaration.
2707 /// By default, performs semantic analysis to build the new expression.
2708 /// Subclasses may override this routine to provide different behavior.
2709 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2710 ValueDecl *VD,
2711 const DeclarationNameInfo &NameInfo,
2712 NamedDecl *Found,
2713 TemplateArgumentListInfo *TemplateArgs) {
2714 CXXScopeSpec SS;
2715 SS.Adopt(QualifierLoc);
2716 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2717 TemplateArgs);
2720 /// Build a new expression in parentheses.
2722 /// By default, performs semantic analysis to build the new expression.
2723 /// Subclasses may override this routine to provide different behavior.
2724 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2725 SourceLocation RParen) {
2726 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2729 /// Build a new pseudo-destructor expression.
2731 /// By default, performs semantic analysis to build the new expression.
2732 /// Subclasses may override this routine to provide different behavior.
2733 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2734 SourceLocation OperatorLoc,
2735 bool isArrow,
2736 CXXScopeSpec &SS,
2737 TypeSourceInfo *ScopeType,
2738 SourceLocation CCLoc,
2739 SourceLocation TildeLoc,
2740 PseudoDestructorTypeStorage Destroyed);
2742 /// Build a new unary operator expression.
2744 /// By default, performs semantic analysis to build the new expression.
2745 /// Subclasses may override this routine to provide different behavior.
2746 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2747 UnaryOperatorKind Opc,
2748 Expr *SubExpr) {
2749 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2752 /// Build a new builtin offsetof expression.
2754 /// By default, performs semantic analysis to build the new expression.
2755 /// Subclasses may override this routine to provide different behavior.
2756 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2757 TypeSourceInfo *Type,
2758 ArrayRef<Sema::OffsetOfComponent> Components,
2759 SourceLocation RParenLoc) {
2760 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2761 RParenLoc);
2764 /// Build a new sizeof, alignof or vec_step expression with a
2765 /// type argument.
2767 /// By default, performs semantic analysis to build the new expression.
2768 /// Subclasses may override this routine to provide different behavior.
2769 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2770 SourceLocation OpLoc,
2771 UnaryExprOrTypeTrait ExprKind,
2772 SourceRange R) {
2773 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2776 /// Build a new sizeof, alignof or vec step expression with an
2777 /// expression argument.
2779 /// By default, performs semantic analysis to build the new expression.
2780 /// Subclasses may override this routine to provide different behavior.
2781 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2782 UnaryExprOrTypeTrait ExprKind,
2783 SourceRange R) {
2784 ExprResult Result
2785 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2786 if (Result.isInvalid())
2787 return ExprError();
2789 return Result;
2792 /// Build a new array subscript expression.
2794 /// By default, performs semantic analysis to build the new expression.
2795 /// Subclasses may override this routine to provide different behavior.
2796 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2797 SourceLocation LBracketLoc,
2798 Expr *RHS,
2799 SourceLocation RBracketLoc) {
2800 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2801 LBracketLoc, RHS,
2802 RBracketLoc);
2805 /// Build a new matrix subscript expression.
2807 /// By default, performs semantic analysis to build the new expression.
2808 /// Subclasses may override this routine to provide different behavior.
2809 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2810 Expr *ColumnIdx,
2811 SourceLocation RBracketLoc) {
2812 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2813 RBracketLoc);
2816 /// Build a new array section expression.
2818 /// By default, performs semantic analysis to build the new expression.
2819 /// Subclasses may override this routine to provide different behavior.
2820 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2821 SourceLocation LBracketLoc,
2822 Expr *LowerBound,
2823 SourceLocation ColonLocFirst,
2824 SourceLocation ColonLocSecond,
2825 Expr *Length, Expr *Stride,
2826 SourceLocation RBracketLoc) {
2827 if (IsOMPArraySection)
2828 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2829 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2830 Stride, RBracketLoc);
2832 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2833 "Stride/second colon not allowed for OpenACC");
2835 return getSema().OpenACC().ActOnArraySectionExpr(
2836 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2839 /// Build a new array shaping expression.
2841 /// By default, performs semantic analysis to build the new expression.
2842 /// Subclasses may override this routine to provide different behavior.
2843 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2844 SourceLocation RParenLoc,
2845 ArrayRef<Expr *> Dims,
2846 ArrayRef<SourceRange> BracketsRanges) {
2847 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2848 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2851 /// Build a new iterator expression.
2853 /// By default, performs semantic analysis to build the new expression.
2854 /// Subclasses may override this routine to provide different behavior.
2855 ExprResult
2856 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2857 SourceLocation RLoc,
2858 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2859 return getSema().OpenMP().ActOnOMPIteratorExpr(
2860 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2863 /// Build a new call expression.
2865 /// By default, performs semantic analysis to build the new expression.
2866 /// Subclasses may override this routine to provide different behavior.
2867 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2868 MultiExprArg Args,
2869 SourceLocation RParenLoc,
2870 Expr *ExecConfig = nullptr) {
2871 return getSema().ActOnCallExpr(
2872 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2875 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2876 MultiExprArg Args,
2877 SourceLocation RParenLoc) {
2878 return getSema().ActOnArraySubscriptExpr(
2879 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2882 /// Build a new member access expression.
2884 /// By default, performs semantic analysis to build the new expression.
2885 /// Subclasses may override this routine to provide different behavior.
2886 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2887 bool isArrow,
2888 NestedNameSpecifierLoc QualifierLoc,
2889 SourceLocation TemplateKWLoc,
2890 const DeclarationNameInfo &MemberNameInfo,
2891 ValueDecl *Member,
2892 NamedDecl *FoundDecl,
2893 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2894 NamedDecl *FirstQualifierInScope) {
2895 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2896 isArrow);
2897 if (!Member->getDeclName()) {
2898 // We have a reference to an unnamed field. This is always the
2899 // base of an anonymous struct/union member access, i.e. the
2900 // field is always of record type.
2901 assert(Member->getType()->isRecordType() &&
2902 "unnamed member not of record type?");
2904 BaseResult =
2905 getSema().PerformObjectMemberConversion(BaseResult.get(),
2906 QualifierLoc.getNestedNameSpecifier(),
2907 FoundDecl, Member);
2908 if (BaseResult.isInvalid())
2909 return ExprError();
2910 Base = BaseResult.get();
2912 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
2913 // from the AST, so we need to re-insert them if needed (since
2914 // `BuildFieldRefereneExpr()` doesn't do this).
2915 if (!isArrow && Base->isPRValue()) {
2916 BaseResult = getSema().TemporaryMaterializationConversion(Base);
2917 if (BaseResult.isInvalid())
2918 return ExprError();
2919 Base = BaseResult.get();
2922 CXXScopeSpec EmptySS;
2923 return getSema().BuildFieldReferenceExpr(
2924 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
2925 DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()),
2926 MemberNameInfo);
2929 CXXScopeSpec SS;
2930 SS.Adopt(QualifierLoc);
2932 Base = BaseResult.get();
2933 if (Base->containsErrors())
2934 return ExprError();
2936 QualType BaseType = Base->getType();
2938 if (isArrow && !BaseType->isPointerType())
2939 return ExprError();
2941 // FIXME: this involves duplicating earlier analysis in a lot of
2942 // cases; we should avoid this when possible.
2943 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2944 R.addDecl(FoundDecl);
2945 R.resolveKind();
2947 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2948 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {
2949 if (auto *ThisClass = cast<CXXThisExpr>(Base)
2950 ->getType()
2951 ->getPointeeType()
2952 ->getAsCXXRecordDecl()) {
2953 auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());
2954 // In unevaluated contexts, an expression supposed to be a member access
2955 // might reference a member in an unrelated class.
2956 if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))
2957 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2958 VK_LValue, Member->getLocation());
2962 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2963 SS, TemplateKWLoc,
2964 FirstQualifierInScope,
2965 R, ExplicitTemplateArgs,
2966 /*S*/nullptr);
2969 /// Build a new binary operator expression.
2971 /// By default, performs semantic analysis to build the new expression.
2972 /// Subclasses may override this routine to provide different behavior.
2973 ExprResult RebuildBinaryOperator(SourceLocation OpLoc,
2974 BinaryOperatorKind Opc,
2975 Expr *LHS, Expr *RHS) {
2976 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS);
2979 /// Build a new rewritten operator expression.
2981 /// By default, performs semantic analysis to build the new expression.
2982 /// Subclasses may override this routine to provide different behavior.
2983 ExprResult RebuildCXXRewrittenBinaryOperator(
2984 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2985 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2986 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2987 RHS, /*RequiresADL*/false);
2990 /// Build a new conditional operator expression.
2992 /// By default, performs semantic analysis to build the new expression.
2993 /// Subclasses may override this routine to provide different behavior.
2994 ExprResult RebuildConditionalOperator(Expr *Cond,
2995 SourceLocation QuestionLoc,
2996 Expr *LHS,
2997 SourceLocation ColonLoc,
2998 Expr *RHS) {
2999 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
3000 LHS, RHS);
3003 /// Build a new C-style cast expression.
3005 /// By default, performs semantic analysis to build the new expression.
3006 /// Subclasses may override this routine to provide different behavior.
3007 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
3008 TypeSourceInfo *TInfo,
3009 SourceLocation RParenLoc,
3010 Expr *SubExpr) {
3011 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3012 SubExpr);
3015 /// Build a new compound literal expression.
3017 /// By default, performs semantic analysis to build the new expression.
3018 /// Subclasses may override this routine to provide different behavior.
3019 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
3020 TypeSourceInfo *TInfo,
3021 SourceLocation RParenLoc,
3022 Expr *Init) {
3023 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3024 Init);
3027 /// Build a new extended vector element access expression.
3029 /// By default, performs semantic analysis to build the new expression.
3030 /// Subclasses may override this routine to provide different behavior.
3031 ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,
3032 bool IsArrow,
3033 SourceLocation AccessorLoc,
3034 IdentifierInfo &Accessor) {
3036 CXXScopeSpec SS;
3037 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3038 return getSema().BuildMemberReferenceExpr(
3039 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3040 /*FirstQualifierInScope*/ nullptr, NameInfo,
3041 /* TemplateArgs */ nullptr,
3042 /*S*/ nullptr);
3045 /// Build a new initializer list expression.
3047 /// By default, performs semantic analysis to build the new expression.
3048 /// Subclasses may override this routine to provide different behavior.
3049 ExprResult RebuildInitList(SourceLocation LBraceLoc,
3050 MultiExprArg Inits,
3051 SourceLocation RBraceLoc) {
3052 return SemaRef.BuildInitList(LBraceLoc, Inits, RBraceLoc);
3055 /// Build a new designated initializer expression.
3057 /// By default, performs semantic analysis to build the new expression.
3058 /// Subclasses may override this routine to provide different behavior.
3059 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3060 MultiExprArg ArrayExprs,
3061 SourceLocation EqualOrColonLoc,
3062 bool GNUSyntax,
3063 Expr *Init) {
3064 ExprResult Result
3065 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3066 Init);
3067 if (Result.isInvalid())
3068 return ExprError();
3070 return Result;
3073 /// Build a new value-initialized expression.
3075 /// By default, builds the implicit value initialization without performing
3076 /// any semantic analysis. Subclasses may override this routine to provide
3077 /// different behavior.
3078 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3079 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3082 /// Build a new \c va_arg expression.
3084 /// By default, performs semantic analysis to build the new expression.
3085 /// Subclasses may override this routine to provide different behavior.
3086 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3087 Expr *SubExpr, TypeSourceInfo *TInfo,
3088 SourceLocation RParenLoc) {
3089 return getSema().BuildVAArgExpr(BuiltinLoc,
3090 SubExpr, TInfo,
3091 RParenLoc);
3094 /// Build a new expression list in parentheses.
3096 /// By default, performs semantic analysis to build the new expression.
3097 /// Subclasses may override this routine to provide different behavior.
3098 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3099 MultiExprArg SubExprs,
3100 SourceLocation RParenLoc) {
3101 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3104 /// Build a new address-of-label expression.
3106 /// By default, performs semantic analysis, using the name of the label
3107 /// rather than attempting to map the label statement itself.
3108 /// Subclasses may override this routine to provide different behavior.
3109 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3110 SourceLocation LabelLoc, LabelDecl *Label) {
3111 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3114 /// Build a new GNU statement expression.
3116 /// By default, performs semantic analysis to build the new expression.
3117 /// Subclasses may override this routine to provide different behavior.
3118 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3119 SourceLocation RParenLoc, unsigned TemplateDepth) {
3120 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3121 TemplateDepth);
3124 /// Build a new __builtin_choose_expr expression.
3126 /// By default, performs semantic analysis to build the new expression.
3127 /// Subclasses may override this routine to provide different behavior.
3128 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3129 Expr *Cond, Expr *LHS, Expr *RHS,
3130 SourceLocation RParenLoc) {
3131 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3132 Cond, LHS, RHS,
3133 RParenLoc);
3136 /// Build a new generic selection expression with an expression predicate.
3138 /// By default, performs semantic analysis to build the new expression.
3139 /// Subclasses may override this routine to provide different behavior.
3140 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3141 SourceLocation DefaultLoc,
3142 SourceLocation RParenLoc,
3143 Expr *ControllingExpr,
3144 ArrayRef<TypeSourceInfo *> Types,
3145 ArrayRef<Expr *> Exprs) {
3146 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3147 /*PredicateIsExpr=*/true,
3148 ControllingExpr, Types, Exprs);
3151 /// Build a new generic selection expression with a type predicate.
3153 /// By default, performs semantic analysis to build the new expression.
3154 /// Subclasses may override this routine to provide different behavior.
3155 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3156 SourceLocation DefaultLoc,
3157 SourceLocation RParenLoc,
3158 TypeSourceInfo *ControllingType,
3159 ArrayRef<TypeSourceInfo *> Types,
3160 ArrayRef<Expr *> Exprs) {
3161 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3162 /*PredicateIsExpr=*/false,
3163 ControllingType, Types, Exprs);
3166 /// Build a new overloaded operator call expression.
3168 /// By default, performs semantic analysis to build the new expression.
3169 /// The semantic analysis provides the behavior of template instantiation,
3170 /// copying with transformations that turn what looks like an overloaded
3171 /// operator call into a use of a builtin operator, performing
3172 /// argument-dependent lookup, etc. Subclasses may override this routine to
3173 /// provide different behavior.
3174 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3175 SourceLocation OpLoc,
3176 SourceLocation CalleeLoc,
3177 bool RequiresADL,
3178 const UnresolvedSetImpl &Functions,
3179 Expr *First, Expr *Second);
3181 /// Build a new C++ "named" cast expression, such as static_cast or
3182 /// reinterpret_cast.
3184 /// By default, this routine dispatches to one of the more-specific routines
3185 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3186 /// Subclasses may override this routine to provide different behavior.
3187 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3188 Stmt::StmtClass Class,
3189 SourceLocation LAngleLoc,
3190 TypeSourceInfo *TInfo,
3191 SourceLocation RAngleLoc,
3192 SourceLocation LParenLoc,
3193 Expr *SubExpr,
3194 SourceLocation RParenLoc) {
3195 switch (Class) {
3196 case Stmt::CXXStaticCastExprClass:
3197 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3198 RAngleLoc, LParenLoc,
3199 SubExpr, RParenLoc);
3201 case Stmt::CXXDynamicCastExprClass:
3202 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3203 RAngleLoc, LParenLoc,
3204 SubExpr, RParenLoc);
3206 case Stmt::CXXReinterpretCastExprClass:
3207 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3208 RAngleLoc, LParenLoc,
3209 SubExpr,
3210 RParenLoc);
3212 case Stmt::CXXConstCastExprClass:
3213 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3214 RAngleLoc, LParenLoc,
3215 SubExpr, RParenLoc);
3217 case Stmt::CXXAddrspaceCastExprClass:
3218 return getDerived().RebuildCXXAddrspaceCastExpr(
3219 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3221 default:
3222 llvm_unreachable("Invalid C++ named cast");
3226 /// Build a new C++ static_cast expression.
3228 /// By default, performs semantic analysis to build the new expression.
3229 /// Subclasses may override this routine to provide different behavior.
3230 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3231 SourceLocation LAngleLoc,
3232 TypeSourceInfo *TInfo,
3233 SourceLocation RAngleLoc,
3234 SourceLocation LParenLoc,
3235 Expr *SubExpr,
3236 SourceLocation RParenLoc) {
3237 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3238 TInfo, SubExpr,
3239 SourceRange(LAngleLoc, RAngleLoc),
3240 SourceRange(LParenLoc, RParenLoc));
3243 /// Build a new C++ dynamic_cast expression.
3245 /// By default, performs semantic analysis to build the new expression.
3246 /// Subclasses may override this routine to provide different behavior.
3247 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3248 SourceLocation LAngleLoc,
3249 TypeSourceInfo *TInfo,
3250 SourceLocation RAngleLoc,
3251 SourceLocation LParenLoc,
3252 Expr *SubExpr,
3253 SourceLocation RParenLoc) {
3254 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3255 TInfo, SubExpr,
3256 SourceRange(LAngleLoc, RAngleLoc),
3257 SourceRange(LParenLoc, RParenLoc));
3260 /// Build a new C++ reinterpret_cast expression.
3262 /// By default, performs semantic analysis to build the new expression.
3263 /// Subclasses may override this routine to provide different behavior.
3264 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3265 SourceLocation LAngleLoc,
3266 TypeSourceInfo *TInfo,
3267 SourceLocation RAngleLoc,
3268 SourceLocation LParenLoc,
3269 Expr *SubExpr,
3270 SourceLocation RParenLoc) {
3271 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3272 TInfo, SubExpr,
3273 SourceRange(LAngleLoc, RAngleLoc),
3274 SourceRange(LParenLoc, RParenLoc));
3277 /// Build a new C++ const_cast expression.
3279 /// By default, performs semantic analysis to build the new expression.
3280 /// Subclasses may override this routine to provide different behavior.
3281 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3282 SourceLocation LAngleLoc,
3283 TypeSourceInfo *TInfo,
3284 SourceLocation RAngleLoc,
3285 SourceLocation LParenLoc,
3286 Expr *SubExpr,
3287 SourceLocation RParenLoc) {
3288 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3289 TInfo, SubExpr,
3290 SourceRange(LAngleLoc, RAngleLoc),
3291 SourceRange(LParenLoc, RParenLoc));
3294 ExprResult
3295 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3296 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3297 SourceLocation LParenLoc, Expr *SubExpr,
3298 SourceLocation RParenLoc) {
3299 return getSema().BuildCXXNamedCast(
3300 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3301 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3304 /// Build a new C++ functional-style cast expression.
3306 /// By default, performs semantic analysis to build the new expression.
3307 /// Subclasses may override this routine to provide different behavior.
3308 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3309 SourceLocation LParenLoc,
3310 Expr *Sub,
3311 SourceLocation RParenLoc,
3312 bool ListInitialization) {
3313 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3314 // CXXParenListInitExpr. Pass its expanded arguments so that the
3315 // CXXParenListInitExpr can be rebuilt.
3316 if (auto *PLE = dyn_cast<ParenListExpr>(Sub))
3317 return getSema().BuildCXXTypeConstructExpr(
3318 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3319 RParenLoc, ListInitialization);
3320 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3321 MultiExprArg(&Sub, 1), RParenLoc,
3322 ListInitialization);
3325 /// Build a new C++ __builtin_bit_cast expression.
3327 /// By default, performs semantic analysis to build the new expression.
3328 /// Subclasses may override this routine to provide different behavior.
3329 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3330 TypeSourceInfo *TSI, Expr *Sub,
3331 SourceLocation RParenLoc) {
3332 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3335 /// Build a new C++ typeid(type) expression.
3337 /// By default, performs semantic analysis to build the new expression.
3338 /// Subclasses may override this routine to provide different behavior.
3339 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3340 SourceLocation TypeidLoc,
3341 TypeSourceInfo *Operand,
3342 SourceLocation RParenLoc) {
3343 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3344 RParenLoc);
3348 /// Build a new C++ typeid(expr) expression.
3350 /// By default, performs semantic analysis to build the new expression.
3351 /// Subclasses may override this routine to provide different behavior.
3352 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3353 SourceLocation TypeidLoc,
3354 Expr *Operand,
3355 SourceLocation RParenLoc) {
3356 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3357 RParenLoc);
3360 /// Build a new C++ __uuidof(type) expression.
3362 /// By default, performs semantic analysis to build the new expression.
3363 /// Subclasses may override this routine to provide different behavior.
3364 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3365 TypeSourceInfo *Operand,
3366 SourceLocation RParenLoc) {
3367 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3370 /// Build a new C++ __uuidof(expr) expression.
3372 /// By default, performs semantic analysis to build the new expression.
3373 /// Subclasses may override this routine to provide different behavior.
3374 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3375 Expr *Operand, SourceLocation RParenLoc) {
3376 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3379 /// Build a new C++ "this" expression.
3381 /// By default, performs semantic analysis to build a new "this" expression.
3382 /// Subclasses may override this routine to provide different behavior.
3383 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3384 QualType ThisType,
3385 bool isImplicit) {
3386 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3387 return ExprError();
3388 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3391 /// Build a new C++ throw expression.
3393 /// By default, performs semantic analysis to build the new expression.
3394 /// Subclasses may override this routine to provide different behavior.
3395 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3396 bool IsThrownVariableInScope) {
3397 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3400 /// Build a new C++ default-argument expression.
3402 /// By default, builds a new default-argument expression, which does not
3403 /// require any semantic analysis. Subclasses may override this routine to
3404 /// provide different behavior.
3405 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3406 Expr *RewrittenExpr) {
3407 return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param,
3408 RewrittenExpr, getSema().CurContext);
3411 /// Build a new C++11 default-initialization expression.
3413 /// By default, builds a new default field initialization expression, which
3414 /// does not require any semantic analysis. Subclasses may override this
3415 /// routine to provide different behavior.
3416 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3417 FieldDecl *Field) {
3418 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3421 /// Build a new C++ zero-initialization expression.
3423 /// By default, performs semantic analysis to build the new expression.
3424 /// Subclasses may override this routine to provide different behavior.
3425 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3426 SourceLocation LParenLoc,
3427 SourceLocation RParenLoc) {
3428 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3429 /*ListInitialization=*/false);
3432 /// Build a new C++ "new" expression.
3434 /// By default, performs semantic analysis to build the new expression.
3435 /// Subclasses may override this routine to provide different behavior.
3436 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3437 SourceLocation PlacementLParen,
3438 MultiExprArg PlacementArgs,
3439 SourceLocation PlacementRParen,
3440 SourceRange TypeIdParens, QualType AllocatedType,
3441 TypeSourceInfo *AllocatedTypeInfo,
3442 std::optional<Expr *> ArraySize,
3443 SourceRange DirectInitRange, Expr *Initializer) {
3444 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3445 PlacementLParen,
3446 PlacementArgs,
3447 PlacementRParen,
3448 TypeIdParens,
3449 AllocatedType,
3450 AllocatedTypeInfo,
3451 ArraySize,
3452 DirectInitRange,
3453 Initializer);
3456 /// Build a new C++ "delete" expression.
3458 /// By default, performs semantic analysis to build the new expression.
3459 /// Subclasses may override this routine to provide different behavior.
3460 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3461 bool IsGlobalDelete,
3462 bool IsArrayForm,
3463 Expr *Operand) {
3464 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3465 Operand);
3468 /// Build a new type trait expression.
3470 /// By default, performs semantic analysis to build the new expression.
3471 /// Subclasses may override this routine to provide different behavior.
3472 ExprResult RebuildTypeTrait(TypeTrait Trait,
3473 SourceLocation StartLoc,
3474 ArrayRef<TypeSourceInfo *> Args,
3475 SourceLocation RParenLoc) {
3476 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3479 /// Build a new array type trait expression.
3481 /// By default, performs semantic analysis to build the new expression.
3482 /// Subclasses may override this routine to provide different behavior.
3483 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3484 SourceLocation StartLoc,
3485 TypeSourceInfo *TSInfo,
3486 Expr *DimExpr,
3487 SourceLocation RParenLoc) {
3488 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3491 /// Build a new expression trait expression.
3493 /// By default, performs semantic analysis to build the new expression.
3494 /// Subclasses may override this routine to provide different behavior.
3495 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3496 SourceLocation StartLoc,
3497 Expr *Queried,
3498 SourceLocation RParenLoc) {
3499 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3502 /// Build a new (previously unresolved) declaration reference
3503 /// expression.
3505 /// By default, performs semantic analysis to build the new expression.
3506 /// Subclasses may override this routine to provide different behavior.
3507 ExprResult RebuildDependentScopeDeclRefExpr(
3508 NestedNameSpecifierLoc QualifierLoc,
3509 SourceLocation TemplateKWLoc,
3510 const DeclarationNameInfo &NameInfo,
3511 const TemplateArgumentListInfo *TemplateArgs,
3512 bool IsAddressOfOperand,
3513 TypeSourceInfo **RecoveryTSI) {
3514 CXXScopeSpec SS;
3515 SS.Adopt(QualifierLoc);
3517 if (TemplateArgs || TemplateKWLoc.isValid())
3518 return getSema().BuildQualifiedTemplateIdExpr(
3519 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3521 return getSema().BuildQualifiedDeclarationNameExpr(
3522 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3525 /// Build a new template-id expression.
3527 /// By default, performs semantic analysis to build the new expression.
3528 /// Subclasses may override this routine to provide different behavior.
3529 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3530 SourceLocation TemplateKWLoc,
3531 LookupResult &R,
3532 bool RequiresADL,
3533 const TemplateArgumentListInfo *TemplateArgs) {
3534 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3535 TemplateArgs);
3538 /// Build a new object-construction expression.
3540 /// By default, performs semantic analysis to build the new expression.
3541 /// Subclasses may override this routine to provide different behavior.
3542 ExprResult RebuildCXXConstructExpr(
3543 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3544 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3545 bool ListInitialization, bool StdInitListInitialization,
3546 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3547 SourceRange ParenRange) {
3548 // Reconstruct the constructor we originally found, which might be
3549 // different if this is a call to an inherited constructor.
3550 CXXConstructorDecl *FoundCtor = Constructor;
3551 if (Constructor->isInheritingConstructor())
3552 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3554 SmallVector<Expr *, 8> ConvertedArgs;
3555 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3556 ConvertedArgs))
3557 return ExprError();
3559 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3560 IsElidable,
3561 ConvertedArgs,
3562 HadMultipleCandidates,
3563 ListInitialization,
3564 StdInitListInitialization,
3565 RequiresZeroInit, ConstructKind,
3566 ParenRange);
3569 /// Build a new implicit construction via inherited constructor
3570 /// expression.
3571 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3572 CXXConstructorDecl *Constructor,
3573 bool ConstructsVBase,
3574 bool InheritedFromVBase) {
3575 return new (getSema().Context) CXXInheritedCtorInitExpr(
3576 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3579 /// Build a new object-construction expression.
3581 /// By default, performs semantic analysis to build the new expression.
3582 /// Subclasses may override this routine to provide different behavior.
3583 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3584 SourceLocation LParenOrBraceLoc,
3585 MultiExprArg Args,
3586 SourceLocation RParenOrBraceLoc,
3587 bool ListInitialization) {
3588 return getSema().BuildCXXTypeConstructExpr(
3589 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3592 /// Build a new object-construction expression.
3594 /// By default, performs semantic analysis to build the new expression.
3595 /// Subclasses may override this routine to provide different behavior.
3596 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3597 SourceLocation LParenLoc,
3598 MultiExprArg Args,
3599 SourceLocation RParenLoc,
3600 bool ListInitialization) {
3601 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3602 RParenLoc, ListInitialization);
3605 /// Build a new member reference expression.
3607 /// By default, performs semantic analysis to build the new expression.
3608 /// Subclasses may override this routine to provide different behavior.
3609 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3610 QualType BaseType,
3611 bool IsArrow,
3612 SourceLocation OperatorLoc,
3613 NestedNameSpecifierLoc QualifierLoc,
3614 SourceLocation TemplateKWLoc,
3615 NamedDecl *FirstQualifierInScope,
3616 const DeclarationNameInfo &MemberNameInfo,
3617 const TemplateArgumentListInfo *TemplateArgs) {
3618 CXXScopeSpec SS;
3619 SS.Adopt(QualifierLoc);
3621 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3622 OperatorLoc, IsArrow,
3623 SS, TemplateKWLoc,
3624 FirstQualifierInScope,
3625 MemberNameInfo,
3626 TemplateArgs, /*S*/nullptr);
3629 /// Build a new member reference expression.
3631 /// By default, performs semantic analysis to build the new expression.
3632 /// Subclasses may override this routine to provide different behavior.
3633 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3634 SourceLocation OperatorLoc,
3635 bool IsArrow,
3636 NestedNameSpecifierLoc QualifierLoc,
3637 SourceLocation TemplateKWLoc,
3638 NamedDecl *FirstQualifierInScope,
3639 LookupResult &R,
3640 const TemplateArgumentListInfo *TemplateArgs) {
3641 CXXScopeSpec SS;
3642 SS.Adopt(QualifierLoc);
3644 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3645 OperatorLoc, IsArrow,
3646 SS, TemplateKWLoc,
3647 FirstQualifierInScope,
3648 R, TemplateArgs, /*S*/nullptr);
3651 /// Build a new noexcept expression.
3653 /// By default, performs semantic analysis to build the new expression.
3654 /// Subclasses may override this routine to provide different behavior.
3655 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3656 return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd());
3659 /// Build a new expression to compute the length of a parameter pack.
3660 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3661 SourceLocation PackLoc,
3662 SourceLocation RParenLoc,
3663 std::optional<unsigned> Length,
3664 ArrayRef<TemplateArgument> PartialArgs) {
3665 return SizeOfPackExpr::Create(SemaRef.Context, OperatorLoc, Pack, PackLoc,
3666 RParenLoc, Length, PartialArgs);
3669 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3670 SourceLocation RSquareLoc,
3671 Expr *PackIdExpression, Expr *IndexExpr,
3672 ArrayRef<Expr *> ExpandedExprs,
3673 bool FullySubstituted = false) {
3674 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3675 IndexExpr, RSquareLoc, ExpandedExprs,
3676 FullySubstituted);
3679 /// Build a new expression representing a call to a source location
3680 /// builtin.
3682 /// By default, performs semantic analysis to build the new expression.
3683 /// Subclasses may override this routine to provide different behavior.
3684 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3685 SourceLocation BuiltinLoc,
3686 SourceLocation RPLoc,
3687 DeclContext *ParentContext) {
3688 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3689 ParentContext);
3692 /// Build a new Objective-C boxed expression.
3694 /// By default, performs semantic analysis to build the new expression.
3695 /// Subclasses may override this routine to provide different behavior.
3696 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3697 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3698 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3699 TemplateArgumentListInfo *TALI) {
3700 CXXScopeSpec SS;
3701 SS.Adopt(NNS);
3702 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3703 ConceptNameInfo,
3704 FoundDecl,
3705 NamedConcept, TALI);
3706 if (Result.isInvalid())
3707 return ExprError();
3708 return Result;
3711 /// \brief Build a new requires expression.
3713 /// By default, performs semantic analysis to build the new expression.
3714 /// Subclasses may override this routine to provide different behavior.
3715 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3716 RequiresExprBodyDecl *Body,
3717 SourceLocation LParenLoc,
3718 ArrayRef<ParmVarDecl *> LocalParameters,
3719 SourceLocation RParenLoc,
3720 ArrayRef<concepts::Requirement *> Requirements,
3721 SourceLocation ClosingBraceLoc) {
3722 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3723 LocalParameters, RParenLoc, Requirements,
3724 ClosingBraceLoc);
3727 concepts::TypeRequirement *
3728 RebuildTypeRequirement(
3729 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3730 return SemaRef.BuildTypeRequirement(SubstDiag);
3733 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3734 return SemaRef.BuildTypeRequirement(T);
3737 concepts::ExprRequirement *
3738 RebuildExprRequirement(
3739 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3740 SourceLocation NoexceptLoc,
3741 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3742 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
3743 std::move(Ret));
3746 concepts::ExprRequirement *
3747 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3748 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3749 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
3750 std::move(Ret));
3753 concepts::NestedRequirement *
3754 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3755 const ASTConstraintSatisfaction &Satisfaction) {
3756 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3757 Satisfaction);
3760 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3761 return SemaRef.BuildNestedRequirement(Constraint);
3764 /// \brief Build a new Objective-C boxed expression.
3766 /// By default, performs semantic analysis to build the new expression.
3767 /// Subclasses may override this routine to provide different behavior.
3768 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3769 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3772 /// Build a new Objective-C array literal.
3774 /// By default, performs semantic analysis to build the new expression.
3775 /// Subclasses may override this routine to provide different behavior.
3776 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3777 Expr **Elements, unsigned NumElements) {
3778 return getSema().ObjC().BuildObjCArrayLiteral(
3779 Range, MultiExprArg(Elements, NumElements));
3782 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3783 Expr *Base, Expr *Key,
3784 ObjCMethodDecl *getterMethod,
3785 ObjCMethodDecl *setterMethod) {
3786 return getSema().ObjC().BuildObjCSubscriptExpression(
3787 RB, Base, Key, getterMethod, setterMethod);
3790 /// Build a new Objective-C dictionary literal.
3792 /// By default, performs semantic analysis to build the new expression.
3793 /// Subclasses may override this routine to provide different behavior.
3794 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3795 MutableArrayRef<ObjCDictionaryElement> Elements) {
3796 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3799 /// Build a new Objective-C \@encode expression.
3801 /// By default, performs semantic analysis to build the new expression.
3802 /// Subclasses may override this routine to provide different behavior.
3803 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3804 TypeSourceInfo *EncodeTypeInfo,
3805 SourceLocation RParenLoc) {
3806 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
3807 RParenLoc);
3810 /// Build a new Objective-C class message.
3811 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3812 Selector Sel,
3813 ArrayRef<SourceLocation> SelectorLocs,
3814 ObjCMethodDecl *Method,
3815 SourceLocation LBracLoc,
3816 MultiExprArg Args,
3817 SourceLocation RBracLoc) {
3818 return SemaRef.ObjC().BuildClassMessage(
3819 ReceiverTypeInfo, ReceiverTypeInfo->getType(),
3820 /*SuperLoc=*/SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3821 RBracLoc, Args);
3824 /// Build a new Objective-C instance message.
3825 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3826 Selector Sel,
3827 ArrayRef<SourceLocation> SelectorLocs,
3828 ObjCMethodDecl *Method,
3829 SourceLocation LBracLoc,
3830 MultiExprArg Args,
3831 SourceLocation RBracLoc) {
3832 return SemaRef.ObjC().BuildInstanceMessage(Receiver, Receiver->getType(),
3833 /*SuperLoc=*/SourceLocation(),
3834 Sel, Method, LBracLoc,
3835 SelectorLocs, RBracLoc, Args);
3838 /// Build a new Objective-C instance/class message to 'super'.
3839 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3840 Selector Sel,
3841 ArrayRef<SourceLocation> SelectorLocs,
3842 QualType SuperType,
3843 ObjCMethodDecl *Method,
3844 SourceLocation LBracLoc,
3845 MultiExprArg Args,
3846 SourceLocation RBracLoc) {
3847 return Method->isInstanceMethod()
3848 ? SemaRef.ObjC().BuildInstanceMessage(
3849 nullptr, SuperType, SuperLoc, Sel, Method, LBracLoc,
3850 SelectorLocs, RBracLoc, Args)
3851 : SemaRef.ObjC().BuildClassMessage(nullptr, SuperType, SuperLoc,
3852 Sel, Method, LBracLoc,
3853 SelectorLocs, RBracLoc, Args);
3856 /// Build a new Objective-C ivar reference expression.
3858 /// By default, performs semantic analysis to build the new expression.
3859 /// Subclasses may override this routine to provide different behavior.
3860 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3861 SourceLocation IvarLoc,
3862 bool IsArrow, bool IsFreeIvar) {
3863 CXXScopeSpec SS;
3864 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3865 ExprResult Result = getSema().BuildMemberReferenceExpr(
3866 BaseArg, BaseArg->getType(),
3867 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3868 /*FirstQualifierInScope=*/nullptr, NameInfo,
3869 /*TemplateArgs=*/nullptr,
3870 /*S=*/nullptr);
3871 if (IsFreeIvar && Result.isUsable())
3872 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
3873 return Result;
3876 /// Build a new Objective-C property reference expression.
3878 /// By default, performs semantic analysis to build the new expression.
3879 /// Subclasses may override this routine to provide different behavior.
3880 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3881 ObjCPropertyDecl *Property,
3882 SourceLocation PropertyLoc) {
3883 CXXScopeSpec SS;
3884 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3885 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3886 /*FIXME:*/PropertyLoc,
3887 /*IsArrow=*/false,
3888 SS, SourceLocation(),
3889 /*FirstQualifierInScope=*/nullptr,
3890 NameInfo,
3891 /*TemplateArgs=*/nullptr,
3892 /*S=*/nullptr);
3895 /// Build a new Objective-C property reference expression.
3897 /// By default, performs semantic analysis to build the new expression.
3898 /// Subclasses may override this routine to provide different behavior.
3899 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3900 ObjCMethodDecl *Getter,
3901 ObjCMethodDecl *Setter,
3902 SourceLocation PropertyLoc) {
3903 // Since these expressions can only be value-dependent, we do not
3904 // need to perform semantic analysis again.
3905 return Owned(
3906 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3907 VK_LValue, OK_ObjCProperty,
3908 PropertyLoc, Base));
3911 /// Build a new Objective-C "isa" expression.
3913 /// By default, performs semantic analysis to build the new expression.
3914 /// Subclasses may override this routine to provide different behavior.
3915 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
3916 SourceLocation OpLoc, bool IsArrow) {
3917 CXXScopeSpec SS;
3918 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3919 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3920 OpLoc, IsArrow,
3921 SS, SourceLocation(),
3922 /*FirstQualifierInScope=*/nullptr,
3923 NameInfo,
3924 /*TemplateArgs=*/nullptr,
3925 /*S=*/nullptr);
3928 /// Build a new shuffle vector expression.
3930 /// By default, performs semantic analysis to build the new expression.
3931 /// Subclasses may override this routine to provide different behavior.
3932 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
3933 MultiExprArg SubExprs,
3934 SourceLocation RParenLoc) {
3935 // Find the declaration for __builtin_shufflevector
3936 const IdentifierInfo &Name
3937 = SemaRef.Context.Idents.get("__builtin_shufflevector");
3938 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
3939 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
3940 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3942 // Build a reference to the __builtin_shufflevector builtin
3943 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
3944 Expr *Callee = new (SemaRef.Context)
3945 DeclRefExpr(SemaRef.Context, Builtin, false,
3946 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3947 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
3948 Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
3949 CK_BuiltinFnToFnPtr).get();
3951 // Build the CallExpr
3952 ExprResult TheCall = CallExpr::Create(
3953 SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
3954 Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc,
3955 FPOptionsOverride());
3957 // Type-check the __builtin_shufflevector expression.
3958 return SemaRef.BuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
3961 /// Build a new convert vector expression.
3962 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
3963 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3964 SourceLocation RParenLoc) {
3965 return SemaRef.ConvertVectorExpr(SrcExpr, DstTInfo, BuiltinLoc, RParenLoc);
3968 /// Build a new template argument pack expansion.
3970 /// By default, performs semantic analysis to build a new pack expansion
3971 /// for a template argument. Subclasses may override this routine to provide
3972 /// different behavior.
3973 TemplateArgumentLoc
3974 RebuildPackExpansion(TemplateArgumentLoc Pattern, SourceLocation EllipsisLoc,
3975 std::optional<unsigned> NumExpansions) {
3976 switch (Pattern.getArgument().getKind()) {
3977 case TemplateArgument::Expression: {
3978 ExprResult Result
3979 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
3980 EllipsisLoc, NumExpansions);
3981 if (Result.isInvalid())
3982 return TemplateArgumentLoc();
3984 return TemplateArgumentLoc(Result.get(), Result.get());
3987 case TemplateArgument::Template:
3988 return TemplateArgumentLoc(
3989 SemaRef.Context,
3990 TemplateArgument(Pattern.getArgument().getAsTemplate(),
3991 NumExpansions),
3992 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
3993 EllipsisLoc);
3995 case TemplateArgument::Null:
3996 case TemplateArgument::Integral:
3997 case TemplateArgument::Declaration:
3998 case TemplateArgument::StructuralValue:
3999 case TemplateArgument::Pack:
4000 case TemplateArgument::TemplateExpansion:
4001 case TemplateArgument::NullPtr:
4002 llvm_unreachable("Pack expansion pattern has no parameter packs");
4004 case TemplateArgument::Type:
4005 if (TypeSourceInfo *Expansion
4006 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4007 EllipsisLoc,
4008 NumExpansions))
4009 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4010 Expansion);
4011 break;
4014 return TemplateArgumentLoc();
4017 /// Build a new expression pack expansion.
4019 /// By default, performs semantic analysis to build a new pack expansion
4020 /// for an expression. Subclasses may override this routine to provide
4021 /// different behavior.
4022 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4023 std::optional<unsigned> NumExpansions) {
4024 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4027 /// Build a new C++1z fold-expression.
4029 /// By default, performs semantic analysis in order to build a new fold
4030 /// expression.
4031 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4032 SourceLocation LParenLoc, Expr *LHS,
4033 BinaryOperatorKind Operator,
4034 SourceLocation EllipsisLoc, Expr *RHS,
4035 SourceLocation RParenLoc,
4036 std::optional<unsigned> NumExpansions) {
4037 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4038 EllipsisLoc, RHS, RParenLoc,
4039 NumExpansions);
4042 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4043 LambdaScopeInfo *LSI) {
4044 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4045 if (Expr *Init = PVD->getInit())
4046 LSI->ContainsUnexpandedParameterPack |=
4047 Init->containsUnexpandedParameterPack();
4048 else if (PVD->hasUninstantiatedDefaultArg())
4049 LSI->ContainsUnexpandedParameterPack |=
4050 PVD->getUninstantiatedDefaultArg()
4051 ->containsUnexpandedParameterPack();
4053 return getSema().BuildLambdaExpr(StartLoc, EndLoc, LSI);
4056 /// Build an empty C++1z fold-expression with the given operator.
4058 /// By default, produces the fallback value for the fold-expression, or
4059 /// produce an error if there is no fallback value.
4060 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4061 BinaryOperatorKind Operator) {
4062 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4065 /// Build a new atomic operation expression.
4067 /// By default, performs semantic analysis to build the new expression.
4068 /// Subclasses may override this routine to provide different behavior.
4069 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4070 AtomicExpr::AtomicOp Op,
4071 SourceLocation RParenLoc) {
4072 // Use this for all of the locations, since we don't know the difference
4073 // between the call and the expr at this point.
4074 SourceRange Range{BuiltinLoc, RParenLoc};
4075 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4076 Sema::AtomicArgumentOrder::AST);
4079 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4080 ArrayRef<Expr *> SubExprs, QualType Type) {
4081 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4084 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4085 SourceLocation BeginLoc,
4086 SourceLocation DirLoc,
4087 SourceLocation EndLoc,
4088 ArrayRef<OpenACCClause *> Clauses,
4089 StmtResult StrBlock) {
4090 return getSema().OpenACC().ActOnEndStmtDirective(K, BeginLoc, DirLoc,
4091 EndLoc, Clauses, StrBlock);
4094 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4095 SourceLocation DirLoc,
4096 SourceLocation EndLoc,
4097 ArrayRef<OpenACCClause *> Clauses,
4098 StmtResult Loop) {
4099 return getSema().OpenACC().ActOnEndStmtDirective(
4100 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, EndLoc, Clauses, Loop);
4103 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4104 SourceLocation BeginLoc,
4105 SourceLocation DirLoc,
4106 SourceLocation EndLoc,
4107 ArrayRef<OpenACCClause *> Clauses,
4108 StmtResult Loop) {
4109 return getSema().OpenACC().ActOnEndStmtDirective(K, BeginLoc, DirLoc,
4110 EndLoc, Clauses, Loop);
4113 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4114 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4117 private:
4118 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
4119 QualType ObjectType,
4120 NamedDecl *FirstQualifierInScope,
4121 CXXScopeSpec &SS);
4123 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4124 QualType ObjectType,
4125 NamedDecl *FirstQualifierInScope,
4126 CXXScopeSpec &SS);
4128 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
4129 NamedDecl *FirstQualifierInScope,
4130 CXXScopeSpec &SS);
4132 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4133 DependentNameTypeLoc TL,
4134 bool DeducibleTSTContext);
4136 llvm::SmallVector<OpenACCClause *>
4137 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4138 ArrayRef<const OpenACCClause *> OldClauses);
4140 OpenACCClause *
4141 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4142 OpenACCDirectiveKind DirKind,
4143 const OpenACCClause *OldClause);
4146 template <typename Derived>
4147 StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4148 if (!S)
4149 return S;
4151 switch (S->getStmtClass()) {
4152 case Stmt::NoStmtClass: break;
4154 // Transform individual statement nodes
4155 // Pass SDK into statements that can produce a value
4156 #define STMT(Node, Parent) \
4157 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4158 #define VALUESTMT(Node, Parent) \
4159 case Stmt::Node##Class: \
4160 return getDerived().Transform##Node(cast<Node>(S), SDK);
4161 #define ABSTRACT_STMT(Node)
4162 #define EXPR(Node, Parent)
4163 #include "clang/AST/StmtNodes.inc"
4165 // Transform expressions by calling TransformExpr.
4166 #define STMT(Node, Parent)
4167 #define ABSTRACT_STMT(Stmt)
4168 #define EXPR(Node, Parent) case Stmt::Node##Class:
4169 #include "clang/AST/StmtNodes.inc"
4171 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
4173 if (SDK == SDK_StmtExprResult)
4174 E = getSema().ActOnStmtExprResult(E);
4175 return getSema().ActOnExprStmt(E, SDK == SDK_Discarded);
4179 return S;
4182 template<typename Derived>
4183 OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4184 if (!S)
4185 return S;
4187 switch (S->getClauseKind()) {
4188 default: break;
4189 // Transform individual clause nodes
4190 #define GEN_CLANG_CLAUSE_CLASS
4191 #define CLAUSE_CLASS(Enum, Str, Class) \
4192 case Enum: \
4193 return getDerived().Transform##Class(cast<Class>(S));
4194 #include "llvm/Frontend/OpenMP/OMP.inc"
4197 return S;
4201 template<typename Derived>
4202 ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4203 if (!E)
4204 return E;
4206 switch (E->getStmtClass()) {
4207 case Stmt::NoStmtClass: break;
4208 #define STMT(Node, Parent) case Stmt::Node##Class: break;
4209 #define ABSTRACT_STMT(Stmt)
4210 #define EXPR(Node, Parent) \
4211 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4212 #include "clang/AST/StmtNodes.inc"
4215 return E;
4218 template<typename Derived>
4219 ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4220 bool NotCopyInit) {
4221 // Initializers are instantiated like expressions, except that various outer
4222 // layers are stripped.
4223 if (!Init)
4224 return Init;
4226 if (auto *FE = dyn_cast<FullExpr>(Init))
4227 Init = FE->getSubExpr();
4229 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {
4230 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4231 Init = OVE->getSourceExpr();
4234 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
4235 Init = MTE->getSubExpr();
4237 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
4238 Init = Binder->getSubExpr();
4240 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
4241 Init = ICE->getSubExprAsWritten();
4243 if (CXXStdInitializerListExpr *ILE =
4244 dyn_cast<CXXStdInitializerListExpr>(Init))
4245 return TransformInitializer(ILE->getSubExpr(), NotCopyInit);
4247 // If this is copy-initialization, we only need to reconstruct
4248 // InitListExprs. Other forms of copy-initialization will be a no-op if
4249 // the initializer is already the right type.
4250 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
4251 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4252 return getDerived().TransformExpr(Init);
4254 // Revert value-initialization back to empty parens.
4255 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
4256 SourceRange Parens = VIE->getSourceRange();
4257 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4258 Parens.getEnd());
4261 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4262 if (isa<ImplicitValueInitExpr>(Init))
4263 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4264 SourceLocation());
4266 // Revert initialization by constructor back to a parenthesized or braced list
4267 // of expressions. Any other form of initializer can just be reused directly.
4268 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
4269 return getDerived().TransformExpr(Init);
4271 // If the initialization implicitly converted an initializer list to a
4272 // std::initializer_list object, unwrap the std::initializer_list too.
4273 if (Construct && Construct->isStdInitListInitialization())
4274 return TransformInitializer(Construct->getArg(0), NotCopyInit);
4276 // Enter a list-init context if this was list initialization.
4277 EnterExpressionEvaluationContext Context(
4278 getSema(), EnterExpressionEvaluationContext::InitList,
4279 Construct->isListInitialization());
4281 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4282 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4283 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4284 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4285 SmallVector<Expr*, 8> NewArgs;
4286 bool ArgChanged = false;
4287 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4288 /*IsCall*/true, NewArgs, &ArgChanged))
4289 return ExprError();
4291 // If this was list initialization, revert to syntactic list form.
4292 if (Construct->isListInitialization())
4293 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4294 Construct->getEndLoc());
4296 // Build a ParenListExpr to represent anything else.
4297 SourceRange Parens = Construct->getParenOrBraceRange();
4298 if (Parens.isInvalid()) {
4299 // This was a variable declaration's initialization for which no initializer
4300 // was specified.
4301 assert(NewArgs.empty() &&
4302 "no parens or braces but have direct init with arguments?");
4303 return ExprEmpty();
4305 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4306 Parens.getEnd());
4309 template<typename Derived>
4310 bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4311 unsigned NumInputs,
4312 bool IsCall,
4313 SmallVectorImpl<Expr *> &Outputs,
4314 bool *ArgChanged) {
4315 for (unsigned I = 0; I != NumInputs; ++I) {
4316 // If requested, drop call arguments that need to be dropped.
4317 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4318 if (ArgChanged)
4319 *ArgChanged = true;
4321 break;
4324 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
4325 Expr *Pattern = Expansion->getPattern();
4327 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4328 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4329 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4331 // Determine whether the set of unexpanded parameter packs can and should
4332 // be expanded.
4333 bool Expand = true;
4334 bool RetainExpansion = false;
4335 std::optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions();
4336 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4337 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4338 Pattern->getSourceRange(),
4339 Unexpanded,
4340 Expand, RetainExpansion,
4341 NumExpansions))
4342 return true;
4344 if (!Expand) {
4345 // The transform has determined that we should perform a simple
4346 // transformation on the pack expansion, producing another pack
4347 // expansion.
4348 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4349 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4350 if (OutPattern.isInvalid())
4351 return true;
4353 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4354 Expansion->getEllipsisLoc(),
4355 NumExpansions);
4356 if (Out.isInvalid())
4357 return true;
4359 if (ArgChanged)
4360 *ArgChanged = true;
4361 Outputs.push_back(Out.get());
4362 continue;
4365 // Record right away that the argument was changed. This needs
4366 // to happen even if the array expands to nothing.
4367 if (ArgChanged) *ArgChanged = true;
4369 // The transform has determined that we should perform an elementwise
4370 // expansion of the pattern. Do so.
4371 for (unsigned I = 0; I != *NumExpansions; ++I) {
4372 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4373 ExprResult Out = getDerived().TransformExpr(Pattern);
4374 if (Out.isInvalid())
4375 return true;
4377 if (Out.get()->containsUnexpandedParameterPack()) {
4378 Out = getDerived().RebuildPackExpansion(
4379 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4380 if (Out.isInvalid())
4381 return true;
4384 Outputs.push_back(Out.get());
4387 // If we're supposed to retain a pack expansion, do so by temporarily
4388 // forgetting the partially-substituted parameter pack.
4389 if (RetainExpansion) {
4390 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4392 ExprResult Out = getDerived().TransformExpr(Pattern);
4393 if (Out.isInvalid())
4394 return true;
4396 Out = getDerived().RebuildPackExpansion(
4397 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4398 if (Out.isInvalid())
4399 return true;
4401 Outputs.push_back(Out.get());
4404 continue;
4407 ExprResult Result =
4408 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4409 : getDerived().TransformExpr(Inputs[I]);
4410 if (Result.isInvalid())
4411 return true;
4413 if (Result.get() != Inputs[I] && ArgChanged)
4414 *ArgChanged = true;
4416 Outputs.push_back(Result.get());
4419 return false;
4422 template <typename Derived>
4423 Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4424 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4425 if (Var) {
4426 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4427 getDerived().TransformDefinition(Var->getLocation(), Var));
4429 if (!ConditionVar)
4430 return Sema::ConditionError();
4432 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4435 if (Expr) {
4436 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4438 if (CondExpr.isInvalid())
4439 return Sema::ConditionError();
4441 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4442 /*MissingOK=*/true);
4445 return Sema::ConditionResult();
4448 template <typename Derived>
4449 NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4450 NestedNameSpecifierLoc NNS, QualType ObjectType,
4451 NamedDecl *FirstQualifierInScope) {
4452 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4454 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4455 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4456 Qualifier = Qualifier.getPrefix())
4457 Qualifiers.push_back(Qualifier);
4459 insertNNS(NNS);
4461 CXXScopeSpec SS;
4462 while (!Qualifiers.empty()) {
4463 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4464 NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
4466 switch (QNNS->getKind()) {
4467 case NestedNameSpecifier::Identifier: {
4468 Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
4469 Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
4470 ObjectType);
4471 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false,
4472 SS, FirstQualifierInScope, false))
4473 return NestedNameSpecifierLoc();
4474 break;
4477 case NestedNameSpecifier::Namespace: {
4478 NamespaceDecl *NS =
4479 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4480 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4481 SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
4482 break;
4485 case NestedNameSpecifier::NamespaceAlias: {
4486 NamespaceAliasDecl *Alias =
4487 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4488 Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
4489 SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
4490 Q.getLocalEndLoc());
4491 break;
4494 case NestedNameSpecifier::Global:
4495 // There is no meaningful transformation that one could perform on the
4496 // global scope.
4497 SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
4498 break;
4500 case NestedNameSpecifier::Super: {
4501 CXXRecordDecl *RD =
4502 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4503 SourceLocation(), QNNS->getAsRecordDecl()));
4504 SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc());
4505 break;
4508 case NestedNameSpecifier::TypeSpecWithTemplate:
4509 case NestedNameSpecifier::TypeSpec: {
4510 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4511 FirstQualifierInScope, SS);
4513 if (!TL)
4514 return NestedNameSpecifierLoc();
4516 QualType T = TL.getType();
4517 if (T->isDependentType() || T->isRecordType() ||
4518 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4519 if (T->isEnumeralType())
4520 SemaRef.Diag(TL.getBeginLoc(),
4521 diag::warn_cxx98_compat_enum_nested_name_spec);
4523 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4524 SS.Adopt(ETL.getQualifierLoc());
4525 TL = ETL.getNamedTypeLoc();
4528 SS.Extend(SemaRef.Context, TL.getTemplateKeywordLoc(), TL,
4529 Q.getLocalEndLoc());
4530 break;
4532 // If the nested-name-specifier is an invalid type def, don't emit an
4533 // error because a previous error should have already been emitted.
4534 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4535 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4536 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
4537 << T << SS.getRange();
4539 return NestedNameSpecifierLoc();
4543 // The qualifier-in-scope and object type only apply to the leftmost entity.
4544 FirstQualifierInScope = nullptr;
4545 ObjectType = QualType();
4548 // Don't rebuild the nested-name-specifier if we don't have to.
4549 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4550 !getDerived().AlwaysRebuild())
4551 return NNS;
4553 // If we can re-use the source-location data from the original
4554 // nested-name-specifier, do so.
4555 if (SS.location_size() == NNS.getDataLength() &&
4556 memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)
4557 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4559 // Allocate new nested-name-specifier location information.
4560 return SS.getWithLocInContext(SemaRef.Context);
4563 template<typename Derived>
4564 DeclarationNameInfo
4565 TreeTransform<Derived>
4566 ::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4567 DeclarationName Name = NameInfo.getName();
4568 if (!Name)
4569 return DeclarationNameInfo();
4571 switch (Name.getNameKind()) {
4572 case DeclarationName::Identifier:
4573 case DeclarationName::ObjCZeroArgSelector:
4574 case DeclarationName::ObjCOneArgSelector:
4575 case DeclarationName::ObjCMultiArgSelector:
4576 case DeclarationName::CXXOperatorName:
4577 case DeclarationName::CXXLiteralOperatorName:
4578 case DeclarationName::CXXUsingDirective:
4579 return NameInfo;
4581 case DeclarationName::CXXDeductionGuideName: {
4582 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4583 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4584 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4585 if (!NewTemplate)
4586 return DeclarationNameInfo();
4588 DeclarationNameInfo NewNameInfo(NameInfo);
4589 NewNameInfo.setName(
4590 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(NewTemplate));
4591 return NewNameInfo;
4594 case DeclarationName::CXXConstructorName:
4595 case DeclarationName::CXXDestructorName:
4596 case DeclarationName::CXXConversionFunctionName: {
4597 TypeSourceInfo *NewTInfo;
4598 CanQualType NewCanTy;
4599 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4600 NewTInfo = getDerived().TransformType(OldTInfo);
4601 if (!NewTInfo)
4602 return DeclarationNameInfo();
4603 NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
4605 else {
4606 NewTInfo = nullptr;
4607 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4608 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4609 if (NewT.isNull())
4610 return DeclarationNameInfo();
4611 NewCanTy = SemaRef.Context.getCanonicalType(NewT);
4614 DeclarationName NewName
4615 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
4616 NewCanTy);
4617 DeclarationNameInfo NewNameInfo(NameInfo);
4618 NewNameInfo.setName(NewName);
4619 NewNameInfo.setNamedTypeInfo(NewTInfo);
4620 return NewNameInfo;
4624 llvm_unreachable("Unknown name kind.");
4627 template<typename Derived>
4628 TemplateName
4629 TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
4630 TemplateName Name,
4631 SourceLocation NameLoc,
4632 QualType ObjectType,
4633 NamedDecl *FirstQualifierInScope,
4634 bool AllowInjectedClassName) {
4635 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4636 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4637 assert(Template && "qualified template name must refer to a template");
4639 TemplateDecl *TransTemplate
4640 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4641 Template));
4642 if (!TransTemplate)
4643 return TemplateName();
4645 if (!getDerived().AlwaysRebuild() &&
4646 SS.getScopeRep() == QTN->getQualifier() &&
4647 TransTemplate == Template)
4648 return Name;
4650 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4651 TransTemplate);
4654 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4655 if (SS.getScopeRep()) {
4656 // These apply to the scope specifier, not the template.
4657 ObjectType = QualType();
4658 FirstQualifierInScope = nullptr;
4661 if (!getDerived().AlwaysRebuild() &&
4662 SS.getScopeRep() == DTN->getQualifier() &&
4663 ObjectType.isNull())
4664 return Name;
4666 // FIXME: Preserve the location of the "template" keyword.
4667 SourceLocation TemplateKWLoc = NameLoc;
4669 if (DTN->isIdentifier()) {
4670 return getDerived().RebuildTemplateName(SS,
4671 TemplateKWLoc,
4672 *DTN->getIdentifier(),
4673 NameLoc,
4674 ObjectType,
4675 FirstQualifierInScope,
4676 AllowInjectedClassName);
4679 return getDerived().RebuildTemplateName(SS, TemplateKWLoc,
4680 DTN->getOperator(), NameLoc,
4681 ObjectType, AllowInjectedClassName);
4684 // FIXME: Try to preserve more of the TemplateName.
4685 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4686 TemplateDecl *TransTemplate
4687 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4688 Template));
4689 if (!TransTemplate)
4690 return TemplateName();
4692 return getDerived().RebuildTemplateName(SS, /*TemplateKeyword=*/false,
4693 TransTemplate);
4696 if (SubstTemplateTemplateParmPackStorage *SubstPack
4697 = Name.getAsSubstTemplateTemplateParmPack()) {
4698 return getDerived().RebuildTemplateName(
4699 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4700 SubstPack->getIndex(), SubstPack->getFinal());
4703 // These should be getting filtered out before they reach the AST.
4704 llvm_unreachable("overloaded function decl survived to here");
4707 template<typename Derived>
4708 void TreeTransform<Derived>::InventTemplateArgumentLoc(
4709 const TemplateArgument &Arg,
4710 TemplateArgumentLoc &Output) {
4711 Output = getSema().getTrivialTemplateArgumentLoc(
4712 Arg, QualType(), getDerived().getBaseLocation());
4715 template <typename Derived>
4716 bool TreeTransform<Derived>::TransformTemplateArgument(
4717 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4718 bool Uneval) {
4719 const TemplateArgument &Arg = Input.getArgument();
4720 switch (Arg.getKind()) {
4721 case TemplateArgument::Null:
4722 case TemplateArgument::Pack:
4723 llvm_unreachable("Unexpected TemplateArgument");
4725 case TemplateArgument::Integral:
4726 case TemplateArgument::NullPtr:
4727 case TemplateArgument::Declaration:
4728 case TemplateArgument::StructuralValue: {
4729 // Transform a resolved template argument straight to a resolved template
4730 // argument. We get here when substituting into an already-substituted
4731 // template type argument during concept satisfaction checking.
4732 QualType T = Arg.getNonTypeTemplateArgumentType();
4733 QualType NewT = getDerived().TransformType(T);
4734 if (NewT.isNull())
4735 return true;
4737 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
4738 ? Arg.getAsDecl()
4739 : nullptr;
4740 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4741 getDerived().getBaseLocation(), D))
4742 : nullptr;
4743 if (D && !NewD)
4744 return true;
4746 if (NewT == T && D == NewD)
4747 Output = Input;
4748 else if (Arg.getKind() == TemplateArgument::Integral)
4749 Output = TemplateArgumentLoc(
4750 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4751 TemplateArgumentLocInfo());
4752 else if (Arg.getKind() == TemplateArgument::NullPtr)
4753 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4754 TemplateArgumentLocInfo());
4755 else if (Arg.getKind() == TemplateArgument::Declaration)
4756 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4757 TemplateArgumentLocInfo());
4758 else if (Arg.getKind() == TemplateArgument::StructuralValue)
4759 Output = TemplateArgumentLoc(
4760 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
4761 TemplateArgumentLocInfo());
4762 else
4763 llvm_unreachable("unexpected template argument kind");
4765 return false;
4768 case TemplateArgument::Type: {
4769 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4770 if (!DI)
4771 DI = InventTypeSourceInfo(Input.getArgument().getAsType());
4773 DI = getDerived().TransformType(DI);
4774 if (!DI)
4775 return true;
4777 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4778 return false;
4781 case TemplateArgument::Template: {
4782 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4783 if (QualifierLoc) {
4784 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4785 if (!QualifierLoc)
4786 return true;
4789 CXXScopeSpec SS;
4790 SS.Adopt(QualifierLoc);
4791 TemplateName Template = getDerived().TransformTemplateName(
4792 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4793 if (Template.isNull())
4794 return true;
4796 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4797 QualifierLoc, Input.getTemplateNameLoc());
4798 return false;
4801 case TemplateArgument::TemplateExpansion:
4802 llvm_unreachable("Caller should expand pack expansions");
4804 case TemplateArgument::Expression: {
4805 // Template argument expressions are constant expressions.
4806 EnterExpressionEvaluationContext Unevaluated(
4807 getSema(),
4808 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
4809 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
4810 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4811 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
4813 Expr *InputExpr = Input.getSourceExpression();
4814 if (!InputExpr)
4815 InputExpr = Input.getArgument().getAsExpr();
4817 ExprResult E = getDerived().TransformExpr(InputExpr);
4818 E = SemaRef.ActOnConstantExpression(E);
4819 if (E.isInvalid())
4820 return true;
4821 Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
4822 return false;
4826 // Work around bogus GCC warning
4827 return true;
4830 /// Iterator adaptor that invents template argument location information
4831 /// for each of the template arguments in its underlying iterator.
4832 template<typename Derived, typename InputIterator>
4833 class TemplateArgumentLocInventIterator {
4834 TreeTransform<Derived> &Self;
4835 InputIterator Iter;
4837 public:
4838 typedef TemplateArgumentLoc value_type;
4839 typedef TemplateArgumentLoc reference;
4840 typedef typename std::iterator_traits<InputIterator>::difference_type
4841 difference_type;
4842 typedef std::input_iterator_tag iterator_category;
4844 class pointer {
4845 TemplateArgumentLoc Arg;
4847 public:
4848 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4850 const TemplateArgumentLoc *operator->() const { return &Arg; }
4853 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
4854 InputIterator Iter)
4855 : Self(Self), Iter(Iter) { }
4857 TemplateArgumentLocInventIterator &operator++() {
4858 ++Iter;
4859 return *this;
4862 TemplateArgumentLocInventIterator operator++(int) {
4863 TemplateArgumentLocInventIterator Old(*this);
4864 ++(*this);
4865 return Old;
4868 reference operator*() const {
4869 TemplateArgumentLoc Result;
4870 Self.InventTemplateArgumentLoc(*Iter, Result);
4871 return Result;
4874 pointer operator->() const { return pointer(**this); }
4876 friend bool operator==(const TemplateArgumentLocInventIterator &X,
4877 const TemplateArgumentLocInventIterator &Y) {
4878 return X.Iter == Y.Iter;
4881 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
4882 const TemplateArgumentLocInventIterator &Y) {
4883 return X.Iter != Y.Iter;
4887 template<typename Derived>
4888 template<typename InputIterator>
4889 bool TreeTransform<Derived>::TransformTemplateArguments(
4890 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
4891 bool Uneval) {
4892 for (; First != Last; ++First) {
4893 TemplateArgumentLoc Out;
4894 TemplateArgumentLoc In = *First;
4896 if (In.getArgument().getKind() == TemplateArgument::Pack) {
4897 // Unpack argument packs, which we translate them into separate
4898 // arguments.
4899 // FIXME: We could do much better if we could guarantee that the
4900 // TemplateArgumentLocInfo for the pack expansion would be usable for
4901 // all of the template arguments in the argument pack.
4902 typedef TemplateArgumentLocInventIterator<Derived,
4903 TemplateArgument::pack_iterator>
4904 PackLocIterator;
4905 if (TransformTemplateArguments(PackLocIterator(*this,
4906 In.getArgument().pack_begin()),
4907 PackLocIterator(*this,
4908 In.getArgument().pack_end()),
4909 Outputs, Uneval))
4910 return true;
4912 continue;
4915 if (In.getArgument().isPackExpansion()) {
4916 // We have a pack expansion, for which we will be substituting into
4917 // the pattern.
4918 SourceLocation Ellipsis;
4919 std::optional<unsigned> OrigNumExpansions;
4920 TemplateArgumentLoc Pattern
4921 = getSema().getTemplateArgumentPackExpansionPattern(
4922 In, Ellipsis, OrigNumExpansions);
4924 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4925 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4926 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4928 // Determine whether the set of unexpanded parameter packs can and should
4929 // be expanded.
4930 bool Expand = true;
4931 bool RetainExpansion = false;
4932 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4933 if (getDerived().TryExpandParameterPacks(Ellipsis,
4934 Pattern.getSourceRange(),
4935 Unexpanded,
4936 Expand,
4937 RetainExpansion,
4938 NumExpansions))
4939 return true;
4941 if (!Expand) {
4942 // The transform has determined that we should perform a simple
4943 // transformation on the pack expansion, producing another pack
4944 // expansion.
4945 TemplateArgumentLoc OutPattern;
4946 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4947 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
4948 return true;
4950 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
4951 NumExpansions);
4952 if (Out.getArgument().isNull())
4953 return true;
4955 Outputs.addArgument(Out);
4956 continue;
4959 // The transform has determined that we should perform an elementwise
4960 // expansion of the pattern. Do so.
4961 for (unsigned I = 0; I != *NumExpansions; ++I) {
4962 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4964 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4965 return true;
4967 if (Out.getArgument().containsUnexpandedParameterPack()) {
4968 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4969 OrigNumExpansions);
4970 if (Out.getArgument().isNull())
4971 return true;
4974 Outputs.addArgument(Out);
4977 // If we're supposed to retain a pack expansion, do so by temporarily
4978 // forgetting the partially-substituted parameter pack.
4979 if (RetainExpansion) {
4980 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4982 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4983 return true;
4985 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4986 OrigNumExpansions);
4987 if (Out.getArgument().isNull())
4988 return true;
4990 Outputs.addArgument(Out);
4993 continue;
4996 // The simple case:
4997 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
4998 return true;
5000 Outputs.addArgument(Out);
5003 return false;
5007 //===----------------------------------------------------------------------===//
5008 // Type transformation
5009 //===----------------------------------------------------------------------===//
5011 template<typename Derived>
5012 QualType TreeTransform<Derived>::TransformType(QualType T) {
5013 if (getDerived().AlreadyTransformed(T))
5014 return T;
5016 // Temporary workaround. All of these transformations should
5017 // eventually turn into transformations on TypeLocs.
5018 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5019 getDerived().getBaseLocation());
5021 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
5023 if (!NewDI)
5024 return QualType();
5026 return NewDI->getType();
5029 template<typename Derived>
5030 TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
5031 // Refine the base location to the type's location.
5032 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5033 getDerived().getBaseEntity());
5034 if (getDerived().AlreadyTransformed(DI->getType()))
5035 return DI;
5037 TypeLocBuilder TLB;
5039 TypeLoc TL = DI->getTypeLoc();
5040 TLB.reserve(TL.getFullDataSize());
5042 QualType Result = getDerived().TransformType(TLB, TL);
5043 if (Result.isNull())
5044 return nullptr;
5046 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5049 template<typename Derived>
5050 QualType
5051 TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5052 switch (T.getTypeLocClass()) {
5053 #define ABSTRACT_TYPELOC(CLASS, PARENT)
5054 #define TYPELOC(CLASS, PARENT) \
5055 case TypeLoc::CLASS: \
5056 return getDerived().Transform##CLASS##Type(TLB, \
5057 T.castAs<CLASS##TypeLoc>());
5058 #include "clang/AST/TypeLocNodes.def"
5061 llvm_unreachable("unhandled type loc!");
5064 template<typename Derived>
5065 QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5066 if (!isa<DependentNameType>(T))
5067 return TransformType(T);
5069 if (getDerived().AlreadyTransformed(T))
5070 return T;
5071 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5072 getDerived().getBaseLocation());
5073 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
5074 return NewDI ? NewDI->getType() : QualType();
5077 template<typename Derived>
5078 TypeSourceInfo *
5079 TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
5080 if (!isa<DependentNameType>(DI->getType()))
5081 return TransformType(DI);
5083 // Refine the base location to the type's location.
5084 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5085 getDerived().getBaseEntity());
5086 if (getDerived().AlreadyTransformed(DI->getType()))
5087 return DI;
5089 TypeLocBuilder TLB;
5091 TypeLoc TL = DI->getTypeLoc();
5092 TLB.reserve(TL.getFullDataSize());
5094 auto QTL = TL.getAs<QualifiedTypeLoc>();
5095 if (QTL)
5096 TL = QTL.getUnqualifiedLoc();
5098 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5100 QualType Result = getDerived().TransformDependentNameType(
5101 TLB, DNTL, /*DeducedTSTContext*/true);
5102 if (Result.isNull())
5103 return nullptr;
5105 if (QTL) {
5106 Result = getDerived().RebuildQualifiedType(Result, QTL);
5107 if (Result.isNull())
5108 return nullptr;
5109 TLB.TypeWasModifiedSafely(Result);
5112 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5115 template<typename Derived>
5116 QualType
5117 TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5118 QualifiedTypeLoc T) {
5119 QualType Result;
5120 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5121 auto SuppressObjCLifetime =
5122 T.getType().getLocalQualifiers().hasObjCLifetime();
5123 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5124 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5125 SuppressObjCLifetime);
5126 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5127 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5128 TLB, STTP, SuppressObjCLifetime);
5129 } else {
5130 Result = getDerived().TransformType(TLB, UnqualTL);
5133 if (Result.isNull())
5134 return QualType();
5136 Result = getDerived().RebuildQualifiedType(Result, T);
5138 if (Result.isNull())
5139 return QualType();
5141 // RebuildQualifiedType might have updated the type, but not in a way
5142 // that invalidates the TypeLoc. (There's no location information for
5143 // qualifiers.)
5144 TLB.TypeWasModifiedSafely(Result);
5146 return Result;
5149 template <typename Derived>
5150 QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5151 QualifiedTypeLoc TL) {
5153 SourceLocation Loc = TL.getBeginLoc();
5154 Qualifiers Quals = TL.getType().getLocalQualifiers();
5156 if ((T.getAddressSpace() != LangAS::Default &&
5157 Quals.getAddressSpace() != LangAS::Default) &&
5158 T.getAddressSpace() != Quals.getAddressSpace()) {
5159 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)
5160 << TL.getType() << T;
5161 return QualType();
5164 // C++ [dcl.fct]p7:
5165 // [When] adding cv-qualifications on top of the function type [...] the
5166 // cv-qualifiers are ignored.
5167 if (T->isFunctionType()) {
5168 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5169 Quals.getAddressSpace());
5170 return T;
5173 // C++ [dcl.ref]p1:
5174 // when the cv-qualifiers are introduced through the use of a typedef-name
5175 // or decltype-specifier [...] the cv-qualifiers are ignored.
5176 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5177 // applied to a reference type.
5178 if (T->isReferenceType()) {
5179 // The only qualifier that applies to a reference type is restrict.
5180 if (!Quals.hasRestrict())
5181 return T;
5182 Quals = Qualifiers::fromCVRMask(Qualifiers::Restrict);
5185 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5186 // resulting type.
5187 if (Quals.hasObjCLifetime()) {
5188 if (!T->isObjCLifetimeType() && !T->isDependentType())
5189 Quals.removeObjCLifetime();
5190 else if (T.getObjCLifetime()) {
5191 // Objective-C ARC:
5192 // A lifetime qualifier applied to a substituted template parameter
5193 // overrides the lifetime qualifier from the template argument.
5194 const AutoType *AutoTy;
5195 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
5196 // 'auto' types behave the same way as template parameters.
5197 QualType Deduced = AutoTy->getDeducedType();
5198 Qualifiers Qs = Deduced.getQualifiers();
5199 Qs.removeObjCLifetime();
5200 Deduced =
5201 SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);
5202 T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),
5203 AutoTy->isDependentType(),
5204 /*isPack=*/false,
5205 AutoTy->getTypeConstraintConcept(),
5206 AutoTy->getTypeConstraintArguments());
5207 } else {
5208 // Otherwise, complain about the addition of a qualifier to an
5209 // already-qualified type.
5210 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5211 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
5212 Quals.removeObjCLifetime();
5217 return SemaRef.BuildQualifiedType(T, Loc, Quals);
5220 template<typename Derived>
5221 TypeLoc
5222 TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
5223 QualType ObjectType,
5224 NamedDecl *UnqualLookup,
5225 CXXScopeSpec &SS) {
5226 if (getDerived().AlreadyTransformed(TL.getType()))
5227 return TL;
5229 TypeSourceInfo *TSI =
5230 TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS);
5231 if (TSI)
5232 return TSI->getTypeLoc();
5233 return TypeLoc();
5236 template<typename Derived>
5237 TypeSourceInfo *
5238 TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5239 QualType ObjectType,
5240 NamedDecl *UnqualLookup,
5241 CXXScopeSpec &SS) {
5242 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5243 return TSInfo;
5245 return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType,
5246 UnqualLookup, SS);
5249 template <typename Derived>
5250 TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5251 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5252 CXXScopeSpec &SS) {
5253 QualType T = TL.getType();
5254 assert(!getDerived().AlreadyTransformed(T));
5256 TypeLocBuilder TLB;
5257 QualType Result;
5259 if (isa<TemplateSpecializationType>(T)) {
5260 TemplateSpecializationTypeLoc SpecTL =
5261 TL.castAs<TemplateSpecializationTypeLoc>();
5263 TemplateName Template = getDerived().TransformTemplateName(
5264 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5265 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5266 if (Template.isNull())
5267 return nullptr;
5269 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5270 Template);
5271 } else if (isa<DependentTemplateSpecializationType>(T)) {
5272 DependentTemplateSpecializationTypeLoc SpecTL =
5273 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5275 TemplateName Template
5276 = getDerived().RebuildTemplateName(SS,
5277 SpecTL.getTemplateKeywordLoc(),
5278 *SpecTL.getTypePtr()->getIdentifier(),
5279 SpecTL.getTemplateNameLoc(),
5280 ObjectType, UnqualLookup,
5281 /*AllowInjectedClassName*/true);
5282 if (Template.isNull())
5283 return nullptr;
5285 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5286 SpecTL,
5287 Template,
5288 SS);
5289 } else {
5290 // Nothing special needs to be done for these.
5291 Result = getDerived().TransformType(TLB, TL);
5294 if (Result.isNull())
5295 return nullptr;
5297 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5300 template <class TyLoc> static inline
5301 QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5302 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5303 NewT.setNameLoc(T.getNameLoc());
5304 return T.getType();
5307 template<typename Derived>
5308 QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5309 BuiltinTypeLoc T) {
5310 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
5311 NewT.setBuiltinLoc(T.getBuiltinLoc());
5312 if (T.needsExtraLocalData())
5313 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5314 return T.getType();
5317 template<typename Derived>
5318 QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5319 ComplexTypeLoc T) {
5320 // FIXME: recurse?
5321 return TransformTypeSpecType(TLB, T);
5324 template <typename Derived>
5325 QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5326 AdjustedTypeLoc TL) {
5327 // Adjustments applied during transformation are handled elsewhere.
5328 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5331 template<typename Derived>
5332 QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5333 DecayedTypeLoc TL) {
5334 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5335 if (OriginalType.isNull())
5336 return QualType();
5338 QualType Result = TL.getType();
5339 if (getDerived().AlwaysRebuild() ||
5340 OriginalType != TL.getOriginalLoc().getType())
5341 Result = SemaRef.Context.getDecayedType(OriginalType);
5342 TLB.push<DecayedTypeLoc>(Result);
5343 // Nothing to set for DecayedTypeLoc.
5344 return Result;
5347 template <typename Derived>
5348 QualType
5349 TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5350 ArrayParameterTypeLoc TL) {
5351 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5352 if (OriginalType.isNull())
5353 return QualType();
5355 QualType Result = TL.getType();
5356 if (getDerived().AlwaysRebuild() ||
5357 OriginalType != TL.getElementLoc().getType())
5358 Result = SemaRef.Context.getArrayParameterType(OriginalType);
5359 TLB.push<ArrayParameterTypeLoc>(Result);
5360 // Nothing to set for ArrayParameterTypeLoc.
5361 return Result;
5364 template<typename Derived>
5365 QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5366 PointerTypeLoc TL) {
5367 QualType PointeeType
5368 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5369 if (PointeeType.isNull())
5370 return QualType();
5372 QualType Result = TL.getType();
5373 if (PointeeType->getAs<ObjCObjectType>()) {
5374 // A dependent pointer type 'T *' has is being transformed such
5375 // that an Objective-C class type is being replaced for 'T'. The
5376 // resulting pointer type is an ObjCObjectPointerType, not a
5377 // PointerType.
5378 Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
5380 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
5381 NewT.setStarLoc(TL.getStarLoc());
5382 return Result;
5385 if (getDerived().AlwaysRebuild() ||
5386 PointeeType != TL.getPointeeLoc().getType()) {
5387 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5388 if (Result.isNull())
5389 return QualType();
5392 // Objective-C ARC can add lifetime qualifiers to the type that we're
5393 // pointing to.
5394 TLB.TypeWasModifiedSafely(Result->getPointeeType());
5396 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
5397 NewT.setSigilLoc(TL.getSigilLoc());
5398 return Result;
5401 template<typename Derived>
5402 QualType
5403 TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5404 BlockPointerTypeLoc TL) {
5405 QualType PointeeType
5406 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5407 if (PointeeType.isNull())
5408 return QualType();
5410 QualType Result = TL.getType();
5411 if (getDerived().AlwaysRebuild() ||
5412 PointeeType != TL.getPointeeLoc().getType()) {
5413 Result = getDerived().RebuildBlockPointerType(PointeeType,
5414 TL.getSigilLoc());
5415 if (Result.isNull())
5416 return QualType();
5419 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
5420 NewT.setSigilLoc(TL.getSigilLoc());
5421 return Result;
5424 /// Transforms a reference type. Note that somewhat paradoxically we
5425 /// don't care whether the type itself is an l-value type or an r-value
5426 /// type; we only care if the type was *written* as an l-value type
5427 /// or an r-value type.
5428 template<typename Derived>
5429 QualType
5430 TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5431 ReferenceTypeLoc TL) {
5432 const ReferenceType *T = TL.getTypePtr();
5434 // Note that this works with the pointee-as-written.
5435 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5436 if (PointeeType.isNull())
5437 return QualType();
5439 QualType Result = TL.getType();
5440 if (getDerived().AlwaysRebuild() ||
5441 PointeeType != T->getPointeeTypeAsWritten()) {
5442 Result = getDerived().RebuildReferenceType(PointeeType,
5443 T->isSpelledAsLValue(),
5444 TL.getSigilLoc());
5445 if (Result.isNull())
5446 return QualType();
5449 // Objective-C ARC can add lifetime qualifiers to the type that we're
5450 // referring to.
5451 TLB.TypeWasModifiedSafely(
5452 Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5454 // r-value references can be rebuilt as l-value references.
5455 ReferenceTypeLoc NewTL;
5456 if (isa<LValueReferenceType>(Result))
5457 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
5458 else
5459 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
5460 NewTL.setSigilLoc(TL.getSigilLoc());
5462 return Result;
5465 template<typename Derived>
5466 QualType
5467 TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5468 LValueReferenceTypeLoc TL) {
5469 return TransformReferenceType(TLB, TL);
5472 template<typename Derived>
5473 QualType
5474 TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5475 RValueReferenceTypeLoc TL) {
5476 return TransformReferenceType(TLB, TL);
5479 template<typename Derived>
5480 QualType
5481 TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5482 MemberPointerTypeLoc TL) {
5483 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5484 if (PointeeType.isNull())
5485 return QualType();
5487 TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
5488 TypeSourceInfo *NewClsTInfo = nullptr;
5489 if (OldClsTInfo) {
5490 NewClsTInfo = getDerived().TransformType(OldClsTInfo);
5491 if (!NewClsTInfo)
5492 return QualType();
5495 const MemberPointerType *T = TL.getTypePtr();
5496 QualType OldClsType = QualType(T->getClass(), 0);
5497 QualType NewClsType;
5498 if (NewClsTInfo)
5499 NewClsType = NewClsTInfo->getType();
5500 else {
5501 NewClsType = getDerived().TransformType(OldClsType);
5502 if (NewClsType.isNull())
5503 return QualType();
5506 QualType Result = TL.getType();
5507 if (getDerived().AlwaysRebuild() ||
5508 PointeeType != T->getPointeeType() ||
5509 NewClsType != OldClsType) {
5510 Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
5511 TL.getStarLoc());
5512 if (Result.isNull())
5513 return QualType();
5516 // If we had to adjust the pointee type when building a member pointer, make
5517 // sure to push TypeLoc info for it.
5518 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5519 if (MPT && PointeeType != MPT->getPointeeType()) {
5520 assert(isa<AdjustedType>(MPT->getPointeeType()));
5521 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
5524 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
5525 NewTL.setSigilLoc(TL.getSigilLoc());
5526 NewTL.setClassTInfo(NewClsTInfo);
5528 return Result;
5531 template<typename Derived>
5532 QualType
5533 TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5534 ConstantArrayTypeLoc TL) {
5535 const ConstantArrayType *T = TL.getTypePtr();
5536 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5537 if (ElementType.isNull())
5538 return QualType();
5540 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5541 Expr *OldSize = TL.getSizeExpr();
5542 if (!OldSize)
5543 OldSize = const_cast<Expr*>(T->getSizeExpr());
5544 Expr *NewSize = nullptr;
5545 if (OldSize) {
5546 EnterExpressionEvaluationContext Unevaluated(
5547 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5548 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5549 NewSize = SemaRef.ActOnConstantExpression(NewSize).get();
5552 QualType Result = TL.getType();
5553 if (getDerived().AlwaysRebuild() ||
5554 ElementType != T->getElementType() ||
5555 (T->getSizeExpr() && NewSize != OldSize)) {
5556 Result = getDerived().RebuildConstantArrayType(ElementType,
5557 T->getSizeModifier(),
5558 T->getSize(), NewSize,
5559 T->getIndexTypeCVRQualifiers(),
5560 TL.getBracketsRange());
5561 if (Result.isNull())
5562 return QualType();
5565 // We might have either a ConstantArrayType or a VariableArrayType now:
5566 // a ConstantArrayType is allowed to have an element type which is a
5567 // VariableArrayType if the type is dependent. Fortunately, all array
5568 // types have the same location layout.
5569 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5570 NewTL.setLBracketLoc(TL.getLBracketLoc());
5571 NewTL.setRBracketLoc(TL.getRBracketLoc());
5572 NewTL.setSizeExpr(NewSize);
5574 return Result;
5577 template<typename Derived>
5578 QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5579 TypeLocBuilder &TLB,
5580 IncompleteArrayTypeLoc TL) {
5581 const IncompleteArrayType *T = TL.getTypePtr();
5582 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5583 if (ElementType.isNull())
5584 return QualType();
5586 QualType Result = TL.getType();
5587 if (getDerived().AlwaysRebuild() ||
5588 ElementType != T->getElementType()) {
5589 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5590 T->getSizeModifier(),
5591 T->getIndexTypeCVRQualifiers(),
5592 TL.getBracketsRange());
5593 if (Result.isNull())
5594 return QualType();
5597 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
5598 NewTL.setLBracketLoc(TL.getLBracketLoc());
5599 NewTL.setRBracketLoc(TL.getRBracketLoc());
5600 NewTL.setSizeExpr(nullptr);
5602 return Result;
5605 template<typename Derived>
5606 QualType
5607 TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5608 VariableArrayTypeLoc TL) {
5609 const VariableArrayType *T = TL.getTypePtr();
5610 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5611 if (ElementType.isNull())
5612 return QualType();
5614 ExprResult SizeResult;
5616 EnterExpressionEvaluationContext Context(
5617 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5618 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5620 if (SizeResult.isInvalid())
5621 return QualType();
5622 SizeResult =
5623 SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);
5624 if (SizeResult.isInvalid())
5625 return QualType();
5627 Expr *Size = SizeResult.get();
5629 QualType Result = TL.getType();
5630 if (getDerived().AlwaysRebuild() ||
5631 ElementType != T->getElementType() ||
5632 Size != T->getSizeExpr()) {
5633 Result = getDerived().RebuildVariableArrayType(ElementType,
5634 T->getSizeModifier(),
5635 Size,
5636 T->getIndexTypeCVRQualifiers(),
5637 TL.getBracketsRange());
5638 if (Result.isNull())
5639 return QualType();
5642 // We might have constant size array now, but fortunately it has the same
5643 // location layout.
5644 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5645 NewTL.setLBracketLoc(TL.getLBracketLoc());
5646 NewTL.setRBracketLoc(TL.getRBracketLoc());
5647 NewTL.setSizeExpr(Size);
5649 return Result;
5652 template<typename Derived>
5653 QualType
5654 TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5655 DependentSizedArrayTypeLoc TL) {
5656 const DependentSizedArrayType *T = TL.getTypePtr();
5657 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5658 if (ElementType.isNull())
5659 return QualType();
5661 // Array bounds are constant expressions.
5662 EnterExpressionEvaluationContext Unevaluated(
5663 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5665 // If we have a VLA then it won't be a constant.
5666 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5668 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5669 Expr *origSize = TL.getSizeExpr();
5670 if (!origSize) origSize = T->getSizeExpr();
5672 ExprResult sizeResult
5673 = getDerived().TransformExpr(origSize);
5674 sizeResult = SemaRef.ActOnConstantExpression(sizeResult);
5675 if (sizeResult.isInvalid())
5676 return QualType();
5678 Expr *size = sizeResult.get();
5680 QualType Result = TL.getType();
5681 if (getDerived().AlwaysRebuild() ||
5682 ElementType != T->getElementType() ||
5683 size != origSize) {
5684 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5685 T->getSizeModifier(),
5686 size,
5687 T->getIndexTypeCVRQualifiers(),
5688 TL.getBracketsRange());
5689 if (Result.isNull())
5690 return QualType();
5693 // We might have any sort of array type now, but fortunately they
5694 // all have the same location layout.
5695 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5696 NewTL.setLBracketLoc(TL.getLBracketLoc());
5697 NewTL.setRBracketLoc(TL.getRBracketLoc());
5698 NewTL.setSizeExpr(size);
5700 return Result;
5703 template <typename Derived>
5704 QualType TreeTransform<Derived>::TransformDependentVectorType(
5705 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5706 const DependentVectorType *T = TL.getTypePtr();
5707 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5708 if (ElementType.isNull())
5709 return QualType();
5711 EnterExpressionEvaluationContext Unevaluated(
5712 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5714 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5715 Size = SemaRef.ActOnConstantExpression(Size);
5716 if (Size.isInvalid())
5717 return QualType();
5719 QualType Result = TL.getType();
5720 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5721 Size.get() != T->getSizeExpr()) {
5722 Result = getDerived().RebuildDependentVectorType(
5723 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5724 if (Result.isNull())
5725 return QualType();
5728 // Result might be dependent or not.
5729 if (isa<DependentVectorType>(Result)) {
5730 DependentVectorTypeLoc NewTL =
5731 TLB.push<DependentVectorTypeLoc>(Result);
5732 NewTL.setNameLoc(TL.getNameLoc());
5733 } else {
5734 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5735 NewTL.setNameLoc(TL.getNameLoc());
5738 return Result;
5741 template<typename Derived>
5742 QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5743 TypeLocBuilder &TLB,
5744 DependentSizedExtVectorTypeLoc TL) {
5745 const DependentSizedExtVectorType *T = TL.getTypePtr();
5747 // FIXME: ext vector locs should be nested
5748 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5749 if (ElementType.isNull())
5750 return QualType();
5752 // Vector sizes are constant expressions.
5753 EnterExpressionEvaluationContext Unevaluated(
5754 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5756 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5757 Size = SemaRef.ActOnConstantExpression(Size);
5758 if (Size.isInvalid())
5759 return QualType();
5761 QualType Result = TL.getType();
5762 if (getDerived().AlwaysRebuild() ||
5763 ElementType != T->getElementType() ||
5764 Size.get() != T->getSizeExpr()) {
5765 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5766 Size.get(),
5767 T->getAttributeLoc());
5768 if (Result.isNull())
5769 return QualType();
5772 // Result might be dependent or not.
5773 if (isa<DependentSizedExtVectorType>(Result)) {
5774 DependentSizedExtVectorTypeLoc NewTL
5775 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
5776 NewTL.setNameLoc(TL.getNameLoc());
5777 } else {
5778 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5779 NewTL.setNameLoc(TL.getNameLoc());
5782 return Result;
5785 template <typename Derived>
5786 QualType
5787 TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5788 ConstantMatrixTypeLoc TL) {
5789 const ConstantMatrixType *T = TL.getTypePtr();
5790 QualType ElementType = getDerived().TransformType(T->getElementType());
5791 if (ElementType.isNull())
5792 return QualType();
5794 QualType Result = TL.getType();
5795 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5796 Result = getDerived().RebuildConstantMatrixType(
5797 ElementType, T->getNumRows(), T->getNumColumns());
5798 if (Result.isNull())
5799 return QualType();
5802 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);
5803 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5804 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5805 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5806 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5808 return Result;
5811 template <typename Derived>
5812 QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5813 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5814 const DependentSizedMatrixType *T = TL.getTypePtr();
5816 QualType ElementType = getDerived().TransformType(T->getElementType());
5817 if (ElementType.isNull()) {
5818 return QualType();
5821 // Matrix dimensions are constant expressions.
5822 EnterExpressionEvaluationContext Unevaluated(
5823 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5825 Expr *origRows = TL.getAttrRowOperand();
5826 if (!origRows)
5827 origRows = T->getRowExpr();
5828 Expr *origColumns = TL.getAttrColumnOperand();
5829 if (!origColumns)
5830 origColumns = T->getColumnExpr();
5832 ExprResult rowResult = getDerived().TransformExpr(origRows);
5833 rowResult = SemaRef.ActOnConstantExpression(rowResult);
5834 if (rowResult.isInvalid())
5835 return QualType();
5837 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5838 columnResult = SemaRef.ActOnConstantExpression(columnResult);
5839 if (columnResult.isInvalid())
5840 return QualType();
5842 Expr *rows = rowResult.get();
5843 Expr *columns = columnResult.get();
5845 QualType Result = TL.getType();
5846 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5847 rows != origRows || columns != origColumns) {
5848 Result = getDerived().RebuildDependentSizedMatrixType(
5849 ElementType, rows, columns, T->getAttributeLoc());
5851 if (Result.isNull())
5852 return QualType();
5855 // We might have any sort of matrix type now, but fortunately they
5856 // all have the same location layout.
5857 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);
5858 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5859 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5860 NewTL.setAttrRowOperand(rows);
5861 NewTL.setAttrColumnOperand(columns);
5862 return Result;
5865 template <typename Derived>
5866 QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
5867 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
5868 const DependentAddressSpaceType *T = TL.getTypePtr();
5870 QualType pointeeType =
5871 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
5873 if (pointeeType.isNull())
5874 return QualType();
5876 // Address spaces are constant expressions.
5877 EnterExpressionEvaluationContext Unevaluated(
5878 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5880 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
5881 AddrSpace = SemaRef.ActOnConstantExpression(AddrSpace);
5882 if (AddrSpace.isInvalid())
5883 return QualType();
5885 QualType Result = TL.getType();
5886 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
5887 AddrSpace.get() != T->getAddrSpaceExpr()) {
5888 Result = getDerived().RebuildDependentAddressSpaceType(
5889 pointeeType, AddrSpace.get(), T->getAttributeLoc());
5890 if (Result.isNull())
5891 return QualType();
5894 // Result might be dependent or not.
5895 if (isa<DependentAddressSpaceType>(Result)) {
5896 DependentAddressSpaceTypeLoc NewTL =
5897 TLB.push<DependentAddressSpaceTypeLoc>(Result);
5899 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5900 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
5901 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5903 } else {
5904 TLB.TypeWasModifiedSafely(Result);
5907 return Result;
5910 template <typename Derived>
5911 QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
5912 VectorTypeLoc TL) {
5913 const VectorType *T = TL.getTypePtr();
5914 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5915 if (ElementType.isNull())
5916 return QualType();
5918 QualType Result = TL.getType();
5919 if (getDerived().AlwaysRebuild() ||
5920 ElementType != T->getElementType()) {
5921 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
5922 T->getVectorKind());
5923 if (Result.isNull())
5924 return QualType();
5927 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5928 NewTL.setNameLoc(TL.getNameLoc());
5930 return Result;
5933 template<typename Derived>
5934 QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
5935 ExtVectorTypeLoc TL) {
5936 const VectorType *T = TL.getTypePtr();
5937 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5938 if (ElementType.isNull())
5939 return QualType();
5941 QualType Result = TL.getType();
5942 if (getDerived().AlwaysRebuild() ||
5943 ElementType != T->getElementType()) {
5944 Result = getDerived().RebuildExtVectorType(ElementType,
5945 T->getNumElements(),
5946 /*FIXME*/ SourceLocation());
5947 if (Result.isNull())
5948 return QualType();
5951 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5952 NewTL.setNameLoc(TL.getNameLoc());
5954 return Result;
5957 template <typename Derived>
5958 ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
5959 ParmVarDecl *OldParm, int indexAdjustment,
5960 std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
5961 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
5962 TypeSourceInfo *NewDI = nullptr;
5964 if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
5965 // If we're substituting into a pack expansion type and we know the
5966 // length we want to expand to, just substitute for the pattern.
5967 TypeLoc OldTL = OldDI->getTypeLoc();
5968 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
5970 TypeLocBuilder TLB;
5971 TypeLoc NewTL = OldDI->getTypeLoc();
5972 TLB.reserve(NewTL.getFullDataSize());
5974 QualType Result = getDerived().TransformType(TLB,
5975 OldExpansionTL.getPatternLoc());
5976 if (Result.isNull())
5977 return nullptr;
5979 Result = RebuildPackExpansionType(Result,
5980 OldExpansionTL.getPatternLoc().getSourceRange(),
5981 OldExpansionTL.getEllipsisLoc(),
5982 NumExpansions);
5983 if (Result.isNull())
5984 return nullptr;
5986 PackExpansionTypeLoc NewExpansionTL
5987 = TLB.push<PackExpansionTypeLoc>(Result);
5988 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
5989 NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result);
5990 } else
5991 NewDI = getDerived().TransformType(OldDI);
5992 if (!NewDI)
5993 return nullptr;
5995 if (NewDI == OldDI && indexAdjustment == 0)
5996 return OldParm;
5998 ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context,
5999 OldParm->getDeclContext(),
6000 OldParm->getInnerLocStart(),
6001 OldParm->getLocation(),
6002 OldParm->getIdentifier(),
6003 NewDI->getType(),
6004 NewDI,
6005 OldParm->getStorageClass(),
6006 /* DefArg */ nullptr);
6007 newParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
6008 OldParm->getFunctionScopeIndex() + indexAdjustment);
6009 transformedLocalDecl(OldParm, {newParm});
6010 return newParm;
6013 template <typename Derived>
6014 bool TreeTransform<Derived>::TransformFunctionTypeParams(
6015 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6016 const QualType *ParamTypes,
6017 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6018 SmallVectorImpl<QualType> &OutParamTypes,
6019 SmallVectorImpl<ParmVarDecl *> *PVars,
6020 Sema::ExtParameterInfoBuilder &PInfos,
6021 unsigned *LastParamTransformed) {
6022 int indexAdjustment = 0;
6024 unsigned NumParams = Params.size();
6025 for (unsigned i = 0; i != NumParams; ++i) {
6026 if (LastParamTransformed)
6027 *LastParamTransformed = i;
6028 if (ParmVarDecl *OldParm = Params[i]) {
6029 assert(OldParm->getFunctionScopeIndex() == i);
6031 std::optional<unsigned> NumExpansions;
6032 ParmVarDecl *NewParm = nullptr;
6033 if (OldParm->isParameterPack()) {
6034 // We have a function parameter pack that may need to be expanded.
6035 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6037 // Find the parameter packs that could be expanded.
6038 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6039 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6040 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6041 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
6043 // Determine whether we should expand the parameter packs.
6044 bool ShouldExpand = false;
6045 bool RetainExpansion = false;
6046 std::optional<unsigned> OrigNumExpansions;
6047 if (Unexpanded.size() > 0) {
6048 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6049 NumExpansions = OrigNumExpansions;
6050 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
6051 Pattern.getSourceRange(),
6052 Unexpanded,
6053 ShouldExpand,
6054 RetainExpansion,
6055 NumExpansions)) {
6056 return true;
6058 } else {
6059 #ifndef NDEBUG
6060 const AutoType *AT =
6061 Pattern.getType().getTypePtr()->getContainedAutoType();
6062 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6063 "Could not find parameter packs or undeduced auto type!");
6064 #endif
6067 if (ShouldExpand) {
6068 // Expand the function parameter pack into multiple, separate
6069 // parameters.
6070 getDerived().ExpandingFunctionParameterPack(OldParm);
6071 for (unsigned I = 0; I != *NumExpansions; ++I) {
6072 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6073 ParmVarDecl *NewParm
6074 = getDerived().TransformFunctionTypeParam(OldParm,
6075 indexAdjustment++,
6076 OrigNumExpansions,
6077 /*ExpectParameterPack=*/false);
6078 if (!NewParm)
6079 return true;
6081 if (ParamInfos)
6082 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6083 OutParamTypes.push_back(NewParm->getType());
6084 if (PVars)
6085 PVars->push_back(NewParm);
6088 // If we're supposed to retain a pack expansion, do so by temporarily
6089 // forgetting the partially-substituted parameter pack.
6090 if (RetainExpansion) {
6091 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6092 ParmVarDecl *NewParm
6093 = getDerived().TransformFunctionTypeParam(OldParm,
6094 indexAdjustment++,
6095 OrigNumExpansions,
6096 /*ExpectParameterPack=*/false);
6097 if (!NewParm)
6098 return true;
6100 if (ParamInfos)
6101 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6102 OutParamTypes.push_back(NewParm->getType());
6103 if (PVars)
6104 PVars->push_back(NewParm);
6107 // The next parameter should have the same adjustment as the
6108 // last thing we pushed, but we post-incremented indexAdjustment
6109 // on every push. Also, if we push nothing, the adjustment should
6110 // go down by one.
6111 indexAdjustment--;
6113 // We're done with the pack expansion.
6114 continue;
6117 // We'll substitute the parameter now without expanding the pack
6118 // expansion.
6119 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6120 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6121 indexAdjustment,
6122 NumExpansions,
6123 /*ExpectParameterPack=*/true);
6124 assert(NewParm->isParameterPack() &&
6125 "Parameter pack no longer a parameter pack after "
6126 "transformation.");
6127 } else {
6128 NewParm = getDerived().TransformFunctionTypeParam(
6129 OldParm, indexAdjustment, std::nullopt,
6130 /*ExpectParameterPack=*/false);
6133 if (!NewParm)
6134 return true;
6136 if (ParamInfos)
6137 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6138 OutParamTypes.push_back(NewParm->getType());
6139 if (PVars)
6140 PVars->push_back(NewParm);
6141 continue;
6144 // Deal with the possibility that we don't have a parameter
6145 // declaration for this parameter.
6146 assert(ParamTypes);
6147 QualType OldType = ParamTypes[i];
6148 bool IsPackExpansion = false;
6149 std::optional<unsigned> NumExpansions;
6150 QualType NewType;
6151 if (const PackExpansionType *Expansion
6152 = dyn_cast<PackExpansionType>(OldType)) {
6153 // We have a function parameter pack that may need to be expanded.
6154 QualType Pattern = Expansion->getPattern();
6155 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6156 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6158 // Determine whether we should expand the parameter packs.
6159 bool ShouldExpand = false;
6160 bool RetainExpansion = false;
6161 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
6162 Unexpanded,
6163 ShouldExpand,
6164 RetainExpansion,
6165 NumExpansions)) {
6166 return true;
6169 if (ShouldExpand) {
6170 // Expand the function parameter pack into multiple, separate
6171 // parameters.
6172 for (unsigned I = 0; I != *NumExpansions; ++I) {
6173 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6174 QualType NewType = getDerived().TransformType(Pattern);
6175 if (NewType.isNull())
6176 return true;
6178 if (NewType->containsUnexpandedParameterPack()) {
6179 NewType = getSema().getASTContext().getPackExpansionType(
6180 NewType, std::nullopt);
6182 if (NewType.isNull())
6183 return true;
6186 if (ParamInfos)
6187 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6188 OutParamTypes.push_back(NewType);
6189 if (PVars)
6190 PVars->push_back(nullptr);
6193 // We're done with the pack expansion.
6194 continue;
6197 // If we're supposed to retain a pack expansion, do so by temporarily
6198 // forgetting the partially-substituted parameter pack.
6199 if (RetainExpansion) {
6200 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6201 QualType NewType = getDerived().TransformType(Pattern);
6202 if (NewType.isNull())
6203 return true;
6205 if (ParamInfos)
6206 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6207 OutParamTypes.push_back(NewType);
6208 if (PVars)
6209 PVars->push_back(nullptr);
6212 // We'll substitute the parameter now without expanding the pack
6213 // expansion.
6214 OldType = Expansion->getPattern();
6215 IsPackExpansion = true;
6216 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6217 NewType = getDerived().TransformType(OldType);
6218 } else {
6219 NewType = getDerived().TransformType(OldType);
6222 if (NewType.isNull())
6223 return true;
6225 if (IsPackExpansion)
6226 NewType = getSema().Context.getPackExpansionType(NewType,
6227 NumExpansions);
6229 if (ParamInfos)
6230 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6231 OutParamTypes.push_back(NewType);
6232 if (PVars)
6233 PVars->push_back(nullptr);
6236 #ifndef NDEBUG
6237 if (PVars) {
6238 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6239 if (ParmVarDecl *parm = (*PVars)[i])
6240 assert(parm->getFunctionScopeIndex() == i);
6242 #endif
6244 return false;
6247 template<typename Derived>
6248 QualType
6249 TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6250 FunctionProtoTypeLoc TL) {
6251 SmallVector<QualType, 4> ExceptionStorage;
6252 return getDerived().TransformFunctionProtoType(
6253 TLB, TL, nullptr, Qualifiers(),
6254 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6255 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6256 ExceptionStorage, Changed);
6260 template<typename Derived> template<typename Fn>
6261 QualType TreeTransform<Derived>::TransformFunctionProtoType(
6262 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6263 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6265 // Transform the parameters and return type.
6267 // We are required to instantiate the params and return type in source order.
6268 // When the function has a trailing return type, we instantiate the
6269 // parameters before the return type, since the return type can then refer
6270 // to the parameters themselves (via decltype, sizeof, etc.).
6272 SmallVector<QualType, 4> ParamTypes;
6273 SmallVector<ParmVarDecl*, 4> ParamDecls;
6274 Sema::ExtParameterInfoBuilder ExtParamInfos;
6275 const FunctionProtoType *T = TL.getTypePtr();
6277 QualType ResultType;
6279 if (T->hasTrailingReturn()) {
6280 if (getDerived().TransformFunctionTypeParams(
6281 TL.getBeginLoc(), TL.getParams(),
6282 TL.getTypePtr()->param_type_begin(),
6283 T->getExtParameterInfosOrNull(),
6284 ParamTypes, &ParamDecls, ExtParamInfos))
6285 return QualType();
6288 // C++11 [expr.prim.general]p3:
6289 // If a declaration declares a member function or member function
6290 // template of a class X, the expression this is a prvalue of type
6291 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6292 // and the end of the function-definition, member-declarator, or
6293 // declarator.
6294 auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.getCurLexicalContext());
6295 Sema::CXXThisScopeRAII ThisScope(
6296 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6298 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6299 if (ResultType.isNull())
6300 return QualType();
6303 else {
6304 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6305 if (ResultType.isNull())
6306 return QualType();
6308 if (getDerived().TransformFunctionTypeParams(
6309 TL.getBeginLoc(), TL.getParams(),
6310 TL.getTypePtr()->param_type_begin(),
6311 T->getExtParameterInfosOrNull(),
6312 ParamTypes, &ParamDecls, ExtParamInfos))
6313 return QualType();
6316 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6318 bool EPIChanged = false;
6319 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6320 return QualType();
6322 // Handle extended parameter information.
6323 if (auto NewExtParamInfos =
6324 ExtParamInfos.getPointerOrNull(ParamTypes.size())) {
6325 if (!EPI.ExtParameterInfos ||
6326 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6327 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6328 EPIChanged = true;
6330 EPI.ExtParameterInfos = NewExtParamInfos;
6331 } else if (EPI.ExtParameterInfos) {
6332 EPIChanged = true;
6333 EPI.ExtParameterInfos = nullptr;
6336 // Transform any function effects with unevaluated conditions.
6337 // Hold this set in a local for the rest of this function, since EPI
6338 // may need to hold a FunctionEffectsRef pointing into it.
6339 std::optional<FunctionEffectSet> NewFX;
6340 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6341 NewFX.emplace();
6342 EnterExpressionEvaluationContext Unevaluated(
6343 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6345 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6346 FunctionEffectWithCondition NewEC = PrevEC;
6347 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6348 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6349 if (NewExpr.isInvalid())
6350 return QualType();
6351 std::optional<FunctionEffectMode> Mode =
6352 SemaRef.ActOnEffectExpression(NewExpr.get(), PrevEC.Effect.name());
6353 if (!Mode)
6354 return QualType();
6356 // The condition expression has been transformed, and re-evaluated.
6357 // It may or may not have become constant.
6358 switch (*Mode) {
6359 case FunctionEffectMode::True:
6360 NewEC.Cond = {};
6361 break;
6362 case FunctionEffectMode::False:
6363 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6364 NewEC.Cond = {};
6365 break;
6366 case FunctionEffectMode::Dependent:
6367 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6368 break;
6369 case FunctionEffectMode::None:
6370 llvm_unreachable(
6371 "FunctionEffectMode::None shouldn't be possible here");
6374 if (!SemaRef.diagnoseConflictingFunctionEffect(*NewFX, NewEC,
6375 TL.getBeginLoc())) {
6376 FunctionEffectSet::Conflicts Errs;
6377 NewFX->insert(NewEC, Errs);
6378 assert(Errs.empty());
6381 EPI.FunctionEffects = *NewFX;
6382 EPIChanged = true;
6385 QualType Result = TL.getType();
6386 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6387 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6388 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6389 if (Result.isNull())
6390 return QualType();
6393 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
6394 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6395 NewTL.setLParenLoc(TL.getLParenLoc());
6396 NewTL.setRParenLoc(TL.getRParenLoc());
6397 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6398 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6399 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6400 NewTL.setParam(i, ParamDecls[i]);
6402 return Result;
6405 template<typename Derived>
6406 bool TreeTransform<Derived>::TransformExceptionSpec(
6407 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6408 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6409 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6411 // Instantiate a dynamic noexcept expression, if any.
6412 if (isComputedNoexcept(ESI.Type)) {
6413 // Update this scrope because ContextDecl in Sema will be used in
6414 // TransformExpr.
6415 auto *Method = dyn_cast_if_present<CXXMethodDecl>(ESI.SourceTemplate);
6416 Sema::CXXThisScopeRAII ThisScope(
6417 SemaRef, Method ? Method->getParent() : nullptr,
6418 Method ? Method->getMethodQualifiers() : Qualifiers{},
6419 Method != nullptr);
6420 EnterExpressionEvaluationContext Unevaluated(
6421 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6422 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6423 if (NoexceptExpr.isInvalid())
6424 return true;
6426 ExceptionSpecificationType EST = ESI.Type;
6427 NoexceptExpr =
6428 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6429 if (NoexceptExpr.isInvalid())
6430 return true;
6432 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6433 Changed = true;
6434 ESI.NoexceptExpr = NoexceptExpr.get();
6435 ESI.Type = EST;
6438 if (ESI.Type != EST_Dynamic)
6439 return false;
6441 // Instantiate a dynamic exception specification's type.
6442 for (QualType T : ESI.Exceptions) {
6443 if (const PackExpansionType *PackExpansion =
6444 T->getAs<PackExpansionType>()) {
6445 Changed = true;
6447 // We have a pack expansion. Instantiate it.
6448 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6449 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
6450 Unexpanded);
6451 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6453 // Determine whether the set of unexpanded parameter packs can and
6454 // should
6455 // be expanded.
6456 bool Expand = false;
6457 bool RetainExpansion = false;
6458 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
6459 // FIXME: Track the location of the ellipsis (and track source location
6460 // information for the types in the exception specification in general).
6461 if (getDerived().TryExpandParameterPacks(
6462 Loc, SourceRange(), Unexpanded, Expand,
6463 RetainExpansion, NumExpansions))
6464 return true;
6466 if (!Expand) {
6467 // We can't expand this pack expansion into separate arguments yet;
6468 // just substitute into the pattern and create a new pack expansion
6469 // type.
6470 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6471 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6472 if (U.isNull())
6473 return true;
6475 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
6476 Exceptions.push_back(U);
6477 continue;
6480 // Substitute into the pack expansion pattern for each slice of the
6481 // pack.
6482 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6483 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
6485 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6486 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6487 return true;
6489 Exceptions.push_back(U);
6491 } else {
6492 QualType U = getDerived().TransformType(T);
6493 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6494 return true;
6495 if (T != U)
6496 Changed = true;
6498 Exceptions.push_back(U);
6502 ESI.Exceptions = Exceptions;
6503 if (ESI.Exceptions.empty())
6504 ESI.Type = EST_DynamicNone;
6505 return false;
6508 template<typename Derived>
6509 QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6510 TypeLocBuilder &TLB,
6511 FunctionNoProtoTypeLoc TL) {
6512 const FunctionNoProtoType *T = TL.getTypePtr();
6513 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6514 if (ResultType.isNull())
6515 return QualType();
6517 QualType Result = TL.getType();
6518 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6519 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6521 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
6522 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6523 NewTL.setLParenLoc(TL.getLParenLoc());
6524 NewTL.setRParenLoc(TL.getRParenLoc());
6525 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6527 return Result;
6530 template <typename Derived>
6531 QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6532 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6533 const UnresolvedUsingType *T = TL.getTypePtr();
6534 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6535 if (!D)
6536 return QualType();
6538 QualType Result = TL.getType();
6539 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6540 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6541 if (Result.isNull())
6542 return QualType();
6545 // We might get an arbitrary type spec type back. We should at
6546 // least always get a type spec type, though.
6547 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result);
6548 NewTL.setNameLoc(TL.getNameLoc());
6550 return Result;
6553 template <typename Derived>
6554 QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6555 UsingTypeLoc TL) {
6556 const UsingType *T = TL.getTypePtr();
6558 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6559 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6560 if (!Found)
6561 return QualType();
6563 QualType Underlying = getDerived().TransformType(T->desugar());
6564 if (Underlying.isNull())
6565 return QualType();
6567 QualType Result = TL.getType();
6568 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6569 Underlying != T->getUnderlyingType()) {
6570 Result = getDerived().RebuildUsingType(Found, Underlying);
6571 if (Result.isNull())
6572 return QualType();
6575 TLB.pushTypeSpec(Result).setNameLoc(TL.getNameLoc());
6576 return Result;
6579 template<typename Derived>
6580 QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6581 TypedefTypeLoc TL) {
6582 const TypedefType *T = TL.getTypePtr();
6583 TypedefNameDecl *Typedef
6584 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6585 T->getDecl()));
6586 if (!Typedef)
6587 return QualType();
6589 QualType Result = TL.getType();
6590 if (getDerived().AlwaysRebuild() ||
6591 Typedef != T->getDecl()) {
6592 Result = getDerived().RebuildTypedefType(Typedef);
6593 if (Result.isNull())
6594 return QualType();
6597 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
6598 NewTL.setNameLoc(TL.getNameLoc());
6600 return Result;
6603 template<typename Derived>
6604 QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6605 TypeOfExprTypeLoc TL) {
6606 // typeof expressions are not potentially evaluated contexts
6607 EnterExpressionEvaluationContext Unevaluated(
6608 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6609 Sema::ReuseLambdaContextDecl);
6611 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6612 if (E.isInvalid())
6613 return QualType();
6615 E = SemaRef.HandleExprEvaluationContextForTypeof(E.get());
6616 if (E.isInvalid())
6617 return QualType();
6619 QualType Result = TL.getType();
6620 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
6621 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6622 Result =
6623 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6624 if (Result.isNull())
6625 return QualType();
6628 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
6629 NewTL.setTypeofLoc(TL.getTypeofLoc());
6630 NewTL.setLParenLoc(TL.getLParenLoc());
6631 NewTL.setRParenLoc(TL.getRParenLoc());
6633 return Result;
6636 template<typename Derived>
6637 QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6638 TypeOfTypeLoc TL) {
6639 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6640 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6641 if (!New_Under_TI)
6642 return QualType();
6644 QualType Result = TL.getType();
6645 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
6646 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6647 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6648 if (Result.isNull())
6649 return QualType();
6652 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
6653 NewTL.setTypeofLoc(TL.getTypeofLoc());
6654 NewTL.setLParenLoc(TL.getLParenLoc());
6655 NewTL.setRParenLoc(TL.getRParenLoc());
6656 NewTL.setUnmodifiedTInfo(New_Under_TI);
6658 return Result;
6661 template<typename Derived>
6662 QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6663 DecltypeTypeLoc TL) {
6664 const DecltypeType *T = TL.getTypePtr();
6666 // decltype expressions are not potentially evaluated contexts
6667 EnterExpressionEvaluationContext Unevaluated(
6668 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
6669 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
6671 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6672 if (E.isInvalid())
6673 return QualType();
6675 E = getSema().ActOnDecltypeExpression(E.get());
6676 if (E.isInvalid())
6677 return QualType();
6679 QualType Result = TL.getType();
6680 if (getDerived().AlwaysRebuild() ||
6681 E.get() != T->getUnderlyingExpr()) {
6682 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6683 if (Result.isNull())
6684 return QualType();
6686 else E.get();
6688 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
6689 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6690 NewTL.setRParenLoc(TL.getRParenLoc());
6691 return Result;
6694 template <typename Derived>
6695 QualType
6696 TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
6697 PackIndexingTypeLoc TL) {
6698 // Transform the index
6699 ExprResult IndexExpr;
6701 EnterExpressionEvaluationContext ConstantContext(
6702 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6704 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
6705 if (IndexExpr.isInvalid())
6706 return QualType();
6708 QualType Pattern = TL.getPattern();
6710 const PackIndexingType *PIT = TL.getTypePtr();
6711 SmallVector<QualType, 5> SubtitutedTypes;
6712 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
6714 bool NotYetExpanded = Types.empty();
6715 bool FullySubstituted = true;
6717 if (Types.empty() && !PIT->expandsToEmptyPack())
6718 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
6720 for (QualType T : Types) {
6721 if (!T->containsUnexpandedParameterPack()) {
6722 QualType Transformed = getDerived().TransformType(T);
6723 if (Transformed.isNull())
6724 return QualType();
6725 SubtitutedTypes.push_back(Transformed);
6726 continue;
6729 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6730 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
6731 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6732 // Determine whether the set of unexpanded parameter packs can and should
6733 // be expanded.
6734 bool ShouldExpand = true;
6735 bool RetainExpansion = false;
6736 std::optional<unsigned> OrigNumExpansions;
6737 std::optional<unsigned> NumExpansions = OrigNumExpansions;
6738 if (getDerived().TryExpandParameterPacks(TL.getEllipsisLoc(), SourceRange(),
6739 Unexpanded, ShouldExpand,
6740 RetainExpansion, NumExpansions))
6741 return QualType();
6742 if (!ShouldExpand) {
6743 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6744 // FIXME: should we keep TypeLoc for individual expansions in
6745 // PackIndexingTypeLoc?
6746 TypeSourceInfo *TI =
6747 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, TL.getBeginLoc());
6748 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
6749 if (Pack.isNull())
6750 return QualType();
6751 if (NotYetExpanded) {
6752 FullySubstituted = false;
6753 QualType Out = getDerived().RebuildPackIndexingType(
6754 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6755 FullySubstituted);
6756 if (Out.isNull())
6757 return QualType();
6759 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6760 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6761 return Out;
6763 SubtitutedTypes.push_back(Pack);
6764 continue;
6766 for (unsigned I = 0; I != *NumExpansions; ++I) {
6767 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6768 QualType Out = getDerived().TransformType(T);
6769 if (Out.isNull())
6770 return QualType();
6771 SubtitutedTypes.push_back(Out);
6772 FullySubstituted &= !Out->containsUnexpandedParameterPack();
6774 // If we're supposed to retain a pack expansion, do so by temporarily
6775 // forgetting the partially-substituted parameter pack.
6776 if (RetainExpansion) {
6777 FullySubstituted = false;
6778 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6779 QualType Out = getDerived().TransformType(T);
6780 if (Out.isNull())
6781 return QualType();
6782 SubtitutedTypes.push_back(Out);
6786 // A pack indexing type can appear in a larger pack expansion,
6787 // e.g. `Pack...[pack_of_indexes]...`
6788 // so we need to temporarily disable substitution of pack elements
6789 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6790 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
6792 QualType Out = getDerived().RebuildPackIndexingType(
6793 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6794 FullySubstituted, SubtitutedTypes);
6795 if (Out.isNull())
6796 return Out;
6798 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6799 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6800 return Out;
6803 template<typename Derived>
6804 QualType TreeTransform<Derived>::TransformUnaryTransformType(
6805 TypeLocBuilder &TLB,
6806 UnaryTransformTypeLoc TL) {
6807 QualType Result = TL.getType();
6808 if (Result->isDependentType()) {
6809 const UnaryTransformType *T = TL.getTypePtr();
6811 TypeSourceInfo *NewBaseTSI =
6812 getDerived().TransformType(TL.getUnderlyingTInfo());
6813 if (!NewBaseTSI)
6814 return QualType();
6815 QualType NewBase = NewBaseTSI->getType();
6817 Result = getDerived().RebuildUnaryTransformType(NewBase,
6818 T->getUTTKind(),
6819 TL.getKWLoc());
6820 if (Result.isNull())
6821 return QualType();
6824 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
6825 NewTL.setKWLoc(TL.getKWLoc());
6826 NewTL.setParensRange(TL.getParensRange());
6827 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6828 return Result;
6831 template<typename Derived>
6832 QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6833 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6834 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6836 CXXScopeSpec SS;
6837 TemplateName TemplateName = getDerived().TransformTemplateName(
6838 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6839 if (TemplateName.isNull())
6840 return QualType();
6842 QualType OldDeduced = T->getDeducedType();
6843 QualType NewDeduced;
6844 if (!OldDeduced.isNull()) {
6845 NewDeduced = getDerived().TransformType(OldDeduced);
6846 if (NewDeduced.isNull())
6847 return QualType();
6850 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
6851 TemplateName, NewDeduced);
6852 if (Result.isNull())
6853 return QualType();
6855 DeducedTemplateSpecializationTypeLoc NewTL =
6856 TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
6857 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6859 return Result;
6862 template<typename Derived>
6863 QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
6864 RecordTypeLoc TL) {
6865 const RecordType *T = TL.getTypePtr();
6866 RecordDecl *Record
6867 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6868 T->getDecl()));
6869 if (!Record)
6870 return QualType();
6872 QualType Result = TL.getType();
6873 if (getDerived().AlwaysRebuild() ||
6874 Record != T->getDecl()) {
6875 Result = getDerived().RebuildRecordType(Record);
6876 if (Result.isNull())
6877 return QualType();
6880 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
6881 NewTL.setNameLoc(TL.getNameLoc());
6883 return Result;
6886 template<typename Derived>
6887 QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
6888 EnumTypeLoc TL) {
6889 const EnumType *T = TL.getTypePtr();
6890 EnumDecl *Enum
6891 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6892 T->getDecl()));
6893 if (!Enum)
6894 return QualType();
6896 QualType Result = TL.getType();
6897 if (getDerived().AlwaysRebuild() ||
6898 Enum != T->getDecl()) {
6899 Result = getDerived().RebuildEnumType(Enum);
6900 if (Result.isNull())
6901 return QualType();
6904 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
6905 NewTL.setNameLoc(TL.getNameLoc());
6907 return Result;
6910 template<typename Derived>
6911 QualType TreeTransform<Derived>::TransformInjectedClassNameType(
6912 TypeLocBuilder &TLB,
6913 InjectedClassNameTypeLoc TL) {
6914 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
6915 TL.getTypePtr()->getDecl());
6916 if (!D) return QualType();
6918 QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
6919 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
6920 return T;
6923 template<typename Derived>
6924 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6925 TypeLocBuilder &TLB,
6926 TemplateTypeParmTypeLoc TL) {
6927 return getDerived().TransformTemplateTypeParmType(
6928 TLB, TL,
6929 /*SuppressObjCLifetime=*/false);
6932 template <typename Derived>
6933 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6934 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
6935 return TransformTypeSpecType(TLB, TL);
6938 template<typename Derived>
6939 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
6940 TypeLocBuilder &TLB,
6941 SubstTemplateTypeParmTypeLoc TL) {
6942 const SubstTemplateTypeParmType *T = TL.getTypePtr();
6944 Decl *NewReplaced =
6945 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
6947 // Substitute into the replacement type, which itself might involve something
6948 // that needs to be transformed. This only tends to occur with default
6949 // template arguments of template template parameters.
6950 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
6951 QualType Replacement = getDerived().TransformType(T->getReplacementType());
6952 if (Replacement.isNull())
6953 return QualType();
6955 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
6956 Replacement, NewReplaced, T->getIndex(), T->getPackIndex());
6958 // Propagate type-source information.
6959 SubstTemplateTypeParmTypeLoc NewTL
6960 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
6961 NewTL.setNameLoc(TL.getNameLoc());
6962 return Result;
6966 template<typename Derived>
6967 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6968 TypeLocBuilder &TLB,
6969 SubstTemplateTypeParmPackTypeLoc TL) {
6970 return getDerived().TransformSubstTemplateTypeParmPackType(
6971 TLB, TL, /*SuppressObjCLifetime=*/false);
6974 template <typename Derived>
6975 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6976 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
6977 return TransformTypeSpecType(TLB, TL);
6980 template<typename Derived>
6981 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
6982 TypeLocBuilder &TLB,
6983 TemplateSpecializationTypeLoc TL) {
6984 const TemplateSpecializationType *T = TL.getTypePtr();
6986 // The nested-name-specifier never matters in a TemplateSpecializationType,
6987 // because we can't have a dependent nested-name-specifier anyway.
6988 CXXScopeSpec SS;
6989 TemplateName Template
6990 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
6991 TL.getTemplateNameLoc());
6992 if (Template.isNull())
6993 return QualType();
6995 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
6998 template<typename Derived>
6999 QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7000 AtomicTypeLoc TL) {
7001 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7002 if (ValueType.isNull())
7003 return QualType();
7005 QualType Result = TL.getType();
7006 if (getDerived().AlwaysRebuild() ||
7007 ValueType != TL.getValueLoc().getType()) {
7008 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7009 if (Result.isNull())
7010 return QualType();
7013 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
7014 NewTL.setKWLoc(TL.getKWLoc());
7015 NewTL.setLParenLoc(TL.getLParenLoc());
7016 NewTL.setRParenLoc(TL.getRParenLoc());
7018 return Result;
7021 template <typename Derived>
7022 QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7023 PipeTypeLoc TL) {
7024 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7025 if (ValueType.isNull())
7026 return QualType();
7028 QualType Result = TL.getType();
7029 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7030 const PipeType *PT = Result->castAs<PipeType>();
7031 bool isReadPipe = PT->isReadOnly();
7032 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7033 if (Result.isNull())
7034 return QualType();
7037 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);
7038 NewTL.setKWLoc(TL.getKWLoc());
7040 return Result;
7043 template <typename Derived>
7044 QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7045 BitIntTypeLoc TL) {
7046 const BitIntType *EIT = TL.getTypePtr();
7047 QualType Result = TL.getType();
7049 if (getDerived().AlwaysRebuild()) {
7050 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7051 EIT->getNumBits(), TL.getNameLoc());
7052 if (Result.isNull())
7053 return QualType();
7056 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
7057 NewTL.setNameLoc(TL.getNameLoc());
7058 return Result;
7061 template <typename Derived>
7062 QualType TreeTransform<Derived>::TransformDependentBitIntType(
7063 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7064 const DependentBitIntType *EIT = TL.getTypePtr();
7066 EnterExpressionEvaluationContext Unevaluated(
7067 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7068 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7069 BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr);
7071 if (BitsExpr.isInvalid())
7072 return QualType();
7074 QualType Result = TL.getType();
7076 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7077 Result = getDerived().RebuildDependentBitIntType(
7078 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7080 if (Result.isNull())
7081 return QualType();
7084 if (isa<DependentBitIntType>(Result)) {
7085 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);
7086 NewTL.setNameLoc(TL.getNameLoc());
7087 } else {
7088 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
7089 NewTL.setNameLoc(TL.getNameLoc());
7091 return Result;
7094 /// Simple iterator that traverses the template arguments in a
7095 /// container that provides a \c getArgLoc() member function.
7097 /// This iterator is intended to be used with the iterator form of
7098 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7099 template<typename ArgLocContainer>
7100 class TemplateArgumentLocContainerIterator {
7101 ArgLocContainer *Container;
7102 unsigned Index;
7104 public:
7105 typedef TemplateArgumentLoc value_type;
7106 typedef TemplateArgumentLoc reference;
7107 typedef int difference_type;
7108 typedef std::input_iterator_tag iterator_category;
7110 class pointer {
7111 TemplateArgumentLoc Arg;
7113 public:
7114 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7116 const TemplateArgumentLoc *operator->() const {
7117 return &Arg;
7122 TemplateArgumentLocContainerIterator() {}
7124 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7125 unsigned Index)
7126 : Container(&Container), Index(Index) { }
7128 TemplateArgumentLocContainerIterator &operator++() {
7129 ++Index;
7130 return *this;
7133 TemplateArgumentLocContainerIterator operator++(int) {
7134 TemplateArgumentLocContainerIterator Old(*this);
7135 ++(*this);
7136 return Old;
7139 TemplateArgumentLoc operator*() const {
7140 return Container->getArgLoc(Index);
7143 pointer operator->() const {
7144 return pointer(Container->getArgLoc(Index));
7147 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7148 const TemplateArgumentLocContainerIterator &Y) {
7149 return X.Container == Y.Container && X.Index == Y.Index;
7152 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7153 const TemplateArgumentLocContainerIterator &Y) {
7154 return !(X == Y);
7158 template<typename Derived>
7159 QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7160 AutoTypeLoc TL) {
7161 const AutoType *T = TL.getTypePtr();
7162 QualType OldDeduced = T->getDeducedType();
7163 QualType NewDeduced;
7164 if (!OldDeduced.isNull()) {
7165 NewDeduced = getDerived().TransformType(OldDeduced);
7166 if (NewDeduced.isNull())
7167 return QualType();
7170 ConceptDecl *NewCD = nullptr;
7171 TemplateArgumentListInfo NewTemplateArgs;
7172 NestedNameSpecifierLoc NewNestedNameSpec;
7173 if (T->isConstrained()) {
7174 assert(TL.getConceptReference());
7175 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7176 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7178 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7179 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7180 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7181 if (getDerived().TransformTemplateArguments(
7182 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7183 NewTemplateArgs))
7184 return QualType();
7186 if (TL.getNestedNameSpecifierLoc()) {
7187 NewNestedNameSpec
7188 = getDerived().TransformNestedNameSpecifierLoc(
7189 TL.getNestedNameSpecifierLoc());
7190 if (!NewNestedNameSpec)
7191 return QualType();
7195 QualType Result = TL.getType();
7196 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7197 T->isDependentType() || T->isConstrained()) {
7198 // FIXME: Maybe don't rebuild if all template arguments are the same.
7199 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7200 NewArgList.reserve(NewTemplateArgs.size());
7201 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7202 NewArgList.push_back(ArgLoc.getArgument());
7203 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7204 NewArgList);
7205 if (Result.isNull())
7206 return QualType();
7209 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
7210 NewTL.setNameLoc(TL.getNameLoc());
7211 NewTL.setRParenLoc(TL.getRParenLoc());
7212 NewTL.setConceptReference(nullptr);
7214 if (T->isConstrained()) {
7215 DeclarationNameInfo DNI = DeclarationNameInfo(
7216 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7217 TL.getConceptNameLoc(),
7218 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7219 auto *CR = ConceptReference::Create(
7220 SemaRef.Context, NewNestedNameSpec, TL.getTemplateKWLoc(), DNI,
7221 TL.getFoundDecl(), TL.getTypePtr()->getTypeConstraintConcept(),
7222 ASTTemplateArgumentListInfo::Create(SemaRef.Context, NewTemplateArgs));
7223 NewTL.setConceptReference(CR);
7226 return Result;
7229 template <typename Derived>
7230 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7231 TypeLocBuilder &TLB,
7232 TemplateSpecializationTypeLoc TL,
7233 TemplateName Template) {
7234 TemplateArgumentListInfo NewTemplateArgs;
7235 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7236 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7237 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7238 ArgIterator;
7239 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7240 ArgIterator(TL, TL.getNumArgs()),
7241 NewTemplateArgs))
7242 return QualType();
7244 // FIXME: maybe don't rebuild if all the template arguments are the same.
7246 QualType Result =
7247 getDerived().RebuildTemplateSpecializationType(Template,
7248 TL.getTemplateNameLoc(),
7249 NewTemplateArgs);
7251 if (!Result.isNull()) {
7252 // Specializations of template template parameters are represented as
7253 // TemplateSpecializationTypes, and substitution of type alias templates
7254 // within a dependent context can transform them into
7255 // DependentTemplateSpecializationTypes.
7256 if (isa<DependentTemplateSpecializationType>(Result)) {
7257 DependentTemplateSpecializationTypeLoc NewTL
7258 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7259 NewTL.setElaboratedKeywordLoc(SourceLocation());
7260 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
7261 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7262 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7263 NewTL.setLAngleLoc(TL.getLAngleLoc());
7264 NewTL.setRAngleLoc(TL.getRAngleLoc());
7265 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7266 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7267 return Result;
7270 TemplateSpecializationTypeLoc NewTL
7271 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7272 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7273 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7274 NewTL.setLAngleLoc(TL.getLAngleLoc());
7275 NewTL.setRAngleLoc(TL.getRAngleLoc());
7276 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7277 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7280 return Result;
7283 template <typename Derived>
7284 QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
7285 TypeLocBuilder &TLB,
7286 DependentTemplateSpecializationTypeLoc TL,
7287 TemplateName Template,
7288 CXXScopeSpec &SS) {
7289 TemplateArgumentListInfo NewTemplateArgs;
7290 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7291 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7292 typedef TemplateArgumentLocContainerIterator<
7293 DependentTemplateSpecializationTypeLoc> ArgIterator;
7294 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7295 ArgIterator(TL, TL.getNumArgs()),
7296 NewTemplateArgs))
7297 return QualType();
7299 // FIXME: maybe don't rebuild if all the template arguments are the same.
7301 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
7302 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
7303 TL.getTypePtr()->getKeyword(), DTN->getQualifier(),
7304 DTN->getIdentifier(), NewTemplateArgs.arguments());
7306 DependentTemplateSpecializationTypeLoc NewTL
7307 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7308 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7309 NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
7310 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7311 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7312 NewTL.setLAngleLoc(TL.getLAngleLoc());
7313 NewTL.setRAngleLoc(TL.getRAngleLoc());
7314 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7315 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7316 return Result;
7319 QualType Result
7320 = getDerived().RebuildTemplateSpecializationType(Template,
7321 TL.getTemplateNameLoc(),
7322 NewTemplateArgs);
7324 if (!Result.isNull()) {
7325 /// FIXME: Wrap this in an elaborated-type-specifier?
7326 TemplateSpecializationTypeLoc NewTL
7327 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7328 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7329 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7330 NewTL.setLAngleLoc(TL.getLAngleLoc());
7331 NewTL.setRAngleLoc(TL.getRAngleLoc());
7332 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7333 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7336 return Result;
7339 template<typename Derived>
7340 QualType
7341 TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
7342 ElaboratedTypeLoc TL) {
7343 const ElaboratedType *T = TL.getTypePtr();
7345 NestedNameSpecifierLoc QualifierLoc;
7346 // NOTE: the qualifier in an ElaboratedType is optional.
7347 if (TL.getQualifierLoc()) {
7348 QualifierLoc
7349 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7350 if (!QualifierLoc)
7351 return QualType();
7354 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7355 if (NamedT.isNull())
7356 return QualType();
7358 // C++0x [dcl.type.elab]p2:
7359 // If the identifier resolves to a typedef-name or the simple-template-id
7360 // resolves to an alias template specialization, the
7361 // elaborated-type-specifier is ill-formed.
7362 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7363 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7364 if (const TemplateSpecializationType *TST =
7365 NamedT->getAs<TemplateSpecializationType>()) {
7366 TemplateName Template = TST->getTemplateName();
7367 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7368 Template.getAsTemplateDecl())) {
7369 SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
7370 diag::err_tag_reference_non_tag)
7371 << TAT << Sema::NTK_TypeAliasTemplate
7372 << llvm::to_underlying(
7373 ElaboratedType::getTagTypeKindForKeyword(T->getKeyword()));
7374 SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
7379 QualType Result = TL.getType();
7380 if (getDerived().AlwaysRebuild() ||
7381 QualifierLoc != TL.getQualifierLoc() ||
7382 NamedT != T->getNamedType()) {
7383 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7384 T->getKeyword(),
7385 QualifierLoc, NamedT);
7386 if (Result.isNull())
7387 return QualType();
7390 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7391 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7392 NewTL.setQualifierLoc(QualifierLoc);
7393 return Result;
7396 template <typename Derived>
7397 QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7398 AttributedTypeLoc TL) {
7399 const AttributedType *oldType = TL.getTypePtr();
7400 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7401 if (modifiedType.isNull())
7402 return QualType();
7404 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7405 const Attr *oldAttr = TL.getAttr();
7406 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7407 if (oldAttr && !newAttr)
7408 return QualType();
7410 QualType result = TL.getType();
7412 // FIXME: dependent operand expressions?
7413 if (getDerived().AlwaysRebuild() ||
7414 modifiedType != oldType->getModifiedType()) {
7415 // If the equivalent type is equal to the modified type, we don't want to
7416 // transform it as well because:
7418 // 1. The transformation would yield the same result and is therefore
7419 // superfluous, and
7421 // 2. Transforming the same type twice can cause problems, e.g. if it
7422 // is a FunctionProtoType, we may end up instantiating the function
7423 // parameters twice, which causes an assertion since the parameters
7424 // are already bound to their counterparts in the template for this
7425 // instantiation.
7427 QualType equivalentType = modifiedType;
7428 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7429 TypeLocBuilder AuxiliaryTLB;
7430 AuxiliaryTLB.reserve(TL.getFullDataSize());
7431 equivalentType =
7432 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7433 if (equivalentType.isNull())
7434 return QualType();
7437 // Check whether we can add nullability; it is only represented as
7438 // type sugar, and therefore cannot be diagnosed in any other way.
7439 if (auto nullability = oldType->getImmediateNullability()) {
7440 if (!modifiedType->canHaveNullability()) {
7441 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
7442 : TL.getModifiedLoc().getBeginLoc()),
7443 diag::err_nullability_nonpointer)
7444 << DiagNullabilityKind(*nullability, false) << modifiedType;
7445 return QualType();
7449 result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
7450 modifiedType,
7451 equivalentType,
7452 TL.getAttr());
7455 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
7456 newTL.setAttr(newAttr);
7457 return result;
7460 template <typename Derived>
7461 QualType TreeTransform<Derived>::TransformCountAttributedType(
7462 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7463 const CountAttributedType *OldTy = TL.getTypePtr();
7464 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7465 if (InnerTy.isNull())
7466 return QualType();
7468 Expr *OldCount = TL.getCountExpr();
7469 Expr *NewCount = nullptr;
7470 if (OldCount) {
7471 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7472 if (CountResult.isInvalid())
7473 return QualType();
7474 NewCount = CountResult.get();
7477 QualType Result = TL.getType();
7478 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7479 OldCount != NewCount) {
7480 // Currently, CountAttributedType can only wrap incomplete array types.
7481 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7482 InnerTy, NewCount, OldTy->isCountInBytes(), OldTy->isOrNull());
7485 TLB.push<CountAttributedTypeLoc>(Result);
7486 return Result;
7489 template <typename Derived>
7490 QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7491 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7492 // The BTFTagAttributedType is available for C only.
7493 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7496 template <typename Derived>
7497 QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7498 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7500 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7502 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7503 if (WrappedTy.isNull())
7504 return QualType();
7506 QualType ContainedTy = QualType();
7507 QualType OldContainedTy = oldType->getContainedType();
7508 if (!OldContainedTy.isNull()) {
7509 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7510 if (!oldContainedTSI)
7511 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7512 OldContainedTy, SourceLocation());
7513 TypeSourceInfo *ContainedTSI = getDerived().TransformType(oldContainedTSI);
7514 if (!ContainedTSI)
7515 return QualType();
7516 ContainedTy = ContainedTSI->getType();
7519 QualType Result = TL.getType();
7520 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7521 ContainedTy != oldType->getContainedType()) {
7522 Result = SemaRef.Context.getHLSLAttributedResourceType(
7523 WrappedTy, ContainedTy, oldType->getAttrs());
7526 TLB.push<HLSLAttributedResourceTypeLoc>(Result);
7527 return Result;
7530 template<typename Derived>
7531 QualType
7532 TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7533 ParenTypeLoc TL) {
7534 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7535 if (Inner.isNull())
7536 return QualType();
7538 QualType Result = TL.getType();
7539 if (getDerived().AlwaysRebuild() ||
7540 Inner != TL.getInnerLoc().getType()) {
7541 Result = getDerived().RebuildParenType(Inner);
7542 if (Result.isNull())
7543 return QualType();
7546 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
7547 NewTL.setLParenLoc(TL.getLParenLoc());
7548 NewTL.setRParenLoc(TL.getRParenLoc());
7549 return Result;
7552 template <typename Derived>
7553 QualType
7554 TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7555 MacroQualifiedTypeLoc TL) {
7556 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7557 if (Inner.isNull())
7558 return QualType();
7560 QualType Result = TL.getType();
7561 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7562 Result =
7563 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7564 if (Result.isNull())
7565 return QualType();
7568 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
7569 NewTL.setExpansionLoc(TL.getExpansionLoc());
7570 return Result;
7573 template<typename Derived>
7574 QualType TreeTransform<Derived>::TransformDependentNameType(
7575 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7576 return TransformDependentNameType(TLB, TL, false);
7579 template<typename Derived>
7580 QualType TreeTransform<Derived>::TransformDependentNameType(
7581 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7582 const DependentNameType *T = TL.getTypePtr();
7584 NestedNameSpecifierLoc QualifierLoc
7585 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7586 if (!QualifierLoc)
7587 return QualType();
7589 QualType Result
7590 = getDerived().RebuildDependentNameType(T->getKeyword(),
7591 TL.getElaboratedKeywordLoc(),
7592 QualifierLoc,
7593 T->getIdentifier(),
7594 TL.getNameLoc(),
7595 DeducedTSTContext);
7596 if (Result.isNull())
7597 return QualType();
7599 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7600 QualType NamedT = ElabT->getNamedType();
7601 TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
7603 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7604 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7605 NewTL.setQualifierLoc(QualifierLoc);
7606 } else {
7607 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
7608 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7609 NewTL.setQualifierLoc(QualifierLoc);
7610 NewTL.setNameLoc(TL.getNameLoc());
7612 return Result;
7615 template<typename Derived>
7616 QualType TreeTransform<Derived>::
7617 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7618 DependentTemplateSpecializationTypeLoc TL) {
7619 NestedNameSpecifierLoc QualifierLoc;
7620 if (TL.getQualifierLoc()) {
7621 QualifierLoc
7622 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7623 if (!QualifierLoc)
7624 return QualType();
7627 return getDerived()
7628 .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
7631 template<typename Derived>
7632 QualType TreeTransform<Derived>::
7633 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7634 DependentTemplateSpecializationTypeLoc TL,
7635 NestedNameSpecifierLoc QualifierLoc) {
7636 const DependentTemplateSpecializationType *T = TL.getTypePtr();
7638 TemplateArgumentListInfo NewTemplateArgs;
7639 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7640 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7642 typedef TemplateArgumentLocContainerIterator<
7643 DependentTemplateSpecializationTypeLoc> ArgIterator;
7644 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7645 ArgIterator(TL, TL.getNumArgs()),
7646 NewTemplateArgs))
7647 return QualType();
7649 QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
7650 T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(),
7651 T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs,
7652 /*AllowInjectedClassName*/ false);
7653 if (Result.isNull())
7654 return QualType();
7656 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
7657 QualType NamedT = ElabT->getNamedType();
7659 // Copy information relevant to the template specialization.
7660 TemplateSpecializationTypeLoc NamedTL
7661 = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
7662 NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7663 NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7664 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7665 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7666 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7667 NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7669 // Copy information relevant to the elaborated type.
7670 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7671 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7672 NewTL.setQualifierLoc(QualifierLoc);
7673 } else if (isa<DependentTemplateSpecializationType>(Result)) {
7674 DependentTemplateSpecializationTypeLoc SpecTL
7675 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7676 SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7677 SpecTL.setQualifierLoc(QualifierLoc);
7678 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7679 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7680 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7681 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7682 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7683 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7684 } else {
7685 TemplateSpecializationTypeLoc SpecTL
7686 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7687 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7688 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7689 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7690 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7691 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7692 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7694 return Result;
7697 template<typename Derived>
7698 QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7699 PackExpansionTypeLoc TL) {
7700 QualType Pattern
7701 = getDerived().TransformType(TLB, TL.getPatternLoc());
7702 if (Pattern.isNull())
7703 return QualType();
7705 QualType Result = TL.getType();
7706 if (getDerived().AlwaysRebuild() ||
7707 Pattern != TL.getPatternLoc().getType()) {
7708 Result = getDerived().RebuildPackExpansionType(Pattern,
7709 TL.getPatternLoc().getSourceRange(),
7710 TL.getEllipsisLoc(),
7711 TL.getTypePtr()->getNumExpansions());
7712 if (Result.isNull())
7713 return QualType();
7716 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
7717 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7718 return Result;
7721 template<typename Derived>
7722 QualType
7723 TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7724 ObjCInterfaceTypeLoc TL) {
7725 // ObjCInterfaceType is never dependent.
7726 TLB.pushFullCopy(TL);
7727 return TL.getType();
7730 template<typename Derived>
7731 QualType
7732 TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7733 ObjCTypeParamTypeLoc TL) {
7734 const ObjCTypeParamType *T = TL.getTypePtr();
7735 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7736 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7737 if (!OTP)
7738 return QualType();
7740 QualType Result = TL.getType();
7741 if (getDerived().AlwaysRebuild() ||
7742 OTP != T->getDecl()) {
7743 Result = getDerived().RebuildObjCTypeParamType(
7744 OTP, TL.getProtocolLAngleLoc(),
7745 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7746 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7747 if (Result.isNull())
7748 return QualType();
7751 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
7752 if (TL.getNumProtocols()) {
7753 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7754 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7755 NewTL.setProtocolLoc(i, TL.getProtocolLoc(i));
7756 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7758 return Result;
7761 template<typename Derived>
7762 QualType
7763 TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7764 ObjCObjectTypeLoc TL) {
7765 // Transform base type.
7766 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7767 if (BaseType.isNull())
7768 return QualType();
7770 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7772 // Transform type arguments.
7773 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7774 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7775 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7776 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7777 QualType TypeArg = TypeArgInfo->getType();
7778 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7779 AnyChanged = true;
7781 // We have a pack expansion. Instantiate it.
7782 const auto *PackExpansion = PackExpansionLoc.getType()
7783 ->castAs<PackExpansionType>();
7784 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7785 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
7786 Unexpanded);
7787 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7789 // Determine whether the set of unexpanded parameter packs can
7790 // and should be expanded.
7791 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7792 bool Expand = false;
7793 bool RetainExpansion = false;
7794 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
7795 if (getDerived().TryExpandParameterPacks(
7796 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7797 Unexpanded, Expand, RetainExpansion, NumExpansions))
7798 return QualType();
7800 if (!Expand) {
7801 // We can't expand this pack expansion into separate arguments yet;
7802 // just substitute into the pattern and create a new pack expansion
7803 // type.
7804 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
7806 TypeLocBuilder TypeArgBuilder;
7807 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7808 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7809 PatternLoc);
7810 if (NewPatternType.isNull())
7811 return QualType();
7813 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7814 NewPatternType, NumExpansions);
7815 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);
7816 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7817 NewTypeArgInfos.push_back(
7818 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewExpansionType));
7819 continue;
7822 // Substitute into the pack expansion pattern for each slice of the
7823 // pack.
7824 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
7825 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
7827 TypeLocBuilder TypeArgBuilder;
7828 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7830 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
7831 PatternLoc);
7832 if (NewTypeArg.isNull())
7833 return QualType();
7835 NewTypeArgInfos.push_back(
7836 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7839 continue;
7842 TypeLocBuilder TypeArgBuilder;
7843 TypeArgBuilder.reserve(TypeArgLoc.getFullDataSize());
7844 QualType NewTypeArg =
7845 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
7846 if (NewTypeArg.isNull())
7847 return QualType();
7849 // If nothing changed, just keep the old TypeSourceInfo.
7850 if (NewTypeArg == TypeArg) {
7851 NewTypeArgInfos.push_back(TypeArgInfo);
7852 continue;
7855 NewTypeArgInfos.push_back(
7856 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7857 AnyChanged = true;
7860 QualType Result = TL.getType();
7861 if (getDerived().AlwaysRebuild() || AnyChanged) {
7862 // Rebuild the type.
7863 Result = getDerived().RebuildObjCObjectType(
7864 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
7865 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
7866 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7867 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7869 if (Result.isNull())
7870 return QualType();
7873 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);
7874 NewT.setHasBaseTypeAsWritten(true);
7875 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
7876 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
7877 NewT.setTypeArgTInfo(i, NewTypeArgInfos[i]);
7878 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
7879 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7880 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7881 NewT.setProtocolLoc(i, TL.getProtocolLoc(i));
7882 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7883 return Result;
7886 template<typename Derived>
7887 QualType
7888 TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
7889 ObjCObjectPointerTypeLoc TL) {
7890 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
7891 if (PointeeType.isNull())
7892 return QualType();
7894 QualType Result = TL.getType();
7895 if (getDerived().AlwaysRebuild() ||
7896 PointeeType != TL.getPointeeLoc().getType()) {
7897 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
7898 TL.getStarLoc());
7899 if (Result.isNull())
7900 return QualType();
7903 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
7904 NewT.setStarLoc(TL.getStarLoc());
7905 return Result;
7908 //===----------------------------------------------------------------------===//
7909 // Statement transformation
7910 //===----------------------------------------------------------------------===//
7911 template<typename Derived>
7912 StmtResult
7913 TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
7914 return S;
7917 template<typename Derived>
7918 StmtResult
7919 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
7920 return getDerived().TransformCompoundStmt(S, false);
7923 template<typename Derived>
7924 StmtResult
7925 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
7926 bool IsStmtExpr) {
7927 Sema::CompoundScopeRAII CompoundScope(getSema());
7928 Sema::FPFeaturesStateRAII FPSave(getSema());
7929 if (S->hasStoredFPFeatures())
7930 getSema().resetFPOptions(
7931 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
7933 const Stmt *ExprResult = S->getStmtExprResult();
7934 bool SubStmtInvalid = false;
7935 bool SubStmtChanged = false;
7936 SmallVector<Stmt*, 8> Statements;
7937 for (auto *B : S->body()) {
7938 StmtResult Result = getDerived().TransformStmt(
7939 B, IsStmtExpr && B == ExprResult ? SDK_StmtExprResult : SDK_Discarded);
7941 if (Result.isInvalid()) {
7942 // Immediately fail if this was a DeclStmt, since it's very
7943 // likely that this will cause problems for future statements.
7944 if (isa<DeclStmt>(B))
7945 return StmtError();
7947 // Otherwise, just keep processing substatements and fail later.
7948 SubStmtInvalid = true;
7949 continue;
7952 SubStmtChanged = SubStmtChanged || Result.get() != B;
7953 Statements.push_back(Result.getAs<Stmt>());
7956 if (SubStmtInvalid)
7957 return StmtError();
7959 if (!getDerived().AlwaysRebuild() &&
7960 !SubStmtChanged)
7961 return S;
7963 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
7964 Statements,
7965 S->getRBracLoc(),
7966 IsStmtExpr);
7969 template<typename Derived>
7970 StmtResult
7971 TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
7972 ExprResult LHS, RHS;
7974 EnterExpressionEvaluationContext Unevaluated(
7975 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7977 // Transform the left-hand case value.
7978 LHS = getDerived().TransformExpr(S->getLHS());
7979 LHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), LHS);
7980 if (LHS.isInvalid())
7981 return StmtError();
7983 // Transform the right-hand case value (for the GNU case-range extension).
7984 RHS = getDerived().TransformExpr(S->getRHS());
7985 RHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), RHS);
7986 if (RHS.isInvalid())
7987 return StmtError();
7990 // Build the case statement.
7991 // Case statements are always rebuilt so that they will attached to their
7992 // transformed switch statement.
7993 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
7994 LHS.get(),
7995 S->getEllipsisLoc(),
7996 RHS.get(),
7997 S->getColonLoc());
7998 if (Case.isInvalid())
7999 return StmtError();
8001 // Transform the statement following the case
8002 StmtResult SubStmt =
8003 getDerived().TransformStmt(S->getSubStmt());
8004 if (SubStmt.isInvalid())
8005 return StmtError();
8007 // Attach the body to the case statement
8008 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8011 template <typename Derived>
8012 StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8013 // Transform the statement following the default case
8014 StmtResult SubStmt =
8015 getDerived().TransformStmt(S->getSubStmt());
8016 if (SubStmt.isInvalid())
8017 return StmtError();
8019 // Default statements are always rebuilt
8020 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8021 SubStmt.get());
8024 template<typename Derived>
8025 StmtResult
8026 TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8027 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8028 if (SubStmt.isInvalid())
8029 return StmtError();
8031 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8032 S->getDecl());
8033 if (!LD)
8034 return StmtError();
8036 // If we're transforming "in-place" (we're not creating new local
8037 // declarations), assume we're replacing the old label statement
8038 // and clear out the reference to it.
8039 if (LD == S->getDecl())
8040 S->getDecl()->setStmt(nullptr);
8042 // FIXME: Pass the real colon location in.
8043 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8044 cast<LabelDecl>(LD), SourceLocation(),
8045 SubStmt.get());
8048 template <typename Derived>
8049 const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8050 if (!R)
8051 return R;
8053 switch (R->getKind()) {
8054 // Transform attributes by calling TransformXXXAttr.
8055 #define ATTR(X) \
8056 case attr::X: \
8057 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8058 #include "clang/Basic/AttrList.inc"
8060 return R;
8063 template <typename Derived>
8064 const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8065 const Stmt *InstS,
8066 const Attr *R) {
8067 if (!R)
8068 return R;
8070 switch (R->getKind()) {
8071 // Transform attributes by calling TransformStmtXXXAttr.
8072 #define ATTR(X) \
8073 case attr::X: \
8074 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8075 #include "clang/Basic/AttrList.inc"
8077 return TransformAttr(R);
8080 template <typename Derived>
8081 StmtResult
8082 TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8083 StmtDiscardKind SDK) {
8084 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8085 if (SubStmt.isInvalid())
8086 return StmtError();
8088 bool AttrsChanged = false;
8089 SmallVector<const Attr *, 1> Attrs;
8091 // Visit attributes and keep track if any are transformed.
8092 for (const auto *I : S->getAttrs()) {
8093 const Attr *R =
8094 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8095 AttrsChanged |= (I != R);
8096 if (R)
8097 Attrs.push_back(R);
8100 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8101 return S;
8103 // If transforming the attributes failed for all of the attributes in the
8104 // statement, don't make an AttributedStmt without attributes.
8105 if (Attrs.empty())
8106 return SubStmt;
8108 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8109 SubStmt.get());
8112 template<typename Derived>
8113 StmtResult
8114 TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8115 // Transform the initialization statement
8116 StmtResult Init = getDerived().TransformStmt(S->getInit());
8117 if (Init.isInvalid())
8118 return StmtError();
8120 Sema::ConditionResult Cond;
8121 if (!S->isConsteval()) {
8122 // Transform the condition
8123 Cond = getDerived().TransformCondition(
8124 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8125 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8126 : Sema::ConditionKind::Boolean);
8127 if (Cond.isInvalid())
8128 return StmtError();
8131 // If this is a constexpr if, determine which arm we should instantiate.
8132 std::optional<bool> ConstexprConditionValue;
8133 if (S->isConstexpr())
8134 ConstexprConditionValue = Cond.getKnownValue();
8136 // Transform the "then" branch.
8137 StmtResult Then;
8138 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8139 EnterExpressionEvaluationContext Ctx(
8140 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8141 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8142 S->isNonNegatedConsteval());
8144 Then = getDerived().TransformStmt(S->getThen());
8145 if (Then.isInvalid())
8146 return StmtError();
8147 } else {
8148 // Discarded branch is replaced with empty CompoundStmt so we can keep
8149 // proper source location for start and end of original branch, so
8150 // subsequent transformations like CoverageMapping work properly
8151 Then = new (getSema().Context)
8152 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8155 // Transform the "else" branch.
8156 StmtResult Else;
8157 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8158 EnterExpressionEvaluationContext Ctx(
8159 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8160 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8161 S->isNegatedConsteval());
8163 Else = getDerived().TransformStmt(S->getElse());
8164 if (Else.isInvalid())
8165 return StmtError();
8166 } else if (S->getElse() && ConstexprConditionValue &&
8167 *ConstexprConditionValue) {
8168 // Same thing here as with <then> branch, we are discarding it, we can't
8169 // replace it with NULL nor NullStmt as we need to keep for source location
8170 // range, for CoverageMapping
8171 Else = new (getSema().Context)
8172 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8175 if (!getDerived().AlwaysRebuild() &&
8176 Init.get() == S->getInit() &&
8177 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8178 Then.get() == S->getThen() &&
8179 Else.get() == S->getElse())
8180 return S;
8182 return getDerived().RebuildIfStmt(
8183 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8184 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8187 template<typename Derived>
8188 StmtResult
8189 TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8190 // Transform the initialization statement
8191 StmtResult Init = getDerived().TransformStmt(S->getInit());
8192 if (Init.isInvalid())
8193 return StmtError();
8195 // Transform the condition.
8196 Sema::ConditionResult Cond = getDerived().TransformCondition(
8197 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8198 Sema::ConditionKind::Switch);
8199 if (Cond.isInvalid())
8200 return StmtError();
8202 // Rebuild the switch statement.
8203 StmtResult Switch =
8204 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8205 Init.get(), Cond, S->getRParenLoc());
8206 if (Switch.isInvalid())
8207 return StmtError();
8209 // Transform the body of the switch statement.
8210 StmtResult Body = getDerived().TransformStmt(S->getBody());
8211 if (Body.isInvalid())
8212 return StmtError();
8214 // Complete the switch statement.
8215 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8216 Body.get());
8219 template<typename Derived>
8220 StmtResult
8221 TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8222 // Transform the condition
8223 Sema::ConditionResult Cond = getDerived().TransformCondition(
8224 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8225 Sema::ConditionKind::Boolean);
8226 if (Cond.isInvalid())
8227 return StmtError();
8229 // OpenACC Restricts a while-loop inside of certain construct/clause
8230 // combinations, so diagnose that here in OpenACC mode.
8231 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8232 SemaRef.OpenACC().ActOnWhileStmt(S->getBeginLoc());
8234 // Transform the body
8235 StmtResult Body = getDerived().TransformStmt(S->getBody());
8236 if (Body.isInvalid())
8237 return StmtError();
8239 if (!getDerived().AlwaysRebuild() &&
8240 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8241 Body.get() == S->getBody())
8242 return Owned(S);
8244 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8245 Cond, S->getRParenLoc(), Body.get());
8248 template<typename Derived>
8249 StmtResult
8250 TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8251 // OpenACC Restricts a do-loop inside of certain construct/clause
8252 // combinations, so diagnose that here in OpenACC mode.
8253 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8254 SemaRef.OpenACC().ActOnDoStmt(S->getBeginLoc());
8256 // Transform the body
8257 StmtResult Body = getDerived().TransformStmt(S->getBody());
8258 if (Body.isInvalid())
8259 return StmtError();
8261 // Transform the condition
8262 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8263 if (Cond.isInvalid())
8264 return StmtError();
8266 if (!getDerived().AlwaysRebuild() &&
8267 Cond.get() == S->getCond() &&
8268 Body.get() == S->getBody())
8269 return S;
8271 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8272 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8273 S->getRParenLoc());
8276 template<typename Derived>
8277 StmtResult
8278 TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8279 if (getSema().getLangOpts().OpenMP)
8280 getSema().OpenMP().startOpenMPLoop();
8282 // Transform the initialization statement
8283 StmtResult Init = getDerived().TransformStmt(S->getInit());
8284 if (Init.isInvalid())
8285 return StmtError();
8287 // In OpenMP loop region loop control variable must be captured and be
8288 // private. Perform analysis of first part (if any).
8289 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8290 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8291 Init.get());
8293 // Transform the condition
8294 Sema::ConditionResult Cond = getDerived().TransformCondition(
8295 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8296 Sema::ConditionKind::Boolean);
8297 if (Cond.isInvalid())
8298 return StmtError();
8300 // Transform the increment
8301 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8302 if (Inc.isInvalid())
8303 return StmtError();
8305 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8306 if (S->getInc() && !FullInc.get())
8307 return StmtError();
8309 // OpenACC Restricts a for-loop inside of certain construct/clause
8310 // combinations, so diagnose that here in OpenACC mode.
8311 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8312 SemaRef.OpenACC().ActOnForStmtBegin(
8313 S->getBeginLoc(), S->getInit(), Init.get(), S->getCond(),
8314 Cond.get().second, S->getInc(), Inc.get());
8316 // Transform the body
8317 StmtResult Body = getDerived().TransformStmt(S->getBody());
8318 if (Body.isInvalid())
8319 return StmtError();
8321 SemaRef.OpenACC().ActOnForStmtEnd(S->getBeginLoc(), Body);
8323 if (!getDerived().AlwaysRebuild() &&
8324 Init.get() == S->getInit() &&
8325 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8326 Inc.get() == S->getInc() &&
8327 Body.get() == S->getBody())
8328 return S;
8330 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8331 Init.get(), Cond, FullInc,
8332 S->getRParenLoc(), Body.get());
8335 template<typename Derived>
8336 StmtResult
8337 TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8338 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8339 S->getLabel());
8340 if (!LD)
8341 return StmtError();
8343 // Goto statements must always be rebuilt, to resolve the label.
8344 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8345 cast<LabelDecl>(LD));
8348 template<typename Derived>
8349 StmtResult
8350 TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8351 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8352 if (Target.isInvalid())
8353 return StmtError();
8354 Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());
8356 if (!getDerived().AlwaysRebuild() &&
8357 Target.get() == S->getTarget())
8358 return S;
8360 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8361 Target.get());
8364 template<typename Derived>
8365 StmtResult
8366 TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8367 return S;
8370 template<typename Derived>
8371 StmtResult
8372 TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8373 return S;
8376 template<typename Derived>
8377 StmtResult
8378 TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8379 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8380 /*NotCopyInit*/false);
8381 if (Result.isInvalid())
8382 return StmtError();
8384 // FIXME: We always rebuild the return statement because there is no way
8385 // to tell whether the return type of the function has changed.
8386 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8389 template<typename Derived>
8390 StmtResult
8391 TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8392 bool DeclChanged = false;
8393 SmallVector<Decl *, 4> Decls;
8394 LambdaScopeInfo *LSI = getSema().getCurLambda();
8395 for (auto *D : S->decls()) {
8396 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8397 if (!Transformed)
8398 return StmtError();
8400 if (Transformed != D)
8401 DeclChanged = true;
8403 if (LSI) {
8404 if (auto *TD = dyn_cast<TypeDecl>(Transformed))
8405 LSI->ContainsUnexpandedParameterPack |=
8406 getSema()
8407 .getASTContext()
8408 .getTypeDeclType(TD)
8409 .getCanonicalType()
8410 ->containsUnexpandedParameterPack();
8412 if (auto *VD = dyn_cast<VarDecl>(Transformed))
8413 LSI->ContainsUnexpandedParameterPack |=
8414 VD->getType()->containsUnexpandedParameterPack();
8417 Decls.push_back(Transformed);
8420 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8421 return S;
8423 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8426 template<typename Derived>
8427 StmtResult
8428 TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8430 SmallVector<Expr*, 8> Constraints;
8431 SmallVector<Expr*, 8> Exprs;
8432 SmallVector<IdentifierInfo *, 4> Names;
8434 ExprResult AsmString;
8435 SmallVector<Expr*, 8> Clobbers;
8437 bool ExprsChanged = false;
8439 // Go through the outputs.
8440 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8441 Names.push_back(S->getOutputIdentifier(I));
8443 // No need to transform the constraint literal.
8444 Constraints.push_back(S->getOutputConstraintLiteral(I));
8446 // Transform the output expr.
8447 Expr *OutputExpr = S->getOutputExpr(I);
8448 ExprResult Result = getDerived().TransformExpr(OutputExpr);
8449 if (Result.isInvalid())
8450 return StmtError();
8452 ExprsChanged |= Result.get() != OutputExpr;
8454 Exprs.push_back(Result.get());
8457 // Go through the inputs.
8458 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8459 Names.push_back(S->getInputIdentifier(I));
8461 // No need to transform the constraint literal.
8462 Constraints.push_back(S->getInputConstraintLiteral(I));
8464 // Transform the input expr.
8465 Expr *InputExpr = S->getInputExpr(I);
8466 ExprResult Result = getDerived().TransformExpr(InputExpr);
8467 if (Result.isInvalid())
8468 return StmtError();
8470 ExprsChanged |= Result.get() != InputExpr;
8472 Exprs.push_back(Result.get());
8475 // Go through the Labels.
8476 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8477 Names.push_back(S->getLabelIdentifier(I));
8479 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(I));
8480 if (Result.isInvalid())
8481 return StmtError();
8482 ExprsChanged |= Result.get() != S->getLabelExpr(I);
8483 Exprs.push_back(Result.get());
8485 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8486 return S;
8488 // Go through the clobbers.
8489 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
8490 Clobbers.push_back(S->getClobberStringLiteral(I));
8492 // No need to transform the asm string literal.
8493 AsmString = S->getAsmString();
8494 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8495 S->isVolatile(), S->getNumOutputs(),
8496 S->getNumInputs(), Names.data(),
8497 Constraints, Exprs, AsmString.get(),
8498 Clobbers, S->getNumLabels(),
8499 S->getRParenLoc());
8502 template<typename Derived>
8503 StmtResult
8504 TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8505 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8507 bool HadError = false, HadChange = false;
8509 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8510 SmallVector<Expr*, 8> TransformedExprs;
8511 TransformedExprs.reserve(SrcExprs.size());
8512 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8513 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8514 if (!Result.isUsable()) {
8515 HadError = true;
8516 } else {
8517 HadChange |= (Result.get() != SrcExprs[i]);
8518 TransformedExprs.push_back(Result.get());
8522 if (HadError) return StmtError();
8523 if (!HadChange && !getDerived().AlwaysRebuild())
8524 return Owned(S);
8526 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8527 AsmToks, S->getAsmString(),
8528 S->getNumOutputs(), S->getNumInputs(),
8529 S->getAllConstraints(), S->getClobbers(),
8530 TransformedExprs, S->getEndLoc());
8533 // C++ Coroutines
8534 template<typename Derived>
8535 StmtResult
8536 TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8537 auto *ScopeInfo = SemaRef.getCurFunction();
8538 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
8539 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8540 ScopeInfo->NeedsCoroutineSuspends &&
8541 ScopeInfo->CoroutineSuspends.first == nullptr &&
8542 ScopeInfo->CoroutineSuspends.second == nullptr &&
8543 "expected clean scope info");
8545 // Set that we have (possibly-invalid) suspend points before we do anything
8546 // that may fail.
8547 ScopeInfo->setNeedsCoroutineSuspends(false);
8549 // We re-build the coroutine promise object (and the coroutine parameters its
8550 // type and constructor depend on) based on the types used in our current
8551 // function. We must do so, and set it on the current FunctionScopeInfo,
8552 // before attempting to transform the other parts of the coroutine body
8553 // statement, such as the implicit suspend statements (because those
8554 // statements reference the FunctionScopeInfo::CoroutinePromise).
8555 if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation()))
8556 return StmtError();
8557 auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());
8558 if (!Promise)
8559 return StmtError();
8560 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8561 ScopeInfo->CoroutinePromise = Promise;
8563 // Transform the implicit coroutine statements constructed using dependent
8564 // types during the previous parse: initial and final suspensions, the return
8565 // object, and others. We also transform the coroutine function's body.
8566 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8567 if (InitSuspend.isInvalid())
8568 return StmtError();
8569 StmtResult FinalSuspend =
8570 getDerived().TransformStmt(S->getFinalSuspendStmt());
8571 if (FinalSuspend.isInvalid() ||
8572 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get()))
8573 return StmtError();
8574 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
8575 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8577 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8578 if (BodyRes.isInvalid())
8579 return StmtError();
8581 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8582 if (Builder.isInvalid())
8583 return StmtError();
8585 Expr *ReturnObject = S->getReturnValueInit();
8586 assert(ReturnObject && "the return object is expected to be valid");
8587 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8588 /*NoCopyInit*/ false);
8589 if (Res.isInvalid())
8590 return StmtError();
8591 Builder.ReturnValue = Res.get();
8593 // If during the previous parse the coroutine still had a dependent promise
8594 // statement, we may need to build some implicit coroutine statements
8595 // (such as exception and fallthrough handlers) for the first time.
8596 if (S->hasDependentPromiseType()) {
8597 // We can only build these statements, however, if the current promise type
8598 // is not dependent.
8599 if (!Promise->getType()->isDependentType()) {
8600 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8601 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8602 "these nodes should not have been built yet");
8603 if (!Builder.buildDependentStatements())
8604 return StmtError();
8606 } else {
8607 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8608 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8609 if (Res.isInvalid())
8610 return StmtError();
8611 Builder.OnFallthrough = Res.get();
8614 if (auto *OnException = S->getExceptionHandler()) {
8615 StmtResult Res = getDerived().TransformStmt(OnException);
8616 if (Res.isInvalid())
8617 return StmtError();
8618 Builder.OnException = Res.get();
8621 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8622 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8623 if (Res.isInvalid())
8624 return StmtError();
8625 Builder.ReturnStmtOnAllocFailure = Res.get();
8628 // Transform any additional statements we may have already built
8629 assert(S->getAllocate() && S->getDeallocate() &&
8630 "allocation and deallocation calls must already be built");
8631 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8632 if (AllocRes.isInvalid())
8633 return StmtError();
8634 Builder.Allocate = AllocRes.get();
8636 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8637 if (DeallocRes.isInvalid())
8638 return StmtError();
8639 Builder.Deallocate = DeallocRes.get();
8641 if (auto *ResultDecl = S->getResultDecl()) {
8642 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8643 if (Res.isInvalid())
8644 return StmtError();
8645 Builder.ResultDecl = Res.get();
8648 if (auto *ReturnStmt = S->getReturnStmt()) {
8649 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8650 if (Res.isInvalid())
8651 return StmtError();
8652 Builder.ReturnStmt = Res.get();
8656 return getDerived().RebuildCoroutineBodyStmt(Builder);
8659 template<typename Derived>
8660 StmtResult
8661 TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8662 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8663 /*NotCopyInit*/false);
8664 if (Result.isInvalid())
8665 return StmtError();
8667 // Always rebuild; we don't know if this needs to be injected into a new
8668 // context or if the promise type has changed.
8669 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8670 S->isImplicit());
8673 template <typename Derived>
8674 ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8675 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8676 /*NotCopyInit*/ false);
8677 if (Operand.isInvalid())
8678 return ExprError();
8680 // Rebuild the common-expr from the operand rather than transforming it
8681 // separately.
8683 // FIXME: getCurScope() should not be used during template instantiation.
8684 // We should pick up the set of unqualified lookup results for operator
8685 // co_await during the initial parse.
8686 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8687 getSema().getCurScope(), E->getKeywordLoc());
8689 // Always rebuild; we don't know if this needs to be injected into a new
8690 // context or if the promise type has changed.
8691 return getDerived().RebuildCoawaitExpr(
8692 E->getKeywordLoc(), Operand.get(),
8693 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());
8696 template <typename Derived>
8697 ExprResult
8698 TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8699 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8700 /*NotCopyInit*/ false);
8701 if (OperandResult.isInvalid())
8702 return ExprError();
8704 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8705 E->getOperatorCoawaitLookup());
8707 if (LookupResult.isInvalid())
8708 return ExprError();
8710 // Always rebuild; we don't know if this needs to be injected into a new
8711 // context or if the promise type has changed.
8712 return getDerived().RebuildDependentCoawaitExpr(
8713 E->getKeywordLoc(), OperandResult.get(),
8714 cast<UnresolvedLookupExpr>(LookupResult.get()));
8717 template<typename Derived>
8718 ExprResult
8719 TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8720 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8721 /*NotCopyInit*/false);
8722 if (Result.isInvalid())
8723 return ExprError();
8725 // Always rebuild; we don't know if this needs to be injected into a new
8726 // context or if the promise type has changed.
8727 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8730 // Objective-C Statements.
8732 template<typename Derived>
8733 StmtResult
8734 TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8735 // Transform the body of the @try.
8736 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8737 if (TryBody.isInvalid())
8738 return StmtError();
8740 // Transform the @catch statements (if present).
8741 bool AnyCatchChanged = false;
8742 SmallVector<Stmt*, 8> CatchStmts;
8743 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8744 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8745 if (Catch.isInvalid())
8746 return StmtError();
8747 if (Catch.get() != S->getCatchStmt(I))
8748 AnyCatchChanged = true;
8749 CatchStmts.push_back(Catch.get());
8752 // Transform the @finally statement (if present).
8753 StmtResult Finally;
8754 if (S->getFinallyStmt()) {
8755 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8756 if (Finally.isInvalid())
8757 return StmtError();
8760 // If nothing changed, just retain this statement.
8761 if (!getDerived().AlwaysRebuild() &&
8762 TryBody.get() == S->getTryBody() &&
8763 !AnyCatchChanged &&
8764 Finally.get() == S->getFinallyStmt())
8765 return S;
8767 // Build a new statement.
8768 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8769 CatchStmts, Finally.get());
8772 template<typename Derived>
8773 StmtResult
8774 TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8775 // Transform the @catch parameter, if there is one.
8776 VarDecl *Var = nullptr;
8777 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8778 TypeSourceInfo *TSInfo = nullptr;
8779 if (FromVar->getTypeSourceInfo()) {
8780 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8781 if (!TSInfo)
8782 return StmtError();
8785 QualType T;
8786 if (TSInfo)
8787 T = TSInfo->getType();
8788 else {
8789 T = getDerived().TransformType(FromVar->getType());
8790 if (T.isNull())
8791 return StmtError();
8794 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8795 if (!Var)
8796 return StmtError();
8799 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8800 if (Body.isInvalid())
8801 return StmtError();
8803 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
8804 S->getRParenLoc(),
8805 Var, Body.get());
8808 template<typename Derived>
8809 StmtResult
8810 TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
8811 // Transform the body.
8812 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
8813 if (Body.isInvalid())
8814 return StmtError();
8816 // If nothing changed, just retain this statement.
8817 if (!getDerived().AlwaysRebuild() &&
8818 Body.get() == S->getFinallyBody())
8819 return S;
8821 // Build a new statement.
8822 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
8823 Body.get());
8826 template<typename Derived>
8827 StmtResult
8828 TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
8829 ExprResult Operand;
8830 if (S->getThrowExpr()) {
8831 Operand = getDerived().TransformExpr(S->getThrowExpr());
8832 if (Operand.isInvalid())
8833 return StmtError();
8836 if (!getDerived().AlwaysRebuild() &&
8837 Operand.get() == S->getThrowExpr())
8838 return S;
8840 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
8843 template<typename Derived>
8844 StmtResult
8845 TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
8846 ObjCAtSynchronizedStmt *S) {
8847 // Transform the object we are locking.
8848 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
8849 if (Object.isInvalid())
8850 return StmtError();
8851 Object =
8852 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
8853 Object.get());
8854 if (Object.isInvalid())
8855 return StmtError();
8857 // Transform the body.
8858 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
8859 if (Body.isInvalid())
8860 return StmtError();
8862 // If nothing change, just retain the current statement.
8863 if (!getDerived().AlwaysRebuild() &&
8864 Object.get() == S->getSynchExpr() &&
8865 Body.get() == S->getSynchBody())
8866 return S;
8868 // Build a new statement.
8869 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
8870 Object.get(), Body.get());
8873 template<typename Derived>
8874 StmtResult
8875 TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
8876 ObjCAutoreleasePoolStmt *S) {
8877 // Transform the body.
8878 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
8879 if (Body.isInvalid())
8880 return StmtError();
8882 // If nothing changed, just retain this statement.
8883 if (!getDerived().AlwaysRebuild() &&
8884 Body.get() == S->getSubStmt())
8885 return S;
8887 // Build a new statement.
8888 return getDerived().RebuildObjCAutoreleasePoolStmt(
8889 S->getAtLoc(), Body.get());
8892 template<typename Derived>
8893 StmtResult
8894 TreeTransform<Derived>::TransformObjCForCollectionStmt(
8895 ObjCForCollectionStmt *S) {
8896 // Transform the element statement.
8897 StmtResult Element =
8898 getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded);
8899 if (Element.isInvalid())
8900 return StmtError();
8902 // Transform the collection expression.
8903 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
8904 if (Collection.isInvalid())
8905 return StmtError();
8907 // Transform the body.
8908 StmtResult Body = getDerived().TransformStmt(S->getBody());
8909 if (Body.isInvalid())
8910 return StmtError();
8912 // If nothing changed, just retain this statement.
8913 if (!getDerived().AlwaysRebuild() &&
8914 Element.get() == S->getElement() &&
8915 Collection.get() == S->getCollection() &&
8916 Body.get() == S->getBody())
8917 return S;
8919 // Build a new statement.
8920 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
8921 Element.get(),
8922 Collection.get(),
8923 S->getRParenLoc(),
8924 Body.get());
8927 template <typename Derived>
8928 StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
8929 // Transform the exception declaration, if any.
8930 VarDecl *Var = nullptr;
8931 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
8932 TypeSourceInfo *T =
8933 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
8934 if (!T)
8935 return StmtError();
8937 Var = getDerived().RebuildExceptionDecl(
8938 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
8939 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
8940 if (!Var || Var->isInvalidDecl())
8941 return StmtError();
8944 // Transform the actual exception handler.
8945 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
8946 if (Handler.isInvalid())
8947 return StmtError();
8949 if (!getDerived().AlwaysRebuild() && !Var &&
8950 Handler.get() == S->getHandlerBlock())
8951 return S;
8953 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
8956 template <typename Derived>
8957 StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
8958 // Transform the try block itself.
8959 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8960 if (TryBlock.isInvalid())
8961 return StmtError();
8963 // Transform the handlers.
8964 bool HandlerChanged = false;
8965 SmallVector<Stmt *, 8> Handlers;
8966 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
8967 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I));
8968 if (Handler.isInvalid())
8969 return StmtError();
8971 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
8972 Handlers.push_back(Handler.getAs<Stmt>());
8975 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8976 !HandlerChanged)
8977 return S;
8979 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
8980 Handlers);
8983 template<typename Derived>
8984 StmtResult
8985 TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
8986 EnterExpressionEvaluationContext ForRangeInitContext(
8987 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
8988 /*LambdaContextDecl=*/nullptr,
8989 Sema::ExpressionEvaluationContextRecord::EK_Other,
8990 getSema().getLangOpts().CPlusPlus23);
8992 // P2718R0 - Lifetime extension in range-based for loops.
8993 if (getSema().getLangOpts().CPlusPlus23) {
8994 auto &LastRecord = getSema().currentEvaluationContext();
8995 LastRecord.InLifetimeExtendingContext = true;
8996 LastRecord.RebuildDefaultArgOrDefaultInit = true;
8998 StmtResult Init =
8999 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9000 if (Init.isInvalid())
9001 return StmtError();
9003 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9004 if (Range.isInvalid())
9005 return StmtError();
9007 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9008 assert(getSema().getLangOpts().CPlusPlus23 ||
9009 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9010 auto ForRangeLifetimeExtendTemps =
9011 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9013 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9014 if (Begin.isInvalid())
9015 return StmtError();
9016 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9017 if (End.isInvalid())
9018 return StmtError();
9020 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9021 if (Cond.isInvalid())
9022 return StmtError();
9023 if (Cond.get())
9024 Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());
9025 if (Cond.isInvalid())
9026 return StmtError();
9027 if (Cond.get())
9028 Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());
9030 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9031 if (Inc.isInvalid())
9032 return StmtError();
9033 if (Inc.get())
9034 Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());
9036 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9037 if (LoopVar.isInvalid())
9038 return StmtError();
9040 StmtResult NewStmt = S;
9041 if (getDerived().AlwaysRebuild() ||
9042 Init.get() != S->getInit() ||
9043 Range.get() != S->getRangeStmt() ||
9044 Begin.get() != S->getBeginStmt() ||
9045 End.get() != S->getEndStmt() ||
9046 Cond.get() != S->getCond() ||
9047 Inc.get() != S->getInc() ||
9048 LoopVar.get() != S->getLoopVarStmt()) {
9049 NewStmt = getDerived().RebuildCXXForRangeStmt(
9050 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9051 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9052 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9053 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9054 // Might not have attached any initializer to the loop variable.
9055 getSema().ActOnInitializerError(
9056 cast<DeclStmt>(LoopVar.get())->getSingleDecl());
9057 return StmtError();
9061 // OpenACC Restricts a while-loop inside of certain construct/clause
9062 // combinations, so diagnose that here in OpenACC mode.
9063 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9064 SemaRef.OpenACC().ActOnRangeForStmtBegin(S->getBeginLoc(), S, NewStmt.get());
9066 StmtResult Body = getDerived().TransformStmt(S->getBody());
9067 if (Body.isInvalid())
9068 return StmtError();
9070 SemaRef.OpenACC().ActOnForStmtEnd(S->getBeginLoc(), Body);
9072 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9073 // it now so we have a new statement to attach the body to.
9074 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9075 NewStmt = getDerived().RebuildCXXForRangeStmt(
9076 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9077 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9078 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9079 if (NewStmt.isInvalid())
9080 return StmtError();
9083 if (NewStmt.get() == S)
9084 return S;
9086 return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
9089 template<typename Derived>
9090 StmtResult
9091 TreeTransform<Derived>::TransformMSDependentExistsStmt(
9092 MSDependentExistsStmt *S) {
9093 // Transform the nested-name-specifier, if any.
9094 NestedNameSpecifierLoc QualifierLoc;
9095 if (S->getQualifierLoc()) {
9096 QualifierLoc
9097 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9098 if (!QualifierLoc)
9099 return StmtError();
9102 // Transform the declaration name.
9103 DeclarationNameInfo NameInfo = S->getNameInfo();
9104 if (NameInfo.getName()) {
9105 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9106 if (!NameInfo.getName())
9107 return StmtError();
9110 // Check whether anything changed.
9111 if (!getDerived().AlwaysRebuild() &&
9112 QualifierLoc == S->getQualifierLoc() &&
9113 NameInfo.getName() == S->getNameInfo().getName())
9114 return S;
9116 // Determine whether this name exists, if we can.
9117 CXXScopeSpec SS;
9118 SS.Adopt(QualifierLoc);
9119 bool Dependent = false;
9120 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9121 case Sema::IER_Exists:
9122 if (S->isIfExists())
9123 break;
9125 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9127 case Sema::IER_DoesNotExist:
9128 if (S->isIfNotExists())
9129 break;
9131 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9133 case Sema::IER_Dependent:
9134 Dependent = true;
9135 break;
9137 case Sema::IER_Error:
9138 return StmtError();
9141 // We need to continue with the instantiation, so do so now.
9142 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9143 if (SubStmt.isInvalid())
9144 return StmtError();
9146 // If we have resolved the name, just transform to the substatement.
9147 if (!Dependent)
9148 return SubStmt;
9150 // The name is still dependent, so build a dependent expression again.
9151 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9152 S->isIfExists(),
9153 QualifierLoc,
9154 NameInfo,
9155 SubStmt.get());
9158 template<typename Derived>
9159 ExprResult
9160 TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9161 NestedNameSpecifierLoc QualifierLoc;
9162 if (E->getQualifierLoc()) {
9163 QualifierLoc
9164 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9165 if (!QualifierLoc)
9166 return ExprError();
9169 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9170 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9171 if (!PD)
9172 return ExprError();
9174 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9175 if (Base.isInvalid())
9176 return ExprError();
9178 return new (SemaRef.getASTContext())
9179 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9180 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9181 QualifierLoc, E->getMemberLoc());
9184 template <typename Derived>
9185 ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9186 MSPropertySubscriptExpr *E) {
9187 auto BaseRes = getDerived().TransformExpr(E->getBase());
9188 if (BaseRes.isInvalid())
9189 return ExprError();
9190 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9191 if (IdxRes.isInvalid())
9192 return ExprError();
9194 if (!getDerived().AlwaysRebuild() &&
9195 BaseRes.get() == E->getBase() &&
9196 IdxRes.get() == E->getIdx())
9197 return E;
9199 return getDerived().RebuildArraySubscriptExpr(
9200 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9203 template <typename Derived>
9204 StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9205 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9206 if (TryBlock.isInvalid())
9207 return StmtError();
9209 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9210 if (Handler.isInvalid())
9211 return StmtError();
9213 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9214 Handler.get() == S->getHandler())
9215 return S;
9217 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9218 TryBlock.get(), Handler.get());
9221 template <typename Derived>
9222 StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9223 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9224 if (Block.isInvalid())
9225 return StmtError();
9227 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9230 template <typename Derived>
9231 StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9232 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9233 if (FilterExpr.isInvalid())
9234 return StmtError();
9236 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9237 if (Block.isInvalid())
9238 return StmtError();
9240 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9241 Block.get());
9244 template <typename Derived>
9245 StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9246 if (isa<SEHFinallyStmt>(Handler))
9247 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
9248 else
9249 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
9252 template<typename Derived>
9253 StmtResult
9254 TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9255 return S;
9258 //===----------------------------------------------------------------------===//
9259 // OpenMP directive transformation
9260 //===----------------------------------------------------------------------===//
9262 template <typename Derived>
9263 StmtResult
9264 TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9265 // OMPCanonicalLoops are eliminated during transformation, since they will be
9266 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9267 // after transformation.
9268 return getDerived().TransformStmt(L->getLoopStmt());
9271 template <typename Derived>
9272 StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9273 OMPExecutableDirective *D) {
9275 // Transform the clauses
9276 llvm::SmallVector<OMPClause *, 16> TClauses;
9277 ArrayRef<OMPClause *> Clauses = D->clauses();
9278 TClauses.reserve(Clauses.size());
9279 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9280 I != E; ++I) {
9281 if (*I) {
9282 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9283 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9284 getDerived().getSema().OpenMP().EndOpenMPClause();
9285 if (Clause)
9286 TClauses.push_back(Clause);
9287 } else {
9288 TClauses.push_back(nullptr);
9291 StmtResult AssociatedStmt;
9292 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9293 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9294 D->getDirectiveKind(),
9295 /*CurScope=*/nullptr);
9296 StmtResult Body;
9298 Sema::CompoundScopeRAII CompoundScope(getSema());
9299 Stmt *CS;
9300 if (D->getDirectiveKind() == OMPD_atomic ||
9301 D->getDirectiveKind() == OMPD_critical ||
9302 D->getDirectiveKind() == OMPD_section ||
9303 D->getDirectiveKind() == OMPD_master)
9304 CS = D->getAssociatedStmt();
9305 else
9306 CS = D->getRawStmt();
9307 Body = getDerived().TransformStmt(CS);
9308 if (Body.isUsable() && isOpenMPLoopDirective(D->getDirectiveKind()) &&
9309 getSema().getLangOpts().OpenMPIRBuilder)
9310 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9312 AssociatedStmt =
9313 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9314 if (AssociatedStmt.isInvalid()) {
9315 return StmtError();
9318 if (TClauses.size() != Clauses.size()) {
9319 return StmtError();
9322 // Transform directive name for 'omp critical' directive.
9323 DeclarationNameInfo DirName;
9324 if (D->getDirectiveKind() == OMPD_critical) {
9325 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
9326 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9328 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9329 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9330 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();
9331 } else if (D->getDirectiveKind() == OMPD_cancel) {
9332 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();
9335 return getDerived().RebuildOMPExecutableDirective(
9336 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9337 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
9340 /// This is mostly the same as above, but allows 'informational' class
9341 /// directives when rebuilding the stmt. It still takes an
9342 /// OMPExecutableDirective-type argument because we're reusing that as the
9343 /// superclass for the 'assume' directive at present, instead of defining a
9344 /// mostly-identical OMPInformationalDirective parent class.
9345 template <typename Derived>
9346 StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
9347 OMPExecutableDirective *D) {
9349 // Transform the clauses
9350 llvm::SmallVector<OMPClause *, 16> TClauses;
9351 ArrayRef<OMPClause *> Clauses = D->clauses();
9352 TClauses.reserve(Clauses.size());
9353 for (OMPClause *C : Clauses) {
9354 if (C) {
9355 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
9356 OMPClause *Clause = getDerived().TransformOMPClause(C);
9357 getDerived().getSema().OpenMP().EndOpenMPClause();
9358 if (Clause)
9359 TClauses.push_back(Clause);
9360 } else {
9361 TClauses.push_back(nullptr);
9364 StmtResult AssociatedStmt;
9365 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9366 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9367 D->getDirectiveKind(),
9368 /*CurScope=*/nullptr);
9369 StmtResult Body;
9371 Sema::CompoundScopeRAII CompoundScope(getSema());
9372 assert(D->getDirectiveKind() == OMPD_assume &&
9373 "Unexpected informational directive");
9374 Stmt *CS = D->getAssociatedStmt();
9375 Body = getDerived().TransformStmt(CS);
9377 AssociatedStmt =
9378 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9379 if (AssociatedStmt.isInvalid())
9380 return StmtError();
9382 if (TClauses.size() != Clauses.size())
9383 return StmtError();
9385 DeclarationNameInfo DirName;
9387 return getDerived().RebuildOMPInformationalDirective(
9388 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
9389 D->getBeginLoc(), D->getEndLoc());
9392 template <typename Derived>
9393 StmtResult
9394 TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9395 // TODO: Fix This
9396 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)
9397 << getOpenMPDirectiveName(D->getDirectiveKind());
9398 return StmtError();
9401 template <typename Derived>
9402 StmtResult
9403 TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9404 DeclarationNameInfo DirName;
9405 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9406 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9407 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9408 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9409 return Res;
9412 template <typename Derived>
9413 StmtResult
9414 TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9415 DeclarationNameInfo DirName;
9416 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9417 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9418 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9419 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9420 return Res;
9423 template <typename Derived>
9424 StmtResult
9425 TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9426 DeclarationNameInfo DirName;
9427 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9428 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9429 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9430 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9431 return Res;
9434 template <typename Derived>
9435 StmtResult
9436 TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9437 DeclarationNameInfo DirName;
9438 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9439 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9440 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9441 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9442 return Res;
9445 template <typename Derived>
9446 StmtResult
9447 TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
9448 DeclarationNameInfo DirName;
9449 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9450 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9451 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9452 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9453 return Res;
9456 template <typename Derived>
9457 StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
9458 OMPInterchangeDirective *D) {
9459 DeclarationNameInfo DirName;
9460 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9461 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9462 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9463 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9464 return Res;
9467 template <typename Derived>
9468 StmtResult
9469 TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9470 DeclarationNameInfo DirName;
9471 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9472 OMPD_for, DirName, nullptr, D->getBeginLoc());
9473 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9474 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9475 return Res;
9478 template <typename Derived>
9479 StmtResult
9480 TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9481 DeclarationNameInfo DirName;
9482 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9483 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9484 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9485 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9486 return Res;
9489 template <typename Derived>
9490 StmtResult
9491 TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9492 DeclarationNameInfo DirName;
9493 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9494 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9495 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9496 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9497 return Res;
9500 template <typename Derived>
9501 StmtResult
9502 TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9503 DeclarationNameInfo DirName;
9504 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9505 OMPD_section, DirName, nullptr, D->getBeginLoc());
9506 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9507 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9508 return Res;
9511 template <typename Derived>
9512 StmtResult
9513 TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9514 DeclarationNameInfo DirName;
9515 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9516 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9517 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9518 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9519 return Res;
9522 template <typename Derived>
9523 StmtResult
9524 TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9525 DeclarationNameInfo DirName;
9526 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9527 OMPD_single, DirName, nullptr, D->getBeginLoc());
9528 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9529 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9530 return Res;
9533 template <typename Derived>
9534 StmtResult
9535 TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9536 DeclarationNameInfo DirName;
9537 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9538 OMPD_master, DirName, nullptr, D->getBeginLoc());
9539 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9540 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9541 return Res;
9544 template <typename Derived>
9545 StmtResult
9546 TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9547 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9548 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9549 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9550 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9551 return Res;
9554 template <typename Derived>
9555 StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9556 OMPParallelForDirective *D) {
9557 DeclarationNameInfo DirName;
9558 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9559 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9560 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9561 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9562 return Res;
9565 template <typename Derived>
9566 StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9567 OMPParallelForSimdDirective *D) {
9568 DeclarationNameInfo DirName;
9569 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9570 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9571 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9572 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9573 return Res;
9576 template <typename Derived>
9577 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9578 OMPParallelMasterDirective *D) {
9579 DeclarationNameInfo DirName;
9580 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9581 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
9582 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9583 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9584 return Res;
9587 template <typename Derived>
9588 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9589 OMPParallelMaskedDirective *D) {
9590 DeclarationNameInfo DirName;
9591 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9592 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
9593 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9594 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9595 return Res;
9598 template <typename Derived>
9599 StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9600 OMPParallelSectionsDirective *D) {
9601 DeclarationNameInfo DirName;
9602 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9603 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
9604 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9605 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9606 return Res;
9609 template <typename Derived>
9610 StmtResult
9611 TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9612 DeclarationNameInfo DirName;
9613 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9614 OMPD_task, DirName, nullptr, D->getBeginLoc());
9615 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9616 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9617 return Res;
9620 template <typename Derived>
9621 StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9622 OMPTaskyieldDirective *D) {
9623 DeclarationNameInfo DirName;
9624 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9625 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
9626 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9627 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9628 return Res;
9631 template <typename Derived>
9632 StmtResult
9633 TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9634 DeclarationNameInfo DirName;
9635 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9636 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
9637 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9638 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9639 return Res;
9642 template <typename Derived>
9643 StmtResult
9644 TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9645 DeclarationNameInfo DirName;
9646 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9647 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
9648 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9649 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9650 return Res;
9653 template <typename Derived>
9654 StmtResult
9655 TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
9656 DeclarationNameInfo DirName;
9657 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9658 OMPD_assume, DirName, nullptr, D->getBeginLoc());
9659 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
9660 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9661 return Res;
9664 template <typename Derived>
9665 StmtResult
9666 TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9667 DeclarationNameInfo DirName;
9668 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9669 OMPD_error, DirName, nullptr, D->getBeginLoc());
9670 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9671 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9672 return Res;
9675 template <typename Derived>
9676 StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9677 OMPTaskgroupDirective *D) {
9678 DeclarationNameInfo DirName;
9679 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9680 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
9681 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9682 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9683 return Res;
9686 template <typename Derived>
9687 StmtResult
9688 TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9689 DeclarationNameInfo DirName;
9690 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9691 OMPD_flush, DirName, nullptr, D->getBeginLoc());
9692 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9693 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9694 return Res;
9697 template <typename Derived>
9698 StmtResult
9699 TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9700 DeclarationNameInfo DirName;
9701 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9702 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
9703 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9704 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9705 return Res;
9708 template <typename Derived>
9709 StmtResult
9710 TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9711 DeclarationNameInfo DirName;
9712 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9713 OMPD_scan, DirName, nullptr, D->getBeginLoc());
9714 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9715 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9716 return Res;
9719 template <typename Derived>
9720 StmtResult
9721 TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9722 DeclarationNameInfo DirName;
9723 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9724 OMPD_ordered, DirName, nullptr, D->getBeginLoc());
9725 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9726 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9727 return Res;
9730 template <typename Derived>
9731 StmtResult
9732 TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9733 DeclarationNameInfo DirName;
9734 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9735 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
9736 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9737 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9738 return Res;
9741 template <typename Derived>
9742 StmtResult
9743 TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9744 DeclarationNameInfo DirName;
9745 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9746 OMPD_target, DirName, nullptr, D->getBeginLoc());
9747 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9748 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9749 return Res;
9752 template <typename Derived>
9753 StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9754 OMPTargetDataDirective *D) {
9755 DeclarationNameInfo DirName;
9756 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9757 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
9758 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9759 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9760 return Res;
9763 template <typename Derived>
9764 StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9765 OMPTargetEnterDataDirective *D) {
9766 DeclarationNameInfo DirName;
9767 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9768 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
9769 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9770 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9771 return Res;
9774 template <typename Derived>
9775 StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9776 OMPTargetExitDataDirective *D) {
9777 DeclarationNameInfo DirName;
9778 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9779 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
9780 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9781 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9782 return Res;
9785 template <typename Derived>
9786 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
9787 OMPTargetParallelDirective *D) {
9788 DeclarationNameInfo DirName;
9789 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9790 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
9791 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9792 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9793 return Res;
9796 template <typename Derived>
9797 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
9798 OMPTargetParallelForDirective *D) {
9799 DeclarationNameInfo DirName;
9800 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9801 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
9802 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9803 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9804 return Res;
9807 template <typename Derived>
9808 StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
9809 OMPTargetUpdateDirective *D) {
9810 DeclarationNameInfo DirName;
9811 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9812 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
9813 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9814 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9815 return Res;
9818 template <typename Derived>
9819 StmtResult
9820 TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
9821 DeclarationNameInfo DirName;
9822 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9823 OMPD_teams, DirName, nullptr, D->getBeginLoc());
9824 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9825 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9826 return Res;
9829 template <typename Derived>
9830 StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
9831 OMPCancellationPointDirective *D) {
9832 DeclarationNameInfo DirName;
9833 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9834 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
9835 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9836 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9837 return Res;
9840 template <typename Derived>
9841 StmtResult
9842 TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
9843 DeclarationNameInfo DirName;
9844 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9845 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
9846 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9847 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9848 return Res;
9851 template <typename Derived>
9852 StmtResult
9853 TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
9854 DeclarationNameInfo DirName;
9855 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9856 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
9857 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9858 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9859 return Res;
9862 template <typename Derived>
9863 StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
9864 OMPTaskLoopSimdDirective *D) {
9865 DeclarationNameInfo DirName;
9866 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9867 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9868 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9869 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9870 return Res;
9873 template <typename Derived>
9874 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
9875 OMPMasterTaskLoopDirective *D) {
9876 DeclarationNameInfo DirName;
9877 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9878 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
9879 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9880 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9881 return Res;
9884 template <typename Derived>
9885 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
9886 OMPMaskedTaskLoopDirective *D) {
9887 DeclarationNameInfo DirName;
9888 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9889 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9890 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9891 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9892 return Res;
9895 template <typename Derived>
9896 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
9897 OMPMasterTaskLoopSimdDirective *D) {
9898 DeclarationNameInfo DirName;
9899 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9900 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9901 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9902 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9903 return Res;
9906 template <typename Derived>
9907 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
9908 OMPMaskedTaskLoopSimdDirective *D) {
9909 DeclarationNameInfo DirName;
9910 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9911 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9912 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9913 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9914 return Res;
9917 template <typename Derived>
9918 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
9919 OMPParallelMasterTaskLoopDirective *D) {
9920 DeclarationNameInfo DirName;
9921 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9922 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
9923 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9924 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9925 return Res;
9928 template <typename Derived>
9929 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
9930 OMPParallelMaskedTaskLoopDirective *D) {
9931 DeclarationNameInfo DirName;
9932 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9933 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9934 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9935 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9936 return Res;
9939 template <typename Derived>
9940 StmtResult
9941 TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
9942 OMPParallelMasterTaskLoopSimdDirective *D) {
9943 DeclarationNameInfo DirName;
9944 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9945 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9946 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9947 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9948 return Res;
9951 template <typename Derived>
9952 StmtResult
9953 TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
9954 OMPParallelMaskedTaskLoopSimdDirective *D) {
9955 DeclarationNameInfo DirName;
9956 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9957 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9958 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9959 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9960 return Res;
9963 template <typename Derived>
9964 StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
9965 OMPDistributeDirective *D) {
9966 DeclarationNameInfo DirName;
9967 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9968 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
9969 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9970 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9971 return Res;
9974 template <typename Derived>
9975 StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
9976 OMPDistributeParallelForDirective *D) {
9977 DeclarationNameInfo DirName;
9978 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9979 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9980 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9981 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9982 return Res;
9985 template <typename Derived>
9986 StmtResult
9987 TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
9988 OMPDistributeParallelForSimdDirective *D) {
9989 DeclarationNameInfo DirName;
9990 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9991 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9992 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9993 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9994 return Res;
9997 template <typename Derived>
9998 StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
9999 OMPDistributeSimdDirective *D) {
10000 DeclarationNameInfo DirName;
10001 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10002 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10003 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10004 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10005 return Res;
10008 template <typename Derived>
10009 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10010 OMPTargetParallelForSimdDirective *D) {
10011 DeclarationNameInfo DirName;
10012 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10013 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10014 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10015 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10016 return Res;
10019 template <typename Derived>
10020 StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10021 OMPTargetSimdDirective *D) {
10022 DeclarationNameInfo DirName;
10023 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10024 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10025 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10026 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10027 return Res;
10030 template <typename Derived>
10031 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10032 OMPTeamsDistributeDirective *D) {
10033 DeclarationNameInfo DirName;
10034 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10035 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10036 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10037 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10038 return Res;
10041 template <typename Derived>
10042 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10043 OMPTeamsDistributeSimdDirective *D) {
10044 DeclarationNameInfo DirName;
10045 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10046 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10047 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10048 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10049 return Res;
10052 template <typename Derived>
10053 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10054 OMPTeamsDistributeParallelForSimdDirective *D) {
10055 DeclarationNameInfo DirName;
10056 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10057 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10058 D->getBeginLoc());
10059 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10060 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10061 return Res;
10064 template <typename Derived>
10065 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10066 OMPTeamsDistributeParallelForDirective *D) {
10067 DeclarationNameInfo DirName;
10068 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10069 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10070 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10071 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10072 return Res;
10075 template <typename Derived>
10076 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10077 OMPTargetTeamsDirective *D) {
10078 DeclarationNameInfo DirName;
10079 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10080 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10081 auto Res = getDerived().TransformOMPExecutableDirective(D);
10082 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10083 return Res;
10086 template <typename Derived>
10087 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10088 OMPTargetTeamsDistributeDirective *D) {
10089 DeclarationNameInfo DirName;
10090 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10091 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10092 auto Res = getDerived().TransformOMPExecutableDirective(D);
10093 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10094 return Res;
10097 template <typename Derived>
10098 StmtResult
10099 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10100 OMPTargetTeamsDistributeParallelForDirective *D) {
10101 DeclarationNameInfo DirName;
10102 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10103 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10104 D->getBeginLoc());
10105 auto Res = getDerived().TransformOMPExecutableDirective(D);
10106 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10107 return Res;
10110 template <typename Derived>
10111 StmtResult TreeTransform<Derived>::
10112 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10113 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10114 DeclarationNameInfo DirName;
10115 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10116 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10117 D->getBeginLoc());
10118 auto Res = getDerived().TransformOMPExecutableDirective(D);
10119 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10120 return Res;
10123 template <typename Derived>
10124 StmtResult
10125 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10126 OMPTargetTeamsDistributeSimdDirective *D) {
10127 DeclarationNameInfo DirName;
10128 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10129 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10130 auto Res = getDerived().TransformOMPExecutableDirective(D);
10131 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10132 return Res;
10135 template <typename Derived>
10136 StmtResult
10137 TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10138 DeclarationNameInfo DirName;
10139 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10140 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10141 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10142 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10143 return Res;
10146 template <typename Derived>
10147 StmtResult
10148 TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10149 DeclarationNameInfo DirName;
10150 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10151 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10152 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10153 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10154 return Res;
10157 template <typename Derived>
10158 StmtResult
10159 TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10160 DeclarationNameInfo DirName;
10161 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10162 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10163 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10164 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10165 return Res;
10168 template <typename Derived>
10169 StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10170 OMPGenericLoopDirective *D) {
10171 DeclarationNameInfo DirName;
10172 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10173 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10174 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10175 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10176 return Res;
10179 template <typename Derived>
10180 StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10181 OMPTeamsGenericLoopDirective *D) {
10182 DeclarationNameInfo DirName;
10183 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10184 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10185 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10186 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10187 return Res;
10190 template <typename Derived>
10191 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10192 OMPTargetTeamsGenericLoopDirective *D) {
10193 DeclarationNameInfo DirName;
10194 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10195 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10196 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10197 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10198 return Res;
10201 template <typename Derived>
10202 StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10203 OMPParallelGenericLoopDirective *D) {
10204 DeclarationNameInfo DirName;
10205 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10206 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10207 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10208 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10209 return Res;
10212 template <typename Derived>
10213 StmtResult
10214 TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10215 OMPTargetParallelGenericLoopDirective *D) {
10216 DeclarationNameInfo DirName;
10217 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10218 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10219 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10220 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10221 return Res;
10224 //===----------------------------------------------------------------------===//
10225 // OpenMP clause transformation
10226 //===----------------------------------------------------------------------===//
10227 template <typename Derived>
10228 OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10229 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10230 if (Cond.isInvalid())
10231 return nullptr;
10232 return getDerived().RebuildOMPIfClause(
10233 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10234 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10237 template <typename Derived>
10238 OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10239 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10240 if (Cond.isInvalid())
10241 return nullptr;
10242 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10243 C->getLParenLoc(), C->getEndLoc());
10246 template <typename Derived>
10247 OMPClause *
10248 TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10249 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10250 if (NumThreads.isInvalid())
10251 return nullptr;
10252 return getDerived().RebuildOMPNumThreadsClause(
10253 NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10256 template <typename Derived>
10257 OMPClause *
10258 TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10259 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10260 if (E.isInvalid())
10261 return nullptr;
10262 return getDerived().RebuildOMPSafelenClause(
10263 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10266 template <typename Derived>
10267 OMPClause *
10268 TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10269 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10270 if (E.isInvalid())
10271 return nullptr;
10272 return getDerived().RebuildOMPAllocatorClause(
10273 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10276 template <typename Derived>
10277 OMPClause *
10278 TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10279 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10280 if (E.isInvalid())
10281 return nullptr;
10282 return getDerived().RebuildOMPSimdlenClause(
10283 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10286 template <typename Derived>
10287 OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10288 SmallVector<Expr *, 4> TransformedSizes;
10289 TransformedSizes.reserve(C->getNumSizes());
10290 bool Changed = false;
10291 for (Expr *E : C->getSizesRefs()) {
10292 if (!E) {
10293 TransformedSizes.push_back(nullptr);
10294 continue;
10297 ExprResult T = getDerived().TransformExpr(E);
10298 if (T.isInvalid())
10299 return nullptr;
10300 if (E != T.get())
10301 Changed = true;
10302 TransformedSizes.push_back(T.get());
10305 if (!Changed && !getDerived().AlwaysRebuild())
10306 return C;
10307 return RebuildOMPSizesClause(TransformedSizes, C->getBeginLoc(),
10308 C->getLParenLoc(), C->getEndLoc());
10311 template <typename Derived>
10312 OMPClause *
10313 TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
10314 SmallVector<Expr *> TransformedArgs;
10315 TransformedArgs.reserve(C->getNumLoops());
10316 bool Changed = false;
10317 for (Expr *E : C->getArgsRefs()) {
10318 if (!E) {
10319 TransformedArgs.push_back(nullptr);
10320 continue;
10323 ExprResult T = getDerived().TransformExpr(E);
10324 if (T.isInvalid())
10325 return nullptr;
10326 if (E != T.get())
10327 Changed = true;
10328 TransformedArgs.push_back(T.get());
10331 if (!Changed && !getDerived().AlwaysRebuild())
10332 return C;
10333 return RebuildOMPPermutationClause(TransformedArgs, C->getBeginLoc(),
10334 C->getLParenLoc(), C->getEndLoc());
10337 template <typename Derived>
10338 OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10339 if (!getDerived().AlwaysRebuild())
10340 return C;
10341 return RebuildOMPFullClause(C->getBeginLoc(), C->getEndLoc());
10344 template <typename Derived>
10345 OMPClause *
10346 TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10347 ExprResult T = getDerived().TransformExpr(C->getFactor());
10348 if (T.isInvalid())
10349 return nullptr;
10350 Expr *Factor = T.get();
10351 bool Changed = Factor != C->getFactor();
10353 if (!Changed && !getDerived().AlwaysRebuild())
10354 return C;
10355 return RebuildOMPPartialClause(Factor, C->getBeginLoc(), C->getLParenLoc(),
10356 C->getEndLoc());
10359 template <typename Derived>
10360 OMPClause *
10361 TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10362 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10363 if (E.isInvalid())
10364 return nullptr;
10365 return getDerived().RebuildOMPCollapseClause(
10366 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10369 template <typename Derived>
10370 OMPClause *
10371 TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10372 return getDerived().RebuildOMPDefaultClause(
10373 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
10374 C->getLParenLoc(), C->getEndLoc());
10377 template <typename Derived>
10378 OMPClause *
10379 TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10380 return getDerived().RebuildOMPProcBindClause(
10381 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10382 C->getLParenLoc(), C->getEndLoc());
10385 template <typename Derived>
10386 OMPClause *
10387 TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10388 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10389 if (E.isInvalid())
10390 return nullptr;
10391 return getDerived().RebuildOMPScheduleClause(
10392 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10393 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10394 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10395 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10398 template <typename Derived>
10399 OMPClause *
10400 TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10401 ExprResult E;
10402 if (auto *Num = C->getNumForLoops()) {
10403 E = getDerived().TransformExpr(Num);
10404 if (E.isInvalid())
10405 return nullptr;
10407 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10408 C->getLParenLoc(), E.get());
10411 template <typename Derived>
10412 OMPClause *
10413 TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10414 ExprResult E;
10415 if (Expr *Evt = C->getEventHandler()) {
10416 E = getDerived().TransformExpr(Evt);
10417 if (E.isInvalid())
10418 return nullptr;
10420 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10421 C->getLParenLoc(), C->getEndLoc());
10424 template <typename Derived>
10425 OMPClause *
10426 TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10427 // No need to rebuild this clause, no template-dependent parameters.
10428 return C;
10431 template <typename Derived>
10432 OMPClause *
10433 TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10434 // No need to rebuild this clause, no template-dependent parameters.
10435 return C;
10438 template <typename Derived>
10439 OMPClause *
10440 TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10441 // No need to rebuild this clause, no template-dependent parameters.
10442 return C;
10445 template <typename Derived>
10446 OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10447 // No need to rebuild this clause, no template-dependent parameters.
10448 return C;
10451 template <typename Derived>
10452 OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10453 // No need to rebuild this clause, no template-dependent parameters.
10454 return C;
10457 template <typename Derived>
10458 OMPClause *
10459 TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10460 // No need to rebuild this clause, no template-dependent parameters.
10461 return C;
10464 template <typename Derived>
10465 OMPClause *
10466 TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10467 // No need to rebuild this clause, no template-dependent parameters.
10468 return C;
10471 template <typename Derived>
10472 OMPClause *
10473 TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10474 // No need to rebuild this clause, no template-dependent parameters.
10475 return C;
10478 template <typename Derived>
10479 OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10480 // No need to rebuild this clause, no template-dependent parameters.
10481 return C;
10484 template <typename Derived>
10485 OMPClause *
10486 TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
10487 return C;
10490 template <typename Derived>
10491 OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
10492 ExprResult E = getDerived().TransformExpr(C->getExpr());
10493 if (E.isInvalid())
10494 return nullptr;
10495 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
10496 C->getLParenLoc(), C->getEndLoc());
10499 template <typename Derived>
10500 OMPClause *
10501 TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
10502 return C;
10505 template <typename Derived>
10506 OMPClause *
10507 TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
10508 return C;
10510 template <typename Derived>
10511 OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
10512 OMPNoOpenMPRoutinesClause *C) {
10513 return C;
10515 template <typename Derived>
10516 OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
10517 OMPNoParallelismClause *C) {
10518 return C;
10521 template <typename Derived>
10522 OMPClause *
10523 TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10524 // No need to rebuild this clause, no template-dependent parameters.
10525 return C;
10528 template <typename Derived>
10529 OMPClause *
10530 TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10531 // No need to rebuild this clause, no template-dependent parameters.
10532 return C;
10535 template <typename Derived>
10536 OMPClause *
10537 TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10538 // No need to rebuild this clause, no template-dependent parameters.
10539 return C;
10542 template <typename Derived>
10543 OMPClause *
10544 TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10545 // No need to rebuild this clause, no template-dependent parameters.
10546 return C;
10549 template <typename Derived>
10550 OMPClause *
10551 TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10552 // No need to rebuild this clause, no template-dependent parameters.
10553 return C;
10556 template <typename Derived>
10557 OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10558 // No need to rebuild this clause, no template-dependent parameters.
10559 return C;
10562 template <typename Derived>
10563 OMPClause *
10564 TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10565 // No need to rebuild this clause, no template-dependent parameters.
10566 return C;
10569 template <typename Derived>
10570 OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10571 // No need to rebuild this clause, no template-dependent parameters.
10572 return C;
10575 template <typename Derived>
10576 OMPClause *
10577 TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10578 // No need to rebuild this clause, no template-dependent parameters.
10579 return C;
10582 template <typename Derived>
10583 OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10584 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10585 if (IVR.isInvalid())
10586 return nullptr;
10588 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10589 InteropInfo.PreferTypes.reserve(C->varlist_size() - 1);
10590 for (Expr *E : llvm::drop_begin(C->varlist())) {
10591 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
10592 if (ER.isInvalid())
10593 return nullptr;
10594 InteropInfo.PreferTypes.push_back(ER.get());
10596 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10597 C->getBeginLoc(), C->getLParenLoc(),
10598 C->getVarLoc(), C->getEndLoc());
10601 template <typename Derived>
10602 OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10603 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10604 if (ER.isInvalid())
10605 return nullptr;
10606 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10607 C->getLParenLoc(), C->getVarLoc(),
10608 C->getEndLoc());
10611 template <typename Derived>
10612 OMPClause *
10613 TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10614 ExprResult ER;
10615 if (Expr *IV = C->getInteropVar()) {
10616 ER = getDerived().TransformExpr(IV);
10617 if (ER.isInvalid())
10618 return nullptr;
10620 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10621 C->getLParenLoc(), C->getVarLoc(),
10622 C->getEndLoc());
10625 template <typename Derived>
10626 OMPClause *
10627 TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10628 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10629 if (Cond.isInvalid())
10630 return nullptr;
10631 return getDerived().RebuildOMPNovariantsClause(
10632 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10635 template <typename Derived>
10636 OMPClause *
10637 TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
10638 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10639 if (Cond.isInvalid())
10640 return nullptr;
10641 return getDerived().RebuildOMPNocontextClause(
10642 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10645 template <typename Derived>
10646 OMPClause *
10647 TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
10648 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
10649 if (ThreadID.isInvalid())
10650 return nullptr;
10651 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10652 C->getLParenLoc(), C->getEndLoc());
10655 template <typename Derived>
10656 OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10657 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10658 if (E.isInvalid())
10659 return nullptr;
10660 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10661 C->getLParenLoc(), C->getEndLoc());
10664 template <typename Derived>
10665 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10666 OMPUnifiedAddressClause *C) {
10667 llvm_unreachable("unified_address clause cannot appear in dependent context");
10670 template <typename Derived>
10671 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10672 OMPUnifiedSharedMemoryClause *C) {
10673 llvm_unreachable(
10674 "unified_shared_memory clause cannot appear in dependent context");
10677 template <typename Derived>
10678 OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10679 OMPReverseOffloadClause *C) {
10680 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10683 template <typename Derived>
10684 OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10685 OMPDynamicAllocatorsClause *C) {
10686 llvm_unreachable(
10687 "dynamic_allocators clause cannot appear in dependent context");
10690 template <typename Derived>
10691 OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10692 OMPAtomicDefaultMemOrderClause *C) {
10693 llvm_unreachable(
10694 "atomic_default_mem_order clause cannot appear in dependent context");
10697 template <typename Derived>
10698 OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10699 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10700 C->getBeginLoc(), C->getLParenLoc(),
10701 C->getEndLoc());
10704 template <typename Derived>
10705 OMPClause *
10706 TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10707 return getDerived().RebuildOMPSeverityClause(
10708 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10709 C->getLParenLoc(), C->getEndLoc());
10712 template <typename Derived>
10713 OMPClause *
10714 TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10715 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10716 if (E.isInvalid())
10717 return nullptr;
10718 return getDerived().RebuildOMPMessageClause(
10719 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10720 C->getEndLoc());
10723 template <typename Derived>
10724 OMPClause *
10725 TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10726 llvm::SmallVector<Expr *, 16> Vars;
10727 Vars.reserve(C->varlist_size());
10728 for (auto *VE : C->varlist()) {
10729 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10730 if (EVar.isInvalid())
10731 return nullptr;
10732 Vars.push_back(EVar.get());
10734 return getDerived().RebuildOMPPrivateClause(
10735 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10738 template <typename Derived>
10739 OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10740 OMPFirstprivateClause *C) {
10741 llvm::SmallVector<Expr *, 16> Vars;
10742 Vars.reserve(C->varlist_size());
10743 for (auto *VE : C->varlist()) {
10744 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10745 if (EVar.isInvalid())
10746 return nullptr;
10747 Vars.push_back(EVar.get());
10749 return getDerived().RebuildOMPFirstprivateClause(
10750 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10753 template <typename Derived>
10754 OMPClause *
10755 TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10756 llvm::SmallVector<Expr *, 16> Vars;
10757 Vars.reserve(C->varlist_size());
10758 for (auto *VE : C->varlist()) {
10759 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10760 if (EVar.isInvalid())
10761 return nullptr;
10762 Vars.push_back(EVar.get());
10764 return getDerived().RebuildOMPLastprivateClause(
10765 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10766 C->getLParenLoc(), C->getEndLoc());
10769 template <typename Derived>
10770 OMPClause *
10771 TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
10772 llvm::SmallVector<Expr *, 16> Vars;
10773 Vars.reserve(C->varlist_size());
10774 for (auto *VE : C->varlist()) {
10775 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10776 if (EVar.isInvalid())
10777 return nullptr;
10778 Vars.push_back(EVar.get());
10780 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
10781 C->getLParenLoc(), C->getEndLoc());
10784 template <typename Derived>
10785 OMPClause *
10786 TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
10787 llvm::SmallVector<Expr *, 16> Vars;
10788 Vars.reserve(C->varlist_size());
10789 for (auto *VE : C->varlist()) {
10790 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10791 if (EVar.isInvalid())
10792 return nullptr;
10793 Vars.push_back(EVar.get());
10795 CXXScopeSpec ReductionIdScopeSpec;
10796 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10798 DeclarationNameInfo NameInfo = C->getNameInfo();
10799 if (NameInfo.getName()) {
10800 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10801 if (!NameInfo.getName())
10802 return nullptr;
10804 // Build a list of all UDR decls with the same names ranged by the Scopes.
10805 // The Scope boundary is a duplication of the previous decl.
10806 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10807 for (auto *E : C->reduction_ops()) {
10808 // Transform all the decls.
10809 if (E) {
10810 auto *ULE = cast<UnresolvedLookupExpr>(E);
10811 UnresolvedSet<8> Decls;
10812 for (auto *D : ULE->decls()) {
10813 NamedDecl *InstD =
10814 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10815 Decls.addDecl(InstD, InstD->getAccess());
10817 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10818 SemaRef.Context, /*NamingClass=*/nullptr,
10819 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10820 /*ADL=*/true, Decls.begin(), Decls.end(),
10821 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
10822 } else
10823 UnresolvedReductions.push_back(nullptr);
10825 return getDerived().RebuildOMPReductionClause(
10826 Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(),
10827 C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
10828 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10831 template <typename Derived>
10832 OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
10833 OMPTaskReductionClause *C) {
10834 llvm::SmallVector<Expr *, 16> Vars;
10835 Vars.reserve(C->varlist_size());
10836 for (auto *VE : C->varlist()) {
10837 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10838 if (EVar.isInvalid())
10839 return nullptr;
10840 Vars.push_back(EVar.get());
10842 CXXScopeSpec ReductionIdScopeSpec;
10843 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10845 DeclarationNameInfo NameInfo = C->getNameInfo();
10846 if (NameInfo.getName()) {
10847 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10848 if (!NameInfo.getName())
10849 return nullptr;
10851 // Build a list of all UDR decls with the same names ranged by the Scopes.
10852 // The Scope boundary is a duplication of the previous decl.
10853 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10854 for (auto *E : C->reduction_ops()) {
10855 // Transform all the decls.
10856 if (E) {
10857 auto *ULE = cast<UnresolvedLookupExpr>(E);
10858 UnresolvedSet<8> Decls;
10859 for (auto *D : ULE->decls()) {
10860 NamedDecl *InstD =
10861 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10862 Decls.addDecl(InstD, InstD->getAccess());
10864 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10865 SemaRef.Context, /*NamingClass=*/nullptr,
10866 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10867 /*ADL=*/true, Decls.begin(), Decls.end(),
10868 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
10869 } else
10870 UnresolvedReductions.push_back(nullptr);
10872 return getDerived().RebuildOMPTaskReductionClause(
10873 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10874 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10877 template <typename Derived>
10878 OMPClause *
10879 TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
10880 llvm::SmallVector<Expr *, 16> Vars;
10881 Vars.reserve(C->varlist_size());
10882 for (auto *VE : C->varlist()) {
10883 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10884 if (EVar.isInvalid())
10885 return nullptr;
10886 Vars.push_back(EVar.get());
10888 CXXScopeSpec ReductionIdScopeSpec;
10889 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10891 DeclarationNameInfo NameInfo = C->getNameInfo();
10892 if (NameInfo.getName()) {
10893 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10894 if (!NameInfo.getName())
10895 return nullptr;
10897 // Build a list of all UDR decls with the same names ranged by the Scopes.
10898 // The Scope boundary is a duplication of the previous decl.
10899 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10900 for (auto *E : C->reduction_ops()) {
10901 // Transform all the decls.
10902 if (E) {
10903 auto *ULE = cast<UnresolvedLookupExpr>(E);
10904 UnresolvedSet<8> Decls;
10905 for (auto *D : ULE->decls()) {
10906 NamedDecl *InstD =
10907 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10908 Decls.addDecl(InstD, InstD->getAccess());
10910 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10911 SemaRef.Context, /*NamingClass=*/nullptr,
10912 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10913 /*ADL=*/true, Decls.begin(), Decls.end(),
10914 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
10915 } else
10916 UnresolvedReductions.push_back(nullptr);
10918 return getDerived().RebuildOMPInReductionClause(
10919 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10920 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10923 template <typename Derived>
10924 OMPClause *
10925 TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
10926 llvm::SmallVector<Expr *, 16> Vars;
10927 Vars.reserve(C->varlist_size());
10928 for (auto *VE : C->varlist()) {
10929 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10930 if (EVar.isInvalid())
10931 return nullptr;
10932 Vars.push_back(EVar.get());
10934 ExprResult Step = getDerived().TransformExpr(C->getStep());
10935 if (Step.isInvalid())
10936 return nullptr;
10937 return getDerived().RebuildOMPLinearClause(
10938 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
10939 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
10940 C->getEndLoc());
10943 template <typename Derived>
10944 OMPClause *
10945 TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
10946 llvm::SmallVector<Expr *, 16> Vars;
10947 Vars.reserve(C->varlist_size());
10948 for (auto *VE : C->varlist()) {
10949 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10950 if (EVar.isInvalid())
10951 return nullptr;
10952 Vars.push_back(EVar.get());
10954 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
10955 if (Alignment.isInvalid())
10956 return nullptr;
10957 return getDerived().RebuildOMPAlignedClause(
10958 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
10959 C->getColonLoc(), C->getEndLoc());
10962 template <typename Derived>
10963 OMPClause *
10964 TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
10965 llvm::SmallVector<Expr *, 16> Vars;
10966 Vars.reserve(C->varlist_size());
10967 for (auto *VE : C->varlist()) {
10968 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10969 if (EVar.isInvalid())
10970 return nullptr;
10971 Vars.push_back(EVar.get());
10973 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
10974 C->getLParenLoc(), C->getEndLoc());
10977 template <typename Derived>
10978 OMPClause *
10979 TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
10980 llvm::SmallVector<Expr *, 16> Vars;
10981 Vars.reserve(C->varlist_size());
10982 for (auto *VE : C->varlist()) {
10983 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10984 if (EVar.isInvalid())
10985 return nullptr;
10986 Vars.push_back(EVar.get());
10988 return getDerived().RebuildOMPCopyprivateClause(
10989 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10992 template <typename Derived>
10993 OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
10994 llvm::SmallVector<Expr *, 16> Vars;
10995 Vars.reserve(C->varlist_size());
10996 for (auto *VE : C->varlist()) {
10997 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10998 if (EVar.isInvalid())
10999 return nullptr;
11000 Vars.push_back(EVar.get());
11002 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11003 C->getLParenLoc(), C->getEndLoc());
11006 template <typename Derived>
11007 OMPClause *
11008 TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11009 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11010 if (E.isInvalid())
11011 return nullptr;
11012 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11013 C->getLParenLoc(), C->getEndLoc());
11016 template <typename Derived>
11017 OMPClause *
11018 TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11019 llvm::SmallVector<Expr *, 16> Vars;
11020 Expr *DepModifier = C->getModifier();
11021 if (DepModifier) {
11022 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11023 if (DepModRes.isInvalid())
11024 return nullptr;
11025 DepModifier = DepModRes.get();
11027 Vars.reserve(C->varlist_size());
11028 for (auto *VE : C->varlist()) {
11029 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11030 if (EVar.isInvalid())
11031 return nullptr;
11032 Vars.push_back(EVar.get());
11034 return getDerived().RebuildOMPDependClause(
11035 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11036 C->getOmpAllMemoryLoc()},
11037 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11040 template <typename Derived>
11041 OMPClause *
11042 TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11043 ExprResult E = getDerived().TransformExpr(C->getDevice());
11044 if (E.isInvalid())
11045 return nullptr;
11046 return getDerived().RebuildOMPDeviceClause(
11047 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11048 C->getModifierLoc(), C->getEndLoc());
11051 template <typename Derived, class T>
11052 bool transformOMPMappableExprListClause(
11053 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11054 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11055 DeclarationNameInfo &MapperIdInfo,
11056 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11057 // Transform expressions in the list.
11058 Vars.reserve(C->varlist_size());
11059 for (auto *VE : C->varlist()) {
11060 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11061 if (EVar.isInvalid())
11062 return true;
11063 Vars.push_back(EVar.get());
11065 // Transform mapper scope specifier and identifier.
11066 NestedNameSpecifierLoc QualifierLoc;
11067 if (C->getMapperQualifierLoc()) {
11068 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11069 C->getMapperQualifierLoc());
11070 if (!QualifierLoc)
11071 return true;
11073 MapperIdScopeSpec.Adopt(QualifierLoc);
11074 MapperIdInfo = C->getMapperIdInfo();
11075 if (MapperIdInfo.getName()) {
11076 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11077 if (!MapperIdInfo.getName())
11078 return true;
11080 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11081 // the previous user-defined mapper lookup in dependent environment.
11082 for (auto *E : C->mapperlists()) {
11083 // Transform all the decls.
11084 if (E) {
11085 auto *ULE = cast<UnresolvedLookupExpr>(E);
11086 UnresolvedSet<8> Decls;
11087 for (auto *D : ULE->decls()) {
11088 NamedDecl *InstD =
11089 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11090 Decls.addDecl(InstD, InstD->getAccess());
11092 UnresolvedMappers.push_back(UnresolvedLookupExpr::Create(
11093 TT.getSema().Context, /*NamingClass=*/nullptr,
11094 MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
11095 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11096 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11097 } else {
11098 UnresolvedMappers.push_back(nullptr);
11101 return false;
11104 template <typename Derived>
11105 OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11106 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11107 llvm::SmallVector<Expr *, 16> Vars;
11108 Expr *IteratorModifier = C->getIteratorModifier();
11109 if (IteratorModifier) {
11110 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11111 if (MapModRes.isInvalid())
11112 return nullptr;
11113 IteratorModifier = MapModRes.get();
11115 CXXScopeSpec MapperIdScopeSpec;
11116 DeclarationNameInfo MapperIdInfo;
11117 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11118 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11119 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11120 return nullptr;
11121 return getDerived().RebuildOMPMapClause(
11122 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11123 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11124 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11127 template <typename Derived>
11128 OMPClause *
11129 TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11130 Expr *Allocator = C->getAllocator();
11131 if (Allocator) {
11132 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11133 if (AllocatorRes.isInvalid())
11134 return nullptr;
11135 Allocator = AllocatorRes.get();
11137 llvm::SmallVector<Expr *, 16> Vars;
11138 Vars.reserve(C->varlist_size());
11139 for (auto *VE : C->varlist()) {
11140 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11141 if (EVar.isInvalid())
11142 return nullptr;
11143 Vars.push_back(EVar.get());
11145 return getDerived().RebuildOMPAllocateClause(
11146 Allocator, C->getAllocatorModifier(), Vars, C->getBeginLoc(),
11147 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11150 template <typename Derived>
11151 OMPClause *
11152 TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11153 llvm::SmallVector<Expr *, 3> Vars;
11154 Vars.reserve(C->varlist_size());
11155 for (auto *VE : C->varlist()) {
11156 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11157 if (EVar.isInvalid())
11158 return nullptr;
11159 Vars.push_back(EVar.get());
11161 return getDerived().RebuildOMPNumTeamsClause(
11162 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11165 template <typename Derived>
11166 OMPClause *
11167 TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
11168 llvm::SmallVector<Expr *, 3> Vars;
11169 Vars.reserve(C->varlist_size());
11170 for (auto *VE : C->varlist()) {
11171 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11172 if (EVar.isInvalid())
11173 return nullptr;
11174 Vars.push_back(EVar.get());
11176 return getDerived().RebuildOMPThreadLimitClause(
11177 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11180 template <typename Derived>
11181 OMPClause *
11182 TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
11183 ExprResult E = getDerived().TransformExpr(C->getPriority());
11184 if (E.isInvalid())
11185 return nullptr;
11186 return getDerived().RebuildOMPPriorityClause(
11187 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11190 template <typename Derived>
11191 OMPClause *
11192 TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
11193 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
11194 if (E.isInvalid())
11195 return nullptr;
11196 return getDerived().RebuildOMPGrainsizeClause(
11197 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11198 C->getModifierLoc(), C->getEndLoc());
11201 template <typename Derived>
11202 OMPClause *
11203 TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
11204 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
11205 if (E.isInvalid())
11206 return nullptr;
11207 return getDerived().RebuildOMPNumTasksClause(
11208 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11209 C->getModifierLoc(), C->getEndLoc());
11212 template <typename Derived>
11213 OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
11214 ExprResult E = getDerived().TransformExpr(C->getHint());
11215 if (E.isInvalid())
11216 return nullptr;
11217 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
11218 C->getLParenLoc(), C->getEndLoc());
11221 template <typename Derived>
11222 OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
11223 OMPDistScheduleClause *C) {
11224 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11225 if (E.isInvalid())
11226 return nullptr;
11227 return getDerived().RebuildOMPDistScheduleClause(
11228 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11229 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11232 template <typename Derived>
11233 OMPClause *
11234 TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
11235 // Rebuild Defaultmap Clause since we need to invoke the checking of
11236 // defaultmap(none:variable-category) after template initialization.
11237 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
11238 C->getDefaultmapKind(),
11239 C->getBeginLoc(),
11240 C->getLParenLoc(),
11241 C->getDefaultmapModifierLoc(),
11242 C->getDefaultmapKindLoc(),
11243 C->getEndLoc());
11246 template <typename Derived>
11247 OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
11248 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11249 llvm::SmallVector<Expr *, 16> Vars;
11250 CXXScopeSpec MapperIdScopeSpec;
11251 DeclarationNameInfo MapperIdInfo;
11252 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11253 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
11254 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11255 return nullptr;
11256 return getDerived().RebuildOMPToClause(
11257 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11258 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11261 template <typename Derived>
11262 OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
11263 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11264 llvm::SmallVector<Expr *, 16> Vars;
11265 CXXScopeSpec MapperIdScopeSpec;
11266 DeclarationNameInfo MapperIdInfo;
11267 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11268 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
11269 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11270 return nullptr;
11271 return getDerived().RebuildOMPFromClause(
11272 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11273 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11276 template <typename Derived>
11277 OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
11278 OMPUseDevicePtrClause *C) {
11279 llvm::SmallVector<Expr *, 16> Vars;
11280 Vars.reserve(C->varlist_size());
11281 for (auto *VE : C->varlist()) {
11282 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11283 if (EVar.isInvalid())
11284 return nullptr;
11285 Vars.push_back(EVar.get());
11287 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11288 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
11291 template <typename Derived>
11292 OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11293 OMPUseDeviceAddrClause *C) {
11294 llvm::SmallVector<Expr *, 16> Vars;
11295 Vars.reserve(C->varlist_size());
11296 for (auto *VE : C->varlist()) {
11297 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11298 if (EVar.isInvalid())
11299 return nullptr;
11300 Vars.push_back(EVar.get());
11302 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11303 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11306 template <typename Derived>
11307 OMPClause *
11308 TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11309 llvm::SmallVector<Expr *, 16> Vars;
11310 Vars.reserve(C->varlist_size());
11311 for (auto *VE : C->varlist()) {
11312 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11313 if (EVar.isInvalid())
11314 return nullptr;
11315 Vars.push_back(EVar.get());
11317 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11318 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
11321 template <typename Derived>
11322 OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
11323 OMPHasDeviceAddrClause *C) {
11324 llvm::SmallVector<Expr *, 16> Vars;
11325 Vars.reserve(C->varlist_size());
11326 for (auto *VE : C->varlist()) {
11327 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11328 if (EVar.isInvalid())
11329 return nullptr;
11330 Vars.push_back(EVar.get());
11332 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11333 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
11336 template <typename Derived>
11337 OMPClause *
11338 TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
11339 llvm::SmallVector<Expr *, 16> Vars;
11340 Vars.reserve(C->varlist_size());
11341 for (auto *VE : C->varlist()) {
11342 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11343 if (EVar.isInvalid())
11344 return nullptr;
11345 Vars.push_back(EVar.get());
11347 return getDerived().RebuildOMPNontemporalClause(
11348 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11351 template <typename Derived>
11352 OMPClause *
11353 TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
11354 llvm::SmallVector<Expr *, 16> Vars;
11355 Vars.reserve(C->varlist_size());
11356 for (auto *VE : C->varlist()) {
11357 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11358 if (EVar.isInvalid())
11359 return nullptr;
11360 Vars.push_back(EVar.get());
11362 return getDerived().RebuildOMPInclusiveClause(
11363 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11366 template <typename Derived>
11367 OMPClause *
11368 TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
11369 llvm::SmallVector<Expr *, 16> Vars;
11370 Vars.reserve(C->varlist_size());
11371 for (auto *VE : C->varlist()) {
11372 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11373 if (EVar.isInvalid())
11374 return nullptr;
11375 Vars.push_back(EVar.get());
11377 return getDerived().RebuildOMPExclusiveClause(
11378 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11381 template <typename Derived>
11382 OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11383 OMPUsesAllocatorsClause *C) {
11384 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
11385 Data.reserve(C->getNumberOfAllocators());
11386 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11387 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11388 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11389 if (Allocator.isInvalid())
11390 continue;
11391 ExprResult AllocatorTraits;
11392 if (Expr *AT = D.AllocatorTraits) {
11393 AllocatorTraits = getDerived().TransformExpr(AT);
11394 if (AllocatorTraits.isInvalid())
11395 continue;
11397 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11398 NewD.Allocator = Allocator.get();
11399 NewD.AllocatorTraits = AllocatorTraits.get();
11400 NewD.LParenLoc = D.LParenLoc;
11401 NewD.RParenLoc = D.RParenLoc;
11403 return getDerived().RebuildOMPUsesAllocatorsClause(
11404 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11407 template <typename Derived>
11408 OMPClause *
11409 TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11410 SmallVector<Expr *, 4> Locators;
11411 Locators.reserve(C->varlist_size());
11412 ExprResult ModifierRes;
11413 if (Expr *Modifier = C->getModifier()) {
11414 ModifierRes = getDerived().TransformExpr(Modifier);
11415 if (ModifierRes.isInvalid())
11416 return nullptr;
11418 for (Expr *E : C->varlist()) {
11419 ExprResult Locator = getDerived().TransformExpr(E);
11420 if (Locator.isInvalid())
11421 continue;
11422 Locators.push_back(Locator.get());
11424 return getDerived().RebuildOMPAffinityClause(
11425 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11426 ModifierRes.get(), Locators);
11429 template <typename Derived>
11430 OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11431 return getDerived().RebuildOMPOrderClause(
11432 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11433 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11436 template <typename Derived>
11437 OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11438 return getDerived().RebuildOMPBindClause(
11439 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11440 C->getLParenLoc(), C->getEndLoc());
11443 template <typename Derived>
11444 OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11445 OMPXDynCGroupMemClause *C) {
11446 ExprResult Size = getDerived().TransformExpr(C->getSize());
11447 if (Size.isInvalid())
11448 return nullptr;
11449 return getDerived().RebuildOMPXDynCGroupMemClause(
11450 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11453 template <typename Derived>
11454 OMPClause *
11455 TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11456 llvm::SmallVector<Expr *, 16> Vars;
11457 Vars.reserve(C->varlist_size());
11458 for (auto *VE : C->varlist()) {
11459 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11460 if (EVar.isInvalid())
11461 return nullptr;
11462 Vars.push_back(EVar.get());
11464 return getDerived().RebuildOMPDoacrossClause(
11465 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11466 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11469 template <typename Derived>
11470 OMPClause *
11471 TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11472 SmallVector<const Attr *> NewAttrs;
11473 for (auto *A : C->getAttrs())
11474 NewAttrs.push_back(getDerived().TransformAttr(A));
11475 return getDerived().RebuildOMPXAttributeClause(
11476 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11479 template <typename Derived>
11480 OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11481 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11484 //===----------------------------------------------------------------------===//
11485 // OpenACC transformation
11486 //===----------------------------------------------------------------------===//
11487 namespace {
11488 template <typename Derived>
11489 class OpenACCClauseTransform final
11490 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11491 TreeTransform<Derived> &Self;
11492 ArrayRef<const OpenACCClause *> ExistingClauses;
11493 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11494 OpenACCClause *NewClause = nullptr;
11496 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11497 llvm::SmallVector<Expr *> InstantiatedVarList;
11498 for (Expr *CurVar : VarList) {
11499 ExprResult Res = Self.TransformExpr(CurVar);
11501 if (!Res.isUsable())
11502 continue;
11504 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getClauseKind(),
11505 Res.get());
11507 if (Res.isUsable())
11508 InstantiatedVarList.push_back(Res.get());
11511 return InstantiatedVarList;
11514 public:
11515 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11516 ArrayRef<const OpenACCClause *> ExistingClauses,
11517 SemaOpenACC::OpenACCParsedClause &PC)
11518 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
11520 OpenACCClause *CreatedClause() const { return NewClause; }
11522 #define VISIT_CLAUSE(CLAUSE_NAME) \
11523 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11524 #include "clang/Basic/OpenACCClauses.def"
11527 template <typename Derived>
11528 void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11529 const OpenACCDefaultClause &C) {
11530 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11532 NewClause = OpenACCDefaultClause::Create(
11533 Self.getSema().getASTContext(), ParsedClause.getDefaultClauseKind(),
11534 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11535 ParsedClause.getEndLoc());
11538 template <typename Derived>
11539 void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11540 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11541 assert(Cond && "If constructed with invalid Condition");
11542 Sema::ConditionResult Res = Self.TransformCondition(
11543 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11545 if (Res.isInvalid() || !Res.get().second)
11546 return;
11548 ParsedClause.setConditionDetails(Res.get().second);
11550 NewClause = OpenACCIfClause::Create(
11551 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11552 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11553 ParsedClause.getEndLoc());
11556 template <typename Derived>
11557 void OpenACCClauseTransform<Derived>::VisitSelfClause(
11558 const OpenACCSelfClause &C) {
11560 if (C.hasConditionExpr()) {
11561 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11562 Sema::ConditionResult Res =
11563 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
11564 Sema::ConditionKind::Boolean);
11566 if (Res.isInvalid() || !Res.get().second)
11567 return;
11569 ParsedClause.setConditionDetails(Res.get().second);
11572 NewClause = OpenACCSelfClause::Create(
11573 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11574 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11575 ParsedClause.getEndLoc());
11578 template <typename Derived>
11579 void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
11580 const OpenACCNumGangsClause &C) {
11581 llvm::SmallVector<Expr *> InstantiatedIntExprs;
11583 for (Expr *CurIntExpr : C.getIntExprs()) {
11584 ExprResult Res = Self.TransformExpr(CurIntExpr);
11586 if (!Res.isUsable())
11587 return;
11589 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11590 C.getClauseKind(),
11591 C.getBeginLoc(), Res.get());
11592 if (!Res.isUsable())
11593 return;
11595 InstantiatedIntExprs.push_back(Res.get());
11598 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
11599 NewClause = OpenACCNumGangsClause::Create(
11600 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11601 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs(),
11602 ParsedClause.getEndLoc());
11605 template <typename Derived>
11606 void OpenACCClauseTransform<Derived>::VisitPrivateClause(
11607 const OpenACCPrivateClause &C) {
11608 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11609 /*IsReadOnly=*/false, /*IsZero=*/false);
11611 NewClause = OpenACCPrivateClause::Create(
11612 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11613 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11614 ParsedClause.getEndLoc());
11617 template <typename Derived>
11618 void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
11619 const OpenACCFirstPrivateClause &C) {
11620 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11621 /*IsReadOnly=*/false, /*IsZero=*/false);
11623 NewClause = OpenACCFirstPrivateClause::Create(
11624 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11625 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11626 ParsedClause.getEndLoc());
11629 template <typename Derived>
11630 void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
11631 const OpenACCNoCreateClause &C) {
11632 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11633 /*IsReadOnly=*/false, /*IsZero=*/false);
11635 NewClause = OpenACCNoCreateClause::Create(
11636 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11637 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11638 ParsedClause.getEndLoc());
11641 template <typename Derived>
11642 void OpenACCClauseTransform<Derived>::VisitPresentClause(
11643 const OpenACCPresentClause &C) {
11644 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11645 /*IsReadOnly=*/false, /*IsZero=*/false);
11647 NewClause = OpenACCPresentClause::Create(
11648 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11649 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11650 ParsedClause.getEndLoc());
11653 template <typename Derived>
11654 void OpenACCClauseTransform<Derived>::VisitCopyClause(
11655 const OpenACCCopyClause &C) {
11656 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11657 /*IsReadOnly=*/false, /*IsZero=*/false);
11659 NewClause = OpenACCCopyClause::Create(
11660 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11661 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11662 ParsedClause.getVarList(), ParsedClause.getEndLoc());
11665 template <typename Derived>
11666 void OpenACCClauseTransform<Derived>::VisitCopyInClause(
11667 const OpenACCCopyInClause &C) {
11668 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()), C.isReadOnly(),
11669 /*IsZero=*/false);
11671 NewClause = OpenACCCopyInClause::Create(
11672 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11673 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11674 ParsedClause.isReadOnly(), ParsedClause.getVarList(),
11675 ParsedClause.getEndLoc());
11678 template <typename Derived>
11679 void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
11680 const OpenACCCopyOutClause &C) {
11681 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11682 /*IsReadOnly=*/false, C.isZero());
11684 NewClause = OpenACCCopyOutClause::Create(
11685 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11686 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11687 ParsedClause.isZero(), ParsedClause.getVarList(),
11688 ParsedClause.getEndLoc());
11691 template <typename Derived>
11692 void OpenACCClauseTransform<Derived>::VisitCreateClause(
11693 const OpenACCCreateClause &C) {
11694 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11695 /*IsReadOnly=*/false, C.isZero());
11697 NewClause = OpenACCCreateClause::Create(
11698 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11699 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11700 ParsedClause.isZero(), ParsedClause.getVarList(),
11701 ParsedClause.getEndLoc());
11703 template <typename Derived>
11704 void OpenACCClauseTransform<Derived>::VisitAttachClause(
11705 const OpenACCAttachClause &C) {
11706 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
11708 // Ensure each var is a pointer type.
11709 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
11710 return Self.getSema().OpenACC().CheckVarIsPointerType(
11711 OpenACCClauseKind::Attach, E);
11712 }), VarList.end());
11714 ParsedClause.setVarListDetails(VarList,
11715 /*IsReadOnly=*/false, /*IsZero=*/false);
11716 NewClause = OpenACCAttachClause::Create(
11717 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11718 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11719 ParsedClause.getEndLoc());
11722 template <typename Derived>
11723 void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
11724 const OpenACCDevicePtrClause &C) {
11725 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
11727 // Ensure each var is a pointer type.
11728 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
11729 return Self.getSema().OpenACC().CheckVarIsPointerType(
11730 OpenACCClauseKind::DevicePtr, E);
11731 }), VarList.end());
11733 ParsedClause.setVarListDetails(VarList,
11734 /*IsReadOnly=*/false, /*IsZero=*/false);
11735 NewClause = OpenACCDevicePtrClause::Create(
11736 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11737 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11738 ParsedClause.getEndLoc());
11741 template <typename Derived>
11742 void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
11743 const OpenACCNumWorkersClause &C) {
11744 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11745 assert(IntExpr && "num_workers clause constructed with invalid int expr");
11747 ExprResult Res = Self.TransformExpr(IntExpr);
11748 if (!Res.isUsable())
11749 return;
11751 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11752 C.getClauseKind(),
11753 C.getBeginLoc(), Res.get());
11754 if (!Res.isUsable())
11755 return;
11757 ParsedClause.setIntExprDetails(Res.get());
11758 NewClause = OpenACCNumWorkersClause::Create(
11759 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11760 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
11761 ParsedClause.getEndLoc());
11764 template <typename Derived>
11765 void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
11766 const OpenACCVectorLengthClause &C) {
11767 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11768 assert(IntExpr && "vector_length clause constructed with invalid int expr");
11770 ExprResult Res = Self.TransformExpr(IntExpr);
11771 if (!Res.isUsable())
11772 return;
11774 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11775 C.getClauseKind(),
11776 C.getBeginLoc(), Res.get());
11777 if (!Res.isUsable())
11778 return;
11780 ParsedClause.setIntExprDetails(Res.get());
11781 NewClause = OpenACCVectorLengthClause::Create(
11782 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11783 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
11784 ParsedClause.getEndLoc());
11787 template <typename Derived>
11788 void OpenACCClauseTransform<Derived>::VisitAsyncClause(
11789 const OpenACCAsyncClause &C) {
11790 if (C.hasIntExpr()) {
11791 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
11792 if (!Res.isUsable())
11793 return;
11795 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11796 C.getClauseKind(),
11797 C.getBeginLoc(), Res.get());
11798 if (!Res.isUsable())
11799 return;
11800 ParsedClause.setIntExprDetails(Res.get());
11803 NewClause = OpenACCAsyncClause::Create(
11804 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11805 ParsedClause.getLParenLoc(),
11806 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
11807 : nullptr,
11808 ParsedClause.getEndLoc());
11811 template <typename Derived>
11812 void OpenACCClauseTransform<Derived>::VisitWorkerClause(
11813 const OpenACCWorkerClause &C) {
11814 if (C.hasIntExpr()) {
11815 // restrictions on this expression are all "does it exist in certain
11816 // situations" that are not possible to be dependent, so the only check we
11817 // have is that it transforms, and is an int expression.
11818 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
11819 if (!Res.isUsable())
11820 return;
11822 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11823 C.getClauseKind(),
11824 C.getBeginLoc(), Res.get());
11825 if (!Res.isUsable())
11826 return;
11827 ParsedClause.setIntExprDetails(Res.get());
11830 NewClause = OpenACCWorkerClause::Create(
11831 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11832 ParsedClause.getLParenLoc(),
11833 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
11834 : nullptr,
11835 ParsedClause.getEndLoc());
11838 template <typename Derived>
11839 void OpenACCClauseTransform<Derived>::VisitVectorClause(
11840 const OpenACCVectorClause &C) {
11841 if (C.hasIntExpr()) {
11842 // restrictions on this expression are all "does it exist in certain
11843 // situations" that are not possible to be dependent, so the only check we
11844 // have is that it transforms, and is an int expression.
11845 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
11846 if (!Res.isUsable())
11847 return;
11849 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11850 C.getClauseKind(),
11851 C.getBeginLoc(), Res.get());
11852 if (!Res.isUsable())
11853 return;
11854 ParsedClause.setIntExprDetails(Res.get());
11857 NewClause = OpenACCVectorClause::Create(
11858 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11859 ParsedClause.getLParenLoc(),
11860 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
11861 : nullptr,
11862 ParsedClause.getEndLoc());
11865 template <typename Derived>
11866 void OpenACCClauseTransform<Derived>::VisitWaitClause(
11867 const OpenACCWaitClause &C) {
11868 if (!C.getLParenLoc().isInvalid()) {
11869 Expr *DevNumExpr = nullptr;
11870 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
11872 // Instantiate devnum expr if it exists.
11873 if (C.getDevNumExpr()) {
11874 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
11875 if (!Res.isUsable())
11876 return;
11877 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11878 C.getClauseKind(),
11879 C.getBeginLoc(), Res.get());
11880 if (!Res.isUsable())
11881 return;
11883 DevNumExpr = Res.get();
11886 // Instantiate queue ids.
11887 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
11888 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
11889 if (!Res.isUsable())
11890 return;
11891 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11892 C.getClauseKind(),
11893 C.getBeginLoc(), Res.get());
11894 if (!Res.isUsable())
11895 return;
11897 InstantiatedQueueIdExprs.push_back(Res.get());
11900 ParsedClause.setWaitDetails(DevNumExpr, C.getQueuesLoc(),
11901 std::move(InstantiatedQueueIdExprs));
11904 NewClause = OpenACCWaitClause::Create(
11905 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11906 ParsedClause.getLParenLoc(), ParsedClause.getDevNumExpr(),
11907 ParsedClause.getQueuesLoc(), ParsedClause.getQueueIdExprs(),
11908 ParsedClause.getEndLoc());
11911 template <typename Derived>
11912 void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
11913 const OpenACCDeviceTypeClause &C) {
11914 // Nothing to transform here, just create a new version of 'C'.
11915 NewClause = OpenACCDeviceTypeClause::Create(
11916 Self.getSema().getASTContext(), C.getClauseKind(),
11917 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11918 C.getArchitectures(), ParsedClause.getEndLoc());
11921 template <typename Derived>
11922 void OpenACCClauseTransform<Derived>::VisitAutoClause(
11923 const OpenACCAutoClause &C) {
11924 // Nothing to do, so just create a new node.
11925 NewClause = OpenACCAutoClause::Create(Self.getSema().getASTContext(),
11926 ParsedClause.getBeginLoc(),
11927 ParsedClause.getEndLoc());
11930 template <typename Derived>
11931 void OpenACCClauseTransform<Derived>::VisitIndependentClause(
11932 const OpenACCIndependentClause &C) {
11933 NewClause = OpenACCIndependentClause::Create(Self.getSema().getASTContext(),
11934 ParsedClause.getBeginLoc(),
11935 ParsedClause.getEndLoc());
11938 template <typename Derived>
11939 void OpenACCClauseTransform<Derived>::VisitSeqClause(
11940 const OpenACCSeqClause &C) {
11941 NewClause = OpenACCSeqClause::Create(Self.getSema().getASTContext(),
11942 ParsedClause.getBeginLoc(),
11943 ParsedClause.getEndLoc());
11946 template <typename Derived>
11947 void OpenACCClauseTransform<Derived>::VisitReductionClause(
11948 const OpenACCReductionClause &C) {
11949 SmallVector<Expr *> TransformedVars = VisitVarList(C.getVarList());
11950 SmallVector<Expr *> ValidVars;
11952 for (Expr *Var : TransformedVars) {
11953 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
11954 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
11955 if (Res.isUsable())
11956 ValidVars.push_back(Res.get());
11959 NewClause = Self.getSema().OpenACC().CheckReductionClause(
11960 ExistingClauses, ParsedClause.getDirectiveKind(),
11961 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11962 C.getReductionOp(), ValidVars, ParsedClause.getEndLoc());
11965 template <typename Derived>
11966 void OpenACCClauseTransform<Derived>::VisitCollapseClause(
11967 const OpenACCCollapseClause &C) {
11968 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
11969 assert(LoopCount && "collapse clause constructed with invalid loop count");
11971 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
11973 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
11974 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
11975 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
11977 NewLoopCount =
11978 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
11980 if (!NewLoopCount.isUsable())
11981 return;
11983 ParsedClause.setCollapseDetails(C.hasForce(), NewLoopCount.get());
11984 NewClause = OpenACCCollapseClause::Create(
11985 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11986 ParsedClause.getLParenLoc(), ParsedClause.isForce(),
11987 ParsedClause.getLoopCount(), ParsedClause.getEndLoc());
11990 template <typename Derived>
11991 void OpenACCClauseTransform<Derived>::VisitTileClause(
11992 const OpenACCTileClause &C) {
11994 llvm::SmallVector<Expr *> TransformedExprs;
11996 for (Expr *E : C.getSizeExprs()) {
11997 ExprResult NewSizeExpr = Self.TransformExpr(E);
11999 if (!NewSizeExpr.isUsable())
12000 return;
12002 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
12003 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12004 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
12006 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
12008 if (!NewSizeExpr.isUsable())
12009 return;
12010 TransformedExprs.push_back(NewSizeExpr.get());
12013 ParsedClause.setIntExprDetails(TransformedExprs);
12014 NewClause = OpenACCTileClause::Create(
12015 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12016 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs(),
12017 ParsedClause.getEndLoc());
12019 template <typename Derived>
12020 void OpenACCClauseTransform<Derived>::VisitGangClause(
12021 const OpenACCGangClause &C) {
12022 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
12023 llvm::SmallVector<Expr *> TransformedIntExprs;
12025 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
12026 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
12027 if (!ER.isUsable())
12028 continue;
12030 ER = Self.getSema().OpenACC().CheckGangExpr(C.getExpr(I).first, ER.get());
12031 if (!ER.isUsable())
12032 continue;
12033 TransformedGangKinds.push_back(C.getExpr(I).first);
12034 TransformedIntExprs.push_back(ER.get());
12037 NewClause = Self.getSema().OpenACC().CheckGangClause(
12038 ExistingClauses, ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12039 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
12041 } // namespace
12042 template <typename Derived>
12043 OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
12044 ArrayRef<const OpenACCClause *> ExistingClauses,
12045 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
12047 SemaOpenACC::OpenACCParsedClause ParsedClause(
12048 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
12049 ParsedClause.setEndLoc(OldClause->getEndLoc());
12051 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(OldClause))
12052 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
12054 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
12055 ParsedClause};
12056 Transform.Visit(OldClause);
12058 return Transform.CreatedClause();
12061 template <typename Derived>
12062 llvm::SmallVector<OpenACCClause *>
12063 TreeTransform<Derived>::TransformOpenACCClauseList(
12064 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
12065 llvm::SmallVector<OpenACCClause *> TransformedClauses;
12066 for (const auto *Clause : OldClauses) {
12067 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
12068 TransformedClauses, DirKind, Clause))
12069 TransformedClauses.push_back(TransformedClause);
12071 return TransformedClauses;
12074 template <typename Derived>
12075 StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
12076 OpenACCComputeConstruct *C) {
12077 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12079 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12080 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12081 C->clauses());
12083 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
12084 C->getBeginLoc()))
12085 return StmtError();
12087 // Transform Structured Block.
12088 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12089 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12090 C->clauses(), TransformedClauses);
12091 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12092 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12093 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12095 return getDerived().RebuildOpenACCComputeConstruct(
12096 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12097 C->getEndLoc(), TransformedClauses, StrBlock);
12100 template <typename Derived>
12101 StmtResult
12102 TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
12104 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12106 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12107 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12108 C->clauses());
12110 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
12111 C->getBeginLoc()))
12112 return StmtError();
12114 // Transform Loop.
12115 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12116 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12117 C->clauses(), TransformedClauses);
12118 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12119 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12120 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12122 return getDerived().RebuildOpenACCLoopConstruct(
12123 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12124 TransformedClauses, Loop);
12127 template <typename Derived>
12128 StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
12129 OpenACCCombinedConstruct *C) {
12130 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12132 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12133 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12134 C->clauses());
12136 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
12137 C->getBeginLoc()))
12138 return StmtError();
12140 // Transform Loop.
12141 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12142 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12143 C->clauses(), TransformedClauses);
12144 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12145 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12146 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12148 return getDerived().RebuildOpenACCCombinedConstruct(
12149 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12150 C->getEndLoc(), TransformedClauses, Loop);
12153 template <typename Derived>
12154 ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
12155 OpenACCAsteriskSizeExpr *E) {
12156 if (getDerived().AlwaysRebuild())
12157 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
12158 // Nothing can ever change, so there is never anything to transform.
12159 return E;
12162 //===----------------------------------------------------------------------===//
12163 // Expression transformation
12164 //===----------------------------------------------------------------------===//
12165 template<typename Derived>
12166 ExprResult
12167 TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
12168 return TransformExpr(E->getSubExpr());
12171 template <typename Derived>
12172 ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
12173 SYCLUniqueStableNameExpr *E) {
12174 if (!E->isTypeDependent())
12175 return E;
12177 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
12179 if (!NewT)
12180 return ExprError();
12182 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
12183 return E;
12185 return getDerived().RebuildSYCLUniqueStableNameExpr(
12186 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
12189 template<typename Derived>
12190 ExprResult
12191 TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
12192 if (!E->isTypeDependent())
12193 return E;
12195 return getDerived().RebuildPredefinedExpr(E->getLocation(),
12196 E->getIdentKind());
12199 template<typename Derived>
12200 ExprResult
12201 TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
12202 NestedNameSpecifierLoc QualifierLoc;
12203 if (E->getQualifierLoc()) {
12204 QualifierLoc
12205 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
12206 if (!QualifierLoc)
12207 return ExprError();
12210 ValueDecl *ND
12211 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
12212 E->getDecl()));
12213 if (!ND)
12214 return ExprError();
12216 NamedDecl *Found = ND;
12217 if (E->getFoundDecl() != E->getDecl()) {
12218 Found = cast_or_null<NamedDecl>(
12219 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
12220 if (!Found)
12221 return ExprError();
12224 DeclarationNameInfo NameInfo = E->getNameInfo();
12225 if (NameInfo.getName()) {
12226 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
12227 if (!NameInfo.getName())
12228 return ExprError();
12231 if (!getDerived().AlwaysRebuild() &&
12232 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
12233 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
12234 Found == E->getFoundDecl() &&
12235 NameInfo.getName() == E->getDecl()->getDeclName() &&
12236 !E->hasExplicitTemplateArgs()) {
12238 // Mark it referenced in the new context regardless.
12239 // FIXME: this is a bit instantiation-specific.
12240 SemaRef.MarkDeclRefReferenced(E);
12242 return E;
12245 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
12246 if (E->hasExplicitTemplateArgs()) {
12247 TemplateArgs = &TransArgs;
12248 TransArgs.setLAngleLoc(E->getLAngleLoc());
12249 TransArgs.setRAngleLoc(E->getRAngleLoc());
12250 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
12251 E->getNumTemplateArgs(),
12252 TransArgs))
12253 return ExprError();
12256 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
12257 Found, TemplateArgs);
12260 template<typename Derived>
12261 ExprResult
12262 TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
12263 return E;
12266 template <typename Derived>
12267 ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
12268 FixedPointLiteral *E) {
12269 return E;
12272 template<typename Derived>
12273 ExprResult
12274 TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
12275 return E;
12278 template<typename Derived>
12279 ExprResult
12280 TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
12281 return E;
12284 template<typename Derived>
12285 ExprResult
12286 TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
12287 return E;
12290 template<typename Derived>
12291 ExprResult
12292 TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
12293 return E;
12296 template<typename Derived>
12297 ExprResult
12298 TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
12299 return getDerived().TransformCallExpr(E);
12302 template<typename Derived>
12303 ExprResult
12304 TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
12305 ExprResult ControllingExpr;
12306 TypeSourceInfo *ControllingType = nullptr;
12307 if (E->isExprPredicate())
12308 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
12309 else
12310 ControllingType = getDerived().TransformType(E->getControllingType());
12312 if (ControllingExpr.isInvalid() && !ControllingType)
12313 return ExprError();
12315 SmallVector<Expr *, 4> AssocExprs;
12316 SmallVector<TypeSourceInfo *, 4> AssocTypes;
12317 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
12318 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
12319 if (TSI) {
12320 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
12321 if (!AssocType)
12322 return ExprError();
12323 AssocTypes.push_back(AssocType);
12324 } else {
12325 AssocTypes.push_back(nullptr);
12328 ExprResult AssocExpr =
12329 getDerived().TransformExpr(Assoc.getAssociationExpr());
12330 if (AssocExpr.isInvalid())
12331 return ExprError();
12332 AssocExprs.push_back(AssocExpr.get());
12335 if (!ControllingType)
12336 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
12337 E->getDefaultLoc(),
12338 E->getRParenLoc(),
12339 ControllingExpr.get(),
12340 AssocTypes,
12341 AssocExprs);
12342 return getDerived().RebuildGenericSelectionExpr(
12343 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
12344 ControllingType, AssocTypes, AssocExprs);
12347 template<typename Derived>
12348 ExprResult
12349 TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
12350 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12351 if (SubExpr.isInvalid())
12352 return ExprError();
12354 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
12355 return E;
12357 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
12358 E->getRParen());
12361 /// The operand of a unary address-of operator has special rules: it's
12362 /// allowed to refer to a non-static member of a class even if there's no 'this'
12363 /// object available.
12364 template<typename Derived>
12365 ExprResult
12366 TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
12367 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
12368 return getDerived().TransformDependentScopeDeclRefExpr(
12369 DRE, /*IsAddressOfOperand=*/true, nullptr);
12370 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E))
12371 return getDerived().TransformUnresolvedLookupExpr(
12372 ULE, /*IsAddressOfOperand=*/true);
12373 else
12374 return getDerived().TransformExpr(E);
12377 template<typename Derived>
12378 ExprResult
12379 TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
12380 ExprResult SubExpr;
12381 if (E->getOpcode() == UO_AddrOf)
12382 SubExpr = TransformAddressOfOperand(E->getSubExpr());
12383 else
12384 SubExpr = TransformExpr(E->getSubExpr());
12385 if (SubExpr.isInvalid())
12386 return ExprError();
12388 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
12389 return E;
12391 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
12392 E->getOpcode(),
12393 SubExpr.get());
12396 template<typename Derived>
12397 ExprResult
12398 TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
12399 // Transform the type.
12400 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
12401 if (!Type)
12402 return ExprError();
12404 // Transform all of the components into components similar to what the
12405 // parser uses.
12406 // FIXME: It would be slightly more efficient in the non-dependent case to
12407 // just map FieldDecls, rather than requiring the rebuilder to look for
12408 // the fields again. However, __builtin_offsetof is rare enough in
12409 // template code that we don't care.
12410 bool ExprChanged = false;
12411 typedef Sema::OffsetOfComponent Component;
12412 SmallVector<Component, 4> Components;
12413 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
12414 const OffsetOfNode &ON = E->getComponent(I);
12415 Component Comp;
12416 Comp.isBrackets = true;
12417 Comp.LocStart = ON.getSourceRange().getBegin();
12418 Comp.LocEnd = ON.getSourceRange().getEnd();
12419 switch (ON.getKind()) {
12420 case OffsetOfNode::Array: {
12421 Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
12422 ExprResult Index = getDerived().TransformExpr(FromIndex);
12423 if (Index.isInvalid())
12424 return ExprError();
12426 ExprChanged = ExprChanged || Index.get() != FromIndex;
12427 Comp.isBrackets = true;
12428 Comp.U.E = Index.get();
12429 break;
12432 case OffsetOfNode::Field:
12433 case OffsetOfNode::Identifier:
12434 Comp.isBrackets = false;
12435 Comp.U.IdentInfo = ON.getFieldName();
12436 if (!Comp.U.IdentInfo)
12437 continue;
12439 break;
12441 case OffsetOfNode::Base:
12442 // Will be recomputed during the rebuild.
12443 continue;
12446 Components.push_back(Comp);
12449 // If nothing changed, retain the existing expression.
12450 if (!getDerived().AlwaysRebuild() &&
12451 Type == E->getTypeSourceInfo() &&
12452 !ExprChanged)
12453 return E;
12455 // Build a new offsetof expression.
12456 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
12457 Components, E->getRParenLoc());
12460 template<typename Derived>
12461 ExprResult
12462 TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
12463 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
12464 "opaque value expression requires transformation");
12465 return E;
12468 template<typename Derived>
12469 ExprResult
12470 TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
12471 return E;
12474 template <typename Derived>
12475 ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
12476 llvm::SmallVector<Expr *, 8> Children;
12477 bool Changed = false;
12478 for (Expr *C : E->subExpressions()) {
12479 ExprResult NewC = getDerived().TransformExpr(C);
12480 if (NewC.isInvalid())
12481 return ExprError();
12482 Children.push_back(NewC.get());
12484 Changed |= NewC.get() != C;
12486 if (!getDerived().AlwaysRebuild() && !Changed)
12487 return E;
12488 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
12489 Children, E->getType());
12492 template<typename Derived>
12493 ExprResult
12494 TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
12495 // Rebuild the syntactic form. The original syntactic form has
12496 // opaque-value expressions in it, so strip those away and rebuild
12497 // the result. This is a really awful way of doing this, but the
12498 // better solution (rebuilding the semantic expressions and
12499 // rebinding OVEs as necessary) doesn't work; we'd need
12500 // TreeTransform to not strip away implicit conversions.
12501 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
12502 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
12503 if (result.isInvalid()) return ExprError();
12505 // If that gives us a pseudo-object result back, the pseudo-object
12506 // expression must have been an lvalue-to-rvalue conversion which we
12507 // should reapply.
12508 if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
12509 result = SemaRef.PseudoObject().checkRValue(result.get());
12511 return result;
12514 template<typename Derived>
12515 ExprResult
12516 TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
12517 UnaryExprOrTypeTraitExpr *E) {
12518 if (E->isArgumentType()) {
12519 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
12521 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
12522 if (!NewT)
12523 return ExprError();
12525 if (!getDerived().AlwaysRebuild() && OldT == NewT)
12526 return E;
12528 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
12529 E->getKind(),
12530 E->getSourceRange());
12533 // C++0x [expr.sizeof]p1:
12534 // The operand is either an expression, which is an unevaluated operand
12535 // [...]
12536 EnterExpressionEvaluationContext Unevaluated(
12537 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
12538 Sema::ReuseLambdaContextDecl);
12540 // Try to recover if we have something like sizeof(T::X) where X is a type.
12541 // Notably, there must be *exactly* one set of parens if X is a type.
12542 TypeSourceInfo *RecoveryTSI = nullptr;
12543 ExprResult SubExpr;
12544 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
12545 if (auto *DRE =
12546 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
12547 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
12548 PE, DRE, false, &RecoveryTSI);
12549 else
12550 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
12552 if (RecoveryTSI) {
12553 return getDerived().RebuildUnaryExprOrTypeTrait(
12554 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
12555 } else if (SubExpr.isInvalid())
12556 return ExprError();
12558 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
12559 return E;
12561 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
12562 E->getOperatorLoc(),
12563 E->getKind(),
12564 E->getSourceRange());
12567 template<typename Derived>
12568 ExprResult
12569 TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
12570 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12571 if (LHS.isInvalid())
12572 return ExprError();
12574 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
12575 if (RHS.isInvalid())
12576 return ExprError();
12579 if (!getDerived().AlwaysRebuild() &&
12580 LHS.get() == E->getLHS() &&
12581 RHS.get() == E->getRHS())
12582 return E;
12584 return getDerived().RebuildArraySubscriptExpr(
12585 LHS.get(),
12586 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
12589 template <typename Derived>
12590 ExprResult
12591 TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
12592 ExprResult Base = getDerived().TransformExpr(E->getBase());
12593 if (Base.isInvalid())
12594 return ExprError();
12596 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
12597 if (RowIdx.isInvalid())
12598 return ExprError();
12600 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
12601 if (ColumnIdx.isInvalid())
12602 return ExprError();
12604 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
12605 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
12606 return E;
12608 return getDerived().RebuildMatrixSubscriptExpr(
12609 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
12612 template <typename Derived>
12613 ExprResult
12614 TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
12615 ExprResult Base = getDerived().TransformExpr(E->getBase());
12616 if (Base.isInvalid())
12617 return ExprError();
12619 ExprResult LowerBound;
12620 if (E->getLowerBound()) {
12621 LowerBound = getDerived().TransformExpr(E->getLowerBound());
12622 if (LowerBound.isInvalid())
12623 return ExprError();
12626 ExprResult Length;
12627 if (E->getLength()) {
12628 Length = getDerived().TransformExpr(E->getLength());
12629 if (Length.isInvalid())
12630 return ExprError();
12633 ExprResult Stride;
12634 if (E->isOMPArraySection()) {
12635 if (Expr *Str = E->getStride()) {
12636 Stride = getDerived().TransformExpr(Str);
12637 if (Stride.isInvalid())
12638 return ExprError();
12642 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
12643 LowerBound.get() == E->getLowerBound() &&
12644 Length.get() == E->getLength() &&
12645 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
12646 return E;
12648 return getDerived().RebuildArraySectionExpr(
12649 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
12650 LowerBound.get(), E->getColonLocFirst(),
12651 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
12652 Length.get(), Stride.get(), E->getRBracketLoc());
12655 template <typename Derived>
12656 ExprResult
12657 TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
12658 ExprResult Base = getDerived().TransformExpr(E->getBase());
12659 if (Base.isInvalid())
12660 return ExprError();
12662 SmallVector<Expr *, 4> Dims;
12663 bool ErrorFound = false;
12664 for (Expr *Dim : E->getDimensions()) {
12665 ExprResult DimRes = getDerived().TransformExpr(Dim);
12666 if (DimRes.isInvalid()) {
12667 ErrorFound = true;
12668 continue;
12670 Dims.push_back(DimRes.get());
12673 if (ErrorFound)
12674 return ExprError();
12675 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
12676 E->getRParenLoc(), Dims,
12677 E->getBracketsRanges());
12680 template <typename Derived>
12681 ExprResult
12682 TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
12683 unsigned NumIterators = E->numOfIterators();
12684 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
12686 bool ErrorFound = false;
12687 bool NeedToRebuild = getDerived().AlwaysRebuild();
12688 for (unsigned I = 0; I < NumIterators; ++I) {
12689 auto *D = cast<VarDecl>(E->getIteratorDecl(I));
12690 Data[I].DeclIdent = D->getIdentifier();
12691 Data[I].DeclIdentLoc = D->getLocation();
12692 if (D->getLocation() == D->getBeginLoc()) {
12693 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
12694 "Implicit type must be int.");
12695 } else {
12696 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
12697 QualType DeclTy = getDerived().TransformType(D->getType());
12698 Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI);
12700 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
12701 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
12702 ExprResult End = getDerived().TransformExpr(Range.End);
12703 ExprResult Step = getDerived().TransformExpr(Range.Step);
12704 ErrorFound = ErrorFound ||
12705 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
12706 !Data[I].Type.get().isNull())) ||
12707 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
12708 if (ErrorFound)
12709 continue;
12710 Data[I].Range.Begin = Begin.get();
12711 Data[I].Range.End = End.get();
12712 Data[I].Range.Step = Step.get();
12713 Data[I].AssignLoc = E->getAssignLoc(I);
12714 Data[I].ColonLoc = E->getColonLoc(I);
12715 Data[I].SecColonLoc = E->getSecondColonLoc(I);
12716 NeedToRebuild =
12717 NeedToRebuild ||
12718 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
12719 D->getType().getTypePtrOrNull()) ||
12720 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
12721 Range.Step != Data[I].Range.Step;
12723 if (ErrorFound)
12724 return ExprError();
12725 if (!NeedToRebuild)
12726 return E;
12728 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
12729 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
12730 if (!Res.isUsable())
12731 return Res;
12732 auto *IE = cast<OMPIteratorExpr>(Res.get());
12733 for (unsigned I = 0; I < NumIterators; ++I)
12734 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
12735 IE->getIteratorDecl(I));
12736 return Res;
12739 template<typename Derived>
12740 ExprResult
12741 TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
12742 // Transform the callee.
12743 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
12744 if (Callee.isInvalid())
12745 return ExprError();
12747 // Transform arguments.
12748 bool ArgChanged = false;
12749 SmallVector<Expr*, 8> Args;
12750 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
12751 &ArgChanged))
12752 return ExprError();
12754 if (!getDerived().AlwaysRebuild() &&
12755 Callee.get() == E->getCallee() &&
12756 !ArgChanged)
12757 return SemaRef.MaybeBindToTemporary(E);
12759 // FIXME: Wrong source location information for the '('.
12760 SourceLocation FakeLParenLoc
12761 = ((Expr *)Callee.get())->getSourceRange().getBegin();
12763 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12764 if (E->hasStoredFPFeatures()) {
12765 FPOptionsOverride NewOverrides = E->getFPFeatures();
12766 getSema().CurFPFeatures =
12767 NewOverrides.applyOverrides(getSema().getLangOpts());
12768 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12771 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
12772 Args,
12773 E->getRParenLoc());
12776 template<typename Derived>
12777 ExprResult
12778 TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
12779 ExprResult Base = getDerived().TransformExpr(E->getBase());
12780 if (Base.isInvalid())
12781 return ExprError();
12783 NestedNameSpecifierLoc QualifierLoc;
12784 if (E->hasQualifier()) {
12785 QualifierLoc
12786 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
12788 if (!QualifierLoc)
12789 return ExprError();
12791 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
12793 ValueDecl *Member
12794 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
12795 E->getMemberDecl()));
12796 if (!Member)
12797 return ExprError();
12799 NamedDecl *FoundDecl = E->getFoundDecl();
12800 if (FoundDecl == E->getMemberDecl()) {
12801 FoundDecl = Member;
12802 } else {
12803 FoundDecl = cast_or_null<NamedDecl>(
12804 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
12805 if (!FoundDecl)
12806 return ExprError();
12809 if (!getDerived().AlwaysRebuild() &&
12810 Base.get() == E->getBase() &&
12811 QualifierLoc == E->getQualifierLoc() &&
12812 Member == E->getMemberDecl() &&
12813 FoundDecl == E->getFoundDecl() &&
12814 !E->hasExplicitTemplateArgs()) {
12816 // Skip for member expression of (this->f), rebuilt thisi->f is needed
12817 // for Openmp where the field need to be privatizized in the case.
12818 if (!(isa<CXXThisExpr>(E->getBase()) &&
12819 getSema().OpenMP().isOpenMPRebuildMemberExpr(
12820 cast<ValueDecl>(Member)))) {
12821 // Mark it referenced in the new context regardless.
12822 // FIXME: this is a bit instantiation-specific.
12823 SemaRef.MarkMemberReferenced(E);
12824 return E;
12828 TemplateArgumentListInfo TransArgs;
12829 if (E->hasExplicitTemplateArgs()) {
12830 TransArgs.setLAngleLoc(E->getLAngleLoc());
12831 TransArgs.setRAngleLoc(E->getRAngleLoc());
12832 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
12833 E->getNumTemplateArgs(),
12834 TransArgs))
12835 return ExprError();
12838 // FIXME: Bogus source location for the operator
12839 SourceLocation FakeOperatorLoc =
12840 SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
12842 // FIXME: to do this check properly, we will need to preserve the
12843 // first-qualifier-in-scope here, just in case we had a dependent
12844 // base (and therefore couldn't do the check) and a
12845 // nested-name-qualifier (and therefore could do the lookup).
12846 NamedDecl *FirstQualifierInScope = nullptr;
12847 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
12848 if (MemberNameInfo.getName()) {
12849 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
12850 if (!MemberNameInfo.getName())
12851 return ExprError();
12854 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
12855 E->isArrow(),
12856 QualifierLoc,
12857 TemplateKWLoc,
12858 MemberNameInfo,
12859 Member,
12860 FoundDecl,
12861 (E->hasExplicitTemplateArgs()
12862 ? &TransArgs : nullptr),
12863 FirstQualifierInScope);
12866 template<typename Derived>
12867 ExprResult
12868 TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
12869 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12870 if (LHS.isInvalid())
12871 return ExprError();
12873 ExprResult RHS =
12874 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
12875 if (RHS.isInvalid())
12876 return ExprError();
12878 if (!getDerived().AlwaysRebuild() &&
12879 LHS.get() == E->getLHS() &&
12880 RHS.get() == E->getRHS())
12881 return E;
12883 if (E->isCompoundAssignmentOp())
12884 // FPFeatures has already been established from trailing storage
12885 return getDerived().RebuildBinaryOperator(
12886 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
12887 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12888 FPOptionsOverride NewOverrides(E->getFPFeatures());
12889 getSema().CurFPFeatures =
12890 NewOverrides.applyOverrides(getSema().getLangOpts());
12891 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12892 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
12893 LHS.get(), RHS.get());
12896 template <typename Derived>
12897 ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
12898 CXXRewrittenBinaryOperator *E) {
12899 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
12901 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
12902 if (LHS.isInvalid())
12903 return ExprError();
12905 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
12906 if (RHS.isInvalid())
12907 return ExprError();
12909 // Extract the already-resolved callee declarations so that we can restrict
12910 // ourselves to using them as the unqualified lookup results when rebuilding.
12911 UnresolvedSet<2> UnqualLookups;
12912 bool ChangedAnyLookups = false;
12913 Expr *PossibleBinOps[] = {E->getSemanticForm(),
12914 const_cast<Expr *>(Decomp.InnerBinOp)};
12915 for (Expr *PossibleBinOp : PossibleBinOps) {
12916 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());
12917 if (!Op)
12918 continue;
12919 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());
12920 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))
12921 continue;
12923 // Transform the callee in case we built a call to a local extern
12924 // declaration.
12925 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
12926 E->getOperatorLoc(), Callee->getFoundDecl()));
12927 if (!Found)
12928 return ExprError();
12929 if (Found != Callee->getFoundDecl())
12930 ChangedAnyLookups = true;
12931 UnqualLookups.addDecl(Found);
12934 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
12935 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
12936 // Mark all functions used in the rewrite as referenced. Note that when
12937 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
12938 // function calls, and/or there might be a user-defined conversion sequence
12939 // applied to the operands of the <.
12940 // FIXME: this is a bit instantiation-specific.
12941 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
12942 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);
12943 return E;
12946 return getDerived().RebuildCXXRewrittenBinaryOperator(
12947 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
12950 template<typename Derived>
12951 ExprResult
12952 TreeTransform<Derived>::TransformCompoundAssignOperator(
12953 CompoundAssignOperator *E) {
12954 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12955 FPOptionsOverride NewOverrides(E->getFPFeatures());
12956 getSema().CurFPFeatures =
12957 NewOverrides.applyOverrides(getSema().getLangOpts());
12958 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12959 return getDerived().TransformBinaryOperator(E);
12962 template<typename Derived>
12963 ExprResult TreeTransform<Derived>::
12964 TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
12965 // Just rebuild the common and RHS expressions and see whether we
12966 // get any changes.
12968 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
12969 if (commonExpr.isInvalid())
12970 return ExprError();
12972 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
12973 if (rhs.isInvalid())
12974 return ExprError();
12976 if (!getDerived().AlwaysRebuild() &&
12977 commonExpr.get() == e->getCommon() &&
12978 rhs.get() == e->getFalseExpr())
12979 return e;
12981 return getDerived().RebuildConditionalOperator(commonExpr.get(),
12982 e->getQuestionLoc(),
12983 nullptr,
12984 e->getColonLoc(),
12985 rhs.get());
12988 template<typename Derived>
12989 ExprResult
12990 TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
12991 ExprResult Cond = getDerived().TransformExpr(E->getCond());
12992 if (Cond.isInvalid())
12993 return ExprError();
12995 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12996 if (LHS.isInvalid())
12997 return ExprError();
12999 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13000 if (RHS.isInvalid())
13001 return ExprError();
13003 if (!getDerived().AlwaysRebuild() &&
13004 Cond.get() == E->getCond() &&
13005 LHS.get() == E->getLHS() &&
13006 RHS.get() == E->getRHS())
13007 return E;
13009 return getDerived().RebuildConditionalOperator(Cond.get(),
13010 E->getQuestionLoc(),
13011 LHS.get(),
13012 E->getColonLoc(),
13013 RHS.get());
13016 template<typename Derived>
13017 ExprResult
13018 TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
13019 // Implicit casts are eliminated during transformation, since they
13020 // will be recomputed by semantic analysis after transformation.
13021 return getDerived().TransformExpr(E->getSubExprAsWritten());
13024 template<typename Derived>
13025 ExprResult
13026 TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
13027 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13028 if (!Type)
13029 return ExprError();
13031 ExprResult SubExpr
13032 = getDerived().TransformExpr(E->getSubExprAsWritten());
13033 if (SubExpr.isInvalid())
13034 return ExprError();
13036 if (!getDerived().AlwaysRebuild() &&
13037 Type == E->getTypeInfoAsWritten() &&
13038 SubExpr.get() == E->getSubExpr())
13039 return E;
13041 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
13042 Type,
13043 E->getRParenLoc(),
13044 SubExpr.get());
13047 template<typename Derived>
13048 ExprResult
13049 TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
13050 TypeSourceInfo *OldT = E->getTypeSourceInfo();
13051 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13052 if (!NewT)
13053 return ExprError();
13055 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
13056 if (Init.isInvalid())
13057 return ExprError();
13059 if (!getDerived().AlwaysRebuild() &&
13060 OldT == NewT &&
13061 Init.get() == E->getInitializer())
13062 return SemaRef.MaybeBindToTemporary(E);
13064 // Note: the expression type doesn't necessarily match the
13065 // type-as-written, but that's okay, because it should always be
13066 // derivable from the initializer.
13068 return getDerived().RebuildCompoundLiteralExpr(
13069 E->getLParenLoc(), NewT,
13070 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
13073 template<typename Derived>
13074 ExprResult
13075 TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
13076 ExprResult Base = getDerived().TransformExpr(E->getBase());
13077 if (Base.isInvalid())
13078 return ExprError();
13080 if (!getDerived().AlwaysRebuild() &&
13081 Base.get() == E->getBase())
13082 return E;
13084 // FIXME: Bad source location
13085 SourceLocation FakeOperatorLoc =
13086 SemaRef.getLocForEndOfToken(E->getBase()->getEndLoc());
13087 return getDerived().RebuildExtVectorElementExpr(
13088 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
13089 E->getAccessor());
13092 template<typename Derived>
13093 ExprResult
13094 TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
13095 if (InitListExpr *Syntactic = E->getSyntacticForm())
13096 E = Syntactic;
13098 bool InitChanged = false;
13100 EnterExpressionEvaluationContext Context(
13101 getSema(), EnterExpressionEvaluationContext::InitList);
13103 SmallVector<Expr*, 4> Inits;
13104 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
13105 Inits, &InitChanged))
13106 return ExprError();
13108 if (!getDerived().AlwaysRebuild() && !InitChanged) {
13109 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
13110 // in some cases. We can't reuse it in general, because the syntactic and
13111 // semantic forms are linked, and we can't know that semantic form will
13112 // match even if the syntactic form does.
13115 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
13116 E->getRBraceLoc());
13119 template<typename Derived>
13120 ExprResult
13121 TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
13122 Designation Desig;
13124 // transform the initializer value
13125 ExprResult Init = getDerived().TransformExpr(E->getInit());
13126 if (Init.isInvalid())
13127 return ExprError();
13129 // transform the designators.
13130 SmallVector<Expr*, 4> ArrayExprs;
13131 bool ExprChanged = false;
13132 for (const DesignatedInitExpr::Designator &D : E->designators()) {
13133 if (D.isFieldDesignator()) {
13134 if (D.getFieldDecl()) {
13135 FieldDecl *Field = cast_or_null<FieldDecl>(
13136 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
13137 if (Field != D.getFieldDecl())
13138 // Rebuild the expression when the transformed FieldDecl is
13139 // different to the already assigned FieldDecl.
13140 ExprChanged = true;
13141 if (Field->isAnonymousStructOrUnion())
13142 continue;
13143 } else {
13144 // Ensure that the designator expression is rebuilt when there isn't
13145 // a resolved FieldDecl in the designator as we don't want to assign
13146 // a FieldDecl to a pattern designator that will be instantiated again.
13147 ExprChanged = true;
13149 Desig.AddDesignator(Designator::CreateFieldDesignator(
13150 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
13151 continue;
13154 if (D.isArrayDesignator()) {
13155 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
13156 if (Index.isInvalid())
13157 return ExprError();
13159 Desig.AddDesignator(
13160 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
13162 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
13163 ArrayExprs.push_back(Index.get());
13164 continue;
13167 assert(D.isArrayRangeDesignator() && "New kind of designator?");
13168 ExprResult Start
13169 = getDerived().TransformExpr(E->getArrayRangeStart(D));
13170 if (Start.isInvalid())
13171 return ExprError();
13173 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
13174 if (End.isInvalid())
13175 return ExprError();
13177 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
13178 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
13180 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
13181 End.get() != E->getArrayRangeEnd(D);
13183 ArrayExprs.push_back(Start.get());
13184 ArrayExprs.push_back(End.get());
13187 if (!getDerived().AlwaysRebuild() &&
13188 Init.get() == E->getInit() &&
13189 !ExprChanged)
13190 return E;
13192 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
13193 E->getEqualOrColonLoc(),
13194 E->usesGNUSyntax(), Init.get());
13197 // Seems that if TransformInitListExpr() only works on the syntactic form of an
13198 // InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
13199 template<typename Derived>
13200 ExprResult
13201 TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
13202 DesignatedInitUpdateExpr *E) {
13203 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
13204 "initializer");
13205 return ExprError();
13208 template<typename Derived>
13209 ExprResult
13210 TreeTransform<Derived>::TransformNoInitExpr(
13211 NoInitExpr *E) {
13212 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
13213 return ExprError();
13216 template<typename Derived>
13217 ExprResult
13218 TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
13219 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
13220 return ExprError();
13223 template<typename Derived>
13224 ExprResult
13225 TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
13226 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
13227 return ExprError();
13230 template<typename Derived>
13231 ExprResult
13232 TreeTransform<Derived>::TransformImplicitValueInitExpr(
13233 ImplicitValueInitExpr *E) {
13234 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
13236 // FIXME: Will we ever have proper type location here? Will we actually
13237 // need to transform the type?
13238 QualType T = getDerived().TransformType(E->getType());
13239 if (T.isNull())
13240 return ExprError();
13242 if (!getDerived().AlwaysRebuild() &&
13243 T == E->getType())
13244 return E;
13246 return getDerived().RebuildImplicitValueInitExpr(T);
13249 template<typename Derived>
13250 ExprResult
13251 TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
13252 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
13253 if (!TInfo)
13254 return ExprError();
13256 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13257 if (SubExpr.isInvalid())
13258 return ExprError();
13260 if (!getDerived().AlwaysRebuild() &&
13261 TInfo == E->getWrittenTypeInfo() &&
13262 SubExpr.get() == E->getSubExpr())
13263 return E;
13265 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
13266 TInfo, E->getRParenLoc());
13269 template<typename Derived>
13270 ExprResult
13271 TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
13272 bool ArgumentChanged = false;
13273 SmallVector<Expr*, 4> Inits;
13274 if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits,
13275 &ArgumentChanged))
13276 return ExprError();
13278 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
13279 Inits,
13280 E->getRParenLoc());
13283 /// Transform an address-of-label expression.
13285 /// By default, the transformation of an address-of-label expression always
13286 /// rebuilds the expression, so that the label identifier can be resolved to
13287 /// the corresponding label statement by semantic analysis.
13288 template<typename Derived>
13289 ExprResult
13290 TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
13291 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
13292 E->getLabel());
13293 if (!LD)
13294 return ExprError();
13296 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
13297 cast<LabelDecl>(LD));
13300 template<typename Derived>
13301 ExprResult
13302 TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
13303 SemaRef.ActOnStartStmtExpr();
13304 StmtResult SubStmt
13305 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
13306 if (SubStmt.isInvalid()) {
13307 SemaRef.ActOnStmtExprError();
13308 return ExprError();
13311 unsigned OldDepth = E->getTemplateDepth();
13312 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
13314 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
13315 SubStmt.get() == E->getSubStmt()) {
13316 // Calling this an 'error' is unintuitive, but it does the right thing.
13317 SemaRef.ActOnStmtExprError();
13318 return SemaRef.MaybeBindToTemporary(E);
13321 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
13322 E->getRParenLoc(), NewDepth);
13325 template<typename Derived>
13326 ExprResult
13327 TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
13328 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13329 if (Cond.isInvalid())
13330 return ExprError();
13332 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13333 if (LHS.isInvalid())
13334 return ExprError();
13336 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13337 if (RHS.isInvalid())
13338 return ExprError();
13340 if (!getDerived().AlwaysRebuild() &&
13341 Cond.get() == E->getCond() &&
13342 LHS.get() == E->getLHS() &&
13343 RHS.get() == E->getRHS())
13344 return E;
13346 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
13347 Cond.get(), LHS.get(), RHS.get(),
13348 E->getRParenLoc());
13351 template<typename Derived>
13352 ExprResult
13353 TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
13354 return E;
13357 template<typename Derived>
13358 ExprResult
13359 TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
13360 switch (E->getOperator()) {
13361 case OO_New:
13362 case OO_Delete:
13363 case OO_Array_New:
13364 case OO_Array_Delete:
13365 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
13367 case OO_Subscript:
13368 case OO_Call: {
13369 // This is a call to an object's operator().
13370 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
13372 // Transform the object itself.
13373 ExprResult Object = getDerived().TransformExpr(E->getArg(0));
13374 if (Object.isInvalid())
13375 return ExprError();
13377 // FIXME: Poor location information
13378 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
13379 static_cast<Expr *>(Object.get())->getEndLoc());
13381 // Transform the call arguments.
13382 SmallVector<Expr*, 8> Args;
13383 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
13384 Args))
13385 return ExprError();
13387 if (E->getOperator() == OO_Subscript)
13388 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
13389 Args, E->getEndLoc());
13391 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
13392 E->getEndLoc());
13395 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
13396 case OO_##Name: \
13397 break;
13399 #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
13400 #include "clang/Basic/OperatorKinds.def"
13402 case OO_Conditional:
13403 llvm_unreachable("conditional operator is not actually overloadable");
13405 case OO_None:
13406 case NUM_OVERLOADED_OPERATORS:
13407 llvm_unreachable("not an overloaded operator?");
13410 ExprResult First;
13411 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
13412 First = getDerived().TransformAddressOfOperand(E->getArg(0));
13413 else
13414 First = getDerived().TransformExpr(E->getArg(0));
13415 if (First.isInvalid())
13416 return ExprError();
13418 ExprResult Second;
13419 if (E->getNumArgs() == 2) {
13420 Second =
13421 getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);
13422 if (Second.isInvalid())
13423 return ExprError();
13426 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13427 FPOptionsOverride NewOverrides(E->getFPFeatures());
13428 getSema().CurFPFeatures =
13429 NewOverrides.applyOverrides(getSema().getLangOpts());
13430 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13432 Expr *Callee = E->getCallee();
13433 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
13434 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
13435 Sema::LookupOrdinaryName);
13436 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
13437 return ExprError();
13439 return getDerived().RebuildCXXOperatorCallExpr(
13440 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
13441 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
13444 UnresolvedSet<1> Functions;
13445 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
13446 Callee = ICE->getSubExprAsWritten();
13447 NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();
13448 ValueDecl *VD = cast_or_null<ValueDecl>(
13449 getDerived().TransformDecl(DR->getLocation(), DR));
13450 if (!VD)
13451 return ExprError();
13453 if (!isa<CXXMethodDecl>(VD))
13454 Functions.addDecl(VD);
13456 return getDerived().RebuildCXXOperatorCallExpr(
13457 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
13458 /*RequiresADL=*/false, Functions, First.get(), Second.get());
13461 template<typename Derived>
13462 ExprResult
13463 TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
13464 return getDerived().TransformCallExpr(E);
13467 template <typename Derived>
13468 ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
13469 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(E->getIdentKind()) &&
13470 getSema().CurContext != E->getParentContext();
13472 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
13473 return E;
13475 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
13476 E->getBeginLoc(), E->getEndLoc(),
13477 getSema().CurContext);
13480 template <typename Derived>
13481 ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
13482 return E;
13485 template<typename Derived>
13486 ExprResult
13487 TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
13488 // Transform the callee.
13489 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13490 if (Callee.isInvalid())
13491 return ExprError();
13493 // Transform exec config.
13494 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
13495 if (EC.isInvalid())
13496 return ExprError();
13498 // Transform arguments.
13499 bool ArgChanged = false;
13500 SmallVector<Expr*, 8> Args;
13501 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13502 &ArgChanged))
13503 return ExprError();
13505 if (!getDerived().AlwaysRebuild() &&
13506 Callee.get() == E->getCallee() &&
13507 !ArgChanged)
13508 return SemaRef.MaybeBindToTemporary(E);
13510 // FIXME: Wrong source location information for the '('.
13511 SourceLocation FakeLParenLoc
13512 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13513 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13514 Args,
13515 E->getRParenLoc(), EC.get());
13518 template<typename Derived>
13519 ExprResult
13520 TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
13521 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13522 if (!Type)
13523 return ExprError();
13525 ExprResult SubExpr
13526 = getDerived().TransformExpr(E->getSubExprAsWritten());
13527 if (SubExpr.isInvalid())
13528 return ExprError();
13530 if (!getDerived().AlwaysRebuild() &&
13531 Type == E->getTypeInfoAsWritten() &&
13532 SubExpr.get() == E->getSubExpr())
13533 return E;
13534 return getDerived().RebuildCXXNamedCastExpr(
13535 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
13536 Type, E->getAngleBrackets().getEnd(),
13537 // FIXME. this should be '(' location
13538 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
13541 template<typename Derived>
13542 ExprResult
13543 TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
13544 TypeSourceInfo *TSI =
13545 getDerived().TransformType(BCE->getTypeInfoAsWritten());
13546 if (!TSI)
13547 return ExprError();
13549 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
13550 if (Sub.isInvalid())
13551 return ExprError();
13553 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
13554 Sub.get(), BCE->getEndLoc());
13557 template<typename Derived>
13558 ExprResult
13559 TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
13560 return getDerived().TransformCXXNamedCastExpr(E);
13563 template<typename Derived>
13564 ExprResult
13565 TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
13566 return getDerived().TransformCXXNamedCastExpr(E);
13569 template<typename Derived>
13570 ExprResult
13571 TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
13572 CXXReinterpretCastExpr *E) {
13573 return getDerived().TransformCXXNamedCastExpr(E);
13576 template<typename Derived>
13577 ExprResult
13578 TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
13579 return getDerived().TransformCXXNamedCastExpr(E);
13582 template<typename Derived>
13583 ExprResult
13584 TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
13585 return getDerived().TransformCXXNamedCastExpr(E);
13588 template<typename Derived>
13589 ExprResult
13590 TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
13591 CXXFunctionalCastExpr *E) {
13592 TypeSourceInfo *Type =
13593 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
13594 if (!Type)
13595 return ExprError();
13597 ExprResult SubExpr
13598 = getDerived().TransformExpr(E->getSubExprAsWritten());
13599 if (SubExpr.isInvalid())
13600 return ExprError();
13602 if (!getDerived().AlwaysRebuild() &&
13603 Type == E->getTypeInfoAsWritten() &&
13604 SubExpr.get() == E->getSubExpr())
13605 return E;
13607 return getDerived().RebuildCXXFunctionalCastExpr(Type,
13608 E->getLParenLoc(),
13609 SubExpr.get(),
13610 E->getRParenLoc(),
13611 E->isListInitialization());
13614 template<typename Derived>
13615 ExprResult
13616 TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
13617 if (E->isTypeOperand()) {
13618 TypeSourceInfo *TInfo
13619 = getDerived().TransformType(E->getTypeOperandSourceInfo());
13620 if (!TInfo)
13621 return ExprError();
13623 if (!getDerived().AlwaysRebuild() &&
13624 TInfo == E->getTypeOperandSourceInfo())
13625 return E;
13627 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
13628 TInfo, E->getEndLoc());
13631 // Typeid's operand is an unevaluated context, unless it's a polymorphic
13632 // type. We must not unilaterally enter unevaluated context here, as then
13633 // semantic processing can re-transform an already transformed operand.
13634 Expr *Op = E->getExprOperand();
13635 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
13636 if (E->isGLValue())
13637 if (auto *RecordT = Op->getType()->getAs<RecordType>())
13638 if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
13639 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
13641 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
13642 Sema::ReuseLambdaContextDecl);
13644 ExprResult SubExpr = getDerived().TransformExpr(Op);
13645 if (SubExpr.isInvalid())
13646 return ExprError();
13648 if (!getDerived().AlwaysRebuild() &&
13649 SubExpr.get() == E->getExprOperand())
13650 return E;
13652 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
13653 SubExpr.get(), E->getEndLoc());
13656 template<typename Derived>
13657 ExprResult
13658 TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
13659 if (E->isTypeOperand()) {
13660 TypeSourceInfo *TInfo
13661 = getDerived().TransformType(E->getTypeOperandSourceInfo());
13662 if (!TInfo)
13663 return ExprError();
13665 if (!getDerived().AlwaysRebuild() &&
13666 TInfo == E->getTypeOperandSourceInfo())
13667 return E;
13669 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
13670 TInfo, E->getEndLoc());
13673 EnterExpressionEvaluationContext Unevaluated(
13674 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13676 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
13677 if (SubExpr.isInvalid())
13678 return ExprError();
13680 if (!getDerived().AlwaysRebuild() &&
13681 SubExpr.get() == E->getExprOperand())
13682 return E;
13684 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
13685 SubExpr.get(), E->getEndLoc());
13688 template<typename Derived>
13689 ExprResult
13690 TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
13691 return E;
13694 template<typename Derived>
13695 ExprResult
13696 TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
13697 CXXNullPtrLiteralExpr *E) {
13698 return E;
13701 template<typename Derived>
13702 ExprResult
13703 TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
13705 // In lambdas, the qualifiers of the type depends of where in
13706 // the call operator `this` appear, and we do not have a good way to
13707 // rebuild this information, so we transform the type.
13709 // In other contexts, the type of `this` may be overrided
13710 // for type deduction, so we need to recompute it.
13712 // Always recompute the type if we're in the body of a lambda, and
13713 // 'this' is dependent on a lambda's explicit object parameter.
13714 QualType T = [&]() {
13715 auto &S = getSema();
13716 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
13717 return S.getCurrentThisType();
13718 if (S.getCurLambda())
13719 return getDerived().TransformType(E->getType());
13720 return S.getCurrentThisType();
13721 }();
13723 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
13724 // Mark it referenced in the new context regardless.
13725 // FIXME: this is a bit instantiation-specific.
13726 getSema().MarkThisReferenced(E);
13727 return E;
13730 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
13733 template<typename Derived>
13734 ExprResult
13735 TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
13736 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13737 if (SubExpr.isInvalid())
13738 return ExprError();
13740 if (!getDerived().AlwaysRebuild() &&
13741 SubExpr.get() == E->getSubExpr())
13742 return E;
13744 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
13745 E->isThrownVariableInScope());
13748 template<typename Derived>
13749 ExprResult
13750 TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
13751 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
13752 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
13753 if (!Param)
13754 return ExprError();
13756 ExprResult InitRes;
13757 if (E->hasRewrittenInit()) {
13758 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
13759 if (InitRes.isInvalid())
13760 return ExprError();
13763 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
13764 E->getUsedContext() == SemaRef.CurContext &&
13765 InitRes.get() == E->getRewrittenExpr())
13766 return E;
13768 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
13769 InitRes.get());
13772 template<typename Derived>
13773 ExprResult
13774 TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
13775 FieldDecl *Field = cast_or_null<FieldDecl>(
13776 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
13777 if (!Field)
13778 return ExprError();
13780 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
13781 E->getUsedContext() == SemaRef.CurContext)
13782 return E;
13784 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
13787 template<typename Derived>
13788 ExprResult
13789 TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
13790 CXXScalarValueInitExpr *E) {
13791 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
13792 if (!T)
13793 return ExprError();
13795 if (!getDerived().AlwaysRebuild() &&
13796 T == E->getTypeSourceInfo())
13797 return E;
13799 return getDerived().RebuildCXXScalarValueInitExpr(T,
13800 /*FIXME:*/T->getTypeLoc().getEndLoc(),
13801 E->getRParenLoc());
13804 template<typename Derived>
13805 ExprResult
13806 TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
13807 // Transform the type that we're allocating
13808 TypeSourceInfo *AllocTypeInfo =
13809 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
13810 if (!AllocTypeInfo)
13811 return ExprError();
13813 // Transform the size of the array we're allocating (if any).
13814 std::optional<Expr *> ArraySize;
13815 if (E->isArray()) {
13816 ExprResult NewArraySize;
13817 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
13818 NewArraySize = getDerived().TransformExpr(*OldArraySize);
13819 if (NewArraySize.isInvalid())
13820 return ExprError();
13822 ArraySize = NewArraySize.get();
13825 // Transform the placement arguments (if any).
13826 bool ArgumentChanged = false;
13827 SmallVector<Expr*, 8> PlacementArgs;
13828 if (getDerived().TransformExprs(E->getPlacementArgs(),
13829 E->getNumPlacementArgs(), true,
13830 PlacementArgs, &ArgumentChanged))
13831 return ExprError();
13833 // Transform the initializer (if any).
13834 Expr *OldInit = E->getInitializer();
13835 ExprResult NewInit;
13836 if (OldInit)
13837 NewInit = getDerived().TransformInitializer(OldInit, true);
13838 if (NewInit.isInvalid())
13839 return ExprError();
13841 // Transform new operator and delete operator.
13842 FunctionDecl *OperatorNew = nullptr;
13843 if (E->getOperatorNew()) {
13844 OperatorNew = cast_or_null<FunctionDecl>(
13845 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
13846 if (!OperatorNew)
13847 return ExprError();
13850 FunctionDecl *OperatorDelete = nullptr;
13851 if (E->getOperatorDelete()) {
13852 OperatorDelete = cast_or_null<FunctionDecl>(
13853 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
13854 if (!OperatorDelete)
13855 return ExprError();
13858 if (!getDerived().AlwaysRebuild() &&
13859 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
13860 ArraySize == E->getArraySize() &&
13861 NewInit.get() == OldInit &&
13862 OperatorNew == E->getOperatorNew() &&
13863 OperatorDelete == E->getOperatorDelete() &&
13864 !ArgumentChanged) {
13865 // Mark any declarations we need as referenced.
13866 // FIXME: instantiation-specific.
13867 if (OperatorNew)
13868 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorNew);
13869 if (OperatorDelete)
13870 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
13872 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
13873 QualType ElementType
13874 = SemaRef.Context.getBaseElementType(E->getAllocatedType());
13875 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
13876 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
13877 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
13878 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor);
13883 return E;
13886 QualType AllocType = AllocTypeInfo->getType();
13887 if (!ArraySize) {
13888 // If no array size was specified, but the new expression was
13889 // instantiated with an array type (e.g., "new T" where T is
13890 // instantiated with "int[4]"), extract the outer bound from the
13891 // array type as our array size. We do this with constant and
13892 // dependently-sized array types.
13893 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);
13894 if (!ArrayT) {
13895 // Do nothing
13896 } else if (const ConstantArrayType *ConsArrayT
13897 = dyn_cast<ConstantArrayType>(ArrayT)) {
13898 ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),
13899 SemaRef.Context.getSizeType(),
13900 /*FIXME:*/ E->getBeginLoc());
13901 AllocType = ConsArrayT->getElementType();
13902 } else if (const DependentSizedArrayType *DepArrayT
13903 = dyn_cast<DependentSizedArrayType>(ArrayT)) {
13904 if (DepArrayT->getSizeExpr()) {
13905 ArraySize = DepArrayT->getSizeExpr();
13906 AllocType = DepArrayT->getElementType();
13911 return getDerived().RebuildCXXNewExpr(
13912 E->getBeginLoc(), E->isGlobalNew(),
13913 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
13914 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
13915 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
13918 template<typename Derived>
13919 ExprResult
13920 TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
13921 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
13922 if (Operand.isInvalid())
13923 return ExprError();
13925 // Transform the delete operator, if known.
13926 FunctionDecl *OperatorDelete = nullptr;
13927 if (E->getOperatorDelete()) {
13928 OperatorDelete = cast_or_null<FunctionDecl>(
13929 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
13930 if (!OperatorDelete)
13931 return ExprError();
13934 if (!getDerived().AlwaysRebuild() &&
13935 Operand.get() == E->getArgument() &&
13936 OperatorDelete == E->getOperatorDelete()) {
13937 // Mark any declarations we need as referenced.
13938 // FIXME: instantiation-specific.
13939 if (OperatorDelete)
13940 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
13942 if (!E->getArgument()->isTypeDependent()) {
13943 QualType Destroyed = SemaRef.Context.getBaseElementType(
13944 E->getDestroyedType());
13945 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
13946 CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
13947 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
13948 SemaRef.LookupDestructor(Record));
13952 return E;
13955 return getDerived().RebuildCXXDeleteExpr(
13956 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
13959 template<typename Derived>
13960 ExprResult
13961 TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
13962 CXXPseudoDestructorExpr *E) {
13963 ExprResult Base = getDerived().TransformExpr(E->getBase());
13964 if (Base.isInvalid())
13965 return ExprError();
13967 ParsedType ObjectTypePtr;
13968 bool MayBePseudoDestructor = false;
13969 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
13970 E->getOperatorLoc(),
13971 E->isArrow()? tok::arrow : tok::period,
13972 ObjectTypePtr,
13973 MayBePseudoDestructor);
13974 if (Base.isInvalid())
13975 return ExprError();
13977 QualType ObjectType = ObjectTypePtr.get();
13978 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
13979 if (QualifierLoc) {
13980 QualifierLoc
13981 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
13982 if (!QualifierLoc)
13983 return ExprError();
13985 CXXScopeSpec SS;
13986 SS.Adopt(QualifierLoc);
13988 PseudoDestructorTypeStorage Destroyed;
13989 if (E->getDestroyedTypeInfo()) {
13990 TypeSourceInfo *DestroyedTypeInfo
13991 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
13992 ObjectType, nullptr, SS);
13993 if (!DestroyedTypeInfo)
13994 return ExprError();
13995 Destroyed = DestroyedTypeInfo;
13996 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
13997 // We aren't likely to be able to resolve the identifier down to a type
13998 // now anyway, so just retain the identifier.
13999 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
14000 E->getDestroyedTypeLoc());
14001 } else {
14002 // Look for a destructor known with the given name.
14003 ParsedType T = SemaRef.getDestructorName(
14004 *E->getDestroyedTypeIdentifier(), E->getDestroyedTypeLoc(),
14005 /*Scope=*/nullptr, SS, ObjectTypePtr, false);
14006 if (!T)
14007 return ExprError();
14009 Destroyed
14010 = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),
14011 E->getDestroyedTypeLoc());
14014 TypeSourceInfo *ScopeTypeInfo = nullptr;
14015 if (E->getScopeTypeInfo()) {
14016 CXXScopeSpec EmptySS;
14017 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
14018 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
14019 if (!ScopeTypeInfo)
14020 return ExprError();
14023 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
14024 E->getOperatorLoc(),
14025 E->isArrow(),
14027 ScopeTypeInfo,
14028 E->getColonColonLoc(),
14029 E->getTildeLoc(),
14030 Destroyed);
14033 template <typename Derived>
14034 bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
14035 bool RequiresADL,
14036 LookupResult &R) {
14037 // Transform all the decls.
14038 bool AllEmptyPacks = true;
14039 for (auto *OldD : Old->decls()) {
14040 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
14041 if (!InstD) {
14042 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
14043 // This can happen because of dependent hiding.
14044 if (isa<UsingShadowDecl>(OldD))
14045 continue;
14046 else {
14047 R.clear();
14048 return true;
14052 // Expand using pack declarations.
14053 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
14054 ArrayRef<NamedDecl*> Decls = SingleDecl;
14055 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
14056 Decls = UPD->expansions();
14058 // Expand using declarations.
14059 for (auto *D : Decls) {
14060 if (auto *UD = dyn_cast<UsingDecl>(D)) {
14061 for (auto *SD : UD->shadows())
14062 R.addDecl(SD);
14063 } else {
14064 R.addDecl(D);
14068 AllEmptyPacks &= Decls.empty();
14071 // C++ [temp.res]/8.4.2:
14072 // The program is ill-formed, no diagnostic required, if [...] lookup for
14073 // a name in the template definition found a using-declaration, but the
14074 // lookup in the corresponding scope in the instantiation odoes not find
14075 // any declarations because the using-declaration was a pack expansion and
14076 // the corresponding pack is empty
14077 if (AllEmptyPacks && !RequiresADL) {
14078 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
14079 << isa<UnresolvedMemberExpr>(Old) << Old->getName();
14080 return true;
14083 // Resolve a kind, but don't do any further analysis. If it's
14084 // ambiguous, the callee needs to deal with it.
14085 R.resolveKind();
14087 if (Old->hasTemplateKeyword() && !R.empty()) {
14088 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
14089 getSema().FilterAcceptableTemplateNames(R,
14090 /*AllowFunctionTemplates=*/true,
14091 /*AllowDependent=*/true);
14092 if (R.empty()) {
14093 // If a 'template' keyword was used, a lookup that finds only non-template
14094 // names is an error.
14095 getSema().Diag(R.getNameLoc(),
14096 diag::err_template_kw_refers_to_non_template)
14097 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
14098 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
14099 getSema().Diag(FoundDecl->getLocation(),
14100 diag::note_template_kw_refers_to_non_template)
14101 << R.getLookupName();
14102 return true;
14106 return false;
14109 template <typename Derived>
14110 ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
14111 UnresolvedLookupExpr *Old) {
14112 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
14115 template <typename Derived>
14116 ExprResult
14117 TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
14118 bool IsAddressOfOperand) {
14119 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
14120 Sema::LookupOrdinaryName);
14122 // Transform the declaration set.
14123 if (TransformOverloadExprDecls(Old, Old->requiresADL(), R))
14124 return ExprError();
14126 // Rebuild the nested-name qualifier, if present.
14127 CXXScopeSpec SS;
14128 if (Old->getQualifierLoc()) {
14129 NestedNameSpecifierLoc QualifierLoc
14130 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
14131 if (!QualifierLoc)
14132 return ExprError();
14134 SS.Adopt(QualifierLoc);
14137 if (Old->getNamingClass()) {
14138 CXXRecordDecl *NamingClass
14139 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
14140 Old->getNameLoc(),
14141 Old->getNamingClass()));
14142 if (!NamingClass) {
14143 R.clear();
14144 return ExprError();
14147 R.setNamingClass(NamingClass);
14150 // Rebuild the template arguments, if any.
14151 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
14152 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
14153 if (Old->hasExplicitTemplateArgs() &&
14154 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14155 Old->getNumTemplateArgs(),
14156 TransArgs)) {
14157 R.clear();
14158 return ExprError();
14161 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
14162 // a non-static data member is named in an unevaluated operand, or when
14163 // a member is named in a dependent class scope function template explicit
14164 // specialization that is neither declared static nor with an explicit object
14165 // parameter.
14166 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
14167 return SemaRef.BuildPossibleImplicitMemberExpr(
14168 SS, TemplateKWLoc, R,
14169 Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
14170 /*S=*/nullptr);
14172 // If we have neither explicit template arguments, nor the template keyword,
14173 // it's a normal declaration name or member reference.
14174 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
14175 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
14177 // If we have template arguments, then rebuild the template-id expression.
14178 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
14179 Old->requiresADL(), &TransArgs);
14182 template<typename Derived>
14183 ExprResult
14184 TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
14185 bool ArgChanged = false;
14186 SmallVector<TypeSourceInfo *, 4> Args;
14187 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
14188 TypeSourceInfo *From = E->getArg(I);
14189 TypeLoc FromTL = From->getTypeLoc();
14190 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
14191 TypeLocBuilder TLB;
14192 TLB.reserve(FromTL.getFullDataSize());
14193 QualType To = getDerived().TransformType(TLB, FromTL);
14194 if (To.isNull())
14195 return ExprError();
14197 if (To == From->getType())
14198 Args.push_back(From);
14199 else {
14200 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14201 ArgChanged = true;
14203 continue;
14206 ArgChanged = true;
14208 // We have a pack expansion. Instantiate it.
14209 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
14210 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
14211 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14212 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
14214 // Determine whether the set of unexpanded parameter packs can and should
14215 // be expanded.
14216 bool Expand = true;
14217 bool RetainExpansion = false;
14218 std::optional<unsigned> OrigNumExpansions =
14219 ExpansionTL.getTypePtr()->getNumExpansions();
14220 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14221 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
14222 PatternTL.getSourceRange(),
14223 Unexpanded,
14224 Expand, RetainExpansion,
14225 NumExpansions))
14226 return ExprError();
14228 if (!Expand) {
14229 // The transform has determined that we should perform a simple
14230 // transformation on the pack expansion, producing another pack
14231 // expansion.
14232 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14234 TypeLocBuilder TLB;
14235 TLB.reserve(From->getTypeLoc().getFullDataSize());
14237 QualType To = getDerived().TransformType(TLB, PatternTL);
14238 if (To.isNull())
14239 return ExprError();
14241 To = getDerived().RebuildPackExpansionType(To,
14242 PatternTL.getSourceRange(),
14243 ExpansionTL.getEllipsisLoc(),
14244 NumExpansions);
14245 if (To.isNull())
14246 return ExprError();
14248 PackExpansionTypeLoc ToExpansionTL
14249 = TLB.push<PackExpansionTypeLoc>(To);
14250 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14251 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14252 continue;
14255 // Expand the pack expansion by substituting for each argument in the
14256 // pack(s).
14257 for (unsigned I = 0; I != *NumExpansions; ++I) {
14258 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
14259 TypeLocBuilder TLB;
14260 TLB.reserve(PatternTL.getFullDataSize());
14261 QualType To = getDerived().TransformType(TLB, PatternTL);
14262 if (To.isNull())
14263 return ExprError();
14265 if (To->containsUnexpandedParameterPack()) {
14266 To = getDerived().RebuildPackExpansionType(To,
14267 PatternTL.getSourceRange(),
14268 ExpansionTL.getEllipsisLoc(),
14269 NumExpansions);
14270 if (To.isNull())
14271 return ExprError();
14273 PackExpansionTypeLoc ToExpansionTL
14274 = TLB.push<PackExpansionTypeLoc>(To);
14275 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14278 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14281 if (!RetainExpansion)
14282 continue;
14284 // If we're supposed to retain a pack expansion, do so by temporarily
14285 // forgetting the partially-substituted parameter pack.
14286 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14288 TypeLocBuilder TLB;
14289 TLB.reserve(From->getTypeLoc().getFullDataSize());
14291 QualType To = getDerived().TransformType(TLB, PatternTL);
14292 if (To.isNull())
14293 return ExprError();
14295 To = getDerived().RebuildPackExpansionType(To,
14296 PatternTL.getSourceRange(),
14297 ExpansionTL.getEllipsisLoc(),
14298 NumExpansions);
14299 if (To.isNull())
14300 return ExprError();
14302 PackExpansionTypeLoc ToExpansionTL
14303 = TLB.push<PackExpansionTypeLoc>(To);
14304 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14305 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14308 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14309 return E;
14311 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
14312 E->getEndLoc());
14315 template<typename Derived>
14316 ExprResult
14317 TreeTransform<Derived>::TransformConceptSpecializationExpr(
14318 ConceptSpecializationExpr *E) {
14319 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
14320 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
14321 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14322 Old->NumTemplateArgs, TransArgs))
14323 return ExprError();
14325 return getDerived().RebuildConceptSpecializationExpr(
14326 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
14327 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
14328 &TransArgs);
14331 template<typename Derived>
14332 ExprResult
14333 TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
14334 SmallVector<ParmVarDecl*, 4> TransParams;
14335 SmallVector<QualType, 4> TransParamTypes;
14336 Sema::ExtParameterInfoBuilder ExtParamInfos;
14338 // C++2a [expr.prim.req]p2
14339 // Expressions appearing within a requirement-body are unevaluated operands.
14340 EnterExpressionEvaluationContext Ctx(
14341 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
14342 Sema::ReuseLambdaContextDecl);
14344 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
14345 getSema().Context, getSema().CurContext,
14346 E->getBody()->getBeginLoc());
14348 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
14350 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
14351 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
14352 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
14354 for (ParmVarDecl *Param : TransParams)
14355 if (Param)
14356 Param->setDeclContext(Body);
14358 // On failure to transform, TransformRequiresTypeParams returns an expression
14359 // in the event that the transformation of the type params failed in some way.
14360 // It is expected that this will result in a 'not satisfied' Requires clause
14361 // when instantiating.
14362 if (!TypeParamResult.isUnset())
14363 return TypeParamResult;
14365 SmallVector<concepts::Requirement *, 4> TransReqs;
14366 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
14367 TransReqs))
14368 return ExprError();
14370 for (concepts::Requirement *Req : TransReqs) {
14371 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
14372 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
14373 ER->getReturnTypeRequirement()
14374 .getTypeConstraintTemplateParameterList()->getParam(0)
14375 ->setDeclContext(Body);
14380 return getDerived().RebuildRequiresExpr(
14381 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
14382 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
14385 template<typename Derived>
14386 bool TreeTransform<Derived>::TransformRequiresExprRequirements(
14387 ArrayRef<concepts::Requirement *> Reqs,
14388 SmallVectorImpl<concepts::Requirement *> &Transformed) {
14389 for (concepts::Requirement *Req : Reqs) {
14390 concepts::Requirement *TransReq = nullptr;
14391 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
14392 TransReq = getDerived().TransformTypeRequirement(TypeReq);
14393 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
14394 TransReq = getDerived().TransformExprRequirement(ExprReq);
14395 else
14396 TransReq = getDerived().TransformNestedRequirement(
14397 cast<concepts::NestedRequirement>(Req));
14398 if (!TransReq)
14399 return true;
14400 Transformed.push_back(TransReq);
14402 return false;
14405 template<typename Derived>
14406 concepts::TypeRequirement *
14407 TreeTransform<Derived>::TransformTypeRequirement(
14408 concepts::TypeRequirement *Req) {
14409 if (Req->isSubstitutionFailure()) {
14410 if (getDerived().AlwaysRebuild())
14411 return getDerived().RebuildTypeRequirement(
14412 Req->getSubstitutionDiagnostic());
14413 return Req;
14415 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
14416 if (!TransType)
14417 return nullptr;
14418 return getDerived().RebuildTypeRequirement(TransType);
14421 template<typename Derived>
14422 concepts::ExprRequirement *
14423 TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
14424 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
14425 if (Req->isExprSubstitutionFailure())
14426 TransExpr = Req->getExprSubstitutionDiagnostic();
14427 else {
14428 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
14429 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
14430 TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
14431 if (TransExprRes.isInvalid())
14432 return nullptr;
14433 TransExpr = TransExprRes.get();
14436 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
14437 const auto &RetReq = Req->getReturnTypeRequirement();
14438 if (RetReq.isEmpty())
14439 TransRetReq.emplace();
14440 else if (RetReq.isSubstitutionFailure())
14441 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
14442 else if (RetReq.isTypeConstraint()) {
14443 TemplateParameterList *OrigTPL =
14444 RetReq.getTypeConstraintTemplateParameterList();
14445 TemplateParameterList *TPL =
14446 getDerived().TransformTemplateParameterList(OrigTPL);
14447 if (!TPL)
14448 return nullptr;
14449 TransRetReq.emplace(TPL);
14451 assert(TransRetReq && "All code paths leading here must set TransRetReq");
14452 if (Expr *E = TransExpr.dyn_cast<Expr *>())
14453 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
14454 Req->getNoexceptLoc(),
14455 std::move(*TransRetReq));
14456 return getDerived().RebuildExprRequirement(
14457 cast<concepts::Requirement::SubstitutionDiagnostic *>(TransExpr),
14458 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
14461 template<typename Derived>
14462 concepts::NestedRequirement *
14463 TreeTransform<Derived>::TransformNestedRequirement(
14464 concepts::NestedRequirement *Req) {
14465 if (Req->hasInvalidConstraint()) {
14466 if (getDerived().AlwaysRebuild())
14467 return getDerived().RebuildNestedRequirement(
14468 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
14469 return Req;
14471 ExprResult TransConstraint =
14472 getDerived().TransformExpr(Req->getConstraintExpr());
14473 if (TransConstraint.isInvalid())
14474 return nullptr;
14475 return getDerived().RebuildNestedRequirement(TransConstraint.get());
14478 template<typename Derived>
14479 ExprResult
14480 TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
14481 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
14482 if (!T)
14483 return ExprError();
14485 if (!getDerived().AlwaysRebuild() &&
14486 T == E->getQueriedTypeSourceInfo())
14487 return E;
14489 ExprResult SubExpr;
14491 EnterExpressionEvaluationContext Unevaluated(
14492 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14493 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
14494 if (SubExpr.isInvalid())
14495 return ExprError();
14497 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
14498 return E;
14501 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
14502 SubExpr.get(), E->getEndLoc());
14505 template<typename Derived>
14506 ExprResult
14507 TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
14508 ExprResult SubExpr;
14510 EnterExpressionEvaluationContext Unevaluated(
14511 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14512 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
14513 if (SubExpr.isInvalid())
14514 return ExprError();
14516 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
14517 return E;
14520 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
14521 SubExpr.get(), E->getEndLoc());
14524 template <typename Derived>
14525 ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
14526 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
14527 TypeSourceInfo **RecoveryTSI) {
14528 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
14529 DRE, AddrTaken, RecoveryTSI);
14531 // Propagate both errors and recovered types, which return ExprEmpty.
14532 if (!NewDRE.isUsable())
14533 return NewDRE;
14535 // We got an expr, wrap it up in parens.
14536 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
14537 return PE;
14538 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
14539 PE->getRParen());
14542 template <typename Derived>
14543 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
14544 DependentScopeDeclRefExpr *E) {
14545 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
14546 nullptr);
14549 template <typename Derived>
14550 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
14551 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
14552 TypeSourceInfo **RecoveryTSI) {
14553 assert(E->getQualifierLoc());
14554 NestedNameSpecifierLoc QualifierLoc =
14555 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
14556 if (!QualifierLoc)
14557 return ExprError();
14558 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
14560 // TODO: If this is a conversion-function-id, verify that the
14561 // destination type name (if present) resolves the same way after
14562 // instantiation as it did in the local scope.
14564 DeclarationNameInfo NameInfo =
14565 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
14566 if (!NameInfo.getName())
14567 return ExprError();
14569 if (!E->hasExplicitTemplateArgs()) {
14570 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
14571 // Note: it is sufficient to compare the Name component of NameInfo:
14572 // if name has not changed, DNLoc has not changed either.
14573 NameInfo.getName() == E->getDeclName())
14574 return E;
14576 return getDerived().RebuildDependentScopeDeclRefExpr(
14577 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
14578 IsAddressOfOperand, RecoveryTSI);
14581 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
14582 if (getDerived().TransformTemplateArguments(
14583 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
14584 return ExprError();
14586 return getDerived().RebuildDependentScopeDeclRefExpr(
14587 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
14588 RecoveryTSI);
14591 template<typename Derived>
14592 ExprResult
14593 TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
14594 // CXXConstructExprs other than for list-initialization and
14595 // CXXTemporaryObjectExpr are always implicit, so when we have
14596 // a 1-argument construction we just transform that argument.
14597 if (getDerived().AllowSkippingCXXConstructExpr() &&
14598 ((E->getNumArgs() == 1 ||
14599 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) &&
14600 (!getDerived().DropCallArgument(E->getArg(0))) &&
14601 !E->isListInitialization()))
14602 return getDerived().TransformInitializer(E->getArg(0),
14603 /*DirectInit*/ false);
14605 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
14607 QualType T = getDerived().TransformType(E->getType());
14608 if (T.isNull())
14609 return ExprError();
14611 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
14612 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
14613 if (!Constructor)
14614 return ExprError();
14616 bool ArgumentChanged = false;
14617 SmallVector<Expr*, 8> Args;
14619 EnterExpressionEvaluationContext Context(
14620 getSema(), EnterExpressionEvaluationContext::InitList,
14621 E->isListInitialization());
14622 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14623 &ArgumentChanged))
14624 return ExprError();
14627 if (!getDerived().AlwaysRebuild() &&
14628 T == E->getType() &&
14629 Constructor == E->getConstructor() &&
14630 !ArgumentChanged) {
14631 // Mark the constructor as referenced.
14632 // FIXME: Instantiation-specific
14633 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
14634 return E;
14637 return getDerived().RebuildCXXConstructExpr(
14638 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
14639 E->hadMultipleCandidates(), E->isListInitialization(),
14640 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
14641 E->getConstructionKind(), E->getParenOrBraceRange());
14644 template<typename Derived>
14645 ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
14646 CXXInheritedCtorInitExpr *E) {
14647 QualType T = getDerived().TransformType(E->getType());
14648 if (T.isNull())
14649 return ExprError();
14651 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
14652 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
14653 if (!Constructor)
14654 return ExprError();
14656 if (!getDerived().AlwaysRebuild() &&
14657 T == E->getType() &&
14658 Constructor == E->getConstructor()) {
14659 // Mark the constructor as referenced.
14660 // FIXME: Instantiation-specific
14661 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
14662 return E;
14665 return getDerived().RebuildCXXInheritedCtorInitExpr(
14666 T, E->getLocation(), Constructor,
14667 E->constructsVBase(), E->inheritedFromVBase());
14670 /// Transform a C++ temporary-binding expression.
14672 /// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
14673 /// transform the subexpression and return that.
14674 template<typename Derived>
14675 ExprResult
14676 TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
14677 if (auto *Dtor = E->getTemporary()->getDestructor())
14678 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
14679 const_cast<CXXDestructorDecl *>(Dtor));
14680 return getDerived().TransformExpr(E->getSubExpr());
14683 /// Transform a C++ expression that contains cleanups that should
14684 /// be run after the expression is evaluated.
14686 /// Since ExprWithCleanups nodes are implicitly generated, we
14687 /// just transform the subexpression and return that.
14688 template<typename Derived>
14689 ExprResult
14690 TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
14691 return getDerived().TransformExpr(E->getSubExpr());
14694 template<typename Derived>
14695 ExprResult
14696 TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
14697 CXXTemporaryObjectExpr *E) {
14698 TypeSourceInfo *T =
14699 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
14700 if (!T)
14701 return ExprError();
14703 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
14704 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
14705 if (!Constructor)
14706 return ExprError();
14708 bool ArgumentChanged = false;
14709 SmallVector<Expr*, 8> Args;
14710 Args.reserve(E->getNumArgs());
14712 EnterExpressionEvaluationContext Context(
14713 getSema(), EnterExpressionEvaluationContext::InitList,
14714 E->isListInitialization());
14715 if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14716 &ArgumentChanged))
14717 return ExprError();
14719 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
14720 ExprResult Res = RebuildInitList(E->getBeginLoc(), Args, E->getEndLoc());
14721 if (Res.isInvalid())
14722 return ExprError();
14723 Args = {Res.get()};
14727 if (!getDerived().AlwaysRebuild() &&
14728 T == E->getTypeSourceInfo() &&
14729 Constructor == E->getConstructor() &&
14730 !ArgumentChanged) {
14731 // FIXME: Instantiation-specific
14732 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
14733 return SemaRef.MaybeBindToTemporary(E);
14736 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
14737 return getDerived().RebuildCXXTemporaryObjectExpr(
14738 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
14741 template<typename Derived>
14742 ExprResult
14743 TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
14744 // Transform any init-capture expressions before entering the scope of the
14745 // lambda body, because they are not semantically within that scope.
14746 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
14747 struct TransformedInitCapture {
14748 // The location of the ... if the result is retaining a pack expansion.
14749 SourceLocation EllipsisLoc;
14750 // Zero or more expansions of the init-capture.
14751 SmallVector<InitCaptureInfoTy, 4> Expansions;
14753 SmallVector<TransformedInitCapture, 4> InitCaptures;
14754 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
14755 for (LambdaExpr::capture_iterator C = E->capture_begin(),
14756 CEnd = E->capture_end();
14757 C != CEnd; ++C) {
14758 if (!E->isInitCapture(C))
14759 continue;
14761 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
14762 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
14764 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
14765 std::optional<unsigned> NumExpansions) {
14766 ExprResult NewExprInitResult = getDerived().TransformInitializer(
14767 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
14769 if (NewExprInitResult.isInvalid()) {
14770 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
14771 return;
14773 Expr *NewExprInit = NewExprInitResult.get();
14775 QualType NewInitCaptureType =
14776 getSema().buildLambdaInitCaptureInitialization(
14777 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
14778 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
14779 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=
14780 VarDecl::CInit,
14781 NewExprInit);
14782 Result.Expansions.push_back(
14783 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
14786 // If this is an init-capture pack, consider expanding the pack now.
14787 if (OldVD->isParameterPack()) {
14788 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
14789 ->getTypeLoc()
14790 .castAs<PackExpansionTypeLoc>();
14791 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14792 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
14794 // Determine whether the set of unexpanded parameter packs can and should
14795 // be expanded.
14796 bool Expand = true;
14797 bool RetainExpansion = false;
14798 std::optional<unsigned> OrigNumExpansions =
14799 ExpansionTL.getTypePtr()->getNumExpansions();
14800 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14801 if (getDerived().TryExpandParameterPacks(
14802 ExpansionTL.getEllipsisLoc(),
14803 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
14804 RetainExpansion, NumExpansions))
14805 return ExprError();
14806 assert(!RetainExpansion && "Should not need to retain expansion after a "
14807 "capture since it cannot be extended");
14808 if (Expand) {
14809 for (unsigned I = 0; I != *NumExpansions; ++I) {
14810 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14811 SubstInitCapture(SourceLocation(), std::nullopt);
14813 } else {
14814 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
14815 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
14817 } else {
14818 SubstInitCapture(SourceLocation(), std::nullopt);
14822 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
14823 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
14825 // Create the local class that will describe the lambda.
14827 // FIXME: DependencyKind below is wrong when substituting inside a templated
14828 // context that isn't a DeclContext (such as a variable template), or when
14829 // substituting an unevaluated lambda inside of a function's parameter's type
14830 // - as parameter types are not instantiated from within a function's DC. We
14831 // use evaluation contexts to distinguish the function parameter case.
14832 CXXRecordDecl::LambdaDependencyKind DependencyKind =
14833 CXXRecordDecl::LDK_Unknown;
14834 DeclContext *DC = getSema().CurContext;
14835 // A RequiresExprBodyDecl is not interesting for dependencies.
14836 // For the following case,
14838 // template <typename>
14839 // concept C = requires { [] {}; };
14841 // template <class F>
14842 // struct Widget;
14844 // template <C F>
14845 // struct Widget<F> {};
14847 // While we are substituting Widget<F>, the parent of DC would be
14848 // the template specialization itself. Thus, the lambda expression
14849 // will be deemed as dependent even if there are no dependent template
14850 // arguments.
14851 // (A ClassTemplateSpecializationDecl is always a dependent context.)
14852 while (DC->isRequiresExprBody())
14853 DC = DC->getParent();
14854 if ((getSema().isUnevaluatedContext() ||
14855 getSema().isConstantEvaluatedContext()) &&
14856 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
14857 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
14859 CXXRecordDecl *OldClass = E->getLambdaClass();
14860 CXXRecordDecl *Class = getSema().createLambdaClosureType(
14861 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
14862 E->getCaptureDefault());
14863 getDerived().transformedLocalDecl(OldClass, {Class});
14865 CXXMethodDecl *NewCallOperator =
14866 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
14868 // Enter the scope of the lambda.
14869 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
14870 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
14871 E->hasExplicitParameters(), E->isMutable());
14873 // Introduce the context of the call operator.
14874 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
14875 /*NewThisContext*/false);
14877 bool Invalid = false;
14879 // Transform captures.
14880 for (LambdaExpr::capture_iterator C = E->capture_begin(),
14881 CEnd = E->capture_end();
14882 C != CEnd; ++C) {
14883 // When we hit the first implicit capture, tell Sema that we've finished
14884 // the list of explicit captures.
14885 if (C->isImplicit())
14886 break;
14888 // Capturing 'this' is trivial.
14889 if (C->capturesThis()) {
14890 // If this is a lambda that is part of a default member initialiser
14891 // and which we're instantiating outside the class that 'this' is
14892 // supposed to refer to, adjust the type of 'this' accordingly.
14894 // Otherwise, leave the type of 'this' as-is.
14895 Sema::CXXThisScopeRAII ThisScope(
14896 getSema(),
14897 dyn_cast_if_present<CXXRecordDecl>(
14898 getSema().getFunctionLevelDeclContext()),
14899 Qualifiers());
14900 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
14901 /*BuildAndDiagnose*/ true, nullptr,
14902 C->getCaptureKind() == LCK_StarThis);
14903 continue;
14905 // Captured expression will be recaptured during captured variables
14906 // rebuilding.
14907 if (C->capturesVLAType())
14908 continue;
14910 // Rebuild init-captures, including the implied field declaration.
14911 if (E->isInitCapture(C)) {
14912 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
14914 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
14915 llvm::SmallVector<Decl*, 4> NewVDs;
14917 for (InitCaptureInfoTy &Info : NewC.Expansions) {
14918 ExprResult Init = Info.first;
14919 QualType InitQualType = Info.second;
14920 if (Init.isInvalid() || InitQualType.isNull()) {
14921 Invalid = true;
14922 break;
14924 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
14925 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
14926 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
14927 getSema().CurContext);
14928 if (!NewVD) {
14929 Invalid = true;
14930 break;
14932 NewVDs.push_back(NewVD);
14933 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
14934 // Cases we want to tackle:
14935 // ([C(Pack)] {}, ...)
14936 // But rule out cases e.g.
14937 // [...C = Pack()] {}
14938 if (NewC.EllipsisLoc.isInvalid())
14939 LSI->ContainsUnexpandedParameterPack |=
14940 Init.get()->containsUnexpandedParameterPack();
14943 if (Invalid)
14944 break;
14946 getDerived().transformedLocalDecl(OldVD, NewVDs);
14947 continue;
14950 assert(C->capturesVariable() && "unexpected kind of lambda capture");
14952 // Determine the capture kind for Sema.
14953 Sema::TryCaptureKind Kind
14954 = C->isImplicit()? Sema::TryCapture_Implicit
14955 : C->getCaptureKind() == LCK_ByCopy
14956 ? Sema::TryCapture_ExplicitByVal
14957 : Sema::TryCapture_ExplicitByRef;
14958 SourceLocation EllipsisLoc;
14959 if (C->isPackExpansion()) {
14960 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
14961 bool ShouldExpand = false;
14962 bool RetainExpansion = false;
14963 std::optional<unsigned> NumExpansions;
14964 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
14965 C->getLocation(),
14966 Unexpanded,
14967 ShouldExpand, RetainExpansion,
14968 NumExpansions)) {
14969 Invalid = true;
14970 continue;
14973 if (ShouldExpand) {
14974 // The transform has determined that we should perform an expansion;
14975 // transform and capture each of the arguments.
14976 // expansion of the pattern. Do so.
14977 auto *Pack = cast<VarDecl>(C->getCapturedVar());
14978 for (unsigned I = 0; I != *NumExpansions; ++I) {
14979 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14980 VarDecl *CapturedVar
14981 = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
14982 Pack));
14983 if (!CapturedVar) {
14984 Invalid = true;
14985 continue;
14988 // Capture the transformed variable.
14989 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
14992 // FIXME: Retain a pack expansion if RetainExpansion is true.
14994 continue;
14997 EllipsisLoc = C->getEllipsisLoc();
15000 // Transform the captured variable.
15001 auto *CapturedVar = cast_or_null<ValueDecl>(
15002 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15003 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
15004 Invalid = true;
15005 continue;
15008 // This is not an init-capture; however it contains an unexpanded pack e.g.
15009 // ([Pack] {}(), ...)
15010 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
15011 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
15013 // Capture the transformed variable.
15014 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
15015 EllipsisLoc);
15017 getSema().finishLambdaExplicitCaptures(LSI);
15019 // Transform the template parameters, and add them to the current
15020 // instantiation scope. The null case is handled correctly.
15021 auto TPL = getDerived().TransformTemplateParameterList(
15022 E->getTemplateParameterList());
15023 LSI->GLTemplateParameterList = TPL;
15024 if (TPL) {
15025 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
15026 TPL);
15027 LSI->ContainsUnexpandedParameterPack |=
15028 TPL->containsUnexpandedParameterPack();
15031 TypeLocBuilder NewCallOpTLBuilder;
15032 TypeLoc OldCallOpTypeLoc =
15033 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
15034 QualType NewCallOpType =
15035 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
15036 if (NewCallOpType.isNull())
15037 return ExprError();
15038 LSI->ContainsUnexpandedParameterPack |=
15039 NewCallOpType->containsUnexpandedParameterPack();
15040 TypeSourceInfo *NewCallOpTSI =
15041 NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
15043 // The type may be an AttributedType or some other kind of sugar;
15044 // get the actual underlying FunctionProtoType.
15045 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
15046 assert(FPTL && "Not a FunctionProtoType?");
15048 getSema().CompleteLambdaCallOperator(
15049 NewCallOperator, E->getCallOperator()->getLocation(),
15050 E->getCallOperator()->getInnerLocStart(),
15051 E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
15052 E->getCallOperator()->getConstexprKind(),
15053 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
15054 E->hasExplicitResultType());
15056 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
15057 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
15060 // Number the lambda for linkage purposes if necessary.
15061 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
15063 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
15064 if (getDerived().ReplacingOriginal()) {
15065 Numbering = OldClass->getLambdaNumbering();
15068 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
15071 // FIXME: Sema's lambda-building mechanism expects us to push an expression
15072 // evaluation context even if we're not transforming the function body.
15073 getSema().PushExpressionEvaluationContext(
15074 E->getCallOperator()->isConsteval() ?
15075 Sema::ExpressionEvaluationContext::ImmediateFunctionContext :
15076 Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
15077 getSema().currentEvaluationContext().InImmediateEscalatingFunctionContext =
15078 getSema().getLangOpts().CPlusPlus20 &&
15079 E->getCallOperator()->isImmediateEscalating();
15081 Sema::CodeSynthesisContext C;
15082 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
15083 C.PointOfInstantiation = E->getBody()->getBeginLoc();
15084 getSema().pushCodeSynthesisContext(C);
15086 // Instantiate the body of the lambda expression.
15087 StmtResult Body =
15088 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
15090 getSema().popCodeSynthesisContext();
15092 // ActOnLambda* will pop the function scope for us.
15093 FuncScopeCleanup.disable();
15095 if (Body.isInvalid()) {
15096 SavedContext.pop();
15097 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
15098 /*IsInstantiation=*/true);
15099 return ExprError();
15102 // Copy the LSI before ActOnFinishFunctionBody removes it.
15103 // FIXME: This is dumb. Store the lambda information somewhere that outlives
15104 // the call operator.
15105 auto LSICopy = *LSI;
15106 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
15107 /*IsInstantiation*/ true);
15108 SavedContext.pop();
15110 // Recompute the dependency of the lambda so that we can defer the lambda call
15111 // construction until after we have all the necessary template arguments. For
15112 // example, given
15114 // template <class> struct S {
15115 // template <class U>
15116 // using Type = decltype([](U){}(42.0));
15117 // };
15118 // void foo() {
15119 // using T = S<int>::Type<float>;
15120 // ^~~~~~
15121 // }
15123 // We would end up here from instantiating S<int> when ensuring its
15124 // completeness. That would transform the lambda call expression regardless of
15125 // the absence of the corresponding argument for U.
15127 // Going ahead with unsubstituted type U makes things worse: we would soon
15128 // compare the argument type (which is float) against the parameter U
15129 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
15130 // error suggesting unmatched types 'U' and 'float'!
15132 // That said, everything will be fine if we defer that semantic checking.
15133 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
15134 // dependent. Since the CallExpr's dependency boils down to the lambda's
15135 // dependency in this case, we can harness that by recomputing the dependency
15136 // from the instantiation arguments.
15138 // FIXME: Creating the type of a lambda requires us to have a dependency
15139 // value, which happens before its substitution. We update its dependency
15140 // *after* the substitution in case we can't decide the dependency
15141 // so early, e.g. because we want to see if any of the *substituted*
15142 // parameters are dependent.
15143 DependencyKind = getDerived().ComputeLambdaDependency(&LSICopy);
15144 Class->setLambdaDependencyKind(DependencyKind);
15145 // Clean up the type cache created previously. Then, we re-create a type for
15146 // such Decl with the new DependencyKind.
15147 Class->setTypeForDecl(nullptr);
15148 getSema().Context.getTypeDeclType(Class);
15150 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
15151 Body.get()->getEndLoc(), &LSICopy);
15154 template<typename Derived>
15155 StmtResult
15156 TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
15157 return TransformStmt(S);
15160 template<typename Derived>
15161 StmtResult
15162 TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
15163 // Transform captures.
15164 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15165 CEnd = E->capture_end();
15166 C != CEnd; ++C) {
15167 // When we hit the first implicit capture, tell Sema that we've finished
15168 // the list of explicit captures.
15169 if (!C->isImplicit())
15170 continue;
15172 // Capturing 'this' is trivial.
15173 if (C->capturesThis()) {
15174 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15175 /*BuildAndDiagnose*/ true, nullptr,
15176 C->getCaptureKind() == LCK_StarThis);
15177 continue;
15179 // Captured expression will be recaptured during captured variables
15180 // rebuilding.
15181 if (C->capturesVLAType())
15182 continue;
15184 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15185 assert(!E->isInitCapture(C) && "implicit init-capture?");
15187 // Transform the captured variable.
15188 VarDecl *CapturedVar = cast_or_null<VarDecl>(
15189 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15190 if (!CapturedVar || CapturedVar->isInvalidDecl())
15191 return StmtError();
15193 // Capture the transformed variable.
15194 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
15197 return S;
15200 template<typename Derived>
15201 ExprResult
15202 TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
15203 CXXUnresolvedConstructExpr *E) {
15204 TypeSourceInfo *T =
15205 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15206 if (!T)
15207 return ExprError();
15209 bool ArgumentChanged = false;
15210 SmallVector<Expr*, 8> Args;
15211 Args.reserve(E->getNumArgs());
15213 EnterExpressionEvaluationContext Context(
15214 getSema(), EnterExpressionEvaluationContext::InitList,
15215 E->isListInitialization());
15216 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
15217 &ArgumentChanged))
15218 return ExprError();
15221 if (!getDerived().AlwaysRebuild() &&
15222 T == E->getTypeSourceInfo() &&
15223 !ArgumentChanged)
15224 return E;
15226 // FIXME: we're faking the locations of the commas
15227 return getDerived().RebuildCXXUnresolvedConstructExpr(
15228 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
15231 template<typename Derived>
15232 ExprResult
15233 TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
15234 CXXDependentScopeMemberExpr *E) {
15235 // Transform the base of the expression.
15236 ExprResult Base((Expr*) nullptr);
15237 Expr *OldBase;
15238 QualType BaseType;
15239 QualType ObjectType;
15240 if (!E->isImplicitAccess()) {
15241 OldBase = E->getBase();
15242 Base = getDerived().TransformExpr(OldBase);
15243 if (Base.isInvalid())
15244 return ExprError();
15246 // Start the member reference and compute the object's type.
15247 ParsedType ObjectTy;
15248 bool MayBePseudoDestructor = false;
15249 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
15250 E->getOperatorLoc(),
15251 E->isArrow()? tok::arrow : tok::period,
15252 ObjectTy,
15253 MayBePseudoDestructor);
15254 if (Base.isInvalid())
15255 return ExprError();
15257 ObjectType = ObjectTy.get();
15258 BaseType = ((Expr*) Base.get())->getType();
15259 } else {
15260 OldBase = nullptr;
15261 BaseType = getDerived().TransformType(E->getBaseType());
15262 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
15265 // Transform the first part of the nested-name-specifier that qualifies
15266 // the member name.
15267 NamedDecl *FirstQualifierInScope
15268 = getDerived().TransformFirstQualifierInScope(
15269 E->getFirstQualifierFoundInScope(),
15270 E->getQualifierLoc().getBeginLoc());
15272 NestedNameSpecifierLoc QualifierLoc;
15273 if (E->getQualifier()) {
15274 QualifierLoc
15275 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
15276 ObjectType,
15277 FirstQualifierInScope);
15278 if (!QualifierLoc)
15279 return ExprError();
15282 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15284 // TODO: If this is a conversion-function-id, verify that the
15285 // destination type name (if present) resolves the same way after
15286 // instantiation as it did in the local scope.
15288 DeclarationNameInfo NameInfo
15289 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
15290 if (!NameInfo.getName())
15291 return ExprError();
15293 if (!E->hasExplicitTemplateArgs()) {
15294 // This is a reference to a member without an explicitly-specified
15295 // template argument list. Optimize for this common case.
15296 if (!getDerived().AlwaysRebuild() &&
15297 Base.get() == OldBase &&
15298 BaseType == E->getBaseType() &&
15299 QualifierLoc == E->getQualifierLoc() &&
15300 NameInfo.getName() == E->getMember() &&
15301 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
15302 return E;
15304 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15305 BaseType,
15306 E->isArrow(),
15307 E->getOperatorLoc(),
15308 QualifierLoc,
15309 TemplateKWLoc,
15310 FirstQualifierInScope,
15311 NameInfo,
15312 /*TemplateArgs*/nullptr);
15315 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15316 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
15317 E->getNumTemplateArgs(),
15318 TransArgs))
15319 return ExprError();
15321 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15322 BaseType,
15323 E->isArrow(),
15324 E->getOperatorLoc(),
15325 QualifierLoc,
15326 TemplateKWLoc,
15327 FirstQualifierInScope,
15328 NameInfo,
15329 &TransArgs);
15332 template <typename Derived>
15333 ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
15334 UnresolvedMemberExpr *Old) {
15335 // Transform the base of the expression.
15336 ExprResult Base((Expr *)nullptr);
15337 QualType BaseType;
15338 if (!Old->isImplicitAccess()) {
15339 Base = getDerived().TransformExpr(Old->getBase());
15340 if (Base.isInvalid())
15341 return ExprError();
15342 Base =
15343 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
15344 if (Base.isInvalid())
15345 return ExprError();
15346 BaseType = Base.get()->getType();
15347 } else {
15348 BaseType = getDerived().TransformType(Old->getBaseType());
15351 NestedNameSpecifierLoc QualifierLoc;
15352 if (Old->getQualifierLoc()) {
15353 QualifierLoc =
15354 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
15355 if (!QualifierLoc)
15356 return ExprError();
15359 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
15361 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
15363 // Transform the declaration set.
15364 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ false, R))
15365 return ExprError();
15367 // Determine the naming class.
15368 if (Old->getNamingClass()) {
15369 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
15370 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
15371 if (!NamingClass)
15372 return ExprError();
15374 R.setNamingClass(NamingClass);
15377 TemplateArgumentListInfo TransArgs;
15378 if (Old->hasExplicitTemplateArgs()) {
15379 TransArgs.setLAngleLoc(Old->getLAngleLoc());
15380 TransArgs.setRAngleLoc(Old->getRAngleLoc());
15381 if (getDerived().TransformTemplateArguments(
15382 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
15383 return ExprError();
15386 // FIXME: to do this check properly, we will need to preserve the
15387 // first-qualifier-in-scope here, just in case we had a dependent
15388 // base (and therefore couldn't do the check) and a
15389 // nested-name-qualifier (and therefore could do the lookup).
15390 NamedDecl *FirstQualifierInScope = nullptr;
15392 return getDerived().RebuildUnresolvedMemberExpr(
15393 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
15394 TemplateKWLoc, FirstQualifierInScope, R,
15395 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
15398 template<typename Derived>
15399 ExprResult
15400 TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
15401 EnterExpressionEvaluationContext Unevaluated(
15402 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15403 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
15404 if (SubExpr.isInvalid())
15405 return ExprError();
15407 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
15408 return E;
15410 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
15413 template<typename Derived>
15414 ExprResult
15415 TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
15416 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
15417 if (Pattern.isInvalid())
15418 return ExprError();
15420 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
15421 return E;
15423 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
15424 E->getNumExpansions());
15427 template<typename Derived>
15428 ExprResult
15429 TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
15430 // If E is not value-dependent, then nothing will change when we transform it.
15431 // Note: This is an instantiation-centric view.
15432 if (!E->isValueDependent())
15433 return E;
15435 EnterExpressionEvaluationContext Unevaluated(
15436 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
15438 ArrayRef<TemplateArgument> PackArgs;
15439 TemplateArgument ArgStorage;
15441 // Find the argument list to transform.
15442 if (E->isPartiallySubstituted()) {
15443 PackArgs = E->getPartialArguments();
15444 } else if (E->isValueDependent()) {
15445 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
15446 bool ShouldExpand = false;
15447 bool RetainExpansion = false;
15448 std::optional<unsigned> NumExpansions;
15449 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
15450 Unexpanded,
15451 ShouldExpand, RetainExpansion,
15452 NumExpansions))
15453 return ExprError();
15455 // If we need to expand the pack, build a template argument from it and
15456 // expand that.
15457 if (ShouldExpand) {
15458 auto *Pack = E->getPack();
15459 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) {
15460 ArgStorage = getSema().Context.getPackExpansionType(
15461 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
15462 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {
15463 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
15464 } else {
15465 auto *VD = cast<ValueDecl>(Pack);
15466 ExprResult DRE = getSema().BuildDeclRefExpr(
15467 VD, VD->getType().getNonLValueExprType(getSema().Context),
15468 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
15469 E->getPackLoc());
15470 if (DRE.isInvalid())
15471 return ExprError();
15472 ArgStorage = new (getSema().Context)
15473 PackExpansionExpr(getSema().Context.DependentTy, DRE.get(),
15474 E->getPackLoc(), std::nullopt);
15476 PackArgs = ArgStorage;
15480 // If we're not expanding the pack, just transform the decl.
15481 if (!PackArgs.size()) {
15482 auto *Pack = cast_or_null<NamedDecl>(
15483 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
15484 if (!Pack)
15485 return ExprError();
15486 return getDerived().RebuildSizeOfPackExpr(
15487 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
15488 std::nullopt, {});
15491 // Try to compute the result without performing a partial substitution.
15492 std::optional<unsigned> Result = 0;
15493 for (const TemplateArgument &Arg : PackArgs) {
15494 if (!Arg.isPackExpansion()) {
15495 Result = *Result + 1;
15496 continue;
15499 TemplateArgumentLoc ArgLoc;
15500 InventTemplateArgumentLoc(Arg, ArgLoc);
15502 // Find the pattern of the pack expansion.
15503 SourceLocation Ellipsis;
15504 std::optional<unsigned> OrigNumExpansions;
15505 TemplateArgumentLoc Pattern =
15506 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
15507 OrigNumExpansions);
15509 // Substitute under the pack expansion. Do not expand the pack (yet).
15510 TemplateArgumentLoc OutPattern;
15511 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15512 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
15513 /*Uneval*/ true))
15514 return true;
15516 // See if we can determine the number of arguments from the result.
15517 std::optional<unsigned> NumExpansions =
15518 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
15519 if (!NumExpansions) {
15520 // No: we must be in an alias template expansion, and we're going to need
15521 // to actually expand the packs.
15522 Result = std::nullopt;
15523 break;
15526 Result = *Result + *NumExpansions;
15529 // Common case: we could determine the number of expansions without
15530 // substituting.
15531 if (Result)
15532 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
15533 E->getPackLoc(),
15534 E->getRParenLoc(), *Result, {});
15536 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
15537 E->getPackLoc());
15539 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
15540 typedef TemplateArgumentLocInventIterator<
15541 Derived, const TemplateArgument*> PackLocIterator;
15542 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
15543 PackLocIterator(*this, PackArgs.end()),
15544 TransformedPackArgs, /*Uneval*/true))
15545 return ExprError();
15548 // Check whether we managed to fully-expand the pack.
15549 // FIXME: Is it possible for us to do so and not hit the early exit path?
15550 SmallVector<TemplateArgument, 8> Args;
15551 bool PartialSubstitution = false;
15552 for (auto &Loc : TransformedPackArgs.arguments()) {
15553 Args.push_back(Loc.getArgument());
15554 if (Loc.getArgument().isPackExpansion())
15555 PartialSubstitution = true;
15558 if (PartialSubstitution)
15559 return getDerived().RebuildSizeOfPackExpr(
15560 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
15561 std::nullopt, Args);
15563 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
15564 E->getPackLoc(), E->getRParenLoc(),
15565 Args.size(), {});
15568 template <typename Derived>
15569 ExprResult
15570 TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
15571 if (!E->isValueDependent())
15572 return E;
15574 // Transform the index
15575 ExprResult IndexExpr;
15577 EnterExpressionEvaluationContext ConstantContext(
15578 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
15579 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
15580 if (IndexExpr.isInvalid())
15581 return ExprError();
15584 SmallVector<Expr *, 5> ExpandedExprs;
15585 bool FullySubstituted = true;
15586 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
15587 Expr *Pattern = E->getPackIdExpression();
15588 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15589 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
15590 Unexpanded);
15591 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
15593 // Determine whether the set of unexpanded parameter packs can and should
15594 // be expanded.
15595 bool ShouldExpand = true;
15596 bool RetainExpansion = false;
15597 std::optional<unsigned> OrigNumExpansions;
15598 std::optional<unsigned> NumExpansions = OrigNumExpansions;
15599 if (getDerived().TryExpandParameterPacks(
15600 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
15601 ShouldExpand, RetainExpansion, NumExpansions))
15602 return true;
15603 if (!ShouldExpand) {
15604 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15605 ExprResult Pack = getDerived().TransformExpr(Pattern);
15606 if (Pack.isInvalid())
15607 return ExprError();
15608 return getDerived().RebuildPackIndexingExpr(
15609 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
15610 {}, /*FullySubstituted=*/false);
15612 for (unsigned I = 0; I != *NumExpansions; ++I) {
15613 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
15614 ExprResult Out = getDerived().TransformExpr(Pattern);
15615 if (Out.isInvalid())
15616 return true;
15617 if (Out.get()->containsUnexpandedParameterPack()) {
15618 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
15619 OrigNumExpansions);
15620 if (Out.isInvalid())
15621 return true;
15622 FullySubstituted = false;
15624 ExpandedExprs.push_back(Out.get());
15626 // If we're supposed to retain a pack expansion, do so by temporarily
15627 // forgetting the partially-substituted parameter pack.
15628 if (RetainExpansion) {
15629 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15631 ExprResult Out = getDerived().TransformExpr(Pattern);
15632 if (Out.isInvalid())
15633 return true;
15635 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
15636 OrigNumExpansions);
15637 if (Out.isInvalid())
15638 return true;
15639 FullySubstituted = false;
15640 ExpandedExprs.push_back(Out.get());
15642 } else if (!E->expandsToEmptyPack()) {
15643 if (getDerived().TransformExprs(E->getExpressions().data(),
15644 E->getExpressions().size(), false,
15645 ExpandedExprs))
15646 return ExprError();
15649 return getDerived().RebuildPackIndexingExpr(
15650 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
15651 IndexExpr.get(), ExpandedExprs, FullySubstituted);
15654 template<typename Derived>
15655 ExprResult
15656 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
15657 SubstNonTypeTemplateParmPackExpr *E) {
15658 // Default behavior is to do nothing with this transformation.
15659 return E;
15662 template<typename Derived>
15663 ExprResult
15664 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
15665 SubstNonTypeTemplateParmExpr *E) {
15666 // Default behavior is to do nothing with this transformation.
15667 return E;
15670 template<typename Derived>
15671 ExprResult
15672 TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
15673 // Default behavior is to do nothing with this transformation.
15674 return E;
15677 template<typename Derived>
15678 ExprResult
15679 TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
15680 MaterializeTemporaryExpr *E) {
15681 return getDerived().TransformExpr(E->getSubExpr());
15684 template<typename Derived>
15685 ExprResult
15686 TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
15687 UnresolvedLookupExpr *Callee = nullptr;
15688 if (Expr *OldCallee = E->getCallee()) {
15689 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
15690 if (CalleeResult.isInvalid())
15691 return ExprError();
15692 Callee = cast<UnresolvedLookupExpr>(CalleeResult.get());
15695 Expr *Pattern = E->getPattern();
15697 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15698 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
15699 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
15701 // Determine whether the set of unexpanded parameter packs can and should
15702 // be expanded.
15703 bool Expand = true;
15704 bool RetainExpansion = false;
15705 std::optional<unsigned> OrigNumExpansions = E->getNumExpansions(),
15706 NumExpansions = OrigNumExpansions;
15707 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
15708 Pattern->getSourceRange(),
15709 Unexpanded,
15710 Expand, RetainExpansion,
15711 NumExpansions))
15712 return true;
15714 if (!Expand) {
15715 // Do not expand any packs here, just transform and rebuild a fold
15716 // expression.
15717 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15719 ExprResult LHS =
15720 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
15721 if (LHS.isInvalid())
15722 return true;
15724 ExprResult RHS =
15725 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
15726 if (RHS.isInvalid())
15727 return true;
15729 if (!getDerived().AlwaysRebuild() &&
15730 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
15731 return E;
15733 return getDerived().RebuildCXXFoldExpr(
15734 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
15735 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
15738 // Formally a fold expression expands to nested parenthesized expressions.
15739 // Enforce this limit to avoid creating trees so deep we can't safely traverse
15740 // them.
15741 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) {
15742 SemaRef.Diag(E->getEllipsisLoc(),
15743 clang::diag::err_fold_expression_limit_exceeded)
15744 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
15745 << E->getSourceRange();
15746 SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);
15747 return ExprError();
15750 // The transform has determined that we should perform an elementwise
15751 // expansion of the pattern. Do so.
15752 ExprResult Result = getDerived().TransformExpr(E->getInit());
15753 if (Result.isInvalid())
15754 return true;
15755 bool LeftFold = E->isLeftFold();
15757 // If we're retaining an expansion for a right fold, it is the innermost
15758 // component and takes the init (if any).
15759 if (!LeftFold && RetainExpansion) {
15760 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15762 ExprResult Out = getDerived().TransformExpr(Pattern);
15763 if (Out.isInvalid())
15764 return true;
15766 Result = getDerived().RebuildCXXFoldExpr(
15767 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
15768 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
15769 if (Result.isInvalid())
15770 return true;
15773 for (unsigned I = 0; I != *NumExpansions; ++I) {
15774 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(
15775 getSema(), LeftFold ? I : *NumExpansions - I - 1);
15776 ExprResult Out = getDerived().TransformExpr(Pattern);
15777 if (Out.isInvalid())
15778 return true;
15780 if (Out.get()->containsUnexpandedParameterPack()) {
15781 // We still have a pack; retain a pack expansion for this slice.
15782 Result = getDerived().RebuildCXXFoldExpr(
15783 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
15784 E->getOperator(), E->getEllipsisLoc(),
15785 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
15786 OrigNumExpansions);
15787 } else if (Result.isUsable()) {
15788 // We've got down to a single element; build a binary operator.
15789 Expr *LHS = LeftFold ? Result.get() : Out.get();
15790 Expr *RHS = LeftFold ? Out.get() : Result.get();
15791 if (Callee) {
15792 UnresolvedSet<16> Functions;
15793 Functions.append(Callee->decls_begin(), Callee->decls_end());
15794 Result = getDerived().RebuildCXXOperatorCallExpr(
15795 BinaryOperator::getOverloadedOperator(E->getOperator()),
15796 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
15797 Functions, LHS, RHS);
15798 } else {
15799 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
15800 E->getOperator(), LHS, RHS);
15802 } else
15803 Result = Out;
15805 if (Result.isInvalid())
15806 return true;
15809 // If we're retaining an expansion for a left fold, it is the outermost
15810 // component and takes the complete expansion so far as its init (if any).
15811 if (LeftFold && RetainExpansion) {
15812 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15814 ExprResult Out = getDerived().TransformExpr(Pattern);
15815 if (Out.isInvalid())
15816 return true;
15818 Result = getDerived().RebuildCXXFoldExpr(
15819 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
15820 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
15821 if (Result.isInvalid())
15822 return true;
15825 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Result.get()))
15826 PE->setIsProducedByFoldExpansion();
15828 // If we had no init and an empty pack, and we're not retaining an expansion,
15829 // then produce a fallback value or error.
15830 if (Result.isUnset())
15831 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
15832 E->getOperator());
15833 return Result;
15836 template <typename Derived>
15837 ExprResult
15838 TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
15839 SmallVector<Expr *, 4> TransformedInits;
15840 ArrayRef<Expr *> InitExprs = E->getInitExprs();
15841 if (TransformExprs(InitExprs.data(), InitExprs.size(), true,
15842 TransformedInits))
15843 return ExprError();
15845 return getDerived().RebuildParenListExpr(E->getBeginLoc(), TransformedInits,
15846 E->getEndLoc());
15849 template<typename Derived>
15850 ExprResult
15851 TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
15852 CXXStdInitializerListExpr *E) {
15853 return getDerived().TransformExpr(E->getSubExpr());
15856 template<typename Derived>
15857 ExprResult
15858 TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
15859 return SemaRef.MaybeBindToTemporary(E);
15862 template<typename Derived>
15863 ExprResult
15864 TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
15865 return E;
15868 template<typename Derived>
15869 ExprResult
15870 TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
15871 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
15872 if (SubExpr.isInvalid())
15873 return ExprError();
15875 if (!getDerived().AlwaysRebuild() &&
15876 SubExpr.get() == E->getSubExpr())
15877 return E;
15879 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
15882 template<typename Derived>
15883 ExprResult
15884 TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
15885 // Transform each of the elements.
15886 SmallVector<Expr *, 8> Elements;
15887 bool ArgChanged = false;
15888 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
15889 /*IsCall=*/false, Elements, &ArgChanged))
15890 return ExprError();
15892 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15893 return SemaRef.MaybeBindToTemporary(E);
15895 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
15896 Elements.data(),
15897 Elements.size());
15900 template<typename Derived>
15901 ExprResult
15902 TreeTransform<Derived>::TransformObjCDictionaryLiteral(
15903 ObjCDictionaryLiteral *E) {
15904 // Transform each of the elements.
15905 SmallVector<ObjCDictionaryElement, 8> Elements;
15906 bool ArgChanged = false;
15907 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
15908 ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);
15910 if (OrigElement.isPackExpansion()) {
15911 // This key/value element is a pack expansion.
15912 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15913 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
15914 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
15915 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
15917 // Determine whether the set of unexpanded parameter packs can
15918 // and should be expanded.
15919 bool Expand = true;
15920 bool RetainExpansion = false;
15921 std::optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
15922 std::optional<unsigned> NumExpansions = OrigNumExpansions;
15923 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
15924 OrigElement.Value->getEndLoc());
15925 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
15926 PatternRange, Unexpanded, Expand,
15927 RetainExpansion, NumExpansions))
15928 return ExprError();
15930 if (!Expand) {
15931 // The transform has determined that we should perform a simple
15932 // transformation on the pack expansion, producing another pack
15933 // expansion.
15934 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15935 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15936 if (Key.isInvalid())
15937 return ExprError();
15939 if (Key.get() != OrigElement.Key)
15940 ArgChanged = true;
15942 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
15943 if (Value.isInvalid())
15944 return ExprError();
15946 if (Value.get() != OrigElement.Value)
15947 ArgChanged = true;
15949 ObjCDictionaryElement Expansion = {
15950 Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions
15952 Elements.push_back(Expansion);
15953 continue;
15956 // Record right away that the argument was changed. This needs
15957 // to happen even if the array expands to nothing.
15958 ArgChanged = true;
15960 // The transform has determined that we should perform an elementwise
15961 // expansion of the pattern. Do so.
15962 for (unsigned I = 0; I != *NumExpansions; ++I) {
15963 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
15964 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15965 if (Key.isInvalid())
15966 return ExprError();
15968 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
15969 if (Value.isInvalid())
15970 return ExprError();
15972 ObjCDictionaryElement Element = {
15973 Key.get(), Value.get(), SourceLocation(), NumExpansions
15976 // If any unexpanded parameter packs remain, we still have a
15977 // pack expansion.
15978 // FIXME: Can this really happen?
15979 if (Key.get()->containsUnexpandedParameterPack() ||
15980 Value.get()->containsUnexpandedParameterPack())
15981 Element.EllipsisLoc = OrigElement.EllipsisLoc;
15983 Elements.push_back(Element);
15986 // FIXME: Retain a pack expansion if RetainExpansion is true.
15988 // We've finished with this pack expansion.
15989 continue;
15992 // Transform and check key.
15993 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15994 if (Key.isInvalid())
15995 return ExprError();
15997 if (Key.get() != OrigElement.Key)
15998 ArgChanged = true;
16000 // Transform and check value.
16001 ExprResult Value
16002 = getDerived().TransformExpr(OrigElement.Value);
16003 if (Value.isInvalid())
16004 return ExprError();
16006 if (Value.get() != OrigElement.Value)
16007 ArgChanged = true;
16009 ObjCDictionaryElement Element = {Key.get(), Value.get(), SourceLocation(),
16010 std::nullopt};
16011 Elements.push_back(Element);
16014 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16015 return SemaRef.MaybeBindToTemporary(E);
16017 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
16018 Elements);
16021 template<typename Derived>
16022 ExprResult
16023 TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
16024 TypeSourceInfo *EncodedTypeInfo
16025 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
16026 if (!EncodedTypeInfo)
16027 return ExprError();
16029 if (!getDerived().AlwaysRebuild() &&
16030 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
16031 return E;
16033 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
16034 EncodedTypeInfo,
16035 E->getRParenLoc());
16038 template<typename Derived>
16039 ExprResult TreeTransform<Derived>::
16040 TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
16041 // This is a kind of implicit conversion, and it needs to get dropped
16042 // and recomputed for the same general reasons that ImplicitCastExprs
16043 // do, as well a more specific one: this expression is only valid when
16044 // it appears *immediately* as an argument expression.
16045 return getDerived().TransformExpr(E->getSubExpr());
16048 template<typename Derived>
16049 ExprResult TreeTransform<Derived>::
16050 TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
16051 TypeSourceInfo *TSInfo
16052 = getDerived().TransformType(E->getTypeInfoAsWritten());
16053 if (!TSInfo)
16054 return ExprError();
16056 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
16057 if (Result.isInvalid())
16058 return ExprError();
16060 if (!getDerived().AlwaysRebuild() &&
16061 TSInfo == E->getTypeInfoAsWritten() &&
16062 Result.get() == E->getSubExpr())
16063 return E;
16065 return SemaRef.ObjC().BuildObjCBridgedCast(
16066 E->getLParenLoc(), E->getBridgeKind(), E->getBridgeKeywordLoc(), TSInfo,
16067 Result.get());
16070 template <typename Derived>
16071 ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
16072 ObjCAvailabilityCheckExpr *E) {
16073 return E;
16076 template<typename Derived>
16077 ExprResult
16078 TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
16079 // Transform arguments.
16080 bool ArgChanged = false;
16081 SmallVector<Expr*, 8> Args;
16082 Args.reserve(E->getNumArgs());
16083 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
16084 &ArgChanged))
16085 return ExprError();
16087 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
16088 // Class message: transform the receiver type.
16089 TypeSourceInfo *ReceiverTypeInfo
16090 = getDerived().TransformType(E->getClassReceiverTypeInfo());
16091 if (!ReceiverTypeInfo)
16092 return ExprError();
16094 // If nothing changed, just retain the existing message send.
16095 if (!getDerived().AlwaysRebuild() &&
16096 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
16097 return SemaRef.MaybeBindToTemporary(E);
16099 // Build a new class message send.
16100 SmallVector<SourceLocation, 16> SelLocs;
16101 E->getSelectorLocs(SelLocs);
16102 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
16103 E->getSelector(),
16104 SelLocs,
16105 E->getMethodDecl(),
16106 E->getLeftLoc(),
16107 Args,
16108 E->getRightLoc());
16110 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
16111 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
16112 if (!E->getMethodDecl())
16113 return ExprError();
16115 // Build a new class message send to 'super'.
16116 SmallVector<SourceLocation, 16> SelLocs;
16117 E->getSelectorLocs(SelLocs);
16118 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
16119 E->getSelector(),
16120 SelLocs,
16121 E->getReceiverType(),
16122 E->getMethodDecl(),
16123 E->getLeftLoc(),
16124 Args,
16125 E->getRightLoc());
16128 // Instance message: transform the receiver
16129 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
16130 "Only class and instance messages may be instantiated");
16131 ExprResult Receiver
16132 = getDerived().TransformExpr(E->getInstanceReceiver());
16133 if (Receiver.isInvalid())
16134 return ExprError();
16136 // If nothing changed, just retain the existing message send.
16137 if (!getDerived().AlwaysRebuild() &&
16138 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
16139 return SemaRef.MaybeBindToTemporary(E);
16141 // Build a new instance message send.
16142 SmallVector<SourceLocation, 16> SelLocs;
16143 E->getSelectorLocs(SelLocs);
16144 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
16145 E->getSelector(),
16146 SelLocs,
16147 E->getMethodDecl(),
16148 E->getLeftLoc(),
16149 Args,
16150 E->getRightLoc());
16153 template<typename Derived>
16154 ExprResult
16155 TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
16156 return E;
16159 template<typename Derived>
16160 ExprResult
16161 TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
16162 return E;
16165 template<typename Derived>
16166 ExprResult
16167 TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
16168 // Transform the base expression.
16169 ExprResult Base = getDerived().TransformExpr(E->getBase());
16170 if (Base.isInvalid())
16171 return ExprError();
16173 // We don't need to transform the ivar; it will never change.
16175 // If nothing changed, just retain the existing expression.
16176 if (!getDerived().AlwaysRebuild() &&
16177 Base.get() == E->getBase())
16178 return E;
16180 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
16181 E->getLocation(),
16182 E->isArrow(), E->isFreeIvar());
16185 template<typename Derived>
16186 ExprResult
16187 TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
16188 // 'super' and types never change. Property never changes. Just
16189 // retain the existing expression.
16190 if (!E->isObjectReceiver())
16191 return E;
16193 // Transform the base expression.
16194 ExprResult Base = getDerived().TransformExpr(E->getBase());
16195 if (Base.isInvalid())
16196 return ExprError();
16198 // We don't need to transform the property; it will never change.
16200 // If nothing changed, just retain the existing expression.
16201 if (!getDerived().AlwaysRebuild() &&
16202 Base.get() == E->getBase())
16203 return E;
16205 if (E->isExplicitProperty())
16206 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
16207 E->getExplicitProperty(),
16208 E->getLocation());
16210 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
16211 SemaRef.Context.PseudoObjectTy,
16212 E->getImplicitPropertyGetter(),
16213 E->getImplicitPropertySetter(),
16214 E->getLocation());
16217 template<typename Derived>
16218 ExprResult
16219 TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
16220 // Transform the base expression.
16221 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
16222 if (Base.isInvalid())
16223 return ExprError();
16225 // Transform the key expression.
16226 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
16227 if (Key.isInvalid())
16228 return ExprError();
16230 // If nothing changed, just retain the existing expression.
16231 if (!getDerived().AlwaysRebuild() &&
16232 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
16233 return E;
16235 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
16236 Base.get(), Key.get(),
16237 E->getAtIndexMethodDecl(),
16238 E->setAtIndexMethodDecl());
16241 template<typename Derived>
16242 ExprResult
16243 TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
16244 // Transform the base expression.
16245 ExprResult Base = getDerived().TransformExpr(E->getBase());
16246 if (Base.isInvalid())
16247 return ExprError();
16249 // If nothing changed, just retain the existing expression.
16250 if (!getDerived().AlwaysRebuild() &&
16251 Base.get() == E->getBase())
16252 return E;
16254 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
16255 E->getOpLoc(),
16256 E->isArrow());
16259 template<typename Derived>
16260 ExprResult
16261 TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
16262 bool ArgumentChanged = false;
16263 SmallVector<Expr*, 8> SubExprs;
16264 SubExprs.reserve(E->getNumSubExprs());
16265 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
16266 SubExprs, &ArgumentChanged))
16267 return ExprError();
16269 if (!getDerived().AlwaysRebuild() &&
16270 !ArgumentChanged)
16271 return E;
16273 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
16274 SubExprs,
16275 E->getRParenLoc());
16278 template<typename Derived>
16279 ExprResult
16280 TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
16281 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
16282 if (SrcExpr.isInvalid())
16283 return ExprError();
16285 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
16286 if (!Type)
16287 return ExprError();
16289 if (!getDerived().AlwaysRebuild() &&
16290 Type == E->getTypeSourceInfo() &&
16291 SrcExpr.get() == E->getSrcExpr())
16292 return E;
16294 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
16295 SrcExpr.get(), Type,
16296 E->getRParenLoc());
16299 template<typename Derived>
16300 ExprResult
16301 TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
16302 BlockDecl *oldBlock = E->getBlockDecl();
16304 SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr);
16305 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
16307 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
16308 blockScope->TheDecl->setBlockMissingReturnType(
16309 oldBlock->blockMissingReturnType());
16311 SmallVector<ParmVarDecl*, 4> params;
16312 SmallVector<QualType, 4> paramTypes;
16314 const FunctionProtoType *exprFunctionType = E->getFunctionType();
16316 // Parameter substitution.
16317 Sema::ExtParameterInfoBuilder extParamInfos;
16318 if (getDerived().TransformFunctionTypeParams(
16319 E->getCaretLocation(), oldBlock->parameters(), nullptr,
16320 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
16321 extParamInfos)) {
16322 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
16323 return ExprError();
16326 QualType exprResultType =
16327 getDerived().TransformType(exprFunctionType->getReturnType());
16329 auto epi = exprFunctionType->getExtProtoInfo();
16330 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size());
16332 QualType functionType =
16333 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
16334 blockScope->FunctionType = functionType;
16336 // Set the parameters on the block decl.
16337 if (!params.empty())
16338 blockScope->TheDecl->setParams(params);
16340 if (!oldBlock->blockMissingReturnType()) {
16341 blockScope->HasImplicitReturnType = false;
16342 blockScope->ReturnType = exprResultType;
16345 // Transform the body
16346 StmtResult body = getDerived().TransformStmt(E->getBody());
16347 if (body.isInvalid()) {
16348 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
16349 return ExprError();
16352 #ifndef NDEBUG
16353 // In builds with assertions, make sure that we captured everything we
16354 // captured before.
16355 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
16356 for (const auto &I : oldBlock->captures()) {
16357 VarDecl *oldCapture = I.getVariable();
16359 // Ignore parameter packs.
16360 if (oldCapture->isParameterPack())
16361 continue;
16363 VarDecl *newCapture =
16364 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
16365 oldCapture));
16366 assert(blockScope->CaptureMap.count(newCapture));
16369 // The this pointer may not be captured by the instantiated block, even when
16370 // it's captured by the original block, if the expression causing the
16371 // capture is in the discarded branch of a constexpr if statement.
16372 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
16373 "this pointer isn't captured in the old block");
16375 #endif
16377 return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(),
16378 /*Scope=*/nullptr);
16381 template<typename Derived>
16382 ExprResult
16383 TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
16384 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
16385 if (SrcExpr.isInvalid())
16386 return ExprError();
16388 QualType Type = getDerived().TransformType(E->getType());
16390 return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(),
16391 E->getRParenLoc());
16394 template<typename Derived>
16395 ExprResult
16396 TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
16397 bool ArgumentChanged = false;
16398 SmallVector<Expr*, 8> SubExprs;
16399 SubExprs.reserve(E->getNumSubExprs());
16400 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
16401 SubExprs, &ArgumentChanged))
16402 return ExprError();
16404 if (!getDerived().AlwaysRebuild() &&
16405 !ArgumentChanged)
16406 return E;
16408 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
16409 E->getOp(), E->getRParenLoc());
16412 //===----------------------------------------------------------------------===//
16413 // Type reconstruction
16414 //===----------------------------------------------------------------------===//
16416 template<typename Derived>
16417 QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
16418 SourceLocation Star) {
16419 return SemaRef.BuildPointerType(PointeeType, Star,
16420 getDerived().getBaseEntity());
16423 template<typename Derived>
16424 QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
16425 SourceLocation Star) {
16426 return SemaRef.BuildBlockPointerType(PointeeType, Star,
16427 getDerived().getBaseEntity());
16430 template<typename Derived>
16431 QualType
16432 TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
16433 bool WrittenAsLValue,
16434 SourceLocation Sigil) {
16435 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue,
16436 Sigil, getDerived().getBaseEntity());
16439 template<typename Derived>
16440 QualType
16441 TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
16442 QualType ClassType,
16443 SourceLocation Sigil) {
16444 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil,
16445 getDerived().getBaseEntity());
16448 template<typename Derived>
16449 QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
16450 const ObjCTypeParamDecl *Decl,
16451 SourceLocation ProtocolLAngleLoc,
16452 ArrayRef<ObjCProtocolDecl *> Protocols,
16453 ArrayRef<SourceLocation> ProtocolLocs,
16454 SourceLocation ProtocolRAngleLoc) {
16455 return SemaRef.ObjC().BuildObjCTypeParamType(
16456 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
16457 /*FailOnError=*/true);
16460 template<typename Derived>
16461 QualType TreeTransform<Derived>::RebuildObjCObjectType(
16462 QualType BaseType,
16463 SourceLocation Loc,
16464 SourceLocation TypeArgsLAngleLoc,
16465 ArrayRef<TypeSourceInfo *> TypeArgs,
16466 SourceLocation TypeArgsRAngleLoc,
16467 SourceLocation ProtocolLAngleLoc,
16468 ArrayRef<ObjCProtocolDecl *> Protocols,
16469 ArrayRef<SourceLocation> ProtocolLocs,
16470 SourceLocation ProtocolRAngleLoc) {
16471 return SemaRef.ObjC().BuildObjCObjectType(
16472 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
16473 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
16474 /*FailOnError=*/true,
16475 /*Rebuilding=*/true);
16478 template<typename Derived>
16479 QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
16480 QualType PointeeType,
16481 SourceLocation Star) {
16482 return SemaRef.Context.getObjCObjectPointerType(PointeeType);
16485 template <typename Derived>
16486 QualType TreeTransform<Derived>::RebuildArrayType(
16487 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
16488 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
16489 if (SizeExpr || !Size)
16490 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
16491 IndexTypeQuals, BracketsRange,
16492 getDerived().getBaseEntity());
16494 QualType Types[] = {
16495 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
16496 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
16497 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
16499 QualType SizeType;
16500 for (const auto &T : Types)
16501 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
16502 SizeType = T;
16503 break;
16506 // Note that we can return a VariableArrayType here in the case where
16507 // the element type was a dependent VariableArrayType.
16508 IntegerLiteral *ArraySize
16509 = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType,
16510 /*FIXME*/BracketsRange.getBegin());
16511 return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize,
16512 IndexTypeQuals, BracketsRange,
16513 getDerived().getBaseEntity());
16516 template <typename Derived>
16517 QualType TreeTransform<Derived>::RebuildConstantArrayType(
16518 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
16519 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
16520 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
16521 IndexTypeQuals, BracketsRange);
16524 template <typename Derived>
16525 QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
16526 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
16527 SourceRange BracketsRange) {
16528 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
16529 IndexTypeQuals, BracketsRange);
16532 template <typename Derived>
16533 QualType TreeTransform<Derived>::RebuildVariableArrayType(
16534 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
16535 unsigned IndexTypeQuals, SourceRange BracketsRange) {
16536 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
16537 SizeExpr,
16538 IndexTypeQuals, BracketsRange);
16541 template <typename Derived>
16542 QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
16543 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
16544 unsigned IndexTypeQuals, SourceRange BracketsRange) {
16545 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
16546 SizeExpr,
16547 IndexTypeQuals, BracketsRange);
16550 template <typename Derived>
16551 QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
16552 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
16553 return SemaRef.BuildAddressSpaceAttr(PointeeType, AddrSpaceExpr,
16554 AttributeLoc);
16557 template <typename Derived>
16558 QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
16559 unsigned NumElements,
16560 VectorKind VecKind) {
16561 // FIXME: semantic checking!
16562 return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);
16565 template <typename Derived>
16566 QualType TreeTransform<Derived>::RebuildDependentVectorType(
16567 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
16568 VectorKind VecKind) {
16569 return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc);
16572 template<typename Derived>
16573 QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
16574 unsigned NumElements,
16575 SourceLocation AttributeLoc) {
16576 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
16577 NumElements, true);
16578 IntegerLiteral *VectorSize
16579 = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
16580 AttributeLoc);
16581 return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
16584 template<typename Derived>
16585 QualType
16586 TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
16587 Expr *SizeExpr,
16588 SourceLocation AttributeLoc) {
16589 return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
16592 template <typename Derived>
16593 QualType TreeTransform<Derived>::RebuildConstantMatrixType(
16594 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
16595 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
16596 NumColumns);
16599 template <typename Derived>
16600 QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
16601 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
16602 SourceLocation AttributeLoc) {
16603 return SemaRef.BuildMatrixType(ElementType, RowExpr, ColumnExpr,
16604 AttributeLoc);
16607 template<typename Derived>
16608 QualType TreeTransform<Derived>::RebuildFunctionProtoType(
16609 QualType T,
16610 MutableArrayRef<QualType> ParamTypes,
16611 const FunctionProtoType::ExtProtoInfo &EPI) {
16612 return SemaRef.BuildFunctionType(T, ParamTypes,
16613 getDerived().getBaseLocation(),
16614 getDerived().getBaseEntity(),
16615 EPI);
16618 template<typename Derived>
16619 QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
16620 return SemaRef.Context.getFunctionNoProtoType(T);
16623 template<typename Derived>
16624 QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
16625 Decl *D) {
16626 assert(D && "no decl found");
16627 if (D->isInvalidDecl()) return QualType();
16629 // FIXME: Doesn't account for ObjCInterfaceDecl!
16630 if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
16631 // A valid resolved using typename pack expansion decl can have multiple
16632 // UsingDecls, but they must each have exactly one type, and it must be
16633 // the same type in every case. But we must have at least one expansion!
16634 if (UPD->expansions().empty()) {
16635 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
16636 << UPD->isCXXClassMember() << UPD;
16637 return QualType();
16640 // We might still have some unresolved types. Try to pick a resolved type
16641 // if we can. The final instantiation will check that the remaining
16642 // unresolved types instantiate to the type we pick.
16643 QualType FallbackT;
16644 QualType T;
16645 for (auto *E : UPD->expansions()) {
16646 QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
16647 if (ThisT.isNull())
16648 continue;
16649 else if (ThisT->getAs<UnresolvedUsingType>())
16650 FallbackT = ThisT;
16651 else if (T.isNull())
16652 T = ThisT;
16653 else
16654 assert(getSema().Context.hasSameType(ThisT, T) &&
16655 "mismatched resolved types in using pack expansion");
16657 return T.isNull() ? FallbackT : T;
16658 } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
16659 assert(Using->hasTypename() &&
16660 "UnresolvedUsingTypenameDecl transformed to non-typename using");
16662 // A valid resolved using typename decl points to exactly one type decl.
16663 assert(++Using->shadow_begin() == Using->shadow_end());
16665 UsingShadowDecl *Shadow = *Using->shadow_begin();
16666 if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), Loc))
16667 return QualType();
16668 return SemaRef.Context.getUsingType(
16669 Shadow, SemaRef.Context.getTypeDeclType(
16670 cast<TypeDecl>(Shadow->getTargetDecl())));
16671 } else {
16672 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
16673 "UnresolvedUsingTypenameDecl transformed to non-using decl");
16674 return SemaRef.Context.getTypeDeclType(
16675 cast<UnresolvedUsingTypenameDecl>(D));
16679 template <typename Derived>
16680 QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
16681 TypeOfKind Kind) {
16682 return SemaRef.BuildTypeofExprType(E, Kind);
16685 template<typename Derived>
16686 QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
16687 TypeOfKind Kind) {
16688 return SemaRef.Context.getTypeOfType(Underlying, Kind);
16691 template <typename Derived>
16692 QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
16693 return SemaRef.BuildDecltypeType(E);
16696 template <typename Derived>
16697 QualType TreeTransform<Derived>::RebuildPackIndexingType(
16698 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
16699 SourceLocation EllipsisLoc, bool FullySubstituted,
16700 ArrayRef<QualType> Expansions) {
16701 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
16702 FullySubstituted, Expansions);
16705 template<typename Derived>
16706 QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
16707 UnaryTransformType::UTTKind UKind,
16708 SourceLocation Loc) {
16709 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
16712 template<typename Derived>
16713 QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
16714 TemplateName Template,
16715 SourceLocation TemplateNameLoc,
16716 TemplateArgumentListInfo &TemplateArgs) {
16717 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
16720 template<typename Derived>
16721 QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
16722 SourceLocation KWLoc) {
16723 return SemaRef.BuildAtomicType(ValueType, KWLoc);
16726 template<typename Derived>
16727 QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
16728 SourceLocation KWLoc,
16729 bool isReadPipe) {
16730 return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc)
16731 : SemaRef.BuildWritePipeType(ValueType, KWLoc);
16734 template <typename Derived>
16735 QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
16736 unsigned NumBits,
16737 SourceLocation Loc) {
16738 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
16739 NumBits, true);
16740 IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,
16741 SemaRef.Context.IntTy, Loc);
16742 return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc);
16745 template <typename Derived>
16746 QualType TreeTransform<Derived>::RebuildDependentBitIntType(
16747 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
16748 return SemaRef.BuildBitIntType(IsUnsigned, NumBitsExpr, Loc);
16751 template<typename Derived>
16752 TemplateName
16753 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
16754 bool TemplateKW,
16755 TemplateDecl *Template) {
16756 return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW,
16757 TemplateName(Template));
16760 template<typename Derived>
16761 TemplateName
16762 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
16763 SourceLocation TemplateKWLoc,
16764 const IdentifierInfo &Name,
16765 SourceLocation NameLoc,
16766 QualType ObjectType,
16767 NamedDecl *FirstQualifierInScope,
16768 bool AllowInjectedClassName) {
16769 UnqualifiedId TemplateName;
16770 TemplateName.setIdentifier(&Name, NameLoc);
16771 Sema::TemplateTy Template;
16772 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
16773 TemplateName, ParsedType::make(ObjectType),
16774 /*EnteringContext=*/false, Template,
16775 AllowInjectedClassName);
16776 return Template.get();
16779 template<typename Derived>
16780 TemplateName
16781 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
16782 SourceLocation TemplateKWLoc,
16783 OverloadedOperatorKind Operator,
16784 SourceLocation NameLoc,
16785 QualType ObjectType,
16786 bool AllowInjectedClassName) {
16787 UnqualifiedId Name;
16788 // FIXME: Bogus location information.
16789 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
16790 Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);
16791 Sema::TemplateTy Template;
16792 getSema().ActOnTemplateName(
16793 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(ObjectType),
16794 /*EnteringContext=*/false, Template, AllowInjectedClassName);
16795 return Template.get();
16798 template <typename Derived>
16799 ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
16800 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
16801 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
16802 Expr *Second) {
16803 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
16805 if (First->getObjectKind() == OK_ObjCProperty) {
16806 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
16807 if (BinaryOperator::isAssignmentOp(Opc))
16808 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/nullptr, OpLoc,
16809 Opc, First, Second);
16810 ExprResult Result = SemaRef.CheckPlaceholderExpr(First);
16811 if (Result.isInvalid())
16812 return ExprError();
16813 First = Result.get();
16816 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
16817 ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
16818 if (Result.isInvalid())
16819 return ExprError();
16820 Second = Result.get();
16823 // Determine whether this should be a builtin operation.
16824 if (Op == OO_Subscript) {
16825 if (!First->getType()->isOverloadableType() &&
16826 !Second->getType()->isOverloadableType())
16827 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
16828 OpLoc);
16829 } else if (Op == OO_Arrow) {
16830 // It is possible that the type refers to a RecoveryExpr created earlier
16831 // in the tree transformation.
16832 if (First->getType()->isDependentType())
16833 return ExprError();
16834 // -> is never a builtin operation.
16835 return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);
16836 } else if (Second == nullptr || isPostIncDec) {
16837 if (!First->getType()->isOverloadableType() ||
16838 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
16839 // The argument is not of overloadable type, or this is an expression
16840 // of the form &Class::member, so try to create a built-in unary
16841 // operation.
16842 UnaryOperatorKind Opc
16843 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
16845 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
16847 } else {
16848 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
16849 !First->getType()->isOverloadableType() &&
16850 !Second->getType()->isOverloadableType()) {
16851 // Neither of the arguments is type-dependent or has an overloadable
16852 // type, so try to create a built-in binary operation.
16853 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
16854 ExprResult Result
16855 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
16856 if (Result.isInvalid())
16857 return ExprError();
16859 return Result;
16863 // Create the overloaded operator invocation for unary operators.
16864 if (!Second || isPostIncDec) {
16865 UnaryOperatorKind Opc
16866 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
16867 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First,
16868 RequiresADL);
16871 // Create the overloaded operator invocation for binary operators.
16872 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
16873 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions,
16874 First, Second, RequiresADL);
16875 if (Result.isInvalid())
16876 return ExprError();
16878 return Result;
16881 template<typename Derived>
16882 ExprResult
16883 TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
16884 SourceLocation OperatorLoc,
16885 bool isArrow,
16886 CXXScopeSpec &SS,
16887 TypeSourceInfo *ScopeType,
16888 SourceLocation CCLoc,
16889 SourceLocation TildeLoc,
16890 PseudoDestructorTypeStorage Destroyed) {
16891 QualType BaseType = Base->getType();
16892 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
16893 (!isArrow && !BaseType->getAs<RecordType>()) ||
16894 (isArrow && BaseType->getAs<PointerType>() &&
16895 !BaseType->castAs<PointerType>()->getPointeeType()
16896 ->template getAs<RecordType>())){
16897 // This pseudo-destructor expression is still a pseudo-destructor.
16898 return SemaRef.BuildPseudoDestructorExpr(
16899 Base, OperatorLoc, isArrow ? tok::arrow : tok::period, SS, ScopeType,
16900 CCLoc, TildeLoc, Destroyed);
16903 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
16904 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
16905 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
16906 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
16907 NameInfo.setNamedTypeInfo(DestroyedType);
16909 // The scope type is now known to be a valid nested name specifier
16910 // component. Tack it on to the end of the nested name specifier.
16911 if (ScopeType) {
16912 if (!ScopeType->getType()->getAs<TagType>()) {
16913 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
16914 diag::err_expected_class_or_namespace)
16915 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
16916 return ExprError();
16918 SS.Extend(SemaRef.Context, SourceLocation(), ScopeType->getTypeLoc(),
16919 CCLoc);
16922 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
16923 return getSema().BuildMemberReferenceExpr(Base, BaseType,
16924 OperatorLoc, isArrow,
16925 SS, TemplateKWLoc,
16926 /*FIXME: FirstQualifier*/ nullptr,
16927 NameInfo,
16928 /*TemplateArgs*/ nullptr,
16929 /*S*/nullptr);
16932 template<typename Derived>
16933 StmtResult
16934 TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
16935 SourceLocation Loc = S->getBeginLoc();
16936 CapturedDecl *CD = S->getCapturedDecl();
16937 unsigned NumParams = CD->getNumParams();
16938 unsigned ContextParamPos = CD->getContextParamPosition();
16939 SmallVector<Sema::CapturedParamNameType, 4> Params;
16940 for (unsigned I = 0; I < NumParams; ++I) {
16941 if (I != ContextParamPos) {
16942 Params.push_back(
16943 std::make_pair(
16944 CD->getParam(I)->getName(),
16945 getDerived().TransformType(CD->getParam(I)->getType())));
16946 } else {
16947 Params.push_back(std::make_pair(StringRef(), QualType()));
16950 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
16951 S->getCapturedRegionKind(), Params);
16952 StmtResult Body;
16954 Sema::CompoundScopeRAII CompoundScope(getSema());
16955 Body = getDerived().TransformStmt(S->getCapturedStmt());
16958 if (Body.isInvalid()) {
16959 getSema().ActOnCapturedRegionError();
16960 return StmtError();
16963 return getSema().ActOnCapturedRegionEnd(Body.get());
16966 template <typename Derived>
16967 ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
16968 // We can transform the base expression and allow argument resolution to fill
16969 // in the rest.
16970 return getDerived().TransformExpr(E->getArgLValue());
16973 } // end namespace clang
16975 #endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H