[DFAJumpThreading] Remove incoming StartBlock from all phis when unfolding select...
[llvm-project.git] / clang / lib / Sema / TreeTransform.h
blobac12b39a5978b2026e42b572087dc1984ec89675
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/StmtOpenMP.h"
31 #include "clang/Basic/DiagnosticParse.h"
32 #include "clang/Basic/OpenMPKinds.h"
33 #include "clang/Sema/Designator.h"
34 #include "clang/Sema/EnterExpressionEvaluationContext.h"
35 #include "clang/Sema/Lookup.h"
36 #include "clang/Sema/Ownership.h"
37 #include "clang/Sema/ParsedTemplate.h"
38 #include "clang/Sema/ScopeInfo.h"
39 #include "clang/Sema/SemaDiagnostic.h"
40 #include "clang/Sema/SemaInternal.h"
41 #include "llvm/ADT/ArrayRef.h"
42 #include "llvm/Support/ErrorHandling.h"
43 #include <algorithm>
44 #include <optional>
46 using namespace llvm::omp;
48 namespace clang {
49 using namespace sema;
51 /// A semantic tree transformation that allows one to transform one
52 /// abstract syntax tree into another.
53 ///
54 /// A new tree transformation is defined by creating a new subclass \c X of
55 /// \c TreeTransform<X> and then overriding certain operations to provide
56 /// behavior specific to that transformation. For example, template
57 /// instantiation is implemented as a tree transformation where the
58 /// transformation of TemplateTypeParmType nodes involves substituting the
59 /// template arguments for their corresponding template parameters; a similar
60 /// transformation is performed for non-type template parameters and
61 /// template template parameters.
62 ///
63 /// This tree-transformation template uses static polymorphism to allow
64 /// subclasses to customize any of its operations. Thus, a subclass can
65 /// override any of the transformation or rebuild operators by providing an
66 /// operation with the same signature as the default implementation. The
67 /// overriding function should not be virtual.
68 ///
69 /// Semantic tree transformations are split into two stages, either of which
70 /// can be replaced by a subclass. The "transform" step transforms an AST node
71 /// or the parts of an AST node using the various transformation functions,
72 /// then passes the pieces on to the "rebuild" step, which constructs a new AST
73 /// node of the appropriate kind from the pieces. The default transformation
74 /// routines recursively transform the operands to composite AST nodes (e.g.,
75 /// the pointee type of a PointerType node) and, if any of those operand nodes
76 /// were changed by the transformation, invokes the rebuild operation to create
77 /// a new AST node.
78 ///
79 /// Subclasses can customize the transformation at various levels. The
80 /// most coarse-grained transformations involve replacing TransformType(),
81 /// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
82 /// TransformTemplateName(), or TransformTemplateArgument() with entirely
83 /// new implementations.
84 ///
85 /// For more fine-grained transformations, subclasses can replace any of the
86 /// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
87 /// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
88 /// replacing TransformTemplateTypeParmType() allows template instantiation
89 /// to substitute template arguments for their corresponding template
90 /// parameters. Additionally, subclasses can override the \c RebuildXXX
91 /// functions to control how AST nodes are rebuilt when their operands change.
92 /// By default, \c TreeTransform will invoke semantic analysis to rebuild
93 /// AST nodes. However, certain other tree transformations (e.g, cloning) may
94 /// be able to use more efficient rebuild steps.
95 ///
96 /// There are a handful of other functions that can be overridden, allowing one
97 /// to avoid traversing nodes that don't need any transformation
98 /// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
99 /// operands have not changed (\c AlwaysRebuild()), and customize the
100 /// default locations and entity names used for type-checking
101 /// (\c getBaseLocation(), \c getBaseEntity()).
102 template<typename Derived>
103 class TreeTransform {
104 /// Private RAII object that helps us forget and then re-remember
105 /// the template argument corresponding to a partially-substituted parameter
106 /// pack.
107 class ForgetPartiallySubstitutedPackRAII {
108 Derived &Self;
109 TemplateArgument Old;
111 public:
112 ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) {
113 Old = Self.ForgetPartiallySubstitutedPack();
116 ~ForgetPartiallySubstitutedPackRAII() {
117 Self.RememberPartiallySubstitutedPack(Old);
121 protected:
122 Sema &SemaRef;
124 /// The set of local declarations that have been transformed, for
125 /// cases where we are forced to build new declarations within the transformer
126 /// rather than in the subclass (e.g., lambda closure types).
127 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
129 public:
130 /// Initializes a new tree transformer.
131 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
133 /// Retrieves a reference to the derived class.
134 Derived &getDerived() { return static_cast<Derived&>(*this); }
136 /// Retrieves a reference to the derived class.
137 const Derived &getDerived() const {
138 return static_cast<const Derived&>(*this);
141 static inline ExprResult Owned(Expr *E) { return E; }
142 static inline StmtResult Owned(Stmt *S) { return S; }
144 /// Retrieves a reference to the semantic analysis object used for
145 /// this tree transform.
146 Sema &getSema() const { return SemaRef; }
148 /// Whether the transformation should always rebuild AST nodes, even
149 /// if none of the children have changed.
151 /// Subclasses may override this function to specify when the transformation
152 /// should rebuild all AST nodes.
154 /// We must always rebuild all AST nodes when performing variadic template
155 /// pack expansion, in order to avoid violating the AST invariant that each
156 /// statement node appears at most once in its containing declaration.
157 bool AlwaysRebuild() { return SemaRef.ArgumentPackSubstitutionIndex != -1; }
159 /// Whether the transformation is forming an expression or statement that
160 /// replaces the original. In this case, we'll reuse mangling numbers from
161 /// existing lambdas.
162 bool ReplacingOriginal() { return false; }
164 /// Wether CXXConstructExpr can be skipped when they are implicit.
165 /// They will be reconstructed when used if needed.
166 /// This is useful when the user that cause rebuilding of the
167 /// CXXConstructExpr is outside of the expression at which the TreeTransform
168 /// started.
169 bool AllowSkippingCXXConstructExpr() { return true; }
171 /// Returns the location of the entity being transformed, if that
172 /// information was not available elsewhere in the AST.
174 /// By default, returns no source-location information. Subclasses can
175 /// provide an alternative implementation that provides better location
176 /// information.
177 SourceLocation getBaseLocation() { return SourceLocation(); }
179 /// Returns the name of the entity being transformed, if that
180 /// information was not available elsewhere in the AST.
182 /// By default, returns an empty name. Subclasses can provide an alternative
183 /// implementation with a more precise name.
184 DeclarationName getBaseEntity() { return DeclarationName(); }
186 /// Sets the "base" location and entity when that
187 /// information is known based on another transformation.
189 /// By default, the source location and entity are ignored. Subclasses can
190 /// override this function to provide a customized implementation.
191 void setBase(SourceLocation Loc, DeclarationName Entity) { }
193 /// RAII object that temporarily sets the base location and entity
194 /// used for reporting diagnostics in types.
195 class TemporaryBase {
196 TreeTransform &Self;
197 SourceLocation OldLocation;
198 DeclarationName OldEntity;
200 public:
201 TemporaryBase(TreeTransform &Self, SourceLocation Location,
202 DeclarationName Entity) : Self(Self) {
203 OldLocation = Self.getDerived().getBaseLocation();
204 OldEntity = Self.getDerived().getBaseEntity();
206 if (Location.isValid())
207 Self.getDerived().setBase(Location, Entity);
210 ~TemporaryBase() {
211 Self.getDerived().setBase(OldLocation, OldEntity);
215 /// Determine whether the given type \p T has already been
216 /// transformed.
218 /// Subclasses can provide an alternative implementation of this routine
219 /// to short-circuit evaluation when it is known that a given type will
220 /// not change. For example, template instantiation need not traverse
221 /// non-dependent types.
222 bool AlreadyTransformed(QualType T) {
223 return T.isNull();
226 /// Transform a template parameter depth level.
228 /// During a transformation that transforms template parameters, this maps
229 /// an old template parameter depth to a new depth.
230 unsigned TransformTemplateDepth(unsigned Depth) {
231 return Depth;
234 /// Determine whether the given call argument should be dropped, e.g.,
235 /// because it is a default argument.
237 /// Subclasses can provide an alternative implementation of this routine to
238 /// determine which kinds of call arguments get dropped. By default,
239 /// CXXDefaultArgument nodes are dropped (prior to transformation).
240 bool DropCallArgument(Expr *E) {
241 return E->isDefaultArgument();
244 /// Determine whether we should expand a pack expansion with the
245 /// given set of parameter packs into separate arguments by repeatedly
246 /// transforming the pattern.
248 /// By default, the transformer never tries to expand pack expansions.
249 /// Subclasses can override this routine to provide different behavior.
251 /// \param EllipsisLoc The location of the ellipsis that identifies the
252 /// pack expansion.
254 /// \param PatternRange The source range that covers the entire pattern of
255 /// the pack expansion.
257 /// \param Unexpanded The set of unexpanded parameter packs within the
258 /// pattern.
260 /// \param ShouldExpand Will be set to \c true if the transformer should
261 /// expand the corresponding pack expansions into separate arguments. When
262 /// set, \c NumExpansions must also be set.
264 /// \param RetainExpansion Whether the caller should add an unexpanded
265 /// pack expansion after all of the expanded arguments. This is used
266 /// when extending explicitly-specified template argument packs per
267 /// C++0x [temp.arg.explicit]p9.
269 /// \param NumExpansions The number of separate arguments that will be in
270 /// the expanded form of the corresponding pack expansion. This is both an
271 /// input and an output parameter, which can be set by the caller if the
272 /// number of expansions is known a priori (e.g., due to a prior substitution)
273 /// and will be set by the callee when the number of expansions is known.
274 /// The callee must set this value when \c ShouldExpand is \c true; it may
275 /// set this value in other cases.
277 /// \returns true if an error occurred (e.g., because the parameter packs
278 /// are to be instantiated with arguments of different lengths), false
279 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
280 /// must be set.
281 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
282 SourceRange PatternRange,
283 ArrayRef<UnexpandedParameterPack> Unexpanded,
284 bool &ShouldExpand, bool &RetainExpansion,
285 std::optional<unsigned> &NumExpansions) {
286 ShouldExpand = false;
287 return false;
290 /// "Forget" about the partially-substituted pack template argument,
291 /// when performing an instantiation that must preserve the parameter pack
292 /// use.
294 /// This routine is meant to be overridden by the template instantiator.
295 TemplateArgument ForgetPartiallySubstitutedPack() {
296 return TemplateArgument();
299 /// "Remember" the partially-substituted pack template argument
300 /// after performing an instantiation that must preserve the parameter pack
301 /// use.
303 /// This routine is meant to be overridden by the template instantiator.
304 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
306 /// Note to the derived class when a function parameter pack is
307 /// being expanded.
308 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
310 /// Transforms the given type into another type.
312 /// By default, this routine transforms a type by creating a
313 /// TypeSourceInfo for it and delegating to the appropriate
314 /// function. This is expensive, but we don't mind, because
315 /// this method is deprecated anyway; all users should be
316 /// switched to storing TypeSourceInfos.
318 /// \returns the transformed type.
319 QualType TransformType(QualType T);
321 /// Transforms the given type-with-location into a new
322 /// type-with-location.
324 /// By default, this routine transforms a type by delegating to the
325 /// appropriate TransformXXXType to build a new type. Subclasses
326 /// may override this function (to take over all type
327 /// transformations) or some set of the TransformXXXType functions
328 /// to alter the transformation.
329 TypeSourceInfo *TransformType(TypeSourceInfo *DI);
331 /// Transform the given type-with-location into a new
332 /// type, collecting location information in the given builder
333 /// as necessary.
335 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
337 /// Transform a type that is permitted to produce a
338 /// DeducedTemplateSpecializationType.
340 /// This is used in the (relatively rare) contexts where it is acceptable
341 /// for transformation to produce a class template type with deduced
342 /// template arguments.
343 /// @{
344 QualType TransformTypeWithDeducedTST(QualType T);
345 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *DI);
346 /// @}
348 /// The reason why the value of a statement is not discarded, if any.
349 enum StmtDiscardKind {
350 SDK_Discarded,
351 SDK_NotDiscarded,
352 SDK_StmtExprResult,
355 /// Transform the given statement.
357 /// By default, this routine transforms a statement by delegating to the
358 /// appropriate TransformXXXStmt function to transform a specific kind of
359 /// statement or the TransformExpr() function to transform an expression.
360 /// Subclasses may override this function to transform statements using some
361 /// other mechanism.
363 /// \returns the transformed statement.
364 StmtResult TransformStmt(Stmt *S, StmtDiscardKind SDK = SDK_Discarded);
366 /// Transform the given statement.
368 /// By default, this routine transforms a statement by delegating to the
369 /// appropriate TransformOMPXXXClause function to transform a specific kind
370 /// of clause. Subclasses may override this function to transform statements
371 /// using some other mechanism.
373 /// \returns the transformed OpenMP clause.
374 OMPClause *TransformOMPClause(OMPClause *S);
376 /// Transform the given attribute.
378 /// By default, this routine transforms a statement by delegating to the
379 /// appropriate TransformXXXAttr function to transform a specific kind
380 /// of attribute. Subclasses may override this function to transform
381 /// attributed statements/types using some other mechanism.
383 /// \returns the transformed attribute
384 const Attr *TransformAttr(const Attr *S);
386 // Transform the given statement attribute.
388 // Delegates to the appropriate TransformXXXAttr function to transform a
389 // specific kind of statement attribute. Unlike the non-statement taking
390 // version of this, this implements all attributes, not just pragmas.
391 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
392 const Attr *A);
394 // Transform the specified attribute.
396 // Subclasses should override the transformation of attributes with a pragma
397 // spelling to transform expressions stored within the attribute.
399 // \returns the transformed attribute.
400 #define ATTR(X) \
401 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
402 #include "clang/Basic/AttrList.inc"
404 // Transform the specified attribute.
406 // Subclasses should override the transformation of attributes to do
407 // transformation and checking of statement attributes. By default, this
408 // delegates to the non-statement taking version.
410 // \returns the transformed attribute.
411 #define ATTR(X) \
412 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
413 const X##Attr *A) { \
414 return getDerived().Transform##X##Attr(A); \
416 #include "clang/Basic/AttrList.inc"
418 /// Transform the given expression.
420 /// By default, this routine transforms an expression by delegating to the
421 /// appropriate TransformXXXExpr function to build a new expression.
422 /// Subclasses may override this function to transform expressions using some
423 /// other mechanism.
425 /// \returns the transformed expression.
426 ExprResult TransformExpr(Expr *E);
428 /// Transform the given initializer.
430 /// By default, this routine transforms an initializer by stripping off the
431 /// semantic nodes added by initialization, then passing the result to
432 /// TransformExpr or TransformExprs.
434 /// \returns the transformed initializer.
435 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
437 /// Transform the given list of expressions.
439 /// This routine transforms a list of expressions by invoking
440 /// \c TransformExpr() for each subexpression. However, it also provides
441 /// support for variadic templates by expanding any pack expansions (if the
442 /// derived class permits such expansion) along the way. When pack expansions
443 /// are present, the number of outputs may not equal the number of inputs.
445 /// \param Inputs The set of expressions to be transformed.
447 /// \param NumInputs The number of expressions in \c Inputs.
449 /// \param IsCall If \c true, then this transform is being performed on
450 /// function-call arguments, and any arguments that should be dropped, will
451 /// be.
453 /// \param Outputs The transformed input expressions will be added to this
454 /// vector.
456 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
457 /// due to transformation.
459 /// \returns true if an error occurred, false otherwise.
460 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
461 SmallVectorImpl<Expr *> &Outputs,
462 bool *ArgChanged = nullptr);
464 /// Transform the given declaration, which is referenced from a type
465 /// or expression.
467 /// By default, acts as the identity function on declarations, unless the
468 /// transformer has had to transform the declaration itself. Subclasses
469 /// may override this function to provide alternate behavior.
470 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
471 llvm::DenseMap<Decl *, Decl *>::iterator Known
472 = TransformedLocalDecls.find(D);
473 if (Known != TransformedLocalDecls.end())
474 return Known->second;
476 return D;
479 /// Transform the specified condition.
481 /// By default, this transforms the variable and expression and rebuilds
482 /// the condition.
483 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
484 Expr *Expr,
485 Sema::ConditionKind Kind);
487 /// Transform the attributes associated with the given declaration and
488 /// place them on the new declaration.
490 /// By default, this operation does nothing. Subclasses may override this
491 /// behavior to transform attributes.
492 void transformAttrs(Decl *Old, Decl *New) { }
494 /// Note that a local declaration has been transformed by this
495 /// transformer.
497 /// Local declarations are typically transformed via a call to
498 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
499 /// the transformer itself has to transform the declarations. This routine
500 /// can be overridden by a subclass that keeps track of such mappings.
501 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
502 assert(New.size() == 1 &&
503 "must override transformedLocalDecl if performing pack expansion");
504 TransformedLocalDecls[Old] = New.front();
507 /// Transform the definition of the given declaration.
509 /// By default, invokes TransformDecl() to transform the declaration.
510 /// Subclasses may override this function to provide alternate behavior.
511 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
512 return getDerived().TransformDecl(Loc, D);
515 /// Transform the given declaration, which was the first part of a
516 /// nested-name-specifier in a member access expression.
518 /// This specific declaration transformation only applies to the first
519 /// identifier in a nested-name-specifier of a member access expression, e.g.,
520 /// the \c T in \c x->T::member
522 /// By default, invokes TransformDecl() to transform the declaration.
523 /// Subclasses may override this function to provide alternate behavior.
524 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
525 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
528 /// Transform the set of declarations in an OverloadExpr.
529 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
530 LookupResult &R);
532 /// Transform the given nested-name-specifier with source-location
533 /// information.
535 /// By default, transforms all of the types and declarations within the
536 /// nested-name-specifier. Subclasses may override this function to provide
537 /// alternate behavior.
538 NestedNameSpecifierLoc
539 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
540 QualType ObjectType = QualType(),
541 NamedDecl *FirstQualifierInScope = nullptr);
543 /// Transform the given declaration name.
545 /// By default, transforms the types of conversion function, constructor,
546 /// and destructor names and then (if needed) rebuilds the declaration name.
547 /// Identifiers and selectors are returned unmodified. Subclasses may
548 /// override this function to provide alternate behavior.
549 DeclarationNameInfo
550 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
552 bool TransformRequiresExprRequirements(
553 ArrayRef<concepts::Requirement *> Reqs,
554 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
555 concepts::TypeRequirement *
556 TransformTypeRequirement(concepts::TypeRequirement *Req);
557 concepts::ExprRequirement *
558 TransformExprRequirement(concepts::ExprRequirement *Req);
559 concepts::NestedRequirement *
560 TransformNestedRequirement(concepts::NestedRequirement *Req);
562 /// Transform the given template name.
564 /// \param SS The nested-name-specifier that qualifies the template
565 /// name. This nested-name-specifier must already have been transformed.
567 /// \param Name The template name to transform.
569 /// \param NameLoc The source location of the template name.
571 /// \param ObjectType If we're translating a template name within a member
572 /// access expression, this is the type of the object whose member template
573 /// is being referenced.
575 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
576 /// also refers to a name within the current (lexical) scope, this is the
577 /// declaration it refers to.
579 /// By default, transforms the template name by transforming the declarations
580 /// and nested-name-specifiers that occur within the template name.
581 /// Subclasses may override this function to provide alternate behavior.
582 TemplateName
583 TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
584 SourceLocation NameLoc,
585 QualType ObjectType = QualType(),
586 NamedDecl *FirstQualifierInScope = nullptr,
587 bool AllowInjectedClassName = false);
589 /// Transform the given template argument.
591 /// By default, this operation transforms the type, expression, or
592 /// declaration stored within the template argument and constructs a
593 /// new template argument from the transformed result. Subclasses may
594 /// override this function to provide alternate behavior.
596 /// Returns true if there was an error.
597 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
598 TemplateArgumentLoc &Output,
599 bool Uneval = false);
601 /// Transform the given set of template arguments.
603 /// By default, this operation transforms all of the template arguments
604 /// in the input set using \c TransformTemplateArgument(), and appends
605 /// the transformed arguments to the output list.
607 /// Note that this overload of \c TransformTemplateArguments() is merely
608 /// a convenience function. Subclasses that wish to override this behavior
609 /// should override the iterator-based member template version.
611 /// \param Inputs The set of template arguments to be transformed.
613 /// \param NumInputs The number of template arguments in \p Inputs.
615 /// \param Outputs The set of transformed template arguments output by this
616 /// routine.
618 /// Returns true if an error occurred.
619 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
620 unsigned NumInputs,
621 TemplateArgumentListInfo &Outputs,
622 bool Uneval = false) {
623 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
624 Uneval);
627 /// Transform the given set of template arguments.
629 /// By default, this operation transforms all of the template arguments
630 /// in the input set using \c TransformTemplateArgument(), and appends
631 /// the transformed arguments to the output list.
633 /// \param First An iterator to the first template argument.
635 /// \param Last An iterator one step past the last template argument.
637 /// \param Outputs The set of transformed template arguments output by this
638 /// routine.
640 /// Returns true if an error occurred.
641 template<typename InputIterator>
642 bool TransformTemplateArguments(InputIterator First,
643 InputIterator Last,
644 TemplateArgumentListInfo &Outputs,
645 bool Uneval = false);
647 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
648 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
649 TemplateArgumentLoc &ArgLoc);
651 /// Fakes up a TypeSourceInfo for a type.
652 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
653 return SemaRef.Context.getTrivialTypeSourceInfo(T,
654 getDerived().getBaseLocation());
657 #define ABSTRACT_TYPELOC(CLASS, PARENT)
658 #define TYPELOC(CLASS, PARENT) \
659 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
660 #include "clang/AST/TypeLocNodes.def"
662 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
663 TemplateTypeParmTypeLoc TL,
664 bool SuppressObjCLifetime);
665 QualType
666 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
667 SubstTemplateTypeParmPackTypeLoc TL,
668 bool SuppressObjCLifetime);
670 template<typename Fn>
671 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
672 FunctionProtoTypeLoc TL,
673 CXXRecordDecl *ThisContext,
674 Qualifiers ThisTypeQuals,
675 Fn TransformExceptionSpec);
677 bool TransformExceptionSpec(SourceLocation Loc,
678 FunctionProtoType::ExceptionSpecInfo &ESI,
679 SmallVectorImpl<QualType> &Exceptions,
680 bool &Changed);
682 StmtResult TransformSEHHandler(Stmt *Handler);
684 QualType
685 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
686 TemplateSpecializationTypeLoc TL,
687 TemplateName Template);
689 QualType
690 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
691 DependentTemplateSpecializationTypeLoc TL,
692 TemplateName Template,
693 CXXScopeSpec &SS);
695 QualType TransformDependentTemplateSpecializationType(
696 TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
697 NestedNameSpecifierLoc QualifierLoc);
699 /// Transforms the parameters of a function type into the
700 /// given vectors.
702 /// The result vectors should be kept in sync; null entries in the
703 /// variables vector are acceptable.
705 /// LastParamTransformed, if non-null, will be set to the index of the last
706 /// parameter on which transfromation was started. In the event of an error,
707 /// this will contain the parameter which failed to instantiate.
709 /// Return true on error.
710 bool TransformFunctionTypeParams(
711 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
712 const QualType *ParamTypes,
713 const FunctionProtoType::ExtParameterInfo *ParamInfos,
714 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
715 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
717 bool TransformFunctionTypeParams(
718 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
719 const QualType *ParamTypes,
720 const FunctionProtoType::ExtParameterInfo *ParamInfos,
721 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
722 Sema::ExtParameterInfoBuilder &PInfos) {
723 return getDerived().TransformFunctionTypeParams(
724 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
727 /// Transforms the parameters of a requires expresison into the given vectors.
729 /// The result vectors should be kept in sync; null entries in the
730 /// variables vector are acceptable.
732 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
733 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
734 /// which are cases where transformation shouldn't continue.
735 ExprResult TransformRequiresTypeParams(
736 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
737 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
738 SmallVectorImpl<QualType> &PTypes,
739 SmallVectorImpl<ParmVarDecl *> &TransParams,
740 Sema::ExtParameterInfoBuilder &PInfos) {
741 if (getDerived().TransformFunctionTypeParams(
742 KWLoc, Params, /*ParamTypes=*/nullptr,
743 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
744 return ExprError();
746 return ExprResult{};
749 /// Transforms a single function-type parameter. Return null
750 /// on error.
752 /// \param indexAdjustment - A number to add to the parameter's
753 /// scope index; can be negative
754 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
755 int indexAdjustment,
756 std::optional<unsigned> NumExpansions,
757 bool ExpectParameterPack);
759 /// Transform the body of a lambda-expression.
760 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
761 /// Alternative implementation of TransformLambdaBody that skips transforming
762 /// the body.
763 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
765 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
767 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
768 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
770 TemplateParameterList *TransformTemplateParameterList(
771 TemplateParameterList *TPL) {
772 return TPL;
775 ExprResult TransformAddressOfOperand(Expr *E);
777 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
778 bool IsAddressOfOperand,
779 TypeSourceInfo **RecoveryTSI);
781 ExprResult TransformParenDependentScopeDeclRefExpr(
782 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
783 TypeSourceInfo **RecoveryTSI);
785 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
787 // FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
788 // amount of stack usage with clang.
789 #define STMT(Node, Parent) \
790 LLVM_ATTRIBUTE_NOINLINE \
791 StmtResult Transform##Node(Node *S);
792 #define VALUESTMT(Node, Parent) \
793 LLVM_ATTRIBUTE_NOINLINE \
794 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
795 #define EXPR(Node, Parent) \
796 LLVM_ATTRIBUTE_NOINLINE \
797 ExprResult Transform##Node(Node *E);
798 #define ABSTRACT_STMT(Stmt)
799 #include "clang/AST/StmtNodes.inc"
801 #define GEN_CLANG_CLAUSE_CLASS
802 #define CLAUSE_CLASS(Enum, Str, Class) \
803 LLVM_ATTRIBUTE_NOINLINE \
804 OMPClause *Transform##Class(Class *S);
805 #include "llvm/Frontend/OpenMP/OMP.inc"
807 /// Build a new qualified type given its unqualified type and type location.
809 /// By default, this routine adds type qualifiers only to types that can
810 /// have qualifiers, and silently suppresses those qualifiers that are not
811 /// permitted. Subclasses may override this routine to provide different
812 /// behavior.
813 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
815 /// Build a new pointer type given its pointee type.
817 /// By default, performs semantic analysis when building the pointer type.
818 /// Subclasses may override this routine to provide different behavior.
819 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
821 /// Build a new block pointer type given its pointee type.
823 /// By default, performs semantic analysis when building the block pointer
824 /// type. Subclasses may override this routine to provide different behavior.
825 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
827 /// Build a new reference type given the type it references.
829 /// By default, performs semantic analysis when building the
830 /// reference type. Subclasses may override this routine to provide
831 /// different behavior.
833 /// \param LValue whether the type was written with an lvalue sigil
834 /// or an rvalue sigil.
835 QualType RebuildReferenceType(QualType ReferentType,
836 bool LValue,
837 SourceLocation Sigil);
839 /// Build a new member pointer type given the pointee type and the
840 /// class type it refers into.
842 /// By default, performs semantic analysis when building the member pointer
843 /// type. Subclasses may override this routine to provide different behavior.
844 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
845 SourceLocation Sigil);
847 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
848 SourceLocation ProtocolLAngleLoc,
849 ArrayRef<ObjCProtocolDecl *> Protocols,
850 ArrayRef<SourceLocation> ProtocolLocs,
851 SourceLocation ProtocolRAngleLoc);
853 /// Build an Objective-C object type.
855 /// By default, performs semantic analysis when building the object type.
856 /// Subclasses may override this routine to provide different behavior.
857 QualType RebuildObjCObjectType(QualType BaseType,
858 SourceLocation Loc,
859 SourceLocation TypeArgsLAngleLoc,
860 ArrayRef<TypeSourceInfo *> TypeArgs,
861 SourceLocation TypeArgsRAngleLoc,
862 SourceLocation ProtocolLAngleLoc,
863 ArrayRef<ObjCProtocolDecl *> Protocols,
864 ArrayRef<SourceLocation> ProtocolLocs,
865 SourceLocation ProtocolRAngleLoc);
867 /// Build a new Objective-C object pointer type given the pointee type.
869 /// By default, directly builds the pointer type, with no additional semantic
870 /// analysis.
871 QualType RebuildObjCObjectPointerType(QualType PointeeType,
872 SourceLocation Star);
874 /// Build a new array type given the element type, size
875 /// modifier, size of the array (if known), size expression, and index type
876 /// qualifiers.
878 /// By default, performs semantic analysis when building the array type.
879 /// Subclasses may override this routine to provide different behavior.
880 /// Also by default, all of the other Rebuild*Array
881 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
882 const llvm::APInt *Size, Expr *SizeExpr,
883 unsigned IndexTypeQuals, SourceRange BracketsRange);
885 /// Build a new constant array type given the element type, size
886 /// modifier, (known) size of the array, and index type qualifiers.
888 /// By default, performs semantic analysis when building the array type.
889 /// Subclasses may override this routine to provide different behavior.
890 QualType RebuildConstantArrayType(QualType ElementType,
891 ArraySizeModifier SizeMod,
892 const llvm::APInt &Size, Expr *SizeExpr,
893 unsigned IndexTypeQuals,
894 SourceRange BracketsRange);
896 /// Build a new incomplete array type given the element type, size
897 /// modifier, and index type qualifiers.
899 /// By default, performs semantic analysis when building the array type.
900 /// Subclasses may override this routine to provide different behavior.
901 QualType RebuildIncompleteArrayType(QualType ElementType,
902 ArraySizeModifier SizeMod,
903 unsigned IndexTypeQuals,
904 SourceRange BracketsRange);
906 /// Build a new variable-length array type given the element type,
907 /// size modifier, size expression, 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 RebuildVariableArrayType(QualType ElementType,
912 ArraySizeModifier SizeMod, Expr *SizeExpr,
913 unsigned IndexTypeQuals,
914 SourceRange BracketsRange);
916 /// Build a new dependent-sized array type given the element type,
917 /// size modifier, size expression, and index type qualifiers.
919 /// By default, performs semantic analysis when building the array type.
920 /// Subclasses may override this routine to provide different behavior.
921 QualType RebuildDependentSizedArrayType(QualType ElementType,
922 ArraySizeModifier SizeMod,
923 Expr *SizeExpr,
924 unsigned IndexTypeQuals,
925 SourceRange BracketsRange);
927 /// Build a new vector type given the element type and
928 /// number of elements.
930 /// By default, performs semantic analysis when building the vector type.
931 /// Subclasses may override this routine to provide different behavior.
932 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
933 VectorKind VecKind);
935 /// Build a new potentially dependently-sized extended vector type
936 /// given the element type and number of elements.
938 /// By default, performs semantic analysis when building the vector type.
939 /// Subclasses may override this routine to provide different behavior.
940 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
941 SourceLocation AttributeLoc, VectorKind);
943 /// Build a new extended vector type given the element type and
944 /// number of elements.
946 /// By default, performs semantic analysis when building the vector type.
947 /// Subclasses may override this routine to provide different behavior.
948 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
949 SourceLocation AttributeLoc);
951 /// Build a new potentially dependently-sized extended vector type
952 /// given the element type and number of elements.
954 /// By default, performs semantic analysis when building the vector type.
955 /// Subclasses may override this routine to provide different behavior.
956 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
957 Expr *SizeExpr,
958 SourceLocation AttributeLoc);
960 /// Build a new matrix type given the element type and dimensions.
961 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
962 unsigned NumColumns);
964 /// Build a new matrix type given the type and dependently-defined
965 /// dimensions.
966 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
967 Expr *ColumnExpr,
968 SourceLocation AttributeLoc);
970 /// Build a new DependentAddressSpaceType or return the pointee
971 /// type variable with the correct address space (retrieved from
972 /// AddrSpaceExpr) applied to it. The former will be returned in cases
973 /// where the address space remains dependent.
975 /// By default, performs semantic analysis when building the type with address
976 /// space applied. Subclasses may override this routine to provide different
977 /// behavior.
978 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
979 Expr *AddrSpaceExpr,
980 SourceLocation AttributeLoc);
982 /// Build a new function type.
984 /// By default, performs semantic analysis when building the function type.
985 /// Subclasses may override this routine to provide different behavior.
986 QualType RebuildFunctionProtoType(QualType T,
987 MutableArrayRef<QualType> ParamTypes,
988 const FunctionProtoType::ExtProtoInfo &EPI);
990 /// Build a new unprototyped function type.
991 QualType RebuildFunctionNoProtoType(QualType ResultType);
993 /// Rebuild an unresolved typename type, given the decl that
994 /// the UnresolvedUsingTypenameDecl was transformed to.
995 QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D);
997 /// Build a new type found via an alias.
998 QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying) {
999 return SemaRef.Context.getUsingType(Found, Underlying);
1002 /// Build a new typedef type.
1003 QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
1004 return SemaRef.Context.getTypeDeclType(Typedef);
1007 /// Build a new MacroDefined type.
1008 QualType RebuildMacroQualifiedType(QualType T,
1009 const IdentifierInfo *MacroII) {
1010 return SemaRef.Context.getMacroQualifiedType(T, MacroII);
1013 /// Build a new class/struct/union type.
1014 QualType RebuildRecordType(RecordDecl *Record) {
1015 return SemaRef.Context.getTypeDeclType(Record);
1018 /// Build a new Enum type.
1019 QualType RebuildEnumType(EnumDecl *Enum) {
1020 return SemaRef.Context.getTypeDeclType(Enum);
1023 /// Build a new typeof(expr) type.
1025 /// By default, performs semantic analysis when building the typeof type.
1026 /// Subclasses may override this routine to provide different behavior.
1027 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1028 TypeOfKind Kind);
1030 /// Build a new typeof(type) type.
1032 /// By default, builds a new TypeOfType with the given underlying type.
1033 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1035 /// Build a new unary transform type.
1036 QualType RebuildUnaryTransformType(QualType BaseType,
1037 UnaryTransformType::UTTKind UKind,
1038 SourceLocation Loc);
1040 /// Build a new C++11 decltype type.
1042 /// By default, performs semantic analysis when building the decltype type.
1043 /// Subclasses may override this routine to provide different behavior.
1044 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1046 /// Build a new C++11 auto type.
1048 /// By default, builds a new AutoType with the given deduced type.
1049 QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword,
1050 ConceptDecl *TypeConstraintConcept,
1051 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1052 // Note, IsDependent is always false here: we implicitly convert an 'auto'
1053 // which has been deduced to a dependent type into an undeduced 'auto', so
1054 // that we'll retry deduction after the transformation.
1055 return SemaRef.Context.getAutoType(Deduced, Keyword,
1056 /*IsDependent*/ false, /*IsPack=*/false,
1057 TypeConstraintConcept,
1058 TypeConstraintArgs);
1061 /// By default, builds a new DeducedTemplateSpecializationType with the given
1062 /// deduced type.
1063 QualType RebuildDeducedTemplateSpecializationType(TemplateName Template,
1064 QualType Deduced) {
1065 return SemaRef.Context.getDeducedTemplateSpecializationType(
1066 Template, Deduced, /*IsDependent*/ false);
1069 /// Build a new template specialization type.
1071 /// By default, performs semantic analysis when building the template
1072 /// specialization type. Subclasses may override this routine to provide
1073 /// different behavior.
1074 QualType RebuildTemplateSpecializationType(TemplateName Template,
1075 SourceLocation TemplateLoc,
1076 TemplateArgumentListInfo &Args);
1078 /// Build a new parenthesized type.
1080 /// By default, builds a new ParenType type from the inner type.
1081 /// Subclasses may override this routine to provide different behavior.
1082 QualType RebuildParenType(QualType InnerType) {
1083 return SemaRef.BuildParenType(InnerType);
1086 /// Build a new qualified name type.
1088 /// By default, builds a new ElaboratedType type from the keyword,
1089 /// the nested-name-specifier and the named type.
1090 /// Subclasses may override this routine to provide different behavior.
1091 QualType RebuildElaboratedType(SourceLocation KeywordLoc,
1092 ElaboratedTypeKeyword Keyword,
1093 NestedNameSpecifierLoc QualifierLoc,
1094 QualType Named) {
1095 return SemaRef.Context.getElaboratedType(Keyword,
1096 QualifierLoc.getNestedNameSpecifier(),
1097 Named);
1100 /// Build a new typename type that refers to a template-id.
1102 /// By default, builds a new DependentNameType type from the
1103 /// nested-name-specifier and the given type. Subclasses may override
1104 /// this routine to provide different behavior.
1105 QualType RebuildDependentTemplateSpecializationType(
1106 ElaboratedTypeKeyword Keyword,
1107 NestedNameSpecifierLoc QualifierLoc,
1108 SourceLocation TemplateKWLoc,
1109 const IdentifierInfo *Name,
1110 SourceLocation NameLoc,
1111 TemplateArgumentListInfo &Args,
1112 bool AllowInjectedClassName) {
1113 // Rebuild the template name.
1114 // TODO: avoid TemplateName abstraction
1115 CXXScopeSpec SS;
1116 SS.Adopt(QualifierLoc);
1117 TemplateName InstName = getDerived().RebuildTemplateName(
1118 SS, TemplateKWLoc, *Name, NameLoc, QualType(), nullptr,
1119 AllowInjectedClassName);
1121 if (InstName.isNull())
1122 return QualType();
1124 // If it's still dependent, make a dependent specialization.
1125 if (InstName.getAsDependentTemplateName())
1126 return SemaRef.Context.getDependentTemplateSpecializationType(
1127 Keyword, QualifierLoc.getNestedNameSpecifier(), Name,
1128 Args.arguments());
1130 // Otherwise, make an elaborated type wrapping a non-dependent
1131 // specialization.
1132 QualType T =
1133 getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
1134 if (T.isNull())
1135 return QualType();
1136 return SemaRef.Context.getElaboratedType(
1137 Keyword, QualifierLoc.getNestedNameSpecifier(), T);
1140 /// Build a new typename type that refers to an identifier.
1142 /// By default, performs semantic analysis when building the typename type
1143 /// (or elaborated type). Subclasses may override this routine to provide
1144 /// different behavior.
1145 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1146 SourceLocation KeywordLoc,
1147 NestedNameSpecifierLoc QualifierLoc,
1148 const IdentifierInfo *Id,
1149 SourceLocation IdLoc,
1150 bool DeducedTSTContext) {
1151 CXXScopeSpec SS;
1152 SS.Adopt(QualifierLoc);
1154 if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
1155 // If the name is still dependent, just build a new dependent name type.
1156 if (!SemaRef.computeDeclContext(SS))
1157 return SemaRef.Context.getDependentNameType(Keyword,
1158 QualifierLoc.getNestedNameSpecifier(),
1159 Id);
1162 if (Keyword == ElaboratedTypeKeyword::None ||
1163 Keyword == ElaboratedTypeKeyword::Typename) {
1164 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1165 *Id, IdLoc, DeducedTSTContext);
1168 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1170 // We had a dependent elaborated-type-specifier that has been transformed
1171 // into a non-dependent elaborated-type-specifier. Find the tag we're
1172 // referring to.
1173 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1174 DeclContext *DC = SemaRef.computeDeclContext(SS, false);
1175 if (!DC)
1176 return QualType();
1178 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1179 return QualType();
1181 TagDecl *Tag = nullptr;
1182 SemaRef.LookupQualifiedName(Result, DC);
1183 switch (Result.getResultKind()) {
1184 case LookupResult::NotFound:
1185 case LookupResult::NotFoundInCurrentInstantiation:
1186 break;
1188 case LookupResult::Found:
1189 Tag = Result.getAsSingle<TagDecl>();
1190 break;
1192 case LookupResult::FoundOverloaded:
1193 case LookupResult::FoundUnresolvedValue:
1194 llvm_unreachable("Tag lookup cannot find non-tags");
1196 case LookupResult::Ambiguous:
1197 // Let the LookupResult structure handle ambiguities.
1198 return QualType();
1201 if (!Tag) {
1202 // Check where the name exists but isn't a tag type and use that to emit
1203 // better diagnostics.
1204 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1205 SemaRef.LookupQualifiedName(Result, DC);
1206 switch (Result.getResultKind()) {
1207 case LookupResult::Found:
1208 case LookupResult::FoundOverloaded:
1209 case LookupResult::FoundUnresolvedValue: {
1210 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1211 Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind);
1212 SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag)
1213 << SomeDecl << NTK << llvm::to_underlying(Kind);
1214 SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
1215 break;
1217 default:
1218 SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
1219 << llvm::to_underlying(Kind) << Id << DC
1220 << QualifierLoc.getSourceRange();
1221 break;
1223 return QualType();
1226 if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false,
1227 IdLoc, Id)) {
1228 SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
1229 SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
1230 return QualType();
1233 // Build the elaborated-type-specifier type.
1234 QualType T = SemaRef.Context.getTypeDeclType(Tag);
1235 return SemaRef.Context.getElaboratedType(Keyword,
1236 QualifierLoc.getNestedNameSpecifier(),
1240 /// Build a new pack expansion type.
1242 /// By default, builds a new PackExpansionType type from the given pattern.
1243 /// Subclasses may override this routine to provide different behavior.
1244 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1245 SourceLocation EllipsisLoc,
1246 std::optional<unsigned> NumExpansions) {
1247 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1248 NumExpansions);
1251 /// Build a new atomic type given its value type.
1253 /// By default, performs semantic analysis when building the atomic type.
1254 /// Subclasses may override this routine to provide different behavior.
1255 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1257 /// Build a new pipe type given its value type.
1258 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1259 bool isReadPipe);
1261 /// Build a bit-precise int given its value type.
1262 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1263 SourceLocation Loc);
1265 /// Build a dependent bit-precise int given its value type.
1266 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1267 SourceLocation Loc);
1269 /// Build a new template name given a nested name specifier, a flag
1270 /// indicating whether the "template" keyword was provided, and the template
1271 /// that the template name refers to.
1273 /// By default, builds the new template name directly. Subclasses may override
1274 /// this routine to provide different behavior.
1275 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1276 bool TemplateKW,
1277 TemplateDecl *Template);
1279 /// Build a new template name given a nested name specifier and the
1280 /// name that is referred to as a template.
1282 /// By default, performs semantic analysis to determine whether the name can
1283 /// be resolved to a specific template, then builds the appropriate kind of
1284 /// template name. Subclasses may override this routine to provide different
1285 /// behavior.
1286 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1287 SourceLocation TemplateKWLoc,
1288 const IdentifierInfo &Name,
1289 SourceLocation NameLoc, QualType ObjectType,
1290 NamedDecl *FirstQualifierInScope,
1291 bool AllowInjectedClassName);
1293 /// Build a new template name given a nested name specifier and the
1294 /// overloaded operator name that is referred to as a template.
1296 /// By default, performs semantic analysis to determine whether the name can
1297 /// be resolved to a specific template, then builds the appropriate kind of
1298 /// template name. Subclasses may override this routine to provide different
1299 /// behavior.
1300 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1301 SourceLocation TemplateKWLoc,
1302 OverloadedOperatorKind Operator,
1303 SourceLocation NameLoc, QualType ObjectType,
1304 bool AllowInjectedClassName);
1306 /// Build a new template name given a template template parameter pack
1307 /// and the
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(const TemplateArgument &ArgPack,
1314 Decl *AssociatedDecl, unsigned Index,
1315 bool Final) {
1316 return getSema().Context.getSubstTemplateTemplateParmPack(
1317 ArgPack, AssociatedDecl, Index, Final);
1320 /// Build a new compound statement.
1322 /// By default, performs semantic analysis to build the new statement.
1323 /// Subclasses may override this routine to provide different behavior.
1324 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1325 MultiStmtArg Statements,
1326 SourceLocation RBraceLoc,
1327 bool IsStmtExpr) {
1328 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1329 IsStmtExpr);
1332 /// Build a new case statement.
1334 /// By default, performs semantic analysis to build the new statement.
1335 /// Subclasses may override this routine to provide different behavior.
1336 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1337 Expr *LHS,
1338 SourceLocation EllipsisLoc,
1339 Expr *RHS,
1340 SourceLocation ColonLoc) {
1341 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1342 ColonLoc);
1345 /// Attach the body to a new case statement.
1347 /// By default, performs semantic analysis to build the new statement.
1348 /// Subclasses may override this routine to provide different behavior.
1349 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1350 getSema().ActOnCaseStmtBody(S, Body);
1351 return S;
1354 /// Build a new default statement.
1356 /// By default, performs semantic analysis to build the new statement.
1357 /// Subclasses may override this routine to provide different behavior.
1358 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1359 SourceLocation ColonLoc,
1360 Stmt *SubStmt) {
1361 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1362 /*CurScope=*/nullptr);
1365 /// Build a new label statement.
1367 /// By default, performs semantic analysis to build the new statement.
1368 /// Subclasses may override this routine to provide different behavior.
1369 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1370 SourceLocation ColonLoc, Stmt *SubStmt) {
1371 return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt);
1374 /// Build a new attributed statement.
1376 /// By default, performs semantic analysis to build the new statement.
1377 /// Subclasses may override this routine to provide different behavior.
1378 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1379 ArrayRef<const Attr *> Attrs,
1380 Stmt *SubStmt) {
1381 return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt);
1384 /// Build a new "if" statement.
1386 /// By default, performs semantic analysis to build the new statement.
1387 /// Subclasses may override this routine to provide different behavior.
1388 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1389 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1390 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1391 SourceLocation ElseLoc, Stmt *Else) {
1392 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1393 Then, ElseLoc, Else);
1396 /// Start building a new switch statement.
1398 /// By default, performs semantic analysis to build the new statement.
1399 /// Subclasses may override this routine to provide different behavior.
1400 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1401 SourceLocation LParenLoc, Stmt *Init,
1402 Sema::ConditionResult Cond,
1403 SourceLocation RParenLoc) {
1404 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1405 RParenLoc);
1408 /// Attach the body to the switch statement.
1410 /// By default, performs semantic analysis to build the new statement.
1411 /// Subclasses may override this routine to provide different behavior.
1412 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1413 Stmt *Switch, Stmt *Body) {
1414 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1417 /// Build a new while statement.
1419 /// By default, performs semantic analysis to build the new statement.
1420 /// Subclasses may override this routine to provide different behavior.
1421 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1422 Sema::ConditionResult Cond,
1423 SourceLocation RParenLoc, Stmt *Body) {
1424 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1427 /// Build a new do-while statement.
1429 /// By default, performs semantic analysis to build the new statement.
1430 /// Subclasses may override this routine to provide different behavior.
1431 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1432 SourceLocation WhileLoc, SourceLocation LParenLoc,
1433 Expr *Cond, SourceLocation RParenLoc) {
1434 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1435 Cond, RParenLoc);
1438 /// Build a new for statement.
1440 /// By default, performs semantic analysis to build the new statement.
1441 /// Subclasses may override this routine to provide different behavior.
1442 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1443 Stmt *Init, Sema::ConditionResult Cond,
1444 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1445 Stmt *Body) {
1446 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1447 Inc, RParenLoc, Body);
1450 /// Build a new goto statement.
1452 /// By default, performs semantic analysis to build the new statement.
1453 /// Subclasses may override this routine to provide different behavior.
1454 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1455 LabelDecl *Label) {
1456 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1459 /// Build a new indirect goto statement.
1461 /// By default, performs semantic analysis to build the new statement.
1462 /// Subclasses may override this routine to provide different behavior.
1463 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1464 SourceLocation StarLoc,
1465 Expr *Target) {
1466 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1469 /// Build a new return statement.
1471 /// By default, performs semantic analysis to build the new statement.
1472 /// Subclasses may override this routine to provide different behavior.
1473 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1474 return getSema().BuildReturnStmt(ReturnLoc, Result);
1477 /// Build a new declaration statement.
1479 /// By default, performs semantic analysis to build the new statement.
1480 /// Subclasses may override this routine to provide different behavior.
1481 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1482 SourceLocation StartLoc, SourceLocation EndLoc) {
1483 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1484 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1487 /// Build a new inline asm statement.
1489 /// By default, performs semantic analysis to build the new statement.
1490 /// Subclasses may override this routine to provide different behavior.
1491 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1492 bool IsVolatile, unsigned NumOutputs,
1493 unsigned NumInputs, IdentifierInfo **Names,
1494 MultiExprArg Constraints, MultiExprArg Exprs,
1495 Expr *AsmString, MultiExprArg Clobbers,
1496 unsigned NumLabels,
1497 SourceLocation RParenLoc) {
1498 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1499 NumInputs, Names, Constraints, Exprs,
1500 AsmString, Clobbers, NumLabels, RParenLoc);
1503 /// Build a new MS style inline asm statement.
1505 /// By default, performs semantic analysis to build the new statement.
1506 /// Subclasses may override this routine to provide different behavior.
1507 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1508 ArrayRef<Token> AsmToks,
1509 StringRef AsmString,
1510 unsigned NumOutputs, unsigned NumInputs,
1511 ArrayRef<StringRef> Constraints,
1512 ArrayRef<StringRef> Clobbers,
1513 ArrayRef<Expr*> Exprs,
1514 SourceLocation EndLoc) {
1515 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1516 NumOutputs, NumInputs,
1517 Constraints, Clobbers, Exprs, EndLoc);
1520 /// Build a new co_return statement.
1522 /// By default, performs semantic analysis to build the new statement.
1523 /// Subclasses may override this routine to provide different behavior.
1524 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1525 bool IsImplicit) {
1526 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1529 /// Build a new co_await expression.
1531 /// By default, performs semantic analysis to build the new expression.
1532 /// Subclasses may override this routine to provide different behavior.
1533 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1534 UnresolvedLookupExpr *OpCoawaitLookup,
1535 bool IsImplicit) {
1536 // This function rebuilds a coawait-expr given its operator.
1537 // For an explicit coawait-expr, the rebuild involves the full set
1538 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1539 // including calling await_transform().
1540 // For an implicit coawait-expr, we need to rebuild the "operator
1541 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1542 // This mirrors how the implicit CoawaitExpr is originally created
1543 // in Sema::ActOnCoroutineBodyStart().
1544 if (IsImplicit) {
1545 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1546 CoawaitLoc, Operand, OpCoawaitLookup);
1547 if (Suspend.isInvalid())
1548 return ExprError();
1549 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1550 Suspend.get(), true);
1553 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1554 OpCoawaitLookup);
1557 /// Build a new co_await expression.
1559 /// By default, performs semantic analysis to build the new expression.
1560 /// Subclasses may override this routine to provide different behavior.
1561 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1562 Expr *Result,
1563 UnresolvedLookupExpr *Lookup) {
1564 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1567 /// Build a new co_yield expression.
1569 /// By default, performs semantic analysis to build the new expression.
1570 /// Subclasses may override this routine to provide different behavior.
1571 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1572 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1575 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1576 return getSema().BuildCoroutineBodyStmt(Args);
1579 /// Build a new Objective-C \@try statement.
1581 /// By default, performs semantic analysis to build the new statement.
1582 /// Subclasses may override this routine to provide different behavior.
1583 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1584 Stmt *TryBody,
1585 MultiStmtArg CatchStmts,
1586 Stmt *Finally) {
1587 return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1588 Finally);
1591 /// Rebuild an Objective-C exception declaration.
1593 /// By default, performs semantic analysis to build the new declaration.
1594 /// Subclasses may override this routine to provide different behavior.
1595 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1596 TypeSourceInfo *TInfo, QualType T) {
1597 return getSema().BuildObjCExceptionDecl(TInfo, T,
1598 ExceptionDecl->getInnerLocStart(),
1599 ExceptionDecl->getLocation(),
1600 ExceptionDecl->getIdentifier());
1603 /// Build a new Objective-C \@catch statement.
1605 /// By default, performs semantic analysis to build the new statement.
1606 /// Subclasses may override this routine to provide different behavior.
1607 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1608 SourceLocation RParenLoc,
1609 VarDecl *Var,
1610 Stmt *Body) {
1611 return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
1612 Var, Body);
1615 /// Build a new Objective-C \@finally statement.
1617 /// By default, performs semantic analysis to build the new statement.
1618 /// Subclasses may override this routine to provide different behavior.
1619 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1620 Stmt *Body) {
1621 return getSema().ActOnObjCAtFinallyStmt(AtLoc, Body);
1624 /// Build a new Objective-C \@throw statement.
1626 /// By default, performs semantic analysis to build the new statement.
1627 /// Subclasses may override this routine to provide different behavior.
1628 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1629 Expr *Operand) {
1630 return getSema().BuildObjCAtThrowStmt(AtLoc, Operand);
1633 /// Build a new OpenMP Canonical loop.
1635 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1636 /// OMPCanonicalLoop.
1637 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1638 return getSema().ActOnOpenMPCanonicalLoop(LoopStmt);
1641 /// Build a new OpenMP executable directive.
1643 /// By default, performs semantic analysis to build the new statement.
1644 /// Subclasses may override this routine to provide different behavior.
1645 StmtResult RebuildOMPExecutableDirective(
1646 OpenMPDirectiveKind Kind, DeclarationNameInfo DirName,
1647 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
1648 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
1649 OpenMPDirectiveKind PrevMappedDirective = OMPD_unknown) {
1651 return getSema().ActOnOpenMPExecutableDirective(
1652 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc,
1653 PrevMappedDirective);
1656 /// Build a new OpenMP 'if' clause.
1658 /// By default, performs semantic analysis to build the new OpenMP clause.
1659 /// Subclasses may override this routine to provide different behavior.
1660 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1661 Expr *Condition, SourceLocation StartLoc,
1662 SourceLocation LParenLoc,
1663 SourceLocation NameModifierLoc,
1664 SourceLocation ColonLoc,
1665 SourceLocation EndLoc) {
1666 return getSema().ActOnOpenMPIfClause(NameModifier, Condition, StartLoc,
1667 LParenLoc, NameModifierLoc, ColonLoc,
1668 EndLoc);
1671 /// Build a new OpenMP 'final' clause.
1673 /// By default, performs semantic analysis to build the new OpenMP clause.
1674 /// Subclasses may override this routine to provide different behavior.
1675 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1676 SourceLocation LParenLoc,
1677 SourceLocation EndLoc) {
1678 return getSema().ActOnOpenMPFinalClause(Condition, StartLoc, LParenLoc,
1679 EndLoc);
1682 /// Build a new OpenMP 'num_threads' clause.
1684 /// By default, performs semantic analysis to build the new OpenMP clause.
1685 /// Subclasses may override this routine to provide different behavior.
1686 OMPClause *RebuildOMPNumThreadsClause(Expr *NumThreads,
1687 SourceLocation StartLoc,
1688 SourceLocation LParenLoc,
1689 SourceLocation EndLoc) {
1690 return getSema().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc,
1691 LParenLoc, EndLoc);
1694 /// Build a new OpenMP 'safelen' clause.
1696 /// By default, performs semantic analysis to build the new OpenMP clause.
1697 /// Subclasses may override this routine to provide different behavior.
1698 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1699 SourceLocation LParenLoc,
1700 SourceLocation EndLoc) {
1701 return getSema().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc, EndLoc);
1704 /// Build a new OpenMP 'simdlen' clause.
1706 /// By default, performs semantic analysis to build the new OpenMP clause.
1707 /// Subclasses may override this routine to provide different behavior.
1708 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1709 SourceLocation LParenLoc,
1710 SourceLocation EndLoc) {
1711 return getSema().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc, EndLoc);
1714 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1715 SourceLocation StartLoc,
1716 SourceLocation LParenLoc,
1717 SourceLocation EndLoc) {
1718 return getSema().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc, EndLoc);
1721 /// Build a new OpenMP 'full' clause.
1722 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1723 SourceLocation EndLoc) {
1724 return getSema().ActOnOpenMPFullClause(StartLoc, EndLoc);
1727 /// Build a new OpenMP 'partial' clause.
1728 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1729 SourceLocation LParenLoc,
1730 SourceLocation EndLoc) {
1731 return getSema().ActOnOpenMPPartialClause(Factor, StartLoc, LParenLoc,
1732 EndLoc);
1735 /// Build a new OpenMP 'allocator' clause.
1737 /// By default, performs semantic analysis to build the new OpenMP clause.
1738 /// Subclasses may override this routine to provide different behavior.
1739 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1740 SourceLocation LParenLoc,
1741 SourceLocation EndLoc) {
1742 return getSema().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc, EndLoc);
1745 /// Build a new OpenMP 'collapse' clause.
1747 /// By default, performs semantic analysis to build the new OpenMP clause.
1748 /// Subclasses may override this routine to provide different behavior.
1749 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1750 SourceLocation LParenLoc,
1751 SourceLocation EndLoc) {
1752 return getSema().ActOnOpenMPCollapseClause(Num, StartLoc, LParenLoc,
1753 EndLoc);
1756 /// Build a new OpenMP 'default' clause.
1758 /// By default, performs semantic analysis to build the new OpenMP clause.
1759 /// Subclasses may override this routine to provide different behavior.
1760 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1761 SourceLocation StartLoc,
1762 SourceLocation LParenLoc,
1763 SourceLocation EndLoc) {
1764 return getSema().ActOnOpenMPDefaultClause(Kind, KindKwLoc,
1765 StartLoc, LParenLoc, EndLoc);
1768 /// Build a new OpenMP 'proc_bind' clause.
1770 /// By default, performs semantic analysis to build the new OpenMP clause.
1771 /// Subclasses may override this routine to provide different behavior.
1772 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1773 SourceLocation KindKwLoc,
1774 SourceLocation StartLoc,
1775 SourceLocation LParenLoc,
1776 SourceLocation EndLoc) {
1777 return getSema().ActOnOpenMPProcBindClause(Kind, KindKwLoc,
1778 StartLoc, LParenLoc, EndLoc);
1781 /// Build a new OpenMP 'schedule' clause.
1783 /// By default, performs semantic analysis to build the new OpenMP clause.
1784 /// Subclasses may override this routine to provide different behavior.
1785 OMPClause *RebuildOMPScheduleClause(
1786 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1787 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1788 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1789 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1790 return getSema().ActOnOpenMPScheduleClause(
1791 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1792 CommaLoc, EndLoc);
1795 /// Build a new OpenMP 'ordered' clause.
1797 /// By default, performs semantic analysis to build the new OpenMP clause.
1798 /// Subclasses may override this routine to provide different behavior.
1799 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1800 SourceLocation EndLoc,
1801 SourceLocation LParenLoc, Expr *Num) {
1802 return getSema().ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Num);
1805 /// Build a new OpenMP 'private' clause.
1807 /// By default, performs semantic analysis to build the new OpenMP clause.
1808 /// Subclasses may override this routine to provide different behavior.
1809 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1810 SourceLocation StartLoc,
1811 SourceLocation LParenLoc,
1812 SourceLocation EndLoc) {
1813 return getSema().ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc,
1814 EndLoc);
1817 /// Build a new OpenMP 'firstprivate' clause.
1819 /// By default, performs semantic analysis to build the new OpenMP clause.
1820 /// Subclasses may override this routine to provide different behavior.
1821 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1822 SourceLocation StartLoc,
1823 SourceLocation LParenLoc,
1824 SourceLocation EndLoc) {
1825 return getSema().ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc,
1826 EndLoc);
1829 /// Build a new OpenMP 'lastprivate' clause.
1831 /// By default, performs semantic analysis to build the new OpenMP clause.
1832 /// Subclasses may override this routine to provide different behavior.
1833 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1834 OpenMPLastprivateModifier LPKind,
1835 SourceLocation LPKindLoc,
1836 SourceLocation ColonLoc,
1837 SourceLocation StartLoc,
1838 SourceLocation LParenLoc,
1839 SourceLocation EndLoc) {
1840 return getSema().ActOnOpenMPLastprivateClause(
1841 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1844 /// Build a new OpenMP 'shared' clause.
1846 /// By default, performs semantic analysis to build the new OpenMP clause.
1847 /// Subclasses may override this routine to provide different behavior.
1848 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1849 SourceLocation StartLoc,
1850 SourceLocation LParenLoc,
1851 SourceLocation EndLoc) {
1852 return getSema().ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc,
1853 EndLoc);
1856 /// Build a new OpenMP 'reduction' clause.
1858 /// By default, performs semantic analysis to build the new statement.
1859 /// Subclasses may override this routine to provide different behavior.
1860 OMPClause *RebuildOMPReductionClause(
1861 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1862 SourceLocation StartLoc, SourceLocation LParenLoc,
1863 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1864 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1865 const DeclarationNameInfo &ReductionId,
1866 ArrayRef<Expr *> UnresolvedReductions) {
1867 return getSema().ActOnOpenMPReductionClause(
1868 VarList, Modifier, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
1869 ReductionIdScopeSpec, ReductionId, UnresolvedReductions);
1872 /// Build a new OpenMP 'task_reduction' clause.
1874 /// By default, performs semantic analysis to build the new statement.
1875 /// Subclasses may override this routine to provide different behavior.
1876 OMPClause *RebuildOMPTaskReductionClause(
1877 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1878 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1879 CXXScopeSpec &ReductionIdScopeSpec,
1880 const DeclarationNameInfo &ReductionId,
1881 ArrayRef<Expr *> UnresolvedReductions) {
1882 return getSema().ActOnOpenMPTaskReductionClause(
1883 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1884 ReductionId, UnresolvedReductions);
1887 /// Build a new OpenMP 'in_reduction' clause.
1889 /// By default, performs semantic analysis to build the new statement.
1890 /// Subclasses may override this routine to provide different behavior.
1891 OMPClause *
1892 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1893 SourceLocation LParenLoc, SourceLocation ColonLoc,
1894 SourceLocation EndLoc,
1895 CXXScopeSpec &ReductionIdScopeSpec,
1896 const DeclarationNameInfo &ReductionId,
1897 ArrayRef<Expr *> UnresolvedReductions) {
1898 return getSema().ActOnOpenMPInReductionClause(
1899 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1900 ReductionId, UnresolvedReductions);
1903 /// Build a new OpenMP 'linear' clause.
1905 /// By default, performs semantic analysis to build the new OpenMP clause.
1906 /// Subclasses may override this routine to provide different behavior.
1907 OMPClause *RebuildOMPLinearClause(
1908 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1909 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1910 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1911 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
1912 return getSema().ActOnOpenMPLinearClause(VarList, Step, StartLoc, LParenLoc,
1913 Modifier, ModifierLoc, ColonLoc,
1914 StepModifierLoc, EndLoc);
1917 /// Build a new OpenMP 'aligned' clause.
1919 /// By default, performs semantic analysis to build the new OpenMP clause.
1920 /// Subclasses may override this routine to provide different behavior.
1921 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
1922 SourceLocation StartLoc,
1923 SourceLocation LParenLoc,
1924 SourceLocation ColonLoc,
1925 SourceLocation EndLoc) {
1926 return getSema().ActOnOpenMPAlignedClause(VarList, Alignment, StartLoc,
1927 LParenLoc, ColonLoc, EndLoc);
1930 /// Build a new OpenMP 'copyin' clause.
1932 /// By default, performs semantic analysis to build the new OpenMP clause.
1933 /// Subclasses may override this routine to provide different behavior.
1934 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
1935 SourceLocation StartLoc,
1936 SourceLocation LParenLoc,
1937 SourceLocation EndLoc) {
1938 return getSema().ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc,
1939 EndLoc);
1942 /// Build a new OpenMP 'copyprivate' clause.
1944 /// By default, performs semantic analysis to build the new OpenMP clause.
1945 /// Subclasses may override this routine to provide different behavior.
1946 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
1947 SourceLocation StartLoc,
1948 SourceLocation LParenLoc,
1949 SourceLocation EndLoc) {
1950 return getSema().ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc,
1951 EndLoc);
1954 /// Build a new OpenMP 'flush' pseudo clause.
1956 /// By default, performs semantic analysis to build the new OpenMP clause.
1957 /// Subclasses may override this routine to provide different behavior.
1958 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
1959 SourceLocation StartLoc,
1960 SourceLocation LParenLoc,
1961 SourceLocation EndLoc) {
1962 return getSema().ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc,
1963 EndLoc);
1966 /// Build a new OpenMP 'depobj' pseudo clause.
1968 /// By default, performs semantic analysis to build the new OpenMP clause.
1969 /// Subclasses may override this routine to provide different behavior.
1970 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
1971 SourceLocation LParenLoc,
1972 SourceLocation EndLoc) {
1973 return getSema().ActOnOpenMPDepobjClause(Depobj, StartLoc, LParenLoc,
1974 EndLoc);
1977 /// Build a new OpenMP 'depend' pseudo clause.
1979 /// By default, performs semantic analysis to build the new OpenMP clause.
1980 /// Subclasses may override this routine to provide different behavior.
1981 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
1982 Expr *DepModifier, ArrayRef<Expr *> VarList,
1983 SourceLocation StartLoc,
1984 SourceLocation LParenLoc,
1985 SourceLocation EndLoc) {
1986 return getSema().ActOnOpenMPDependClause(Data, DepModifier, VarList,
1987 StartLoc, LParenLoc, EndLoc);
1990 /// Build a new OpenMP 'device' clause.
1992 /// By default, performs semantic analysis to build the new statement.
1993 /// Subclasses may override this routine to provide different behavior.
1994 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
1995 Expr *Device, SourceLocation StartLoc,
1996 SourceLocation LParenLoc,
1997 SourceLocation ModifierLoc,
1998 SourceLocation EndLoc) {
1999 return getSema().ActOnOpenMPDeviceClause(Modifier, Device, StartLoc,
2000 LParenLoc, ModifierLoc, EndLoc);
2003 /// Build a new OpenMP 'map' clause.
2005 /// By default, performs semantic analysis to build the new OpenMP clause.
2006 /// Subclasses may override this routine to provide different behavior.
2007 OMPClause *RebuildOMPMapClause(
2008 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2009 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2010 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2011 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2012 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2013 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2014 return getSema().ActOnOpenMPMapClause(
2015 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2016 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2017 ColonLoc, VarList, Locs,
2018 /*NoDiagnose=*/false, UnresolvedMappers);
2021 /// Build a new OpenMP 'allocate' clause.
2023 /// By default, performs semantic analysis to build the new OpenMP clause.
2024 /// Subclasses may override this routine to provide different behavior.
2025 OMPClause *RebuildOMPAllocateClause(Expr *Allocate, ArrayRef<Expr *> VarList,
2026 SourceLocation StartLoc,
2027 SourceLocation LParenLoc,
2028 SourceLocation ColonLoc,
2029 SourceLocation EndLoc) {
2030 return getSema().ActOnOpenMPAllocateClause(Allocate, VarList, StartLoc,
2031 LParenLoc, ColonLoc, EndLoc);
2034 /// Build a new OpenMP 'num_teams' clause.
2036 /// By default, performs semantic analysis to build the new statement.
2037 /// Subclasses may override this routine to provide different behavior.
2038 OMPClause *RebuildOMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc,
2039 SourceLocation LParenLoc,
2040 SourceLocation EndLoc) {
2041 return getSema().ActOnOpenMPNumTeamsClause(NumTeams, StartLoc, LParenLoc,
2042 EndLoc);
2045 /// Build a new OpenMP 'thread_limit' clause.
2047 /// By default, performs semantic analysis to build the new statement.
2048 /// Subclasses may override this routine to provide different behavior.
2049 OMPClause *RebuildOMPThreadLimitClause(Expr *ThreadLimit,
2050 SourceLocation StartLoc,
2051 SourceLocation LParenLoc,
2052 SourceLocation EndLoc) {
2053 return getSema().ActOnOpenMPThreadLimitClause(ThreadLimit, StartLoc,
2054 LParenLoc, EndLoc);
2057 /// Build a new OpenMP 'priority' clause.
2059 /// By default, performs semantic analysis to build the new statement.
2060 /// Subclasses may override this routine to provide different behavior.
2061 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2062 SourceLocation LParenLoc,
2063 SourceLocation EndLoc) {
2064 return getSema().ActOnOpenMPPriorityClause(Priority, StartLoc, LParenLoc,
2065 EndLoc);
2068 /// Build a new OpenMP 'grainsize' clause.
2070 /// By default, performs semantic analysis to build the new statement.
2071 /// Subclasses may override this routine to provide different behavior.
2072 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2073 Expr *Device, SourceLocation StartLoc,
2074 SourceLocation LParenLoc,
2075 SourceLocation ModifierLoc,
2076 SourceLocation EndLoc) {
2077 return getSema().ActOnOpenMPGrainsizeClause(Modifier, Device, StartLoc,
2078 LParenLoc, ModifierLoc, EndLoc);
2081 /// Build a new OpenMP 'num_tasks' clause.
2083 /// By default, performs semantic analysis to build the new statement.
2084 /// Subclasses may override this routine to provide different behavior.
2085 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2086 Expr *NumTasks, SourceLocation StartLoc,
2087 SourceLocation LParenLoc,
2088 SourceLocation ModifierLoc,
2089 SourceLocation EndLoc) {
2090 return getSema().ActOnOpenMPNumTasksClause(Modifier, NumTasks, StartLoc,
2091 LParenLoc, ModifierLoc, EndLoc);
2094 /// Build a new OpenMP 'hint' clause.
2096 /// By default, performs semantic analysis to build the new statement.
2097 /// Subclasses may override this routine to provide different behavior.
2098 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2099 SourceLocation LParenLoc,
2100 SourceLocation EndLoc) {
2101 return getSema().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc, EndLoc);
2104 /// Build a new OpenMP 'detach' clause.
2106 /// By default, performs semantic analysis to build the new statement.
2107 /// Subclasses may override this routine to provide different behavior.
2108 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2109 SourceLocation LParenLoc,
2110 SourceLocation EndLoc) {
2111 return getSema().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
2114 /// Build a new OpenMP 'dist_schedule' clause.
2116 /// By default, performs semantic analysis to build the new OpenMP clause.
2117 /// Subclasses may override this routine to provide different behavior.
2118 OMPClause *
2119 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2120 Expr *ChunkSize, SourceLocation StartLoc,
2121 SourceLocation LParenLoc, SourceLocation KindLoc,
2122 SourceLocation CommaLoc, SourceLocation EndLoc) {
2123 return getSema().ActOnOpenMPDistScheduleClause(
2124 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2127 /// Build a new OpenMP 'to' clause.
2129 /// By default, performs semantic analysis to build the new statement.
2130 /// Subclasses may override this routine to provide different behavior.
2131 OMPClause *
2132 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2133 ArrayRef<SourceLocation> MotionModifiersLoc,
2134 CXXScopeSpec &MapperIdScopeSpec,
2135 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2136 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2137 ArrayRef<Expr *> UnresolvedMappers) {
2138 return getSema().ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
2139 MapperIdScopeSpec, MapperId, ColonLoc,
2140 VarList, Locs, UnresolvedMappers);
2143 /// Build a new OpenMP 'from' clause.
2145 /// By default, performs semantic analysis to build the new statement.
2146 /// Subclasses may override this routine to provide different behavior.
2147 OMPClause *
2148 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2149 ArrayRef<SourceLocation> MotionModifiersLoc,
2150 CXXScopeSpec &MapperIdScopeSpec,
2151 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2152 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2153 ArrayRef<Expr *> UnresolvedMappers) {
2154 return getSema().ActOnOpenMPFromClause(
2155 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2156 ColonLoc, VarList, Locs, UnresolvedMappers);
2159 /// Build a new OpenMP 'use_device_ptr' clause.
2161 /// By default, performs semantic analysis to build the new OpenMP clause.
2162 /// Subclasses may override this routine to provide different behavior.
2163 OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
2164 const OMPVarListLocTy &Locs) {
2165 return getSema().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2168 /// Build a new OpenMP 'use_device_addr' clause.
2170 /// By default, performs semantic analysis to build the new OpenMP clause.
2171 /// Subclasses may override this routine to provide different behavior.
2172 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2173 const OMPVarListLocTy &Locs) {
2174 return getSema().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2177 /// Build a new OpenMP 'is_device_ptr' clause.
2179 /// By default, performs semantic analysis to build the new OpenMP clause.
2180 /// Subclasses may override this routine to provide different behavior.
2181 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2182 const OMPVarListLocTy &Locs) {
2183 return getSema().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2186 /// Build a new OpenMP 'has_device_addr' clause.
2188 /// By default, performs semantic analysis to build the new OpenMP clause.
2189 /// Subclasses may override this routine to provide different behavior.
2190 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2191 const OMPVarListLocTy &Locs) {
2192 return getSema().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2195 /// Build a new OpenMP 'defaultmap' clause.
2197 /// By default, performs semantic analysis to build the new OpenMP clause.
2198 /// Subclasses may override this routine to provide different behavior.
2199 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2200 OpenMPDefaultmapClauseKind Kind,
2201 SourceLocation StartLoc,
2202 SourceLocation LParenLoc,
2203 SourceLocation MLoc,
2204 SourceLocation KindLoc,
2205 SourceLocation EndLoc) {
2206 return getSema().ActOnOpenMPDefaultmapClause(M, Kind, StartLoc, LParenLoc,
2207 MLoc, KindLoc, EndLoc);
2210 /// Build a new OpenMP 'nontemporal' clause.
2212 /// By default, performs semantic analysis to build the new OpenMP clause.
2213 /// Subclasses may override this routine to provide different behavior.
2214 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2215 SourceLocation StartLoc,
2216 SourceLocation LParenLoc,
2217 SourceLocation EndLoc) {
2218 return getSema().ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc,
2219 EndLoc);
2222 /// Build a new OpenMP 'inclusive' clause.
2224 /// By default, performs semantic analysis to build the new OpenMP clause.
2225 /// Subclasses may override this routine to provide different behavior.
2226 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2227 SourceLocation StartLoc,
2228 SourceLocation LParenLoc,
2229 SourceLocation EndLoc) {
2230 return getSema().ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc,
2231 EndLoc);
2234 /// Build a new OpenMP 'exclusive' clause.
2236 /// By default, performs semantic analysis to build the new OpenMP clause.
2237 /// Subclasses may override this routine to provide different behavior.
2238 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2239 SourceLocation StartLoc,
2240 SourceLocation LParenLoc,
2241 SourceLocation EndLoc) {
2242 return getSema().ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc,
2243 EndLoc);
2246 /// Build a new OpenMP 'uses_allocators' clause.
2248 /// By default, performs semantic analysis to build the new OpenMP clause.
2249 /// Subclasses may override this routine to provide different behavior.
2250 OMPClause *RebuildOMPUsesAllocatorsClause(
2251 ArrayRef<Sema::UsesAllocatorsData> Data, SourceLocation StartLoc,
2252 SourceLocation LParenLoc, SourceLocation EndLoc) {
2253 return getSema().ActOnOpenMPUsesAllocatorClause(StartLoc, LParenLoc, EndLoc,
2254 Data);
2257 /// Build a new OpenMP 'affinity' clause.
2259 /// By default, performs semantic analysis to build the new OpenMP clause.
2260 /// Subclasses may override this routine to provide different behavior.
2261 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2262 SourceLocation LParenLoc,
2263 SourceLocation ColonLoc,
2264 SourceLocation EndLoc, Expr *Modifier,
2265 ArrayRef<Expr *> Locators) {
2266 return getSema().ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc,
2267 EndLoc, Modifier, Locators);
2270 /// Build a new OpenMP 'order' clause.
2272 /// By default, performs semantic analysis to build the new OpenMP clause.
2273 /// Subclasses may override this routine to provide different behavior.
2274 OMPClause *RebuildOMPOrderClause(
2275 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2276 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2277 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2278 return getSema().ActOnOpenMPOrderClause(Modifier, Kind, StartLoc, LParenLoc,
2279 ModifierKwLoc, KindKwLoc, EndLoc);
2282 /// Build a new OpenMP 'init' clause.
2284 /// By default, performs semantic analysis to build the new OpenMP clause.
2285 /// Subclasses may override this routine to provide different behavior.
2286 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2287 SourceLocation StartLoc,
2288 SourceLocation LParenLoc,
2289 SourceLocation VarLoc,
2290 SourceLocation EndLoc) {
2291 return getSema().ActOnOpenMPInitClause(InteropVar, InteropInfo, StartLoc,
2292 LParenLoc, VarLoc, EndLoc);
2295 /// Build a new OpenMP 'use' clause.
2297 /// By default, performs semantic analysis to build the new OpenMP clause.
2298 /// Subclasses may override this routine to provide different behavior.
2299 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2300 SourceLocation LParenLoc,
2301 SourceLocation VarLoc, SourceLocation EndLoc) {
2302 return getSema().ActOnOpenMPUseClause(InteropVar, StartLoc, LParenLoc,
2303 VarLoc, EndLoc);
2306 /// Build a new OpenMP 'destroy' clause.
2308 /// By default, performs semantic analysis to build the new OpenMP clause.
2309 /// Subclasses may override this routine to provide different behavior.
2310 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2311 SourceLocation LParenLoc,
2312 SourceLocation VarLoc,
2313 SourceLocation EndLoc) {
2314 return getSema().ActOnOpenMPDestroyClause(InteropVar, StartLoc, LParenLoc,
2315 VarLoc, EndLoc);
2318 /// Build a new OpenMP 'novariants' clause.
2320 /// By default, performs semantic analysis to build the new OpenMP clause.
2321 /// Subclasses may override this routine to provide different behavior.
2322 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2323 SourceLocation StartLoc,
2324 SourceLocation LParenLoc,
2325 SourceLocation EndLoc) {
2326 return getSema().ActOnOpenMPNovariantsClause(Condition, StartLoc, LParenLoc,
2327 EndLoc);
2330 /// Build a new OpenMP 'nocontext' clause.
2332 /// By default, performs semantic analysis to build the new OpenMP clause.
2333 /// Subclasses may override this routine to provide different behavior.
2334 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2335 SourceLocation LParenLoc,
2336 SourceLocation EndLoc) {
2337 return getSema().ActOnOpenMPNocontextClause(Condition, StartLoc, LParenLoc,
2338 EndLoc);
2341 /// Build a new OpenMP 'filter' clause.
2343 /// By default, performs semantic analysis to build the new OpenMP clause.
2344 /// Subclasses may override this routine to provide different behavior.
2345 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2346 SourceLocation LParenLoc,
2347 SourceLocation EndLoc) {
2348 return getSema().ActOnOpenMPFilterClause(ThreadID, StartLoc, LParenLoc,
2349 EndLoc);
2352 /// Build a new OpenMP 'bind' clause.
2354 /// By default, performs semantic analysis to build the new OpenMP clause.
2355 /// Subclasses may override this routine to provide different behavior.
2356 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2357 SourceLocation KindLoc,
2358 SourceLocation StartLoc,
2359 SourceLocation LParenLoc,
2360 SourceLocation EndLoc) {
2361 return getSema().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc, LParenLoc,
2362 EndLoc);
2365 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2367 /// By default, performs semantic analysis to build the new OpenMP clause.
2368 /// Subclasses may override this routine to provide different behavior.
2369 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2370 SourceLocation LParenLoc,
2371 SourceLocation EndLoc) {
2372 return getSema().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc, LParenLoc,
2373 EndLoc);
2376 /// Build a new OpenMP 'ompx_attribute' 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 *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2381 SourceLocation StartLoc,
2382 SourceLocation LParenLoc,
2383 SourceLocation EndLoc) {
2384 return getSema().ActOnOpenMPXAttributeClause(Attrs, StartLoc, LParenLoc,
2385 EndLoc);
2388 /// Build a new OpenMP 'ompx_bare' 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 *RebuildOMPXBareClause(SourceLocation StartLoc,
2393 SourceLocation EndLoc) {
2394 return getSema().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2397 /// Build a new OpenMP 'align' clause.
2399 /// By default, performs semantic analysis to build the new OpenMP clause.
2400 /// Subclasses may override this routine to provide different behavior.
2401 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2402 SourceLocation LParenLoc,
2403 SourceLocation EndLoc) {
2404 return getSema().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc, EndLoc);
2407 /// Build a new OpenMP 'at' clause.
2409 /// By default, performs semantic analysis to build the new OpenMP clause.
2410 /// Subclasses may override this routine to provide different behavior.
2411 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2412 SourceLocation StartLoc,
2413 SourceLocation LParenLoc,
2414 SourceLocation EndLoc) {
2415 return getSema().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc, LParenLoc,
2416 EndLoc);
2419 /// Build a new OpenMP 'severity' clause.
2421 /// By default, performs semantic analysis to build the new OpenMP clause.
2422 /// Subclasses may override this routine to provide different behavior.
2423 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2424 SourceLocation KwLoc,
2425 SourceLocation StartLoc,
2426 SourceLocation LParenLoc,
2427 SourceLocation EndLoc) {
2428 return getSema().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc, LParenLoc,
2429 EndLoc);
2432 /// Build a new OpenMP 'message' clause.
2434 /// By default, performs semantic analysis to build the new OpenMP clause.
2435 /// Subclasses may override this routine to provide different behavior.
2436 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2437 SourceLocation LParenLoc,
2438 SourceLocation EndLoc) {
2439 return getSema().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc, EndLoc);
2442 /// Build a new OpenMP 'doacross' clause.
2444 /// By default, performs semantic analysis to build the new OpenMP clause.
2445 /// Subclasses may override this routine to provide different behavior.
2446 OMPClause *
2447 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2448 SourceLocation DepLoc, SourceLocation ColonLoc,
2449 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2450 SourceLocation LParenLoc, SourceLocation EndLoc) {
2451 return getSema().ActOnOpenMPDoacrossClause(
2452 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2455 /// Rebuild the operand to an Objective-C \@synchronized statement.
2457 /// By default, performs semantic analysis to build the new statement.
2458 /// Subclasses may override this routine to provide different behavior.
2459 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2460 Expr *object) {
2461 return getSema().ActOnObjCAtSynchronizedOperand(atLoc, object);
2464 /// Build a new Objective-C \@synchronized statement.
2466 /// By default, performs semantic analysis to build the new statement.
2467 /// Subclasses may override this routine to provide different behavior.
2468 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2469 Expr *Object, Stmt *Body) {
2470 return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2473 /// Build a new Objective-C \@autoreleasepool statement.
2475 /// By default, performs semantic analysis to build the new statement.
2476 /// Subclasses may override this routine to provide different behavior.
2477 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2478 Stmt *Body) {
2479 return getSema().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2482 /// Build a new Objective-C fast enumeration statement.
2484 /// By default, performs semantic analysis to build the new statement.
2485 /// Subclasses may override this routine to provide different behavior.
2486 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2487 Stmt *Element,
2488 Expr *Collection,
2489 SourceLocation RParenLoc,
2490 Stmt *Body) {
2491 StmtResult ForEachStmt = getSema().ActOnObjCForCollectionStmt(ForLoc,
2492 Element,
2493 Collection,
2494 RParenLoc);
2495 if (ForEachStmt.isInvalid())
2496 return StmtError();
2498 return getSema().FinishObjCForCollectionStmt(ForEachStmt.get(), Body);
2501 /// Build a new C++ exception declaration.
2503 /// By default, performs semantic analysis to build the new decaration.
2504 /// Subclasses may override this routine to provide different behavior.
2505 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2506 TypeSourceInfo *Declarator,
2507 SourceLocation StartLoc,
2508 SourceLocation IdLoc,
2509 IdentifierInfo *Id) {
2510 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2511 StartLoc, IdLoc, Id);
2512 if (Var)
2513 getSema().CurContext->addDecl(Var);
2514 return Var;
2517 /// Build a new C++ catch statement.
2519 /// By default, performs semantic analysis to build the new statement.
2520 /// Subclasses may override this routine to provide different behavior.
2521 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2522 VarDecl *ExceptionDecl,
2523 Stmt *Handler) {
2524 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2525 Handler));
2528 /// Build a new C++ try statement.
2530 /// By default, performs semantic analysis to build the new statement.
2531 /// Subclasses may override this routine to provide different behavior.
2532 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2533 ArrayRef<Stmt *> Handlers) {
2534 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2537 /// Build a new C++0x range-based for statement.
2539 /// By default, performs semantic analysis to build the new statement.
2540 /// Subclasses may override this routine to provide different behavior.
2541 StmtResult RebuildCXXForRangeStmt(SourceLocation ForLoc,
2542 SourceLocation CoawaitLoc, Stmt *Init,
2543 SourceLocation ColonLoc, Stmt *Range,
2544 Stmt *Begin, Stmt *End, Expr *Cond,
2545 Expr *Inc, Stmt *LoopVar,
2546 SourceLocation RParenLoc) {
2547 // If we've just learned that the range is actually an Objective-C
2548 // collection, treat this as an Objective-C fast enumeration loop.
2549 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
2550 if (RangeStmt->isSingleDecl()) {
2551 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
2552 if (RangeVar->isInvalidDecl())
2553 return StmtError();
2555 Expr *RangeExpr = RangeVar->getInit();
2556 if (!RangeExpr->isTypeDependent() &&
2557 RangeExpr->getType()->isObjCObjectPointerType()) {
2558 // FIXME: Support init-statements in Objective-C++20 ranged for
2559 // statement.
2560 if (Init) {
2561 return SemaRef.Diag(Init->getBeginLoc(),
2562 diag::err_objc_for_range_init_stmt)
2563 << Init->getSourceRange();
2565 return getSema().ActOnObjCForCollectionStmt(ForLoc, LoopVar,
2566 RangeExpr, RParenLoc);
2572 return getSema().BuildCXXForRangeStmt(ForLoc, CoawaitLoc, Init, ColonLoc,
2573 Range, Begin, End, Cond, Inc, LoopVar,
2574 RParenLoc, Sema::BFRK_Rebuild);
2577 /// Build a new C++0x range-based for statement.
2579 /// By default, performs semantic analysis to build the new statement.
2580 /// Subclasses may override this routine to provide different behavior.
2581 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2582 bool IsIfExists,
2583 NestedNameSpecifierLoc QualifierLoc,
2584 DeclarationNameInfo NameInfo,
2585 Stmt *Nested) {
2586 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2587 QualifierLoc, NameInfo, Nested);
2590 /// Attach body to a C++0x range-based for statement.
2592 /// By default, performs semantic analysis to finish the new statement.
2593 /// Subclasses may override this routine to provide different behavior.
2594 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2595 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2598 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2599 Stmt *TryBlock, Stmt *Handler) {
2600 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2603 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2604 Stmt *Block) {
2605 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2608 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2609 return SEHFinallyStmt::Create(getSema().getASTContext(), Loc, Block);
2612 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2613 SourceLocation LParen,
2614 SourceLocation RParen,
2615 TypeSourceInfo *TSI) {
2616 return getSema().BuildSYCLUniqueStableNameExpr(OpLoc, LParen, RParen, TSI);
2619 /// Build a new predefined expression.
2621 /// By default, performs semantic analysis to build the new expression.
2622 /// Subclasses may override this routine to provide different behavior.
2623 ExprResult RebuildPredefinedExpr(SourceLocation Loc,
2624 PredefinedExpr::IdentKind IK) {
2625 return getSema().BuildPredefinedExpr(Loc, IK);
2628 /// Build a new expression that references a declaration.
2630 /// By default, performs semantic analysis to build the new expression.
2631 /// Subclasses may override this routine to provide different behavior.
2632 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2633 LookupResult &R,
2634 bool RequiresADL) {
2635 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2639 /// Build a new expression that references a declaration.
2641 /// By default, performs semantic analysis to build the new expression.
2642 /// Subclasses may override this routine to provide different behavior.
2643 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2644 ValueDecl *VD,
2645 const DeclarationNameInfo &NameInfo,
2646 NamedDecl *Found,
2647 TemplateArgumentListInfo *TemplateArgs) {
2648 CXXScopeSpec SS;
2649 SS.Adopt(QualifierLoc);
2650 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2651 TemplateArgs);
2654 /// Build a new expression in parentheses.
2656 /// By default, performs semantic analysis to build the new expression.
2657 /// Subclasses may override this routine to provide different behavior.
2658 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2659 SourceLocation RParen) {
2660 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2663 /// Build a new pseudo-destructor expression.
2665 /// By default, performs semantic analysis to build the new expression.
2666 /// Subclasses may override this routine to provide different behavior.
2667 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2668 SourceLocation OperatorLoc,
2669 bool isArrow,
2670 CXXScopeSpec &SS,
2671 TypeSourceInfo *ScopeType,
2672 SourceLocation CCLoc,
2673 SourceLocation TildeLoc,
2674 PseudoDestructorTypeStorage Destroyed);
2676 /// Build a new unary operator expression.
2678 /// By default, performs semantic analysis to build the new expression.
2679 /// Subclasses may override this routine to provide different behavior.
2680 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2681 UnaryOperatorKind Opc,
2682 Expr *SubExpr) {
2683 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2686 /// Build a new builtin offsetof expression.
2688 /// By default, performs semantic analysis to build the new expression.
2689 /// Subclasses may override this routine to provide different behavior.
2690 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2691 TypeSourceInfo *Type,
2692 ArrayRef<Sema::OffsetOfComponent> Components,
2693 SourceLocation RParenLoc) {
2694 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2695 RParenLoc);
2698 /// Build a new sizeof, alignof or vec_step expression with a
2699 /// type argument.
2701 /// By default, performs semantic analysis to build the new expression.
2702 /// Subclasses may override this routine to provide different behavior.
2703 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2704 SourceLocation OpLoc,
2705 UnaryExprOrTypeTrait ExprKind,
2706 SourceRange R) {
2707 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2710 /// Build a new sizeof, alignof or vec step expression with an
2711 /// expression argument.
2713 /// By default, performs semantic analysis to build the new expression.
2714 /// Subclasses may override this routine to provide different behavior.
2715 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2716 UnaryExprOrTypeTrait ExprKind,
2717 SourceRange R) {
2718 ExprResult Result
2719 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2720 if (Result.isInvalid())
2721 return ExprError();
2723 return Result;
2726 /// Build a new array subscript expression.
2728 /// By default, performs semantic analysis to build the new expression.
2729 /// Subclasses may override this routine to provide different behavior.
2730 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2731 SourceLocation LBracketLoc,
2732 Expr *RHS,
2733 SourceLocation RBracketLoc) {
2734 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2735 LBracketLoc, RHS,
2736 RBracketLoc);
2739 /// Build a new matrix subscript expression.
2741 /// By default, performs semantic analysis to build the new expression.
2742 /// Subclasses may override this routine to provide different behavior.
2743 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2744 Expr *ColumnIdx,
2745 SourceLocation RBracketLoc) {
2746 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2747 RBracketLoc);
2750 /// Build a new array section expression.
2752 /// By default, performs semantic analysis to build the new expression.
2753 /// Subclasses may override this routine to provide different behavior.
2754 ExprResult RebuildOMPArraySectionExpr(Expr *Base, SourceLocation LBracketLoc,
2755 Expr *LowerBound,
2756 SourceLocation ColonLocFirst,
2757 SourceLocation ColonLocSecond,
2758 Expr *Length, Expr *Stride,
2759 SourceLocation RBracketLoc) {
2760 return getSema().ActOnOMPArraySectionExpr(Base, LBracketLoc, LowerBound,
2761 ColonLocFirst, ColonLocSecond,
2762 Length, Stride, RBracketLoc);
2765 /// Build a new array shaping expression.
2767 /// By default, performs semantic analysis to build the new expression.
2768 /// Subclasses may override this routine to provide different behavior.
2769 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2770 SourceLocation RParenLoc,
2771 ArrayRef<Expr *> Dims,
2772 ArrayRef<SourceRange> BracketsRanges) {
2773 return getSema().ActOnOMPArrayShapingExpr(Base, LParenLoc, RParenLoc, Dims,
2774 BracketsRanges);
2777 /// Build a new iterator expression.
2779 /// By default, performs semantic analysis to build the new expression.
2780 /// Subclasses may override this routine to provide different behavior.
2781 ExprResult RebuildOMPIteratorExpr(
2782 SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc,
2783 ArrayRef<Sema::OMPIteratorData> Data) {
2784 return getSema().ActOnOMPIteratorExpr(/*Scope=*/nullptr, IteratorKwLoc,
2785 LLoc, RLoc, Data);
2788 /// Build a new call expression.
2790 /// By default, performs semantic analysis to build the new expression.
2791 /// Subclasses may override this routine to provide different behavior.
2792 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2793 MultiExprArg Args,
2794 SourceLocation RParenLoc,
2795 Expr *ExecConfig = nullptr) {
2796 return getSema().ActOnCallExpr(
2797 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2800 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2801 MultiExprArg Args,
2802 SourceLocation RParenLoc) {
2803 return getSema().ActOnArraySubscriptExpr(
2804 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2807 /// Build a new member access expression.
2809 /// By default, performs semantic analysis to build the new expression.
2810 /// Subclasses may override this routine to provide different behavior.
2811 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2812 bool isArrow,
2813 NestedNameSpecifierLoc QualifierLoc,
2814 SourceLocation TemplateKWLoc,
2815 const DeclarationNameInfo &MemberNameInfo,
2816 ValueDecl *Member,
2817 NamedDecl *FoundDecl,
2818 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2819 NamedDecl *FirstQualifierInScope) {
2820 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2821 isArrow);
2822 if (!Member->getDeclName()) {
2823 // We have a reference to an unnamed field. This is always the
2824 // base of an anonymous struct/union member access, i.e. the
2825 // field is always of record type.
2826 assert(Member->getType()->isRecordType() &&
2827 "unnamed member not of record type?");
2829 BaseResult =
2830 getSema().PerformObjectMemberConversion(BaseResult.get(),
2831 QualifierLoc.getNestedNameSpecifier(),
2832 FoundDecl, Member);
2833 if (BaseResult.isInvalid())
2834 return ExprError();
2835 Base = BaseResult.get();
2837 CXXScopeSpec EmptySS;
2838 return getSema().BuildFieldReferenceExpr(
2839 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
2840 DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()), MemberNameInfo);
2843 CXXScopeSpec SS;
2844 SS.Adopt(QualifierLoc);
2846 Base = BaseResult.get();
2847 QualType BaseType = Base->getType();
2849 if (isArrow && !BaseType->isPointerType())
2850 return ExprError();
2852 // FIXME: this involves duplicating earlier analysis in a lot of
2853 // cases; we should avoid this when possible.
2854 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2855 R.addDecl(FoundDecl);
2856 R.resolveKind();
2858 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2859 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {
2860 if (auto *ThisClass = cast<CXXThisExpr>(Base)
2861 ->getType()
2862 ->getPointeeType()
2863 ->getAsCXXRecordDecl()) {
2864 auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());
2865 // In unevaluated contexts, an expression supposed to be a member access
2866 // might reference a member in an unrelated class.
2867 if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))
2868 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2869 VK_LValue, Member->getLocation());
2873 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2874 SS, TemplateKWLoc,
2875 FirstQualifierInScope,
2876 R, ExplicitTemplateArgs,
2877 /*S*/nullptr);
2880 /// Build a new binary operator expression.
2882 /// By default, performs semantic analysis to build the new expression.
2883 /// Subclasses may override this routine to provide different behavior.
2884 ExprResult RebuildBinaryOperator(SourceLocation OpLoc,
2885 BinaryOperatorKind Opc,
2886 Expr *LHS, Expr *RHS) {
2887 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS);
2890 /// Build a new rewritten operator expression.
2892 /// By default, performs semantic analysis to build the new expression.
2893 /// Subclasses may override this routine to provide different behavior.
2894 ExprResult RebuildCXXRewrittenBinaryOperator(
2895 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2896 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2897 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2898 RHS, /*RequiresADL*/false);
2901 /// Build a new conditional operator expression.
2903 /// By default, performs semantic analysis to build the new expression.
2904 /// Subclasses may override this routine to provide different behavior.
2905 ExprResult RebuildConditionalOperator(Expr *Cond,
2906 SourceLocation QuestionLoc,
2907 Expr *LHS,
2908 SourceLocation ColonLoc,
2909 Expr *RHS) {
2910 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
2911 LHS, RHS);
2914 /// Build a new C-style cast expression.
2916 /// By default, performs semantic analysis to build the new expression.
2917 /// Subclasses may override this routine to provide different behavior.
2918 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
2919 TypeSourceInfo *TInfo,
2920 SourceLocation RParenLoc,
2921 Expr *SubExpr) {
2922 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
2923 SubExpr);
2926 /// Build a new compound literal expression.
2928 /// By default, performs semantic analysis to build the new expression.
2929 /// Subclasses may override this routine to provide different behavior.
2930 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
2931 TypeSourceInfo *TInfo,
2932 SourceLocation RParenLoc,
2933 Expr *Init) {
2934 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
2935 Init);
2938 /// Build a new extended vector element access expression.
2940 /// By default, performs semantic analysis to build the new expression.
2941 /// Subclasses may override this routine to provide different behavior.
2942 ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,
2943 bool IsArrow,
2944 SourceLocation AccessorLoc,
2945 IdentifierInfo &Accessor) {
2947 CXXScopeSpec SS;
2948 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
2949 return getSema().BuildMemberReferenceExpr(
2950 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
2951 /*FirstQualifierInScope*/ nullptr, NameInfo,
2952 /* TemplateArgs */ nullptr,
2953 /*S*/ nullptr);
2956 /// Build a new initializer list expression.
2958 /// By default, performs semantic analysis to build the new expression.
2959 /// Subclasses may override this routine to provide different behavior.
2960 ExprResult RebuildInitList(SourceLocation LBraceLoc,
2961 MultiExprArg Inits,
2962 SourceLocation RBraceLoc) {
2963 return SemaRef.BuildInitList(LBraceLoc, Inits, RBraceLoc);
2966 /// Build a new designated initializer expression.
2968 /// By default, performs semantic analysis to build the new expression.
2969 /// Subclasses may override this routine to provide different behavior.
2970 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
2971 MultiExprArg ArrayExprs,
2972 SourceLocation EqualOrColonLoc,
2973 bool GNUSyntax,
2974 Expr *Init) {
2975 ExprResult Result
2976 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
2977 Init);
2978 if (Result.isInvalid())
2979 return ExprError();
2981 return Result;
2984 /// Build a new value-initialized expression.
2986 /// By default, builds the implicit value initialization without performing
2987 /// any semantic analysis. Subclasses may override this routine to provide
2988 /// different behavior.
2989 ExprResult RebuildImplicitValueInitExpr(QualType T) {
2990 return new (SemaRef.Context) ImplicitValueInitExpr(T);
2993 /// Build a new \c va_arg expression.
2995 /// By default, performs semantic analysis to build the new expression.
2996 /// Subclasses may override this routine to provide different behavior.
2997 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
2998 Expr *SubExpr, TypeSourceInfo *TInfo,
2999 SourceLocation RParenLoc) {
3000 return getSema().BuildVAArgExpr(BuiltinLoc,
3001 SubExpr, TInfo,
3002 RParenLoc);
3005 /// Build a new expression list in parentheses.
3007 /// By default, performs semantic analysis to build the new expression.
3008 /// Subclasses may override this routine to provide different behavior.
3009 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3010 MultiExprArg SubExprs,
3011 SourceLocation RParenLoc) {
3012 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3015 /// Build a new address-of-label expression.
3017 /// By default, performs semantic analysis, using the name of the label
3018 /// rather than attempting to map the label statement itself.
3019 /// Subclasses may override this routine to provide different behavior.
3020 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3021 SourceLocation LabelLoc, LabelDecl *Label) {
3022 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3025 /// Build a new GNU statement expression.
3027 /// By default, performs semantic analysis to build the new expression.
3028 /// Subclasses may override this routine to provide different behavior.
3029 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3030 SourceLocation RParenLoc, unsigned TemplateDepth) {
3031 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3032 TemplateDepth);
3035 /// Build a new __builtin_choose_expr expression.
3037 /// By default, performs semantic analysis to build the new expression.
3038 /// Subclasses may override this routine to provide different behavior.
3039 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3040 Expr *Cond, Expr *LHS, Expr *RHS,
3041 SourceLocation RParenLoc) {
3042 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3043 Cond, LHS, RHS,
3044 RParenLoc);
3047 /// Build a new generic selection expression with an expression predicate.
3049 /// By default, performs semantic analysis to build the new expression.
3050 /// Subclasses may override this routine to provide different behavior.
3051 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3052 SourceLocation DefaultLoc,
3053 SourceLocation RParenLoc,
3054 Expr *ControllingExpr,
3055 ArrayRef<TypeSourceInfo *> Types,
3056 ArrayRef<Expr *> Exprs) {
3057 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3058 /*PredicateIsExpr=*/true,
3059 ControllingExpr, Types, Exprs);
3062 /// Build a new generic selection expression with a type predicate.
3064 /// By default, performs semantic analysis to build the new expression.
3065 /// Subclasses may override this routine to provide different behavior.
3066 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3067 SourceLocation DefaultLoc,
3068 SourceLocation RParenLoc,
3069 TypeSourceInfo *ControllingType,
3070 ArrayRef<TypeSourceInfo *> Types,
3071 ArrayRef<Expr *> Exprs) {
3072 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3073 /*PredicateIsExpr=*/false,
3074 ControllingType, Types, Exprs);
3077 /// Build a new overloaded operator call expression.
3079 /// By default, performs semantic analysis to build the new expression.
3080 /// The semantic analysis provides the behavior of template instantiation,
3081 /// copying with transformations that turn what looks like an overloaded
3082 /// operator call into a use of a builtin operator, performing
3083 /// argument-dependent lookup, etc. Subclasses may override this routine to
3084 /// provide different behavior.
3085 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3086 SourceLocation OpLoc,
3087 SourceLocation CalleeLoc,
3088 bool RequiresADL,
3089 const UnresolvedSetImpl &Functions,
3090 Expr *First, Expr *Second);
3092 /// Build a new C++ "named" cast expression, such as static_cast or
3093 /// reinterpret_cast.
3095 /// By default, this routine dispatches to one of the more-specific routines
3096 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3097 /// Subclasses may override this routine to provide different behavior.
3098 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3099 Stmt::StmtClass Class,
3100 SourceLocation LAngleLoc,
3101 TypeSourceInfo *TInfo,
3102 SourceLocation RAngleLoc,
3103 SourceLocation LParenLoc,
3104 Expr *SubExpr,
3105 SourceLocation RParenLoc) {
3106 switch (Class) {
3107 case Stmt::CXXStaticCastExprClass:
3108 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3109 RAngleLoc, LParenLoc,
3110 SubExpr, RParenLoc);
3112 case Stmt::CXXDynamicCastExprClass:
3113 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3114 RAngleLoc, LParenLoc,
3115 SubExpr, RParenLoc);
3117 case Stmt::CXXReinterpretCastExprClass:
3118 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3119 RAngleLoc, LParenLoc,
3120 SubExpr,
3121 RParenLoc);
3123 case Stmt::CXXConstCastExprClass:
3124 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3125 RAngleLoc, LParenLoc,
3126 SubExpr, RParenLoc);
3128 case Stmt::CXXAddrspaceCastExprClass:
3129 return getDerived().RebuildCXXAddrspaceCastExpr(
3130 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3132 default:
3133 llvm_unreachable("Invalid C++ named cast");
3137 /// Build a new C++ static_cast expression.
3139 /// By default, performs semantic analysis to build the new expression.
3140 /// Subclasses may override this routine to provide different behavior.
3141 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3142 SourceLocation LAngleLoc,
3143 TypeSourceInfo *TInfo,
3144 SourceLocation RAngleLoc,
3145 SourceLocation LParenLoc,
3146 Expr *SubExpr,
3147 SourceLocation RParenLoc) {
3148 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3149 TInfo, SubExpr,
3150 SourceRange(LAngleLoc, RAngleLoc),
3151 SourceRange(LParenLoc, RParenLoc));
3154 /// Build a new C++ dynamic_cast expression.
3156 /// By default, performs semantic analysis to build the new expression.
3157 /// Subclasses may override this routine to provide different behavior.
3158 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3159 SourceLocation LAngleLoc,
3160 TypeSourceInfo *TInfo,
3161 SourceLocation RAngleLoc,
3162 SourceLocation LParenLoc,
3163 Expr *SubExpr,
3164 SourceLocation RParenLoc) {
3165 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3166 TInfo, SubExpr,
3167 SourceRange(LAngleLoc, RAngleLoc),
3168 SourceRange(LParenLoc, RParenLoc));
3171 /// Build a new C++ reinterpret_cast expression.
3173 /// By default, performs semantic analysis to build the new expression.
3174 /// Subclasses may override this routine to provide different behavior.
3175 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3176 SourceLocation LAngleLoc,
3177 TypeSourceInfo *TInfo,
3178 SourceLocation RAngleLoc,
3179 SourceLocation LParenLoc,
3180 Expr *SubExpr,
3181 SourceLocation RParenLoc) {
3182 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3183 TInfo, SubExpr,
3184 SourceRange(LAngleLoc, RAngleLoc),
3185 SourceRange(LParenLoc, RParenLoc));
3188 /// Build a new C++ const_cast expression.
3190 /// By default, performs semantic analysis to build the new expression.
3191 /// Subclasses may override this routine to provide different behavior.
3192 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3193 SourceLocation LAngleLoc,
3194 TypeSourceInfo *TInfo,
3195 SourceLocation RAngleLoc,
3196 SourceLocation LParenLoc,
3197 Expr *SubExpr,
3198 SourceLocation RParenLoc) {
3199 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3200 TInfo, SubExpr,
3201 SourceRange(LAngleLoc, RAngleLoc),
3202 SourceRange(LParenLoc, RParenLoc));
3205 ExprResult
3206 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3207 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3208 SourceLocation LParenLoc, Expr *SubExpr,
3209 SourceLocation RParenLoc) {
3210 return getSema().BuildCXXNamedCast(
3211 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3212 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3215 /// Build a new C++ functional-style cast expression.
3217 /// By default, performs semantic analysis to build the new expression.
3218 /// Subclasses may override this routine to provide different behavior.
3219 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3220 SourceLocation LParenLoc,
3221 Expr *Sub,
3222 SourceLocation RParenLoc,
3223 bool ListInitialization) {
3224 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3225 // CXXParenListInitExpr. Pass its expanded arguments so that the
3226 // CXXParenListInitExpr can be rebuilt.
3227 if (auto *PLE = dyn_cast<ParenListExpr>(Sub))
3228 return getSema().BuildCXXTypeConstructExpr(
3229 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3230 RParenLoc, ListInitialization);
3231 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3232 MultiExprArg(&Sub, 1), RParenLoc,
3233 ListInitialization);
3236 /// Build a new C++ __builtin_bit_cast expression.
3238 /// By default, performs semantic analysis to build the new expression.
3239 /// Subclasses may override this routine to provide different behavior.
3240 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3241 TypeSourceInfo *TSI, Expr *Sub,
3242 SourceLocation RParenLoc) {
3243 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3246 /// Build a new C++ typeid(type) expression.
3248 /// By default, performs semantic analysis to build the new expression.
3249 /// Subclasses may override this routine to provide different behavior.
3250 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3251 SourceLocation TypeidLoc,
3252 TypeSourceInfo *Operand,
3253 SourceLocation RParenLoc) {
3254 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3255 RParenLoc);
3259 /// Build a new C++ typeid(expr) expression.
3261 /// By default, performs semantic analysis to build the new expression.
3262 /// Subclasses may override this routine to provide different behavior.
3263 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3264 SourceLocation TypeidLoc,
3265 Expr *Operand,
3266 SourceLocation RParenLoc) {
3267 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3268 RParenLoc);
3271 /// Build a new C++ __uuidof(type) expression.
3273 /// By default, performs semantic analysis to build the new expression.
3274 /// Subclasses may override this routine to provide different behavior.
3275 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3276 TypeSourceInfo *Operand,
3277 SourceLocation RParenLoc) {
3278 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3281 /// Build a new C++ __uuidof(expr) expression.
3283 /// By default, performs semantic analysis to build the new expression.
3284 /// Subclasses may override this routine to provide different behavior.
3285 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3286 Expr *Operand, SourceLocation RParenLoc) {
3287 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3290 /// Build a new C++ "this" expression.
3292 /// By default, builds a new "this" expression without performing any
3293 /// semantic analysis. Subclasses may override this routine to provide
3294 /// different behavior.
3295 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3296 QualType ThisType,
3297 bool isImplicit) {
3298 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3301 /// Build a new C++ throw expression.
3303 /// By default, performs semantic analysis to build the new expression.
3304 /// Subclasses may override this routine to provide different behavior.
3305 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3306 bool IsThrownVariableInScope) {
3307 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3310 /// Build a new C++ default-argument expression.
3312 /// By default, builds a new default-argument expression, which does not
3313 /// require any semantic analysis. Subclasses may override this routine to
3314 /// provide different behavior.
3315 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3316 Expr *RewrittenExpr) {
3317 return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param,
3318 RewrittenExpr, getSema().CurContext);
3321 /// Build a new C++11 default-initialization expression.
3323 /// By default, builds a new default field initialization expression, which
3324 /// does not require any semantic analysis. Subclasses may override this
3325 /// routine to provide different behavior.
3326 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3327 FieldDecl *Field) {
3328 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3331 /// Build a new C++ zero-initialization expression.
3333 /// By default, performs semantic analysis to build the new expression.
3334 /// Subclasses may override this routine to provide different behavior.
3335 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3336 SourceLocation LParenLoc,
3337 SourceLocation RParenLoc) {
3338 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, std::nullopt,
3339 RParenLoc,
3340 /*ListInitialization=*/false);
3343 /// Build a new C++ "new" expression.
3345 /// By default, performs semantic analysis to build the new expression.
3346 /// Subclasses may override this routine to provide different behavior.
3347 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3348 SourceLocation PlacementLParen,
3349 MultiExprArg PlacementArgs,
3350 SourceLocation PlacementRParen,
3351 SourceRange TypeIdParens, QualType AllocatedType,
3352 TypeSourceInfo *AllocatedTypeInfo,
3353 std::optional<Expr *> ArraySize,
3354 SourceRange DirectInitRange, Expr *Initializer) {
3355 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3356 PlacementLParen,
3357 PlacementArgs,
3358 PlacementRParen,
3359 TypeIdParens,
3360 AllocatedType,
3361 AllocatedTypeInfo,
3362 ArraySize,
3363 DirectInitRange,
3364 Initializer);
3367 /// Build a new C++ "delete" expression.
3369 /// By default, performs semantic analysis to build the new expression.
3370 /// Subclasses may override this routine to provide different behavior.
3371 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3372 bool IsGlobalDelete,
3373 bool IsArrayForm,
3374 Expr *Operand) {
3375 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3376 Operand);
3379 /// Build a new type trait expression.
3381 /// By default, performs semantic analysis to build the new expression.
3382 /// Subclasses may override this routine to provide different behavior.
3383 ExprResult RebuildTypeTrait(TypeTrait Trait,
3384 SourceLocation StartLoc,
3385 ArrayRef<TypeSourceInfo *> Args,
3386 SourceLocation RParenLoc) {
3387 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3390 /// Build a new array type trait expression.
3392 /// By default, performs semantic analysis to build the new expression.
3393 /// Subclasses may override this routine to provide different behavior.
3394 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3395 SourceLocation StartLoc,
3396 TypeSourceInfo *TSInfo,
3397 Expr *DimExpr,
3398 SourceLocation RParenLoc) {
3399 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3402 /// Build a new expression trait expression.
3404 /// By default, performs semantic analysis to build the new expression.
3405 /// Subclasses may override this routine to provide different behavior.
3406 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3407 SourceLocation StartLoc,
3408 Expr *Queried,
3409 SourceLocation RParenLoc) {
3410 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3413 /// Build a new (previously unresolved) declaration reference
3414 /// expression.
3416 /// By default, performs semantic analysis to build the new expression.
3417 /// Subclasses may override this routine to provide different behavior.
3418 ExprResult RebuildDependentScopeDeclRefExpr(
3419 NestedNameSpecifierLoc QualifierLoc,
3420 SourceLocation TemplateKWLoc,
3421 const DeclarationNameInfo &NameInfo,
3422 const TemplateArgumentListInfo *TemplateArgs,
3423 bool IsAddressOfOperand,
3424 TypeSourceInfo **RecoveryTSI) {
3425 CXXScopeSpec SS;
3426 SS.Adopt(QualifierLoc);
3428 if (TemplateArgs || TemplateKWLoc.isValid())
3429 return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, NameInfo,
3430 TemplateArgs);
3432 return getSema().BuildQualifiedDeclarationNameExpr(
3433 SS, NameInfo, IsAddressOfOperand, /*S*/nullptr, RecoveryTSI);
3436 /// Build a new template-id expression.
3438 /// By default, performs semantic analysis to build the new expression.
3439 /// Subclasses may override this routine to provide different behavior.
3440 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3441 SourceLocation TemplateKWLoc,
3442 LookupResult &R,
3443 bool RequiresADL,
3444 const TemplateArgumentListInfo *TemplateArgs) {
3445 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3446 TemplateArgs);
3449 /// Build a new object-construction expression.
3451 /// By default, performs semantic analysis to build the new expression.
3452 /// Subclasses may override this routine to provide different behavior.
3453 ExprResult RebuildCXXConstructExpr(QualType T,
3454 SourceLocation Loc,
3455 CXXConstructorDecl *Constructor,
3456 bool IsElidable,
3457 MultiExprArg Args,
3458 bool HadMultipleCandidates,
3459 bool ListInitialization,
3460 bool StdInitListInitialization,
3461 bool RequiresZeroInit,
3462 CXXConstructExpr::ConstructionKind ConstructKind,
3463 SourceRange ParenRange) {
3464 // Reconstruct the constructor we originally found, which might be
3465 // different if this is a call to an inherited constructor.
3466 CXXConstructorDecl *FoundCtor = Constructor;
3467 if (Constructor->isInheritingConstructor())
3468 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3470 SmallVector<Expr *, 8> ConvertedArgs;
3471 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3472 ConvertedArgs))
3473 return ExprError();
3475 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3476 IsElidable,
3477 ConvertedArgs,
3478 HadMultipleCandidates,
3479 ListInitialization,
3480 StdInitListInitialization,
3481 RequiresZeroInit, ConstructKind,
3482 ParenRange);
3485 /// Build a new implicit construction via inherited constructor
3486 /// expression.
3487 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3488 CXXConstructorDecl *Constructor,
3489 bool ConstructsVBase,
3490 bool InheritedFromVBase) {
3491 return new (getSema().Context) CXXInheritedCtorInitExpr(
3492 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3495 /// Build a new object-construction expression.
3497 /// By default, performs semantic analysis to build the new expression.
3498 /// Subclasses may override this routine to provide different behavior.
3499 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3500 SourceLocation LParenOrBraceLoc,
3501 MultiExprArg Args,
3502 SourceLocation RParenOrBraceLoc,
3503 bool ListInitialization) {
3504 return getSema().BuildCXXTypeConstructExpr(
3505 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3508 /// Build a new object-construction expression.
3510 /// By default, performs semantic analysis to build the new expression.
3511 /// Subclasses may override this routine to provide different behavior.
3512 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3513 SourceLocation LParenLoc,
3514 MultiExprArg Args,
3515 SourceLocation RParenLoc,
3516 bool ListInitialization) {
3517 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3518 RParenLoc, ListInitialization);
3521 /// Build a new member reference expression.
3523 /// By default, performs semantic analysis to build the new expression.
3524 /// Subclasses may override this routine to provide different behavior.
3525 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3526 QualType BaseType,
3527 bool IsArrow,
3528 SourceLocation OperatorLoc,
3529 NestedNameSpecifierLoc QualifierLoc,
3530 SourceLocation TemplateKWLoc,
3531 NamedDecl *FirstQualifierInScope,
3532 const DeclarationNameInfo &MemberNameInfo,
3533 const TemplateArgumentListInfo *TemplateArgs) {
3534 CXXScopeSpec SS;
3535 SS.Adopt(QualifierLoc);
3537 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3538 OperatorLoc, IsArrow,
3539 SS, TemplateKWLoc,
3540 FirstQualifierInScope,
3541 MemberNameInfo,
3542 TemplateArgs, /*S*/nullptr);
3545 /// Build a new member reference expression.
3547 /// By default, performs semantic analysis to build the new expression.
3548 /// Subclasses may override this routine to provide different behavior.
3549 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3550 SourceLocation OperatorLoc,
3551 bool IsArrow,
3552 NestedNameSpecifierLoc QualifierLoc,
3553 SourceLocation TemplateKWLoc,
3554 NamedDecl *FirstQualifierInScope,
3555 LookupResult &R,
3556 const TemplateArgumentListInfo *TemplateArgs) {
3557 CXXScopeSpec SS;
3558 SS.Adopt(QualifierLoc);
3560 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3561 OperatorLoc, IsArrow,
3562 SS, TemplateKWLoc,
3563 FirstQualifierInScope,
3564 R, TemplateArgs, /*S*/nullptr);
3567 /// Build a new noexcept expression.
3569 /// By default, performs semantic analysis to build the new expression.
3570 /// Subclasses may override this routine to provide different behavior.
3571 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3572 return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd());
3575 /// Build a new expression to compute the length of a parameter pack.
3576 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3577 SourceLocation PackLoc,
3578 SourceLocation RParenLoc,
3579 std::optional<unsigned> Length,
3580 ArrayRef<TemplateArgument> PartialArgs) {
3581 return SizeOfPackExpr::Create(SemaRef.Context, OperatorLoc, Pack, PackLoc,
3582 RParenLoc, Length, PartialArgs);
3585 /// Build a new expression representing a call to a source location
3586 /// builtin.
3588 /// By default, performs semantic analysis to build the new expression.
3589 /// Subclasses may override this routine to provide different behavior.
3590 ExprResult RebuildSourceLocExpr(SourceLocExpr::IdentKind Kind,
3591 QualType ResultTy, SourceLocation BuiltinLoc,
3592 SourceLocation RPLoc,
3593 DeclContext *ParentContext) {
3594 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3595 ParentContext);
3598 /// Build a new Objective-C boxed expression.
3600 /// By default, performs semantic analysis to build the new expression.
3601 /// Subclasses may override this routine to provide different behavior.
3602 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3603 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3604 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3605 TemplateArgumentListInfo *TALI) {
3606 CXXScopeSpec SS;
3607 SS.Adopt(NNS);
3608 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3609 ConceptNameInfo,
3610 FoundDecl,
3611 NamedConcept, TALI);
3612 if (Result.isInvalid())
3613 return ExprError();
3614 return Result;
3617 /// \brief Build a new requires expression.
3619 /// By default, performs semantic analysis to build the new expression.
3620 /// Subclasses may override this routine to provide different behavior.
3621 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3622 RequiresExprBodyDecl *Body,
3623 SourceLocation LParenLoc,
3624 ArrayRef<ParmVarDecl *> LocalParameters,
3625 SourceLocation RParenLoc,
3626 ArrayRef<concepts::Requirement *> Requirements,
3627 SourceLocation ClosingBraceLoc) {
3628 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3629 LocalParameters, RParenLoc, Requirements,
3630 ClosingBraceLoc);
3633 concepts::TypeRequirement *
3634 RebuildTypeRequirement(
3635 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3636 return SemaRef.BuildTypeRequirement(SubstDiag);
3639 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3640 return SemaRef.BuildTypeRequirement(T);
3643 concepts::ExprRequirement *
3644 RebuildExprRequirement(
3645 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3646 SourceLocation NoexceptLoc,
3647 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3648 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
3649 std::move(Ret));
3652 concepts::ExprRequirement *
3653 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3654 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3655 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
3656 std::move(Ret));
3659 concepts::NestedRequirement *
3660 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3661 const ASTConstraintSatisfaction &Satisfaction) {
3662 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3663 Satisfaction);
3666 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3667 return SemaRef.BuildNestedRequirement(Constraint);
3670 /// \brief Build a new Objective-C boxed expression.
3672 /// By default, performs semantic analysis to build the new expression.
3673 /// Subclasses may override this routine to provide different behavior.
3674 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3675 return getSema().BuildObjCBoxedExpr(SR, ValueExpr);
3678 /// Build a new Objective-C array literal.
3680 /// By default, performs semantic analysis to build the new expression.
3681 /// Subclasses may override this routine to provide different behavior.
3682 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3683 Expr **Elements, unsigned NumElements) {
3684 return getSema().BuildObjCArrayLiteral(Range,
3685 MultiExprArg(Elements, NumElements));
3688 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3689 Expr *Base, Expr *Key,
3690 ObjCMethodDecl *getterMethod,
3691 ObjCMethodDecl *setterMethod) {
3692 return getSema().BuildObjCSubscriptExpression(RB, Base, Key,
3693 getterMethod, setterMethod);
3696 /// Build a new Objective-C dictionary literal.
3698 /// By default, performs semantic analysis to build the new expression.
3699 /// Subclasses may override this routine to provide different behavior.
3700 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3701 MutableArrayRef<ObjCDictionaryElement> Elements) {
3702 return getSema().BuildObjCDictionaryLiteral(Range, Elements);
3705 /// Build a new Objective-C \@encode expression.
3707 /// By default, performs semantic analysis to build the new expression.
3708 /// Subclasses may override this routine to provide different behavior.
3709 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3710 TypeSourceInfo *EncodeTypeInfo,
3711 SourceLocation RParenLoc) {
3712 return SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, RParenLoc);
3715 /// Build a new Objective-C class message.
3716 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3717 Selector Sel,
3718 ArrayRef<SourceLocation> SelectorLocs,
3719 ObjCMethodDecl *Method,
3720 SourceLocation LBracLoc,
3721 MultiExprArg Args,
3722 SourceLocation RBracLoc) {
3723 return SemaRef.BuildClassMessage(ReceiverTypeInfo,
3724 ReceiverTypeInfo->getType(),
3725 /*SuperLoc=*/SourceLocation(),
3726 Sel, Method, LBracLoc, SelectorLocs,
3727 RBracLoc, Args);
3730 /// Build a new Objective-C instance message.
3731 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3732 Selector Sel,
3733 ArrayRef<SourceLocation> SelectorLocs,
3734 ObjCMethodDecl *Method,
3735 SourceLocation LBracLoc,
3736 MultiExprArg Args,
3737 SourceLocation RBracLoc) {
3738 return SemaRef.BuildInstanceMessage(Receiver,
3739 Receiver->getType(),
3740 /*SuperLoc=*/SourceLocation(),
3741 Sel, Method, LBracLoc, SelectorLocs,
3742 RBracLoc, Args);
3745 /// Build a new Objective-C instance/class message to 'super'.
3746 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3747 Selector Sel,
3748 ArrayRef<SourceLocation> SelectorLocs,
3749 QualType SuperType,
3750 ObjCMethodDecl *Method,
3751 SourceLocation LBracLoc,
3752 MultiExprArg Args,
3753 SourceLocation RBracLoc) {
3754 return Method->isInstanceMethod() ? SemaRef.BuildInstanceMessage(nullptr,
3755 SuperType,
3756 SuperLoc,
3757 Sel, Method, LBracLoc, SelectorLocs,
3758 RBracLoc, Args)
3759 : SemaRef.BuildClassMessage(nullptr,
3760 SuperType,
3761 SuperLoc,
3762 Sel, Method, LBracLoc, SelectorLocs,
3763 RBracLoc, Args);
3768 /// Build a new Objective-C ivar reference expression.
3770 /// By default, performs semantic analysis to build the new expression.
3771 /// Subclasses may override this routine to provide different behavior.
3772 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3773 SourceLocation IvarLoc,
3774 bool IsArrow, bool IsFreeIvar) {
3775 CXXScopeSpec SS;
3776 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3777 ExprResult Result = getSema().BuildMemberReferenceExpr(
3778 BaseArg, BaseArg->getType(),
3779 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3780 /*FirstQualifierInScope=*/nullptr, NameInfo,
3781 /*TemplateArgs=*/nullptr,
3782 /*S=*/nullptr);
3783 if (IsFreeIvar && Result.isUsable())
3784 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
3785 return Result;
3788 /// Build a new Objective-C property reference expression.
3790 /// By default, performs semantic analysis to build the new expression.
3791 /// Subclasses may override this routine to provide different behavior.
3792 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3793 ObjCPropertyDecl *Property,
3794 SourceLocation PropertyLoc) {
3795 CXXScopeSpec SS;
3796 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3797 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3798 /*FIXME:*/PropertyLoc,
3799 /*IsArrow=*/false,
3800 SS, SourceLocation(),
3801 /*FirstQualifierInScope=*/nullptr,
3802 NameInfo,
3803 /*TemplateArgs=*/nullptr,
3804 /*S=*/nullptr);
3807 /// Build a new Objective-C property reference expression.
3809 /// By default, performs semantic analysis to build the new expression.
3810 /// Subclasses may override this routine to provide different behavior.
3811 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3812 ObjCMethodDecl *Getter,
3813 ObjCMethodDecl *Setter,
3814 SourceLocation PropertyLoc) {
3815 // Since these expressions can only be value-dependent, we do not
3816 // need to perform semantic analysis again.
3817 return Owned(
3818 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3819 VK_LValue, OK_ObjCProperty,
3820 PropertyLoc, Base));
3823 /// Build a new Objective-C "isa" expression.
3825 /// By default, performs semantic analysis to build the new expression.
3826 /// Subclasses may override this routine to provide different behavior.
3827 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
3828 SourceLocation OpLoc, bool IsArrow) {
3829 CXXScopeSpec SS;
3830 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3831 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3832 OpLoc, IsArrow,
3833 SS, SourceLocation(),
3834 /*FirstQualifierInScope=*/nullptr,
3835 NameInfo,
3836 /*TemplateArgs=*/nullptr,
3837 /*S=*/nullptr);
3840 /// Build a new shuffle vector expression.
3842 /// By default, performs semantic analysis to build the new expression.
3843 /// Subclasses may override this routine to provide different behavior.
3844 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
3845 MultiExprArg SubExprs,
3846 SourceLocation RParenLoc) {
3847 // Find the declaration for __builtin_shufflevector
3848 const IdentifierInfo &Name
3849 = SemaRef.Context.Idents.get("__builtin_shufflevector");
3850 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
3851 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
3852 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3854 // Build a reference to the __builtin_shufflevector builtin
3855 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
3856 Expr *Callee = new (SemaRef.Context)
3857 DeclRefExpr(SemaRef.Context, Builtin, false,
3858 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3859 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
3860 Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
3861 CK_BuiltinFnToFnPtr).get();
3863 // Build the CallExpr
3864 ExprResult TheCall = CallExpr::Create(
3865 SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
3866 Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc,
3867 FPOptionsOverride());
3869 // Type-check the __builtin_shufflevector expression.
3870 return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
3873 /// Build a new convert vector expression.
3874 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
3875 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3876 SourceLocation RParenLoc) {
3877 return SemaRef.SemaConvertVectorExpr(SrcExpr, DstTInfo,
3878 BuiltinLoc, RParenLoc);
3881 /// Build a new template argument pack expansion.
3883 /// By default, performs semantic analysis to build a new pack expansion
3884 /// for a template argument. Subclasses may override this routine to provide
3885 /// different behavior.
3886 TemplateArgumentLoc
3887 RebuildPackExpansion(TemplateArgumentLoc Pattern, SourceLocation EllipsisLoc,
3888 std::optional<unsigned> NumExpansions) {
3889 switch (Pattern.getArgument().getKind()) {
3890 case TemplateArgument::Expression: {
3891 ExprResult Result
3892 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
3893 EllipsisLoc, NumExpansions);
3894 if (Result.isInvalid())
3895 return TemplateArgumentLoc();
3897 return TemplateArgumentLoc(Result.get(), Result.get());
3900 case TemplateArgument::Template:
3901 return TemplateArgumentLoc(
3902 SemaRef.Context,
3903 TemplateArgument(Pattern.getArgument().getAsTemplate(),
3904 NumExpansions),
3905 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
3906 EllipsisLoc);
3908 case TemplateArgument::Null:
3909 case TemplateArgument::Integral:
3910 case TemplateArgument::Declaration:
3911 case TemplateArgument::Pack:
3912 case TemplateArgument::TemplateExpansion:
3913 case TemplateArgument::NullPtr:
3914 llvm_unreachable("Pack expansion pattern has no parameter packs");
3916 case TemplateArgument::Type:
3917 if (TypeSourceInfo *Expansion
3918 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
3919 EllipsisLoc,
3920 NumExpansions))
3921 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
3922 Expansion);
3923 break;
3926 return TemplateArgumentLoc();
3929 /// Build a new expression pack expansion.
3931 /// By default, performs semantic analysis to build a new pack expansion
3932 /// for an expression. Subclasses may override this routine to provide
3933 /// different behavior.
3934 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
3935 std::optional<unsigned> NumExpansions) {
3936 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
3939 /// Build a new C++1z fold-expression.
3941 /// By default, performs semantic analysis in order to build a new fold
3942 /// expression.
3943 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
3944 SourceLocation LParenLoc, Expr *LHS,
3945 BinaryOperatorKind Operator,
3946 SourceLocation EllipsisLoc, Expr *RHS,
3947 SourceLocation RParenLoc,
3948 std::optional<unsigned> NumExpansions) {
3949 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
3950 EllipsisLoc, RHS, RParenLoc,
3951 NumExpansions);
3954 /// Build an empty C++1z fold-expression with the given operator.
3956 /// By default, produces the fallback value for the fold-expression, or
3957 /// produce an error if there is no fallback value.
3958 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
3959 BinaryOperatorKind Operator) {
3960 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
3963 /// Build a new atomic operation expression.
3965 /// By default, performs semantic analysis to build the new expression.
3966 /// Subclasses may override this routine to provide different behavior.
3967 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
3968 AtomicExpr::AtomicOp Op,
3969 SourceLocation RParenLoc) {
3970 // Use this for all of the locations, since we don't know the difference
3971 // between the call and the expr at this point.
3972 SourceRange Range{BuiltinLoc, RParenLoc};
3973 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
3974 Sema::AtomicArgumentOrder::AST);
3977 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
3978 ArrayRef<Expr *> SubExprs, QualType Type) {
3979 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
3982 private:
3983 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
3984 QualType ObjectType,
3985 NamedDecl *FirstQualifierInScope,
3986 CXXScopeSpec &SS);
3988 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
3989 QualType ObjectType,
3990 NamedDecl *FirstQualifierInScope,
3991 CXXScopeSpec &SS);
3993 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
3994 NamedDecl *FirstQualifierInScope,
3995 CXXScopeSpec &SS);
3997 QualType TransformDependentNameType(TypeLocBuilder &TLB,
3998 DependentNameTypeLoc TL,
3999 bool DeducibleTSTContext);
4002 template <typename Derived>
4003 StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4004 if (!S)
4005 return S;
4007 switch (S->getStmtClass()) {
4008 case Stmt::NoStmtClass: break;
4010 // Transform individual statement nodes
4011 // Pass SDK into statements that can produce a value
4012 #define STMT(Node, Parent) \
4013 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4014 #define VALUESTMT(Node, Parent) \
4015 case Stmt::Node##Class: \
4016 return getDerived().Transform##Node(cast<Node>(S), SDK);
4017 #define ABSTRACT_STMT(Node)
4018 #define EXPR(Node, Parent)
4019 #include "clang/AST/StmtNodes.inc"
4021 // Transform expressions by calling TransformExpr.
4022 #define STMT(Node, Parent)
4023 #define ABSTRACT_STMT(Stmt)
4024 #define EXPR(Node, Parent) case Stmt::Node##Class:
4025 #include "clang/AST/StmtNodes.inc"
4027 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
4029 if (SDK == SDK_StmtExprResult)
4030 E = getSema().ActOnStmtExprResult(E);
4031 return getSema().ActOnExprStmt(E, SDK == SDK_Discarded);
4035 return S;
4038 template<typename Derived>
4039 OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4040 if (!S)
4041 return S;
4043 switch (S->getClauseKind()) {
4044 default: break;
4045 // Transform individual clause nodes
4046 #define GEN_CLANG_CLAUSE_CLASS
4047 #define CLAUSE_CLASS(Enum, Str, Class) \
4048 case Enum: \
4049 return getDerived().Transform##Class(cast<Class>(S));
4050 #include "llvm/Frontend/OpenMP/OMP.inc"
4053 return S;
4057 template<typename Derived>
4058 ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4059 if (!E)
4060 return E;
4062 switch (E->getStmtClass()) {
4063 case Stmt::NoStmtClass: break;
4064 #define STMT(Node, Parent) case Stmt::Node##Class: break;
4065 #define ABSTRACT_STMT(Stmt)
4066 #define EXPR(Node, Parent) \
4067 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4068 #include "clang/AST/StmtNodes.inc"
4071 return E;
4074 template<typename Derived>
4075 ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4076 bool NotCopyInit) {
4077 // Initializers are instantiated like expressions, except that various outer
4078 // layers are stripped.
4079 if (!Init)
4080 return Init;
4082 if (auto *FE = dyn_cast<FullExpr>(Init))
4083 Init = FE->getSubExpr();
4085 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {
4086 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4087 Init = OVE->getSourceExpr();
4090 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
4091 Init = MTE->getSubExpr();
4093 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
4094 Init = Binder->getSubExpr();
4096 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
4097 Init = ICE->getSubExprAsWritten();
4099 if (CXXStdInitializerListExpr *ILE =
4100 dyn_cast<CXXStdInitializerListExpr>(Init))
4101 return TransformInitializer(ILE->getSubExpr(), NotCopyInit);
4103 // If this is copy-initialization, we only need to reconstruct
4104 // InitListExprs. Other forms of copy-initialization will be a no-op if
4105 // the initializer is already the right type.
4106 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
4107 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4108 return getDerived().TransformExpr(Init);
4110 // Revert value-initialization back to empty parens.
4111 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
4112 SourceRange Parens = VIE->getSourceRange();
4113 return getDerived().RebuildParenListExpr(Parens.getBegin(), std::nullopt,
4114 Parens.getEnd());
4117 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4118 if (isa<ImplicitValueInitExpr>(Init))
4119 return getDerived().RebuildParenListExpr(SourceLocation(), std::nullopt,
4120 SourceLocation());
4122 // Revert initialization by constructor back to a parenthesized or braced list
4123 // of expressions. Any other form of initializer can just be reused directly.
4124 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
4125 return getDerived().TransformExpr(Init);
4127 // If the initialization implicitly converted an initializer list to a
4128 // std::initializer_list object, unwrap the std::initializer_list too.
4129 if (Construct && Construct->isStdInitListInitialization())
4130 return TransformInitializer(Construct->getArg(0), NotCopyInit);
4132 // Enter a list-init context if this was list initialization.
4133 EnterExpressionEvaluationContext Context(
4134 getSema(), EnterExpressionEvaluationContext::InitList,
4135 Construct->isListInitialization());
4137 SmallVector<Expr*, 8> NewArgs;
4138 bool ArgChanged = false;
4139 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4140 /*IsCall*/true, NewArgs, &ArgChanged))
4141 return ExprError();
4143 // If this was list initialization, revert to syntactic list form.
4144 if (Construct->isListInitialization())
4145 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4146 Construct->getEndLoc());
4148 // Build a ParenListExpr to represent anything else.
4149 SourceRange Parens = Construct->getParenOrBraceRange();
4150 if (Parens.isInvalid()) {
4151 // This was a variable declaration's initialization for which no initializer
4152 // was specified.
4153 assert(NewArgs.empty() &&
4154 "no parens or braces but have direct init with arguments?");
4155 return ExprEmpty();
4157 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4158 Parens.getEnd());
4161 template<typename Derived>
4162 bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4163 unsigned NumInputs,
4164 bool IsCall,
4165 SmallVectorImpl<Expr *> &Outputs,
4166 bool *ArgChanged) {
4167 for (unsigned I = 0; I != NumInputs; ++I) {
4168 // If requested, drop call arguments that need to be dropped.
4169 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4170 if (ArgChanged)
4171 *ArgChanged = true;
4173 break;
4176 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
4177 Expr *Pattern = Expansion->getPattern();
4179 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4180 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4181 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4183 // Determine whether the set of unexpanded parameter packs can and should
4184 // be expanded.
4185 bool Expand = true;
4186 bool RetainExpansion = false;
4187 std::optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions();
4188 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4189 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4190 Pattern->getSourceRange(),
4191 Unexpanded,
4192 Expand, RetainExpansion,
4193 NumExpansions))
4194 return true;
4196 if (!Expand) {
4197 // The transform has determined that we should perform a simple
4198 // transformation on the pack expansion, producing another pack
4199 // expansion.
4200 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4201 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4202 if (OutPattern.isInvalid())
4203 return true;
4205 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4206 Expansion->getEllipsisLoc(),
4207 NumExpansions);
4208 if (Out.isInvalid())
4209 return true;
4211 if (ArgChanged)
4212 *ArgChanged = true;
4213 Outputs.push_back(Out.get());
4214 continue;
4217 // Record right away that the argument was changed. This needs
4218 // to happen even if the array expands to nothing.
4219 if (ArgChanged) *ArgChanged = true;
4221 // The transform has determined that we should perform an elementwise
4222 // expansion of the pattern. Do so.
4223 for (unsigned I = 0; I != *NumExpansions; ++I) {
4224 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4225 ExprResult Out = getDerived().TransformExpr(Pattern);
4226 if (Out.isInvalid())
4227 return true;
4229 if (Out.get()->containsUnexpandedParameterPack()) {
4230 Out = getDerived().RebuildPackExpansion(
4231 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4232 if (Out.isInvalid())
4233 return true;
4236 Outputs.push_back(Out.get());
4239 // If we're supposed to retain a pack expansion, do so by temporarily
4240 // forgetting the partially-substituted parameter pack.
4241 if (RetainExpansion) {
4242 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4244 ExprResult Out = getDerived().TransformExpr(Pattern);
4245 if (Out.isInvalid())
4246 return true;
4248 Out = getDerived().RebuildPackExpansion(
4249 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4250 if (Out.isInvalid())
4251 return true;
4253 Outputs.push_back(Out.get());
4256 continue;
4259 ExprResult Result =
4260 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4261 : getDerived().TransformExpr(Inputs[I]);
4262 if (Result.isInvalid())
4263 return true;
4265 if (Result.get() != Inputs[I] && ArgChanged)
4266 *ArgChanged = true;
4268 Outputs.push_back(Result.get());
4271 return false;
4274 template <typename Derived>
4275 Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4276 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4277 if (Var) {
4278 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4279 getDerived().TransformDefinition(Var->getLocation(), Var));
4281 if (!ConditionVar)
4282 return Sema::ConditionError();
4284 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4287 if (Expr) {
4288 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4290 if (CondExpr.isInvalid())
4291 return Sema::ConditionError();
4293 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4294 /*MissingOK=*/true);
4297 return Sema::ConditionResult();
4300 template <typename Derived>
4301 NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4302 NestedNameSpecifierLoc NNS, QualType ObjectType,
4303 NamedDecl *FirstQualifierInScope) {
4304 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4306 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4307 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4308 Qualifier = Qualifier.getPrefix())
4309 Qualifiers.push_back(Qualifier);
4311 insertNNS(NNS);
4313 CXXScopeSpec SS;
4314 while (!Qualifiers.empty()) {
4315 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4316 NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
4318 switch (QNNS->getKind()) {
4319 case NestedNameSpecifier::Identifier: {
4320 Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
4321 Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
4322 ObjectType);
4323 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false,
4324 SS, FirstQualifierInScope, false))
4325 return NestedNameSpecifierLoc();
4326 break;
4329 case NestedNameSpecifier::Namespace: {
4330 NamespaceDecl *NS =
4331 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4332 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4333 SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
4334 break;
4337 case NestedNameSpecifier::NamespaceAlias: {
4338 NamespaceAliasDecl *Alias =
4339 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4340 Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
4341 SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
4342 Q.getLocalEndLoc());
4343 break;
4346 case NestedNameSpecifier::Global:
4347 // There is no meaningful transformation that one could perform on the
4348 // global scope.
4349 SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
4350 break;
4352 case NestedNameSpecifier::Super: {
4353 CXXRecordDecl *RD =
4354 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4355 SourceLocation(), QNNS->getAsRecordDecl()));
4356 SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc());
4357 break;
4360 case NestedNameSpecifier::TypeSpecWithTemplate:
4361 case NestedNameSpecifier::TypeSpec: {
4362 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4363 FirstQualifierInScope, SS);
4365 if (!TL)
4366 return NestedNameSpecifierLoc();
4368 QualType T = TL.getType();
4369 if (T->isDependentType() || T->isRecordType() ||
4370 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4371 if (T->isEnumeralType())
4372 SemaRef.Diag(TL.getBeginLoc(),
4373 diag::warn_cxx98_compat_enum_nested_name_spec);
4375 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4376 SS.Adopt(ETL.getQualifierLoc());
4377 TL = ETL.getNamedTypeLoc();
4379 SS.Extend(SemaRef.Context, /*FIXME:*/ SourceLocation(), TL,
4380 Q.getLocalEndLoc());
4381 break;
4383 // If the nested-name-specifier is an invalid type def, don't emit an
4384 // error because a previous error should have already been emitted.
4385 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4386 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4387 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
4388 << T << SS.getRange();
4390 return NestedNameSpecifierLoc();
4394 // The qualifier-in-scope and object type only apply to the leftmost entity.
4395 FirstQualifierInScope = nullptr;
4396 ObjectType = QualType();
4399 // Don't rebuild the nested-name-specifier if we don't have to.
4400 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4401 !getDerived().AlwaysRebuild())
4402 return NNS;
4404 // If we can re-use the source-location data from the original
4405 // nested-name-specifier, do so.
4406 if (SS.location_size() == NNS.getDataLength() &&
4407 memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)
4408 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4410 // Allocate new nested-name-specifier location information.
4411 return SS.getWithLocInContext(SemaRef.Context);
4414 template<typename Derived>
4415 DeclarationNameInfo
4416 TreeTransform<Derived>
4417 ::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4418 DeclarationName Name = NameInfo.getName();
4419 if (!Name)
4420 return DeclarationNameInfo();
4422 switch (Name.getNameKind()) {
4423 case DeclarationName::Identifier:
4424 case DeclarationName::ObjCZeroArgSelector:
4425 case DeclarationName::ObjCOneArgSelector:
4426 case DeclarationName::ObjCMultiArgSelector:
4427 case DeclarationName::CXXOperatorName:
4428 case DeclarationName::CXXLiteralOperatorName:
4429 case DeclarationName::CXXUsingDirective:
4430 return NameInfo;
4432 case DeclarationName::CXXDeductionGuideName: {
4433 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4434 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4435 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4436 if (!NewTemplate)
4437 return DeclarationNameInfo();
4439 DeclarationNameInfo NewNameInfo(NameInfo);
4440 NewNameInfo.setName(
4441 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(NewTemplate));
4442 return NewNameInfo;
4445 case DeclarationName::CXXConstructorName:
4446 case DeclarationName::CXXDestructorName:
4447 case DeclarationName::CXXConversionFunctionName: {
4448 TypeSourceInfo *NewTInfo;
4449 CanQualType NewCanTy;
4450 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4451 NewTInfo = getDerived().TransformType(OldTInfo);
4452 if (!NewTInfo)
4453 return DeclarationNameInfo();
4454 NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
4456 else {
4457 NewTInfo = nullptr;
4458 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4459 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4460 if (NewT.isNull())
4461 return DeclarationNameInfo();
4462 NewCanTy = SemaRef.Context.getCanonicalType(NewT);
4465 DeclarationName NewName
4466 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
4467 NewCanTy);
4468 DeclarationNameInfo NewNameInfo(NameInfo);
4469 NewNameInfo.setName(NewName);
4470 NewNameInfo.setNamedTypeInfo(NewTInfo);
4471 return NewNameInfo;
4475 llvm_unreachable("Unknown name kind.");
4478 template<typename Derived>
4479 TemplateName
4480 TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
4481 TemplateName Name,
4482 SourceLocation NameLoc,
4483 QualType ObjectType,
4484 NamedDecl *FirstQualifierInScope,
4485 bool AllowInjectedClassName) {
4486 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4487 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4488 assert(Template && "qualified template name must refer to a template");
4490 TemplateDecl *TransTemplate
4491 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4492 Template));
4493 if (!TransTemplate)
4494 return TemplateName();
4496 if (!getDerived().AlwaysRebuild() &&
4497 SS.getScopeRep() == QTN->getQualifier() &&
4498 TransTemplate == Template)
4499 return Name;
4501 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4502 TransTemplate);
4505 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4506 if (SS.getScopeRep()) {
4507 // These apply to the scope specifier, not the template.
4508 ObjectType = QualType();
4509 FirstQualifierInScope = nullptr;
4512 if (!getDerived().AlwaysRebuild() &&
4513 SS.getScopeRep() == DTN->getQualifier() &&
4514 ObjectType.isNull())
4515 return Name;
4517 // FIXME: Preserve the location of the "template" keyword.
4518 SourceLocation TemplateKWLoc = NameLoc;
4520 if (DTN->isIdentifier()) {
4521 return getDerived().RebuildTemplateName(SS,
4522 TemplateKWLoc,
4523 *DTN->getIdentifier(),
4524 NameLoc,
4525 ObjectType,
4526 FirstQualifierInScope,
4527 AllowInjectedClassName);
4530 return getDerived().RebuildTemplateName(SS, TemplateKWLoc,
4531 DTN->getOperator(), NameLoc,
4532 ObjectType, AllowInjectedClassName);
4535 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4536 TemplateDecl *TransTemplate
4537 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4538 Template));
4539 if (!TransTemplate)
4540 return TemplateName();
4542 if (!getDerived().AlwaysRebuild() &&
4543 TransTemplate == Template)
4544 return Name;
4546 return TemplateName(TransTemplate);
4549 if (SubstTemplateTemplateParmPackStorage *SubstPack
4550 = Name.getAsSubstTemplateTemplateParmPack()) {
4551 return getDerived().RebuildTemplateName(
4552 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4553 SubstPack->getIndex(), SubstPack->getFinal());
4556 // These should be getting filtered out before they reach the AST.
4557 llvm_unreachable("overloaded function decl survived to here");
4560 template<typename Derived>
4561 void TreeTransform<Derived>::InventTemplateArgumentLoc(
4562 const TemplateArgument &Arg,
4563 TemplateArgumentLoc &Output) {
4564 Output = getSema().getTrivialTemplateArgumentLoc(
4565 Arg, QualType(), getDerived().getBaseLocation());
4568 template <typename Derived>
4569 bool TreeTransform<Derived>::TransformTemplateArgument(
4570 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4571 bool Uneval) {
4572 const TemplateArgument &Arg = Input.getArgument();
4573 switch (Arg.getKind()) {
4574 case TemplateArgument::Null:
4575 case TemplateArgument::Pack:
4576 llvm_unreachable("Unexpected TemplateArgument");
4578 case TemplateArgument::Integral:
4579 case TemplateArgument::NullPtr:
4580 case TemplateArgument::Declaration: {
4581 // Transform a resolved template argument straight to a resolved template
4582 // argument. We get here when substituting into an already-substituted
4583 // template type argument during concept satisfaction checking.
4584 QualType T = Arg.getNonTypeTemplateArgumentType();
4585 QualType NewT = getDerived().TransformType(T);
4586 if (NewT.isNull())
4587 return true;
4589 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
4590 ? Arg.getAsDecl()
4591 : nullptr;
4592 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4593 getDerived().getBaseLocation(), D))
4594 : nullptr;
4595 if (D && !NewD)
4596 return true;
4598 if (NewT == T && D == NewD)
4599 Output = Input;
4600 else if (Arg.getKind() == TemplateArgument::Integral)
4601 Output = TemplateArgumentLoc(
4602 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4603 TemplateArgumentLocInfo());
4604 else if (Arg.getKind() == TemplateArgument::NullPtr)
4605 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4606 TemplateArgumentLocInfo());
4607 else
4608 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4609 TemplateArgumentLocInfo());
4611 return false;
4614 case TemplateArgument::Type: {
4615 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4616 if (!DI)
4617 DI = InventTypeSourceInfo(Input.getArgument().getAsType());
4619 DI = getDerived().TransformType(DI);
4620 if (!DI)
4621 return true;
4623 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4624 return false;
4627 case TemplateArgument::Template: {
4628 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4629 if (QualifierLoc) {
4630 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4631 if (!QualifierLoc)
4632 return true;
4635 CXXScopeSpec SS;
4636 SS.Adopt(QualifierLoc);
4637 TemplateName Template = getDerived().TransformTemplateName(
4638 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4639 if (Template.isNull())
4640 return true;
4642 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4643 QualifierLoc, Input.getTemplateNameLoc());
4644 return false;
4647 case TemplateArgument::TemplateExpansion:
4648 llvm_unreachable("Caller should expand pack expansions");
4650 case TemplateArgument::Expression: {
4651 // Template argument expressions are constant expressions.
4652 EnterExpressionEvaluationContext Unevaluated(
4653 getSema(),
4654 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
4655 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
4656 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4657 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
4659 Expr *InputExpr = Input.getSourceExpression();
4660 if (!InputExpr)
4661 InputExpr = Input.getArgument().getAsExpr();
4663 ExprResult E = getDerived().TransformExpr(InputExpr);
4664 E = SemaRef.ActOnConstantExpression(E);
4665 if (E.isInvalid())
4666 return true;
4667 Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
4668 return false;
4672 // Work around bogus GCC warning
4673 return true;
4676 /// Iterator adaptor that invents template argument location information
4677 /// for each of the template arguments in its underlying iterator.
4678 template<typename Derived, typename InputIterator>
4679 class TemplateArgumentLocInventIterator {
4680 TreeTransform<Derived> &Self;
4681 InputIterator Iter;
4683 public:
4684 typedef TemplateArgumentLoc value_type;
4685 typedef TemplateArgumentLoc reference;
4686 typedef typename std::iterator_traits<InputIterator>::difference_type
4687 difference_type;
4688 typedef std::input_iterator_tag iterator_category;
4690 class pointer {
4691 TemplateArgumentLoc Arg;
4693 public:
4694 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4696 const TemplateArgumentLoc *operator->() const { return &Arg; }
4699 TemplateArgumentLocInventIterator() { }
4701 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
4702 InputIterator Iter)
4703 : Self(Self), Iter(Iter) { }
4705 TemplateArgumentLocInventIterator &operator++() {
4706 ++Iter;
4707 return *this;
4710 TemplateArgumentLocInventIterator operator++(int) {
4711 TemplateArgumentLocInventIterator Old(*this);
4712 ++(*this);
4713 return Old;
4716 reference operator*() const {
4717 TemplateArgumentLoc Result;
4718 Self.InventTemplateArgumentLoc(*Iter, Result);
4719 return Result;
4722 pointer operator->() const { return pointer(**this); }
4724 friend bool operator==(const TemplateArgumentLocInventIterator &X,
4725 const TemplateArgumentLocInventIterator &Y) {
4726 return X.Iter == Y.Iter;
4729 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
4730 const TemplateArgumentLocInventIterator &Y) {
4731 return X.Iter != Y.Iter;
4735 template<typename Derived>
4736 template<typename InputIterator>
4737 bool TreeTransform<Derived>::TransformTemplateArguments(
4738 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
4739 bool Uneval) {
4740 for (; First != Last; ++First) {
4741 TemplateArgumentLoc Out;
4742 TemplateArgumentLoc In = *First;
4744 if (In.getArgument().getKind() == TemplateArgument::Pack) {
4745 // Unpack argument packs, which we translate them into separate
4746 // arguments.
4747 // FIXME: We could do much better if we could guarantee that the
4748 // TemplateArgumentLocInfo for the pack expansion would be usable for
4749 // all of the template arguments in the argument pack.
4750 typedef TemplateArgumentLocInventIterator<Derived,
4751 TemplateArgument::pack_iterator>
4752 PackLocIterator;
4753 if (TransformTemplateArguments(PackLocIterator(*this,
4754 In.getArgument().pack_begin()),
4755 PackLocIterator(*this,
4756 In.getArgument().pack_end()),
4757 Outputs, Uneval))
4758 return true;
4760 continue;
4763 if (In.getArgument().isPackExpansion()) {
4764 // We have a pack expansion, for which we will be substituting into
4765 // the pattern.
4766 SourceLocation Ellipsis;
4767 std::optional<unsigned> OrigNumExpansions;
4768 TemplateArgumentLoc Pattern
4769 = getSema().getTemplateArgumentPackExpansionPattern(
4770 In, Ellipsis, OrigNumExpansions);
4772 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4773 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4774 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4776 // Determine whether the set of unexpanded parameter packs can and should
4777 // be expanded.
4778 bool Expand = true;
4779 bool RetainExpansion = false;
4780 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4781 if (getDerived().TryExpandParameterPacks(Ellipsis,
4782 Pattern.getSourceRange(),
4783 Unexpanded,
4784 Expand,
4785 RetainExpansion,
4786 NumExpansions))
4787 return true;
4789 if (!Expand) {
4790 // The transform has determined that we should perform a simple
4791 // transformation on the pack expansion, producing another pack
4792 // expansion.
4793 TemplateArgumentLoc OutPattern;
4794 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4795 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
4796 return true;
4798 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
4799 NumExpansions);
4800 if (Out.getArgument().isNull())
4801 return true;
4803 Outputs.addArgument(Out);
4804 continue;
4807 // The transform has determined that we should perform an elementwise
4808 // expansion of the pattern. Do so.
4809 for (unsigned I = 0; I != *NumExpansions; ++I) {
4810 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4812 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4813 return true;
4815 if (Out.getArgument().containsUnexpandedParameterPack()) {
4816 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4817 OrigNumExpansions);
4818 if (Out.getArgument().isNull())
4819 return true;
4822 Outputs.addArgument(Out);
4825 // If we're supposed to retain a pack expansion, do so by temporarily
4826 // forgetting the partially-substituted parameter pack.
4827 if (RetainExpansion) {
4828 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4830 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4831 return true;
4833 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4834 OrigNumExpansions);
4835 if (Out.getArgument().isNull())
4836 return true;
4838 Outputs.addArgument(Out);
4841 continue;
4844 // The simple case:
4845 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
4846 return true;
4848 Outputs.addArgument(Out);
4851 return false;
4855 //===----------------------------------------------------------------------===//
4856 // Type transformation
4857 //===----------------------------------------------------------------------===//
4859 template<typename Derived>
4860 QualType TreeTransform<Derived>::TransformType(QualType T) {
4861 if (getDerived().AlreadyTransformed(T))
4862 return T;
4864 // Temporary workaround. All of these transformations should
4865 // eventually turn into transformations on TypeLocs.
4866 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4867 getDerived().getBaseLocation());
4869 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
4871 if (!NewDI)
4872 return QualType();
4874 return NewDI->getType();
4877 template<typename Derived>
4878 TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
4879 // Refine the base location to the type's location.
4880 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
4881 getDerived().getBaseEntity());
4882 if (getDerived().AlreadyTransformed(DI->getType()))
4883 return DI;
4885 TypeLocBuilder TLB;
4887 TypeLoc TL = DI->getTypeLoc();
4888 TLB.reserve(TL.getFullDataSize());
4890 QualType Result = getDerived().TransformType(TLB, TL);
4891 if (Result.isNull())
4892 return nullptr;
4894 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
4897 template<typename Derived>
4898 QualType
4899 TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
4900 switch (T.getTypeLocClass()) {
4901 #define ABSTRACT_TYPELOC(CLASS, PARENT)
4902 #define TYPELOC(CLASS, PARENT) \
4903 case TypeLoc::CLASS: \
4904 return getDerived().Transform##CLASS##Type(TLB, \
4905 T.castAs<CLASS##TypeLoc>());
4906 #include "clang/AST/TypeLocNodes.def"
4909 llvm_unreachable("unhandled type loc!");
4912 template<typename Derived>
4913 QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
4914 if (!isa<DependentNameType>(T))
4915 return TransformType(T);
4917 if (getDerived().AlreadyTransformed(T))
4918 return T;
4919 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4920 getDerived().getBaseLocation());
4921 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
4922 return NewDI ? NewDI->getType() : QualType();
4925 template<typename Derived>
4926 TypeSourceInfo *
4927 TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
4928 if (!isa<DependentNameType>(DI->getType()))
4929 return TransformType(DI);
4931 // Refine the base location to the type's location.
4932 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
4933 getDerived().getBaseEntity());
4934 if (getDerived().AlreadyTransformed(DI->getType()))
4935 return DI;
4937 TypeLocBuilder TLB;
4939 TypeLoc TL = DI->getTypeLoc();
4940 TLB.reserve(TL.getFullDataSize());
4942 auto QTL = TL.getAs<QualifiedTypeLoc>();
4943 if (QTL)
4944 TL = QTL.getUnqualifiedLoc();
4946 auto DNTL = TL.castAs<DependentNameTypeLoc>();
4948 QualType Result = getDerived().TransformDependentNameType(
4949 TLB, DNTL, /*DeducedTSTContext*/true);
4950 if (Result.isNull())
4951 return nullptr;
4953 if (QTL) {
4954 Result = getDerived().RebuildQualifiedType(Result, QTL);
4955 if (Result.isNull())
4956 return nullptr;
4957 TLB.TypeWasModifiedSafely(Result);
4960 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
4963 template<typename Derived>
4964 QualType
4965 TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
4966 QualifiedTypeLoc T) {
4967 QualType Result;
4968 TypeLoc UnqualTL = T.getUnqualifiedLoc();
4969 auto SuppressObjCLifetime =
4970 T.getType().getLocalQualifiers().hasObjCLifetime();
4971 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
4972 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
4973 SuppressObjCLifetime);
4974 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
4975 Result = getDerived().TransformSubstTemplateTypeParmPackType(
4976 TLB, STTP, SuppressObjCLifetime);
4977 } else {
4978 Result = getDerived().TransformType(TLB, UnqualTL);
4981 if (Result.isNull())
4982 return QualType();
4984 Result = getDerived().RebuildQualifiedType(Result, T);
4986 if (Result.isNull())
4987 return QualType();
4989 // RebuildQualifiedType might have updated the type, but not in a way
4990 // that invalidates the TypeLoc. (There's no location information for
4991 // qualifiers.)
4992 TLB.TypeWasModifiedSafely(Result);
4994 return Result;
4997 template <typename Derived>
4998 QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
4999 QualifiedTypeLoc TL) {
5001 SourceLocation Loc = TL.getBeginLoc();
5002 Qualifiers Quals = TL.getType().getLocalQualifiers();
5004 if ((T.getAddressSpace() != LangAS::Default &&
5005 Quals.getAddressSpace() != LangAS::Default) &&
5006 T.getAddressSpace() != Quals.getAddressSpace()) {
5007 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)
5008 << TL.getType() << T;
5009 return QualType();
5012 // C++ [dcl.fct]p7:
5013 // [When] adding cv-qualifications on top of the function type [...] the
5014 // cv-qualifiers are ignored.
5015 if (T->isFunctionType()) {
5016 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5017 Quals.getAddressSpace());
5018 return T;
5021 // C++ [dcl.ref]p1:
5022 // when the cv-qualifiers are introduced through the use of a typedef-name
5023 // or decltype-specifier [...] the cv-qualifiers are ignored.
5024 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5025 // applied to a reference type.
5026 if (T->isReferenceType()) {
5027 // The only qualifier that applies to a reference type is restrict.
5028 if (!Quals.hasRestrict())
5029 return T;
5030 Quals = Qualifiers::fromCVRMask(Qualifiers::Restrict);
5033 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5034 // resulting type.
5035 if (Quals.hasObjCLifetime()) {
5036 if (!T->isObjCLifetimeType() && !T->isDependentType())
5037 Quals.removeObjCLifetime();
5038 else if (T.getObjCLifetime()) {
5039 // Objective-C ARC:
5040 // A lifetime qualifier applied to a substituted template parameter
5041 // overrides the lifetime qualifier from the template argument.
5042 const AutoType *AutoTy;
5043 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
5044 // 'auto' types behave the same way as template parameters.
5045 QualType Deduced = AutoTy->getDeducedType();
5046 Qualifiers Qs = Deduced.getQualifiers();
5047 Qs.removeObjCLifetime();
5048 Deduced =
5049 SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);
5050 T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),
5051 AutoTy->isDependentType(),
5052 /*isPack=*/false,
5053 AutoTy->getTypeConstraintConcept(),
5054 AutoTy->getTypeConstraintArguments());
5055 } else {
5056 // Otherwise, complain about the addition of a qualifier to an
5057 // already-qualified type.
5058 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5059 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
5060 Quals.removeObjCLifetime();
5065 return SemaRef.BuildQualifiedType(T, Loc, Quals);
5068 template<typename Derived>
5069 TypeLoc
5070 TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
5071 QualType ObjectType,
5072 NamedDecl *UnqualLookup,
5073 CXXScopeSpec &SS) {
5074 if (getDerived().AlreadyTransformed(TL.getType()))
5075 return TL;
5077 TypeSourceInfo *TSI =
5078 TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS);
5079 if (TSI)
5080 return TSI->getTypeLoc();
5081 return TypeLoc();
5084 template<typename Derived>
5085 TypeSourceInfo *
5086 TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5087 QualType ObjectType,
5088 NamedDecl *UnqualLookup,
5089 CXXScopeSpec &SS) {
5090 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5091 return TSInfo;
5093 return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType,
5094 UnqualLookup, SS);
5097 template <typename Derived>
5098 TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5099 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5100 CXXScopeSpec &SS) {
5101 QualType T = TL.getType();
5102 assert(!getDerived().AlreadyTransformed(T));
5104 TypeLocBuilder TLB;
5105 QualType Result;
5107 if (isa<TemplateSpecializationType>(T)) {
5108 TemplateSpecializationTypeLoc SpecTL =
5109 TL.castAs<TemplateSpecializationTypeLoc>();
5111 TemplateName Template = getDerived().TransformTemplateName(
5112 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5113 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5114 if (Template.isNull())
5115 return nullptr;
5117 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5118 Template);
5119 } else if (isa<DependentTemplateSpecializationType>(T)) {
5120 DependentTemplateSpecializationTypeLoc SpecTL =
5121 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5123 TemplateName Template
5124 = getDerived().RebuildTemplateName(SS,
5125 SpecTL.getTemplateKeywordLoc(),
5126 *SpecTL.getTypePtr()->getIdentifier(),
5127 SpecTL.getTemplateNameLoc(),
5128 ObjectType, UnqualLookup,
5129 /*AllowInjectedClassName*/true);
5130 if (Template.isNull())
5131 return nullptr;
5133 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5134 SpecTL,
5135 Template,
5136 SS);
5137 } else {
5138 // Nothing special needs to be done for these.
5139 Result = getDerived().TransformType(TLB, TL);
5142 if (Result.isNull())
5143 return nullptr;
5145 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5148 template <class TyLoc> static inline
5149 QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5150 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5151 NewT.setNameLoc(T.getNameLoc());
5152 return T.getType();
5155 template<typename Derived>
5156 QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5157 BuiltinTypeLoc T) {
5158 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
5159 NewT.setBuiltinLoc(T.getBuiltinLoc());
5160 if (T.needsExtraLocalData())
5161 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5162 return T.getType();
5165 template<typename Derived>
5166 QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5167 ComplexTypeLoc T) {
5168 // FIXME: recurse?
5169 return TransformTypeSpecType(TLB, T);
5172 template <typename Derived>
5173 QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5174 AdjustedTypeLoc TL) {
5175 // Adjustments applied during transformation are handled elsewhere.
5176 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5179 template<typename Derived>
5180 QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5181 DecayedTypeLoc TL) {
5182 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5183 if (OriginalType.isNull())
5184 return QualType();
5186 QualType Result = TL.getType();
5187 if (getDerived().AlwaysRebuild() ||
5188 OriginalType != TL.getOriginalLoc().getType())
5189 Result = SemaRef.Context.getDecayedType(OriginalType);
5190 TLB.push<DecayedTypeLoc>(Result);
5191 // Nothing to set for DecayedTypeLoc.
5192 return Result;
5195 template<typename Derived>
5196 QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5197 PointerTypeLoc TL) {
5198 QualType PointeeType
5199 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5200 if (PointeeType.isNull())
5201 return QualType();
5203 QualType Result = TL.getType();
5204 if (PointeeType->getAs<ObjCObjectType>()) {
5205 // A dependent pointer type 'T *' has is being transformed such
5206 // that an Objective-C class type is being replaced for 'T'. The
5207 // resulting pointer type is an ObjCObjectPointerType, not a
5208 // PointerType.
5209 Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
5211 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
5212 NewT.setStarLoc(TL.getStarLoc());
5213 return Result;
5216 if (getDerived().AlwaysRebuild() ||
5217 PointeeType != TL.getPointeeLoc().getType()) {
5218 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5219 if (Result.isNull())
5220 return QualType();
5223 // Objective-C ARC can add lifetime qualifiers to the type that we're
5224 // pointing to.
5225 TLB.TypeWasModifiedSafely(Result->getPointeeType());
5227 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
5228 NewT.setSigilLoc(TL.getSigilLoc());
5229 return Result;
5232 template<typename Derived>
5233 QualType
5234 TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5235 BlockPointerTypeLoc TL) {
5236 QualType PointeeType
5237 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5238 if (PointeeType.isNull())
5239 return QualType();
5241 QualType Result = TL.getType();
5242 if (getDerived().AlwaysRebuild() ||
5243 PointeeType != TL.getPointeeLoc().getType()) {
5244 Result = getDerived().RebuildBlockPointerType(PointeeType,
5245 TL.getSigilLoc());
5246 if (Result.isNull())
5247 return QualType();
5250 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
5251 NewT.setSigilLoc(TL.getSigilLoc());
5252 return Result;
5255 /// Transforms a reference type. Note that somewhat paradoxically we
5256 /// don't care whether the type itself is an l-value type or an r-value
5257 /// type; we only care if the type was *written* as an l-value type
5258 /// or an r-value type.
5259 template<typename Derived>
5260 QualType
5261 TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5262 ReferenceTypeLoc TL) {
5263 const ReferenceType *T = TL.getTypePtr();
5265 // Note that this works with the pointee-as-written.
5266 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5267 if (PointeeType.isNull())
5268 return QualType();
5270 QualType Result = TL.getType();
5271 if (getDerived().AlwaysRebuild() ||
5272 PointeeType != T->getPointeeTypeAsWritten()) {
5273 Result = getDerived().RebuildReferenceType(PointeeType,
5274 T->isSpelledAsLValue(),
5275 TL.getSigilLoc());
5276 if (Result.isNull())
5277 return QualType();
5280 // Objective-C ARC can add lifetime qualifiers to the type that we're
5281 // referring to.
5282 TLB.TypeWasModifiedSafely(
5283 Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5285 // r-value references can be rebuilt as l-value references.
5286 ReferenceTypeLoc NewTL;
5287 if (isa<LValueReferenceType>(Result))
5288 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
5289 else
5290 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
5291 NewTL.setSigilLoc(TL.getSigilLoc());
5293 return Result;
5296 template<typename Derived>
5297 QualType
5298 TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5299 LValueReferenceTypeLoc TL) {
5300 return TransformReferenceType(TLB, TL);
5303 template<typename Derived>
5304 QualType
5305 TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5306 RValueReferenceTypeLoc TL) {
5307 return TransformReferenceType(TLB, TL);
5310 template<typename Derived>
5311 QualType
5312 TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5313 MemberPointerTypeLoc TL) {
5314 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5315 if (PointeeType.isNull())
5316 return QualType();
5318 TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
5319 TypeSourceInfo *NewClsTInfo = nullptr;
5320 if (OldClsTInfo) {
5321 NewClsTInfo = getDerived().TransformType(OldClsTInfo);
5322 if (!NewClsTInfo)
5323 return QualType();
5326 const MemberPointerType *T = TL.getTypePtr();
5327 QualType OldClsType = QualType(T->getClass(), 0);
5328 QualType NewClsType;
5329 if (NewClsTInfo)
5330 NewClsType = NewClsTInfo->getType();
5331 else {
5332 NewClsType = getDerived().TransformType(OldClsType);
5333 if (NewClsType.isNull())
5334 return QualType();
5337 QualType Result = TL.getType();
5338 if (getDerived().AlwaysRebuild() ||
5339 PointeeType != T->getPointeeType() ||
5340 NewClsType != OldClsType) {
5341 Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
5342 TL.getStarLoc());
5343 if (Result.isNull())
5344 return QualType();
5347 // If we had to adjust the pointee type when building a member pointer, make
5348 // sure to push TypeLoc info for it.
5349 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5350 if (MPT && PointeeType != MPT->getPointeeType()) {
5351 assert(isa<AdjustedType>(MPT->getPointeeType()));
5352 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
5355 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
5356 NewTL.setSigilLoc(TL.getSigilLoc());
5357 NewTL.setClassTInfo(NewClsTInfo);
5359 return Result;
5362 template<typename Derived>
5363 QualType
5364 TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5365 ConstantArrayTypeLoc TL) {
5366 const ConstantArrayType *T = TL.getTypePtr();
5367 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5368 if (ElementType.isNull())
5369 return QualType();
5371 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5372 Expr *OldSize = TL.getSizeExpr();
5373 if (!OldSize)
5374 OldSize = const_cast<Expr*>(T->getSizeExpr());
5375 Expr *NewSize = nullptr;
5376 if (OldSize) {
5377 EnterExpressionEvaluationContext Unevaluated(
5378 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5379 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5380 NewSize = SemaRef.ActOnConstantExpression(NewSize).get();
5383 QualType Result = TL.getType();
5384 if (getDerived().AlwaysRebuild() ||
5385 ElementType != T->getElementType() ||
5386 (T->getSizeExpr() && NewSize != OldSize)) {
5387 Result = getDerived().RebuildConstantArrayType(ElementType,
5388 T->getSizeModifier(),
5389 T->getSize(), NewSize,
5390 T->getIndexTypeCVRQualifiers(),
5391 TL.getBracketsRange());
5392 if (Result.isNull())
5393 return QualType();
5396 // We might have either a ConstantArrayType or a VariableArrayType now:
5397 // a ConstantArrayType is allowed to have an element type which is a
5398 // VariableArrayType if the type is dependent. Fortunately, all array
5399 // types have the same location layout.
5400 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5401 NewTL.setLBracketLoc(TL.getLBracketLoc());
5402 NewTL.setRBracketLoc(TL.getRBracketLoc());
5403 NewTL.setSizeExpr(NewSize);
5405 return Result;
5408 template<typename Derived>
5409 QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5410 TypeLocBuilder &TLB,
5411 IncompleteArrayTypeLoc TL) {
5412 const IncompleteArrayType *T = TL.getTypePtr();
5413 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5414 if (ElementType.isNull())
5415 return QualType();
5417 QualType Result = TL.getType();
5418 if (getDerived().AlwaysRebuild() ||
5419 ElementType != T->getElementType()) {
5420 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5421 T->getSizeModifier(),
5422 T->getIndexTypeCVRQualifiers(),
5423 TL.getBracketsRange());
5424 if (Result.isNull())
5425 return QualType();
5428 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
5429 NewTL.setLBracketLoc(TL.getLBracketLoc());
5430 NewTL.setRBracketLoc(TL.getRBracketLoc());
5431 NewTL.setSizeExpr(nullptr);
5433 return Result;
5436 template<typename Derived>
5437 QualType
5438 TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5439 VariableArrayTypeLoc TL) {
5440 const VariableArrayType *T = TL.getTypePtr();
5441 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5442 if (ElementType.isNull())
5443 return QualType();
5445 ExprResult SizeResult;
5447 EnterExpressionEvaluationContext Context(
5448 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5449 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5451 if (SizeResult.isInvalid())
5452 return QualType();
5453 SizeResult =
5454 SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);
5455 if (SizeResult.isInvalid())
5456 return QualType();
5458 Expr *Size = SizeResult.get();
5460 QualType Result = TL.getType();
5461 if (getDerived().AlwaysRebuild() ||
5462 ElementType != T->getElementType() ||
5463 Size != T->getSizeExpr()) {
5464 Result = getDerived().RebuildVariableArrayType(ElementType,
5465 T->getSizeModifier(),
5466 Size,
5467 T->getIndexTypeCVRQualifiers(),
5468 TL.getBracketsRange());
5469 if (Result.isNull())
5470 return QualType();
5473 // We might have constant size array now, but fortunately it has the same
5474 // location layout.
5475 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5476 NewTL.setLBracketLoc(TL.getLBracketLoc());
5477 NewTL.setRBracketLoc(TL.getRBracketLoc());
5478 NewTL.setSizeExpr(Size);
5480 return Result;
5483 template<typename Derived>
5484 QualType
5485 TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5486 DependentSizedArrayTypeLoc TL) {
5487 const DependentSizedArrayType *T = TL.getTypePtr();
5488 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5489 if (ElementType.isNull())
5490 return QualType();
5492 // Array bounds are constant expressions.
5493 EnterExpressionEvaluationContext Unevaluated(
5494 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5496 // If we have a VLA then it won't be a constant.
5497 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5499 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5500 Expr *origSize = TL.getSizeExpr();
5501 if (!origSize) origSize = T->getSizeExpr();
5503 ExprResult sizeResult
5504 = getDerived().TransformExpr(origSize);
5505 sizeResult = SemaRef.ActOnConstantExpression(sizeResult);
5506 if (sizeResult.isInvalid())
5507 return QualType();
5509 Expr *size = sizeResult.get();
5511 QualType Result = TL.getType();
5512 if (getDerived().AlwaysRebuild() ||
5513 ElementType != T->getElementType() ||
5514 size != origSize) {
5515 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5516 T->getSizeModifier(),
5517 size,
5518 T->getIndexTypeCVRQualifiers(),
5519 TL.getBracketsRange());
5520 if (Result.isNull())
5521 return QualType();
5524 // We might have any sort of array type now, but fortunately they
5525 // all have the same location layout.
5526 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5527 NewTL.setLBracketLoc(TL.getLBracketLoc());
5528 NewTL.setRBracketLoc(TL.getRBracketLoc());
5529 NewTL.setSizeExpr(size);
5531 return Result;
5534 template <typename Derived>
5535 QualType TreeTransform<Derived>::TransformDependentVectorType(
5536 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5537 const DependentVectorType *T = TL.getTypePtr();
5538 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5539 if (ElementType.isNull())
5540 return QualType();
5542 EnterExpressionEvaluationContext Unevaluated(
5543 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5545 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5546 Size = SemaRef.ActOnConstantExpression(Size);
5547 if (Size.isInvalid())
5548 return QualType();
5550 QualType Result = TL.getType();
5551 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5552 Size.get() != T->getSizeExpr()) {
5553 Result = getDerived().RebuildDependentVectorType(
5554 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5555 if (Result.isNull())
5556 return QualType();
5559 // Result might be dependent or not.
5560 if (isa<DependentVectorType>(Result)) {
5561 DependentVectorTypeLoc NewTL =
5562 TLB.push<DependentVectorTypeLoc>(Result);
5563 NewTL.setNameLoc(TL.getNameLoc());
5564 } else {
5565 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5566 NewTL.setNameLoc(TL.getNameLoc());
5569 return Result;
5572 template<typename Derived>
5573 QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5574 TypeLocBuilder &TLB,
5575 DependentSizedExtVectorTypeLoc TL) {
5576 const DependentSizedExtVectorType *T = TL.getTypePtr();
5578 // FIXME: ext vector locs should be nested
5579 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5580 if (ElementType.isNull())
5581 return QualType();
5583 // Vector sizes are constant expressions.
5584 EnterExpressionEvaluationContext Unevaluated(
5585 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5587 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5588 Size = SemaRef.ActOnConstantExpression(Size);
5589 if (Size.isInvalid())
5590 return QualType();
5592 QualType Result = TL.getType();
5593 if (getDerived().AlwaysRebuild() ||
5594 ElementType != T->getElementType() ||
5595 Size.get() != T->getSizeExpr()) {
5596 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5597 Size.get(),
5598 T->getAttributeLoc());
5599 if (Result.isNull())
5600 return QualType();
5603 // Result might be dependent or not.
5604 if (isa<DependentSizedExtVectorType>(Result)) {
5605 DependentSizedExtVectorTypeLoc NewTL
5606 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
5607 NewTL.setNameLoc(TL.getNameLoc());
5608 } else {
5609 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5610 NewTL.setNameLoc(TL.getNameLoc());
5613 return Result;
5616 template <typename Derived>
5617 QualType
5618 TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5619 ConstantMatrixTypeLoc TL) {
5620 const ConstantMatrixType *T = TL.getTypePtr();
5621 QualType ElementType = getDerived().TransformType(T->getElementType());
5622 if (ElementType.isNull())
5623 return QualType();
5625 QualType Result = TL.getType();
5626 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5627 Result = getDerived().RebuildConstantMatrixType(
5628 ElementType, T->getNumRows(), T->getNumColumns());
5629 if (Result.isNull())
5630 return QualType();
5633 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);
5634 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5635 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5636 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5637 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5639 return Result;
5642 template <typename Derived>
5643 QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5644 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5645 const DependentSizedMatrixType *T = TL.getTypePtr();
5647 QualType ElementType = getDerived().TransformType(T->getElementType());
5648 if (ElementType.isNull()) {
5649 return QualType();
5652 // Matrix dimensions are constant expressions.
5653 EnterExpressionEvaluationContext Unevaluated(
5654 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5656 Expr *origRows = TL.getAttrRowOperand();
5657 if (!origRows)
5658 origRows = T->getRowExpr();
5659 Expr *origColumns = TL.getAttrColumnOperand();
5660 if (!origColumns)
5661 origColumns = T->getColumnExpr();
5663 ExprResult rowResult = getDerived().TransformExpr(origRows);
5664 rowResult = SemaRef.ActOnConstantExpression(rowResult);
5665 if (rowResult.isInvalid())
5666 return QualType();
5668 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5669 columnResult = SemaRef.ActOnConstantExpression(columnResult);
5670 if (columnResult.isInvalid())
5671 return QualType();
5673 Expr *rows = rowResult.get();
5674 Expr *columns = columnResult.get();
5676 QualType Result = TL.getType();
5677 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5678 rows != origRows || columns != origColumns) {
5679 Result = getDerived().RebuildDependentSizedMatrixType(
5680 ElementType, rows, columns, T->getAttributeLoc());
5682 if (Result.isNull())
5683 return QualType();
5686 // We might have any sort of matrix type now, but fortunately they
5687 // all have the same location layout.
5688 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);
5689 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5690 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5691 NewTL.setAttrRowOperand(rows);
5692 NewTL.setAttrColumnOperand(columns);
5693 return Result;
5696 template <typename Derived>
5697 QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
5698 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
5699 const DependentAddressSpaceType *T = TL.getTypePtr();
5701 QualType pointeeType = getDerived().TransformType(T->getPointeeType());
5703 if (pointeeType.isNull())
5704 return QualType();
5706 // Address spaces are constant expressions.
5707 EnterExpressionEvaluationContext Unevaluated(
5708 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5710 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
5711 AddrSpace = SemaRef.ActOnConstantExpression(AddrSpace);
5712 if (AddrSpace.isInvalid())
5713 return QualType();
5715 QualType Result = TL.getType();
5716 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
5717 AddrSpace.get() != T->getAddrSpaceExpr()) {
5718 Result = getDerived().RebuildDependentAddressSpaceType(
5719 pointeeType, AddrSpace.get(), T->getAttributeLoc());
5720 if (Result.isNull())
5721 return QualType();
5724 // Result might be dependent or not.
5725 if (isa<DependentAddressSpaceType>(Result)) {
5726 DependentAddressSpaceTypeLoc NewTL =
5727 TLB.push<DependentAddressSpaceTypeLoc>(Result);
5729 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5730 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
5731 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5733 } else {
5734 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(
5735 Result, getDerived().getBaseLocation());
5736 TransformType(TLB, DI->getTypeLoc());
5739 return Result;
5742 template <typename Derived>
5743 QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
5744 VectorTypeLoc TL) {
5745 const VectorType *T = TL.getTypePtr();
5746 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5747 if (ElementType.isNull())
5748 return QualType();
5750 QualType Result = TL.getType();
5751 if (getDerived().AlwaysRebuild() ||
5752 ElementType != T->getElementType()) {
5753 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
5754 T->getVectorKind());
5755 if (Result.isNull())
5756 return QualType();
5759 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5760 NewTL.setNameLoc(TL.getNameLoc());
5762 return Result;
5765 template<typename Derived>
5766 QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
5767 ExtVectorTypeLoc TL) {
5768 const VectorType *T = TL.getTypePtr();
5769 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5770 if (ElementType.isNull())
5771 return QualType();
5773 QualType Result = TL.getType();
5774 if (getDerived().AlwaysRebuild() ||
5775 ElementType != T->getElementType()) {
5776 Result = getDerived().RebuildExtVectorType(ElementType,
5777 T->getNumElements(),
5778 /*FIXME*/ SourceLocation());
5779 if (Result.isNull())
5780 return QualType();
5783 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5784 NewTL.setNameLoc(TL.getNameLoc());
5786 return Result;
5789 template <typename Derived>
5790 ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
5791 ParmVarDecl *OldParm, int indexAdjustment,
5792 std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
5793 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
5794 TypeSourceInfo *NewDI = nullptr;
5796 if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
5797 // If we're substituting into a pack expansion type and we know the
5798 // length we want to expand to, just substitute for the pattern.
5799 TypeLoc OldTL = OldDI->getTypeLoc();
5800 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
5802 TypeLocBuilder TLB;
5803 TypeLoc NewTL = OldDI->getTypeLoc();
5804 TLB.reserve(NewTL.getFullDataSize());
5806 QualType Result = getDerived().TransformType(TLB,
5807 OldExpansionTL.getPatternLoc());
5808 if (Result.isNull())
5809 return nullptr;
5811 Result = RebuildPackExpansionType(Result,
5812 OldExpansionTL.getPatternLoc().getSourceRange(),
5813 OldExpansionTL.getEllipsisLoc(),
5814 NumExpansions);
5815 if (Result.isNull())
5816 return nullptr;
5818 PackExpansionTypeLoc NewExpansionTL
5819 = TLB.push<PackExpansionTypeLoc>(Result);
5820 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
5821 NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result);
5822 } else
5823 NewDI = getDerived().TransformType(OldDI);
5824 if (!NewDI)
5825 return nullptr;
5827 if (NewDI == OldDI && indexAdjustment == 0)
5828 return OldParm;
5830 ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context,
5831 OldParm->getDeclContext(),
5832 OldParm->getInnerLocStart(),
5833 OldParm->getLocation(),
5834 OldParm->getIdentifier(),
5835 NewDI->getType(),
5836 NewDI,
5837 OldParm->getStorageClass(),
5838 /* DefArg */ nullptr);
5839 newParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
5840 OldParm->getFunctionScopeIndex() + indexAdjustment);
5841 transformedLocalDecl(OldParm, {newParm});
5842 return newParm;
5845 template <typename Derived>
5846 bool TreeTransform<Derived>::TransformFunctionTypeParams(
5847 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
5848 const QualType *ParamTypes,
5849 const FunctionProtoType::ExtParameterInfo *ParamInfos,
5850 SmallVectorImpl<QualType> &OutParamTypes,
5851 SmallVectorImpl<ParmVarDecl *> *PVars,
5852 Sema::ExtParameterInfoBuilder &PInfos,
5853 unsigned *LastParamTransformed) {
5854 int indexAdjustment = 0;
5856 unsigned NumParams = Params.size();
5857 for (unsigned i = 0; i != NumParams; ++i) {
5858 if (LastParamTransformed)
5859 *LastParamTransformed = i;
5860 if (ParmVarDecl *OldParm = Params[i]) {
5861 assert(OldParm->getFunctionScopeIndex() == i);
5863 std::optional<unsigned> NumExpansions;
5864 ParmVarDecl *NewParm = nullptr;
5865 if (OldParm->isParameterPack()) {
5866 // We have a function parameter pack that may need to be expanded.
5867 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5869 // Find the parameter packs that could be expanded.
5870 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
5871 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
5872 TypeLoc Pattern = ExpansionTL.getPatternLoc();
5873 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
5875 // Determine whether we should expand the parameter packs.
5876 bool ShouldExpand = false;
5877 bool RetainExpansion = false;
5878 std::optional<unsigned> OrigNumExpansions;
5879 if (Unexpanded.size() > 0) {
5880 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
5881 NumExpansions = OrigNumExpansions;
5882 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
5883 Pattern.getSourceRange(),
5884 Unexpanded,
5885 ShouldExpand,
5886 RetainExpansion,
5887 NumExpansions)) {
5888 return true;
5890 } else {
5891 #ifndef NDEBUG
5892 const AutoType *AT =
5893 Pattern.getType().getTypePtr()->getContainedAutoType();
5894 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
5895 "Could not find parameter packs or undeduced auto type!");
5896 #endif
5899 if (ShouldExpand) {
5900 // Expand the function parameter pack into multiple, separate
5901 // parameters.
5902 getDerived().ExpandingFunctionParameterPack(OldParm);
5903 for (unsigned I = 0; I != *NumExpansions; ++I) {
5904 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
5905 ParmVarDecl *NewParm
5906 = getDerived().TransformFunctionTypeParam(OldParm,
5907 indexAdjustment++,
5908 OrigNumExpansions,
5909 /*ExpectParameterPack=*/false);
5910 if (!NewParm)
5911 return true;
5913 if (ParamInfos)
5914 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5915 OutParamTypes.push_back(NewParm->getType());
5916 if (PVars)
5917 PVars->push_back(NewParm);
5920 // If we're supposed to retain a pack expansion, do so by temporarily
5921 // forgetting the partially-substituted parameter pack.
5922 if (RetainExpansion) {
5923 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5924 ParmVarDecl *NewParm
5925 = getDerived().TransformFunctionTypeParam(OldParm,
5926 indexAdjustment++,
5927 OrigNumExpansions,
5928 /*ExpectParameterPack=*/false);
5929 if (!NewParm)
5930 return true;
5932 if (ParamInfos)
5933 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5934 OutParamTypes.push_back(NewParm->getType());
5935 if (PVars)
5936 PVars->push_back(NewParm);
5939 // The next parameter should have the same adjustment as the
5940 // last thing we pushed, but we post-incremented indexAdjustment
5941 // on every push. Also, if we push nothing, the adjustment should
5942 // go down by one.
5943 indexAdjustment--;
5945 // We're done with the pack expansion.
5946 continue;
5949 // We'll substitute the parameter now without expanding the pack
5950 // expansion.
5951 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
5952 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
5953 indexAdjustment,
5954 NumExpansions,
5955 /*ExpectParameterPack=*/true);
5956 assert(NewParm->isParameterPack() &&
5957 "Parameter pack no longer a parameter pack after "
5958 "transformation.");
5959 } else {
5960 NewParm = getDerived().TransformFunctionTypeParam(
5961 OldParm, indexAdjustment, std::nullopt,
5962 /*ExpectParameterPack=*/false);
5965 if (!NewParm)
5966 return true;
5968 if (ParamInfos)
5969 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5970 OutParamTypes.push_back(NewParm->getType());
5971 if (PVars)
5972 PVars->push_back(NewParm);
5973 continue;
5976 // Deal with the possibility that we don't have a parameter
5977 // declaration for this parameter.
5978 assert(ParamTypes);
5979 QualType OldType = ParamTypes[i];
5980 bool IsPackExpansion = false;
5981 std::optional<unsigned> NumExpansions;
5982 QualType NewType;
5983 if (const PackExpansionType *Expansion
5984 = dyn_cast<PackExpansionType>(OldType)) {
5985 // We have a function parameter pack that may need to be expanded.
5986 QualType Pattern = Expansion->getPattern();
5987 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5988 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5990 // Determine whether we should expand the parameter packs.
5991 bool ShouldExpand = false;
5992 bool RetainExpansion = false;
5993 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
5994 Unexpanded,
5995 ShouldExpand,
5996 RetainExpansion,
5997 NumExpansions)) {
5998 return true;
6001 if (ShouldExpand) {
6002 // Expand the function parameter pack into multiple, separate
6003 // parameters.
6004 for (unsigned I = 0; I != *NumExpansions; ++I) {
6005 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6006 QualType NewType = getDerived().TransformType(Pattern);
6007 if (NewType.isNull())
6008 return true;
6010 if (NewType->containsUnexpandedParameterPack()) {
6011 NewType = getSema().getASTContext().getPackExpansionType(
6012 NewType, std::nullopt);
6014 if (NewType.isNull())
6015 return true;
6018 if (ParamInfos)
6019 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6020 OutParamTypes.push_back(NewType);
6021 if (PVars)
6022 PVars->push_back(nullptr);
6025 // We're done with the pack expansion.
6026 continue;
6029 // If we're supposed to retain a pack expansion, do so by temporarily
6030 // forgetting the partially-substituted parameter pack.
6031 if (RetainExpansion) {
6032 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6033 QualType NewType = getDerived().TransformType(Pattern);
6034 if (NewType.isNull())
6035 return true;
6037 if (ParamInfos)
6038 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6039 OutParamTypes.push_back(NewType);
6040 if (PVars)
6041 PVars->push_back(nullptr);
6044 // We'll substitute the parameter now without expanding the pack
6045 // expansion.
6046 OldType = Expansion->getPattern();
6047 IsPackExpansion = true;
6048 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6049 NewType = getDerived().TransformType(OldType);
6050 } else {
6051 NewType = getDerived().TransformType(OldType);
6054 if (NewType.isNull())
6055 return true;
6057 if (IsPackExpansion)
6058 NewType = getSema().Context.getPackExpansionType(NewType,
6059 NumExpansions);
6061 if (ParamInfos)
6062 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6063 OutParamTypes.push_back(NewType);
6064 if (PVars)
6065 PVars->push_back(nullptr);
6068 #ifndef NDEBUG
6069 if (PVars) {
6070 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6071 if (ParmVarDecl *parm = (*PVars)[i])
6072 assert(parm->getFunctionScopeIndex() == i);
6074 #endif
6076 return false;
6079 template<typename Derived>
6080 QualType
6081 TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6082 FunctionProtoTypeLoc TL) {
6083 SmallVector<QualType, 4> ExceptionStorage;
6084 TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
6085 return getDerived().TransformFunctionProtoType(
6086 TLB, TL, nullptr, Qualifiers(),
6087 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6088 return This->getDerived().TransformExceptionSpec(
6089 TL.getBeginLoc(), ESI, ExceptionStorage, Changed);
6093 template<typename Derived> template<typename Fn>
6094 QualType TreeTransform<Derived>::TransformFunctionProtoType(
6095 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6096 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6098 // Transform the parameters and return type.
6100 // We are required to instantiate the params and return type in source order.
6101 // When the function has a trailing return type, we instantiate the
6102 // parameters before the return type, since the return type can then refer
6103 // to the parameters themselves (via decltype, sizeof, etc.).
6105 SmallVector<QualType, 4> ParamTypes;
6106 SmallVector<ParmVarDecl*, 4> ParamDecls;
6107 Sema::ExtParameterInfoBuilder ExtParamInfos;
6108 const FunctionProtoType *T = TL.getTypePtr();
6110 QualType ResultType;
6112 if (T->hasTrailingReturn()) {
6113 if (getDerived().TransformFunctionTypeParams(
6114 TL.getBeginLoc(), TL.getParams(),
6115 TL.getTypePtr()->param_type_begin(),
6116 T->getExtParameterInfosOrNull(),
6117 ParamTypes, &ParamDecls, ExtParamInfos))
6118 return QualType();
6121 // C++11 [expr.prim.general]p3:
6122 // If a declaration declares a member function or member function
6123 // template of a class X, the expression this is a prvalue of type
6124 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6125 // and the end of the function-definition, member-declarator, or
6126 // declarator.
6127 Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals);
6129 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6130 if (ResultType.isNull())
6131 return QualType();
6134 else {
6135 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6136 if (ResultType.isNull())
6137 return QualType();
6139 if (getDerived().TransformFunctionTypeParams(
6140 TL.getBeginLoc(), TL.getParams(),
6141 TL.getTypePtr()->param_type_begin(),
6142 T->getExtParameterInfosOrNull(),
6143 ParamTypes, &ParamDecls, ExtParamInfos))
6144 return QualType();
6147 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6149 bool EPIChanged = false;
6150 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6151 return QualType();
6153 // Handle extended parameter information.
6154 if (auto NewExtParamInfos =
6155 ExtParamInfos.getPointerOrNull(ParamTypes.size())) {
6156 if (!EPI.ExtParameterInfos ||
6157 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6158 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6159 EPIChanged = true;
6161 EPI.ExtParameterInfos = NewExtParamInfos;
6162 } else if (EPI.ExtParameterInfos) {
6163 EPIChanged = true;
6164 EPI.ExtParameterInfos = nullptr;
6167 QualType Result = TL.getType();
6168 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6169 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6170 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6171 if (Result.isNull())
6172 return QualType();
6175 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
6176 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6177 NewTL.setLParenLoc(TL.getLParenLoc());
6178 NewTL.setRParenLoc(TL.getRParenLoc());
6179 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6180 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6181 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6182 NewTL.setParam(i, ParamDecls[i]);
6184 return Result;
6187 template<typename Derived>
6188 bool TreeTransform<Derived>::TransformExceptionSpec(
6189 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6190 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6191 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6193 // Instantiate a dynamic noexcept expression, if any.
6194 if (isComputedNoexcept(ESI.Type)) {
6195 EnterExpressionEvaluationContext Unevaluated(
6196 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6197 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6198 if (NoexceptExpr.isInvalid())
6199 return true;
6201 ExceptionSpecificationType EST = ESI.Type;
6202 NoexceptExpr =
6203 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6204 if (NoexceptExpr.isInvalid())
6205 return true;
6207 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6208 Changed = true;
6209 ESI.NoexceptExpr = NoexceptExpr.get();
6210 ESI.Type = EST;
6213 if (ESI.Type != EST_Dynamic)
6214 return false;
6216 // Instantiate a dynamic exception specification's type.
6217 for (QualType T : ESI.Exceptions) {
6218 if (const PackExpansionType *PackExpansion =
6219 T->getAs<PackExpansionType>()) {
6220 Changed = true;
6222 // We have a pack expansion. Instantiate it.
6223 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6224 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
6225 Unexpanded);
6226 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6228 // Determine whether the set of unexpanded parameter packs can and
6229 // should
6230 // be expanded.
6231 bool Expand = false;
6232 bool RetainExpansion = false;
6233 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
6234 // FIXME: Track the location of the ellipsis (and track source location
6235 // information for the types in the exception specification in general).
6236 if (getDerived().TryExpandParameterPacks(
6237 Loc, SourceRange(), Unexpanded, Expand,
6238 RetainExpansion, NumExpansions))
6239 return true;
6241 if (!Expand) {
6242 // We can't expand this pack expansion into separate arguments yet;
6243 // just substitute into the pattern and create a new pack expansion
6244 // type.
6245 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6246 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6247 if (U.isNull())
6248 return true;
6250 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
6251 Exceptions.push_back(U);
6252 continue;
6255 // Substitute into the pack expansion pattern for each slice of the
6256 // pack.
6257 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6258 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
6260 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6261 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6262 return true;
6264 Exceptions.push_back(U);
6266 } else {
6267 QualType U = getDerived().TransformType(T);
6268 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6269 return true;
6270 if (T != U)
6271 Changed = true;
6273 Exceptions.push_back(U);
6277 ESI.Exceptions = Exceptions;
6278 if (ESI.Exceptions.empty())
6279 ESI.Type = EST_DynamicNone;
6280 return false;
6283 template<typename Derived>
6284 QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6285 TypeLocBuilder &TLB,
6286 FunctionNoProtoTypeLoc TL) {
6287 const FunctionNoProtoType *T = TL.getTypePtr();
6288 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6289 if (ResultType.isNull())
6290 return QualType();
6292 QualType Result = TL.getType();
6293 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6294 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6296 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
6297 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6298 NewTL.setLParenLoc(TL.getLParenLoc());
6299 NewTL.setRParenLoc(TL.getRParenLoc());
6300 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6302 return Result;
6305 template <typename Derived>
6306 QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6307 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6308 const UnresolvedUsingType *T = TL.getTypePtr();
6309 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6310 if (!D)
6311 return QualType();
6313 QualType Result = TL.getType();
6314 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6315 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6316 if (Result.isNull())
6317 return QualType();
6320 // We might get an arbitrary type spec type back. We should at
6321 // least always get a type spec type, though.
6322 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result);
6323 NewTL.setNameLoc(TL.getNameLoc());
6325 return Result;
6328 template <typename Derived>
6329 QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6330 UsingTypeLoc TL) {
6331 const UsingType *T = TL.getTypePtr();
6333 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6334 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6335 if (!Found)
6336 return QualType();
6338 QualType Underlying = getDerived().TransformType(T->desugar());
6339 if (Underlying.isNull())
6340 return QualType();
6342 QualType Result = TL.getType();
6343 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6344 Underlying != T->getUnderlyingType()) {
6345 Result = getDerived().RebuildUsingType(Found, Underlying);
6346 if (Result.isNull())
6347 return QualType();
6350 TLB.pushTypeSpec(Result).setNameLoc(TL.getNameLoc());
6351 return Result;
6354 template<typename Derived>
6355 QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6356 TypedefTypeLoc TL) {
6357 const TypedefType *T = TL.getTypePtr();
6358 TypedefNameDecl *Typedef
6359 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6360 T->getDecl()));
6361 if (!Typedef)
6362 return QualType();
6364 QualType Result = TL.getType();
6365 if (getDerived().AlwaysRebuild() ||
6366 Typedef != T->getDecl()) {
6367 Result = getDerived().RebuildTypedefType(Typedef);
6368 if (Result.isNull())
6369 return QualType();
6372 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
6373 NewTL.setNameLoc(TL.getNameLoc());
6375 return Result;
6378 template<typename Derived>
6379 QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6380 TypeOfExprTypeLoc TL) {
6381 // typeof expressions are not potentially evaluated contexts
6382 EnterExpressionEvaluationContext Unevaluated(
6383 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6384 Sema::ReuseLambdaContextDecl);
6386 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6387 if (E.isInvalid())
6388 return QualType();
6390 E = SemaRef.HandleExprEvaluationContextForTypeof(E.get());
6391 if (E.isInvalid())
6392 return QualType();
6394 QualType Result = TL.getType();
6395 TypeOfKind Kind = Result->getAs<TypeOfExprType>()->getKind();
6396 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6397 Result =
6398 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6399 if (Result.isNull())
6400 return QualType();
6403 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
6404 NewTL.setTypeofLoc(TL.getTypeofLoc());
6405 NewTL.setLParenLoc(TL.getLParenLoc());
6406 NewTL.setRParenLoc(TL.getRParenLoc());
6408 return Result;
6411 template<typename Derived>
6412 QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6413 TypeOfTypeLoc TL) {
6414 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6415 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6416 if (!New_Under_TI)
6417 return QualType();
6419 QualType Result = TL.getType();
6420 TypeOfKind Kind = Result->getAs<TypeOfType>()->getKind();
6421 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6422 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6423 if (Result.isNull())
6424 return QualType();
6427 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
6428 NewTL.setTypeofLoc(TL.getTypeofLoc());
6429 NewTL.setLParenLoc(TL.getLParenLoc());
6430 NewTL.setRParenLoc(TL.getRParenLoc());
6431 NewTL.setUnmodifiedTInfo(New_Under_TI);
6433 return Result;
6436 template<typename Derived>
6437 QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6438 DecltypeTypeLoc TL) {
6439 const DecltypeType *T = TL.getTypePtr();
6441 // decltype expressions are not potentially evaluated contexts
6442 EnterExpressionEvaluationContext Unevaluated(
6443 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
6444 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
6446 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6447 if (E.isInvalid())
6448 return QualType();
6450 E = getSema().ActOnDecltypeExpression(E.get());
6451 if (E.isInvalid())
6452 return QualType();
6454 QualType Result = TL.getType();
6455 if (getDerived().AlwaysRebuild() ||
6456 E.get() != T->getUnderlyingExpr()) {
6457 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6458 if (Result.isNull())
6459 return QualType();
6461 else E.get();
6463 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
6464 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6465 NewTL.setRParenLoc(TL.getRParenLoc());
6466 return Result;
6469 template<typename Derived>
6470 QualType TreeTransform<Derived>::TransformUnaryTransformType(
6471 TypeLocBuilder &TLB,
6472 UnaryTransformTypeLoc TL) {
6473 QualType Result = TL.getType();
6474 if (Result->isDependentType()) {
6475 const UnaryTransformType *T = TL.getTypePtr();
6476 QualType NewBase =
6477 getDerived().TransformType(TL.getUnderlyingTInfo())->getType();
6478 Result = getDerived().RebuildUnaryTransformType(NewBase,
6479 T->getUTTKind(),
6480 TL.getKWLoc());
6481 if (Result.isNull())
6482 return QualType();
6485 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
6486 NewTL.setKWLoc(TL.getKWLoc());
6487 NewTL.setParensRange(TL.getParensRange());
6488 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6489 return Result;
6492 template<typename Derived>
6493 QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6494 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6495 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6497 CXXScopeSpec SS;
6498 TemplateName TemplateName = getDerived().TransformTemplateName(
6499 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6500 if (TemplateName.isNull())
6501 return QualType();
6503 QualType OldDeduced = T->getDeducedType();
6504 QualType NewDeduced;
6505 if (!OldDeduced.isNull()) {
6506 NewDeduced = getDerived().TransformType(OldDeduced);
6507 if (NewDeduced.isNull())
6508 return QualType();
6511 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
6512 TemplateName, NewDeduced);
6513 if (Result.isNull())
6514 return QualType();
6516 DeducedTemplateSpecializationTypeLoc NewTL =
6517 TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
6518 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6520 return Result;
6523 template<typename Derived>
6524 QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
6525 RecordTypeLoc TL) {
6526 const RecordType *T = TL.getTypePtr();
6527 RecordDecl *Record
6528 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6529 T->getDecl()));
6530 if (!Record)
6531 return QualType();
6533 QualType Result = TL.getType();
6534 if (getDerived().AlwaysRebuild() ||
6535 Record != T->getDecl()) {
6536 Result = getDerived().RebuildRecordType(Record);
6537 if (Result.isNull())
6538 return QualType();
6541 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
6542 NewTL.setNameLoc(TL.getNameLoc());
6544 return Result;
6547 template<typename Derived>
6548 QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
6549 EnumTypeLoc TL) {
6550 const EnumType *T = TL.getTypePtr();
6551 EnumDecl *Enum
6552 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6553 T->getDecl()));
6554 if (!Enum)
6555 return QualType();
6557 QualType Result = TL.getType();
6558 if (getDerived().AlwaysRebuild() ||
6559 Enum != T->getDecl()) {
6560 Result = getDerived().RebuildEnumType(Enum);
6561 if (Result.isNull())
6562 return QualType();
6565 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
6566 NewTL.setNameLoc(TL.getNameLoc());
6568 return Result;
6571 template<typename Derived>
6572 QualType TreeTransform<Derived>::TransformInjectedClassNameType(
6573 TypeLocBuilder &TLB,
6574 InjectedClassNameTypeLoc TL) {
6575 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
6576 TL.getTypePtr()->getDecl());
6577 if (!D) return QualType();
6579 QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
6580 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
6581 return T;
6584 template<typename Derived>
6585 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6586 TypeLocBuilder &TLB,
6587 TemplateTypeParmTypeLoc TL) {
6588 return getDerived().TransformTemplateTypeParmType(
6589 TLB, TL,
6590 /*SuppressObjCLifetime=*/false);
6593 template <typename Derived>
6594 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6595 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
6596 return TransformTypeSpecType(TLB, TL);
6599 template<typename Derived>
6600 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
6601 TypeLocBuilder &TLB,
6602 SubstTemplateTypeParmTypeLoc TL) {
6603 const SubstTemplateTypeParmType *T = TL.getTypePtr();
6605 Decl *NewReplaced =
6606 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
6608 // Substitute into the replacement type, which itself might involve something
6609 // that needs to be transformed. This only tends to occur with default
6610 // template arguments of template template parameters.
6611 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
6612 QualType Replacement = getDerived().TransformType(T->getReplacementType());
6613 if (Replacement.isNull())
6614 return QualType();
6616 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
6617 Replacement, NewReplaced, T->getIndex(), T->getPackIndex());
6619 // Propagate type-source information.
6620 SubstTemplateTypeParmTypeLoc NewTL
6621 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
6622 NewTL.setNameLoc(TL.getNameLoc());
6623 return Result;
6627 template<typename Derived>
6628 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6629 TypeLocBuilder &TLB,
6630 SubstTemplateTypeParmPackTypeLoc TL) {
6631 return getDerived().TransformSubstTemplateTypeParmPackType(
6632 TLB, TL, /*SuppressObjCLifetime=*/false);
6635 template <typename Derived>
6636 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6637 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
6638 return TransformTypeSpecType(TLB, TL);
6641 template<typename Derived>
6642 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
6643 TypeLocBuilder &TLB,
6644 TemplateSpecializationTypeLoc TL) {
6645 const TemplateSpecializationType *T = TL.getTypePtr();
6647 // The nested-name-specifier never matters in a TemplateSpecializationType,
6648 // because we can't have a dependent nested-name-specifier anyway.
6649 CXXScopeSpec SS;
6650 TemplateName Template
6651 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
6652 TL.getTemplateNameLoc());
6653 if (Template.isNull())
6654 return QualType();
6656 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
6659 template<typename Derived>
6660 QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
6661 AtomicTypeLoc TL) {
6662 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6663 if (ValueType.isNull())
6664 return QualType();
6666 QualType Result = TL.getType();
6667 if (getDerived().AlwaysRebuild() ||
6668 ValueType != TL.getValueLoc().getType()) {
6669 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
6670 if (Result.isNull())
6671 return QualType();
6674 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
6675 NewTL.setKWLoc(TL.getKWLoc());
6676 NewTL.setLParenLoc(TL.getLParenLoc());
6677 NewTL.setRParenLoc(TL.getRParenLoc());
6679 return Result;
6682 template <typename Derived>
6683 QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
6684 PipeTypeLoc TL) {
6685 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6686 if (ValueType.isNull())
6687 return QualType();
6689 QualType Result = TL.getType();
6690 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
6691 const PipeType *PT = Result->castAs<PipeType>();
6692 bool isReadPipe = PT->isReadOnly();
6693 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
6694 if (Result.isNull())
6695 return QualType();
6698 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);
6699 NewTL.setKWLoc(TL.getKWLoc());
6701 return Result;
6704 template <typename Derived>
6705 QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
6706 BitIntTypeLoc TL) {
6707 const BitIntType *EIT = TL.getTypePtr();
6708 QualType Result = TL.getType();
6710 if (getDerived().AlwaysRebuild()) {
6711 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
6712 EIT->getNumBits(), TL.getNameLoc());
6713 if (Result.isNull())
6714 return QualType();
6717 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6718 NewTL.setNameLoc(TL.getNameLoc());
6719 return Result;
6722 template <typename Derived>
6723 QualType TreeTransform<Derived>::TransformDependentBitIntType(
6724 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
6725 const DependentBitIntType *EIT = TL.getTypePtr();
6727 EnterExpressionEvaluationContext Unevaluated(
6728 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6729 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
6730 BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr);
6732 if (BitsExpr.isInvalid())
6733 return QualType();
6735 QualType Result = TL.getType();
6737 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
6738 Result = getDerived().RebuildDependentBitIntType(
6739 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
6741 if (Result.isNull())
6742 return QualType();
6745 if (isa<DependentBitIntType>(Result)) {
6746 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);
6747 NewTL.setNameLoc(TL.getNameLoc());
6748 } else {
6749 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6750 NewTL.setNameLoc(TL.getNameLoc());
6752 return Result;
6755 /// Simple iterator that traverses the template arguments in a
6756 /// container that provides a \c getArgLoc() member function.
6758 /// This iterator is intended to be used with the iterator form of
6759 /// \c TreeTransform<Derived>::TransformTemplateArguments().
6760 template<typename ArgLocContainer>
6761 class TemplateArgumentLocContainerIterator {
6762 ArgLocContainer *Container;
6763 unsigned Index;
6765 public:
6766 typedef TemplateArgumentLoc value_type;
6767 typedef TemplateArgumentLoc reference;
6768 typedef int difference_type;
6769 typedef std::input_iterator_tag iterator_category;
6771 class pointer {
6772 TemplateArgumentLoc Arg;
6774 public:
6775 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
6777 const TemplateArgumentLoc *operator->() const {
6778 return &Arg;
6783 TemplateArgumentLocContainerIterator() {}
6785 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
6786 unsigned Index)
6787 : Container(&Container), Index(Index) { }
6789 TemplateArgumentLocContainerIterator &operator++() {
6790 ++Index;
6791 return *this;
6794 TemplateArgumentLocContainerIterator operator++(int) {
6795 TemplateArgumentLocContainerIterator Old(*this);
6796 ++(*this);
6797 return Old;
6800 TemplateArgumentLoc operator*() const {
6801 return Container->getArgLoc(Index);
6804 pointer operator->() const {
6805 return pointer(Container->getArgLoc(Index));
6808 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
6809 const TemplateArgumentLocContainerIterator &Y) {
6810 return X.Container == Y.Container && X.Index == Y.Index;
6813 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
6814 const TemplateArgumentLocContainerIterator &Y) {
6815 return !(X == Y);
6819 template<typename Derived>
6820 QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
6821 AutoTypeLoc TL) {
6822 const AutoType *T = TL.getTypePtr();
6823 QualType OldDeduced = T->getDeducedType();
6824 QualType NewDeduced;
6825 if (!OldDeduced.isNull()) {
6826 NewDeduced = getDerived().TransformType(OldDeduced);
6827 if (NewDeduced.isNull())
6828 return QualType();
6831 ConceptDecl *NewCD = nullptr;
6832 TemplateArgumentListInfo NewTemplateArgs;
6833 NestedNameSpecifierLoc NewNestedNameSpec;
6834 if (T->isConstrained()) {
6835 assert(TL.getConceptReference());
6836 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
6837 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
6839 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
6840 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
6841 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
6842 if (getDerived().TransformTemplateArguments(
6843 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
6844 NewTemplateArgs))
6845 return QualType();
6847 if (TL.getNestedNameSpecifierLoc()) {
6848 NewNestedNameSpec
6849 = getDerived().TransformNestedNameSpecifierLoc(
6850 TL.getNestedNameSpecifierLoc());
6851 if (!NewNestedNameSpec)
6852 return QualType();
6856 QualType Result = TL.getType();
6857 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
6858 T->isDependentType() || T->isConstrained()) {
6859 // FIXME: Maybe don't rebuild if all template arguments are the same.
6860 llvm::SmallVector<TemplateArgument, 4> NewArgList;
6861 NewArgList.reserve(NewTemplateArgs.size());
6862 for (const auto &ArgLoc : NewTemplateArgs.arguments())
6863 NewArgList.push_back(ArgLoc.getArgument());
6864 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
6865 NewArgList);
6866 if (Result.isNull())
6867 return QualType();
6870 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
6871 NewTL.setNameLoc(TL.getNameLoc());
6872 NewTL.setRParenLoc(TL.getRParenLoc());
6873 NewTL.setConceptReference(nullptr);
6875 if (T->isConstrained()) {
6876 DeclarationNameInfo DNI = DeclarationNameInfo(
6877 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
6878 TL.getConceptNameLoc(),
6879 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
6880 auto *CR = ConceptReference::Create(
6881 SemaRef.Context, NewNestedNameSpec, TL.getTemplateKWLoc(), DNI,
6882 TL.getFoundDecl(), TL.getTypePtr()->getTypeConstraintConcept(),
6883 ASTTemplateArgumentListInfo::Create(SemaRef.Context, NewTemplateArgs));
6884 NewTL.setConceptReference(CR);
6887 return Result;
6890 template <typename Derived>
6891 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
6892 TypeLocBuilder &TLB,
6893 TemplateSpecializationTypeLoc TL,
6894 TemplateName Template) {
6895 TemplateArgumentListInfo NewTemplateArgs;
6896 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
6897 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
6898 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
6899 ArgIterator;
6900 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
6901 ArgIterator(TL, TL.getNumArgs()),
6902 NewTemplateArgs))
6903 return QualType();
6905 // FIXME: maybe don't rebuild if all the template arguments are the same.
6907 QualType Result =
6908 getDerived().RebuildTemplateSpecializationType(Template,
6909 TL.getTemplateNameLoc(),
6910 NewTemplateArgs);
6912 if (!Result.isNull()) {
6913 // Specializations of template template parameters are represented as
6914 // TemplateSpecializationTypes, and substitution of type alias templates
6915 // within a dependent context can transform them into
6916 // DependentTemplateSpecializationTypes.
6917 if (isa<DependentTemplateSpecializationType>(Result)) {
6918 DependentTemplateSpecializationTypeLoc NewTL
6919 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
6920 NewTL.setElaboratedKeywordLoc(SourceLocation());
6921 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
6922 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6923 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6924 NewTL.setLAngleLoc(TL.getLAngleLoc());
6925 NewTL.setRAngleLoc(TL.getRAngleLoc());
6926 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6927 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6928 return Result;
6931 TemplateSpecializationTypeLoc NewTL
6932 = TLB.push<TemplateSpecializationTypeLoc>(Result);
6933 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6934 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6935 NewTL.setLAngleLoc(TL.getLAngleLoc());
6936 NewTL.setRAngleLoc(TL.getRAngleLoc());
6937 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6938 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6941 return Result;
6944 template <typename Derived>
6945 QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
6946 TypeLocBuilder &TLB,
6947 DependentTemplateSpecializationTypeLoc TL,
6948 TemplateName Template,
6949 CXXScopeSpec &SS) {
6950 TemplateArgumentListInfo NewTemplateArgs;
6951 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
6952 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
6953 typedef TemplateArgumentLocContainerIterator<
6954 DependentTemplateSpecializationTypeLoc> ArgIterator;
6955 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
6956 ArgIterator(TL, TL.getNumArgs()),
6957 NewTemplateArgs))
6958 return QualType();
6960 // FIXME: maybe don't rebuild if all the template arguments are the same.
6962 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
6963 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
6964 TL.getTypePtr()->getKeyword(), DTN->getQualifier(),
6965 DTN->getIdentifier(), NewTemplateArgs.arguments());
6967 DependentTemplateSpecializationTypeLoc NewTL
6968 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
6969 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
6970 NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
6971 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6972 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6973 NewTL.setLAngleLoc(TL.getLAngleLoc());
6974 NewTL.setRAngleLoc(TL.getRAngleLoc());
6975 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6976 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6977 return Result;
6980 QualType Result
6981 = getDerived().RebuildTemplateSpecializationType(Template,
6982 TL.getTemplateNameLoc(),
6983 NewTemplateArgs);
6985 if (!Result.isNull()) {
6986 /// FIXME: Wrap this in an elaborated-type-specifier?
6987 TemplateSpecializationTypeLoc NewTL
6988 = TLB.push<TemplateSpecializationTypeLoc>(Result);
6989 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6990 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6991 NewTL.setLAngleLoc(TL.getLAngleLoc());
6992 NewTL.setRAngleLoc(TL.getRAngleLoc());
6993 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6994 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6997 return Result;
7000 template<typename Derived>
7001 QualType
7002 TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
7003 ElaboratedTypeLoc TL) {
7004 const ElaboratedType *T = TL.getTypePtr();
7006 NestedNameSpecifierLoc QualifierLoc;
7007 // NOTE: the qualifier in an ElaboratedType is optional.
7008 if (TL.getQualifierLoc()) {
7009 QualifierLoc
7010 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7011 if (!QualifierLoc)
7012 return QualType();
7015 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7016 if (NamedT.isNull())
7017 return QualType();
7019 // C++0x [dcl.type.elab]p2:
7020 // If the identifier resolves to a typedef-name or the simple-template-id
7021 // resolves to an alias template specialization, the
7022 // elaborated-type-specifier is ill-formed.
7023 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7024 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7025 if (const TemplateSpecializationType *TST =
7026 NamedT->getAs<TemplateSpecializationType>()) {
7027 TemplateName Template = TST->getTemplateName();
7028 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7029 Template.getAsTemplateDecl())) {
7030 SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
7031 diag::err_tag_reference_non_tag)
7032 << TAT << Sema::NTK_TypeAliasTemplate
7033 << llvm::to_underlying(
7034 ElaboratedType::getTagTypeKindForKeyword(T->getKeyword()));
7035 SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
7040 QualType Result = TL.getType();
7041 if (getDerived().AlwaysRebuild() ||
7042 QualifierLoc != TL.getQualifierLoc() ||
7043 NamedT != T->getNamedType()) {
7044 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7045 T->getKeyword(),
7046 QualifierLoc, NamedT);
7047 if (Result.isNull())
7048 return QualType();
7051 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7052 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7053 NewTL.setQualifierLoc(QualifierLoc);
7054 return Result;
7057 template<typename Derived>
7058 QualType TreeTransform<Derived>::TransformAttributedType(
7059 TypeLocBuilder &TLB,
7060 AttributedTypeLoc TL) {
7061 const AttributedType *oldType = TL.getTypePtr();
7062 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7063 if (modifiedType.isNull())
7064 return QualType();
7066 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7067 const Attr *oldAttr = TL.getAttr();
7068 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7069 if (oldAttr && !newAttr)
7070 return QualType();
7072 QualType result = TL.getType();
7074 // FIXME: dependent operand expressions?
7075 if (getDerived().AlwaysRebuild() ||
7076 modifiedType != oldType->getModifiedType()) {
7077 // TODO: this is really lame; we should really be rebuilding the
7078 // equivalent type from first principles.
7079 QualType equivalentType
7080 = getDerived().TransformType(oldType->getEquivalentType());
7081 if (equivalentType.isNull())
7082 return QualType();
7084 // Check whether we can add nullability; it is only represented as
7085 // type sugar, and therefore cannot be diagnosed in any other way.
7086 if (auto nullability = oldType->getImmediateNullability()) {
7087 if (!modifiedType->canHaveNullability()) {
7088 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
7089 : TL.getModifiedLoc().getBeginLoc()),
7090 diag::err_nullability_nonpointer)
7091 << DiagNullabilityKind(*nullability, false) << modifiedType;
7092 return QualType();
7096 result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
7097 modifiedType,
7098 equivalentType);
7101 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
7102 newTL.setAttr(newAttr);
7103 return result;
7106 template <typename Derived>
7107 QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7108 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7109 // The BTFTagAttributedType is available for C only.
7110 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7113 template<typename Derived>
7114 QualType
7115 TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7116 ParenTypeLoc TL) {
7117 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7118 if (Inner.isNull())
7119 return QualType();
7121 QualType Result = TL.getType();
7122 if (getDerived().AlwaysRebuild() ||
7123 Inner != TL.getInnerLoc().getType()) {
7124 Result = getDerived().RebuildParenType(Inner);
7125 if (Result.isNull())
7126 return QualType();
7129 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
7130 NewTL.setLParenLoc(TL.getLParenLoc());
7131 NewTL.setRParenLoc(TL.getRParenLoc());
7132 return Result;
7135 template <typename Derived>
7136 QualType
7137 TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7138 MacroQualifiedTypeLoc TL) {
7139 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7140 if (Inner.isNull())
7141 return QualType();
7143 QualType Result = TL.getType();
7144 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7145 Result =
7146 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7147 if (Result.isNull())
7148 return QualType();
7151 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
7152 NewTL.setExpansionLoc(TL.getExpansionLoc());
7153 return Result;
7156 template<typename Derived>
7157 QualType TreeTransform<Derived>::TransformDependentNameType(
7158 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7159 return TransformDependentNameType(TLB, TL, false);
7162 template<typename Derived>
7163 QualType TreeTransform<Derived>::TransformDependentNameType(
7164 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7165 const DependentNameType *T = TL.getTypePtr();
7167 NestedNameSpecifierLoc QualifierLoc
7168 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7169 if (!QualifierLoc)
7170 return QualType();
7172 QualType Result
7173 = getDerived().RebuildDependentNameType(T->getKeyword(),
7174 TL.getElaboratedKeywordLoc(),
7175 QualifierLoc,
7176 T->getIdentifier(),
7177 TL.getNameLoc(),
7178 DeducedTSTContext);
7179 if (Result.isNull())
7180 return QualType();
7182 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7183 QualType NamedT = ElabT->getNamedType();
7184 TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
7186 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7187 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7188 NewTL.setQualifierLoc(QualifierLoc);
7189 } else {
7190 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
7191 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7192 NewTL.setQualifierLoc(QualifierLoc);
7193 NewTL.setNameLoc(TL.getNameLoc());
7195 return Result;
7198 template<typename Derived>
7199 QualType TreeTransform<Derived>::
7200 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7201 DependentTemplateSpecializationTypeLoc TL) {
7202 NestedNameSpecifierLoc QualifierLoc;
7203 if (TL.getQualifierLoc()) {
7204 QualifierLoc
7205 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7206 if (!QualifierLoc)
7207 return QualType();
7210 return getDerived()
7211 .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
7214 template<typename Derived>
7215 QualType TreeTransform<Derived>::
7216 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7217 DependentTemplateSpecializationTypeLoc TL,
7218 NestedNameSpecifierLoc QualifierLoc) {
7219 const DependentTemplateSpecializationType *T = TL.getTypePtr();
7221 TemplateArgumentListInfo NewTemplateArgs;
7222 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7223 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7225 typedef TemplateArgumentLocContainerIterator<
7226 DependentTemplateSpecializationTypeLoc> ArgIterator;
7227 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7228 ArgIterator(TL, TL.getNumArgs()),
7229 NewTemplateArgs))
7230 return QualType();
7232 QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
7233 T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(),
7234 T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs,
7235 /*AllowInjectedClassName*/ false);
7236 if (Result.isNull())
7237 return QualType();
7239 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
7240 QualType NamedT = ElabT->getNamedType();
7242 // Copy information relevant to the template specialization.
7243 TemplateSpecializationTypeLoc NamedTL
7244 = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
7245 NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7246 NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7247 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7248 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7249 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7250 NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7252 // Copy information relevant to the elaborated type.
7253 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7254 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7255 NewTL.setQualifierLoc(QualifierLoc);
7256 } else if (isa<DependentTemplateSpecializationType>(Result)) {
7257 DependentTemplateSpecializationTypeLoc SpecTL
7258 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7259 SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7260 SpecTL.setQualifierLoc(QualifierLoc);
7261 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7262 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7263 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7264 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7265 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7266 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7267 } else {
7268 TemplateSpecializationTypeLoc SpecTL
7269 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7270 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7271 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7272 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7273 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7274 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7275 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7277 return Result;
7280 template<typename Derived>
7281 QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7282 PackExpansionTypeLoc TL) {
7283 QualType Pattern
7284 = getDerived().TransformType(TLB, TL.getPatternLoc());
7285 if (Pattern.isNull())
7286 return QualType();
7288 QualType Result = TL.getType();
7289 if (getDerived().AlwaysRebuild() ||
7290 Pattern != TL.getPatternLoc().getType()) {
7291 Result = getDerived().RebuildPackExpansionType(Pattern,
7292 TL.getPatternLoc().getSourceRange(),
7293 TL.getEllipsisLoc(),
7294 TL.getTypePtr()->getNumExpansions());
7295 if (Result.isNull())
7296 return QualType();
7299 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
7300 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7301 return Result;
7304 template<typename Derived>
7305 QualType
7306 TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7307 ObjCInterfaceTypeLoc TL) {
7308 // ObjCInterfaceType is never dependent.
7309 TLB.pushFullCopy(TL);
7310 return TL.getType();
7313 template<typename Derived>
7314 QualType
7315 TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7316 ObjCTypeParamTypeLoc TL) {
7317 const ObjCTypeParamType *T = TL.getTypePtr();
7318 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7319 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7320 if (!OTP)
7321 return QualType();
7323 QualType Result = TL.getType();
7324 if (getDerived().AlwaysRebuild() ||
7325 OTP != T->getDecl()) {
7326 Result = getDerived().RebuildObjCTypeParamType(
7327 OTP, TL.getProtocolLAngleLoc(),
7328 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7329 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7330 if (Result.isNull())
7331 return QualType();
7334 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
7335 if (TL.getNumProtocols()) {
7336 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7337 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7338 NewTL.setProtocolLoc(i, TL.getProtocolLoc(i));
7339 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7341 return Result;
7344 template<typename Derived>
7345 QualType
7346 TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7347 ObjCObjectTypeLoc TL) {
7348 // Transform base type.
7349 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7350 if (BaseType.isNull())
7351 return QualType();
7353 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7355 // Transform type arguments.
7356 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7357 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7358 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7359 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7360 QualType TypeArg = TypeArgInfo->getType();
7361 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7362 AnyChanged = true;
7364 // We have a pack expansion. Instantiate it.
7365 const auto *PackExpansion = PackExpansionLoc.getType()
7366 ->castAs<PackExpansionType>();
7367 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7368 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
7369 Unexpanded);
7370 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7372 // Determine whether the set of unexpanded parameter packs can
7373 // and should be expanded.
7374 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7375 bool Expand = false;
7376 bool RetainExpansion = false;
7377 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
7378 if (getDerived().TryExpandParameterPacks(
7379 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7380 Unexpanded, Expand, RetainExpansion, NumExpansions))
7381 return QualType();
7383 if (!Expand) {
7384 // We can't expand this pack expansion into separate arguments yet;
7385 // just substitute into the pattern and create a new pack expansion
7386 // type.
7387 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
7389 TypeLocBuilder TypeArgBuilder;
7390 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7391 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7392 PatternLoc);
7393 if (NewPatternType.isNull())
7394 return QualType();
7396 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7397 NewPatternType, NumExpansions);
7398 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);
7399 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7400 NewTypeArgInfos.push_back(
7401 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewExpansionType));
7402 continue;
7405 // Substitute into the pack expansion pattern for each slice of the
7406 // pack.
7407 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
7408 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
7410 TypeLocBuilder TypeArgBuilder;
7411 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7413 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
7414 PatternLoc);
7415 if (NewTypeArg.isNull())
7416 return QualType();
7418 NewTypeArgInfos.push_back(
7419 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7422 continue;
7425 TypeLocBuilder TypeArgBuilder;
7426 TypeArgBuilder.reserve(TypeArgLoc.getFullDataSize());
7427 QualType NewTypeArg =
7428 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
7429 if (NewTypeArg.isNull())
7430 return QualType();
7432 // If nothing changed, just keep the old TypeSourceInfo.
7433 if (NewTypeArg == TypeArg) {
7434 NewTypeArgInfos.push_back(TypeArgInfo);
7435 continue;
7438 NewTypeArgInfos.push_back(
7439 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7440 AnyChanged = true;
7443 QualType Result = TL.getType();
7444 if (getDerived().AlwaysRebuild() || AnyChanged) {
7445 // Rebuild the type.
7446 Result = getDerived().RebuildObjCObjectType(
7447 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
7448 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
7449 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7450 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7452 if (Result.isNull())
7453 return QualType();
7456 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);
7457 NewT.setHasBaseTypeAsWritten(true);
7458 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
7459 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
7460 NewT.setTypeArgTInfo(i, NewTypeArgInfos[i]);
7461 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
7462 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7463 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7464 NewT.setProtocolLoc(i, TL.getProtocolLoc(i));
7465 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7466 return Result;
7469 template<typename Derived>
7470 QualType
7471 TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
7472 ObjCObjectPointerTypeLoc TL) {
7473 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
7474 if (PointeeType.isNull())
7475 return QualType();
7477 QualType Result = TL.getType();
7478 if (getDerived().AlwaysRebuild() ||
7479 PointeeType != TL.getPointeeLoc().getType()) {
7480 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
7481 TL.getStarLoc());
7482 if (Result.isNull())
7483 return QualType();
7486 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
7487 NewT.setStarLoc(TL.getStarLoc());
7488 return Result;
7491 //===----------------------------------------------------------------------===//
7492 // Statement transformation
7493 //===----------------------------------------------------------------------===//
7494 template<typename Derived>
7495 StmtResult
7496 TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
7497 return S;
7500 template<typename Derived>
7501 StmtResult
7502 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
7503 return getDerived().TransformCompoundStmt(S, false);
7506 template<typename Derived>
7507 StmtResult
7508 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
7509 bool IsStmtExpr) {
7510 Sema::CompoundScopeRAII CompoundScope(getSema());
7511 Sema::FPFeaturesStateRAII FPSave(getSema());
7512 if (S->hasStoredFPFeatures())
7513 getSema().resetFPOptions(
7514 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
7516 const Stmt *ExprResult = S->getStmtExprResult();
7517 bool SubStmtInvalid = false;
7518 bool SubStmtChanged = false;
7519 SmallVector<Stmt*, 8> Statements;
7520 for (auto *B : S->body()) {
7521 StmtResult Result = getDerived().TransformStmt(
7522 B, IsStmtExpr && B == ExprResult ? SDK_StmtExprResult : SDK_Discarded);
7524 if (Result.isInvalid()) {
7525 // Immediately fail if this was a DeclStmt, since it's very
7526 // likely that this will cause problems for future statements.
7527 if (isa<DeclStmt>(B))
7528 return StmtError();
7530 // Otherwise, just keep processing substatements and fail later.
7531 SubStmtInvalid = true;
7532 continue;
7535 SubStmtChanged = SubStmtChanged || Result.get() != B;
7536 Statements.push_back(Result.getAs<Stmt>());
7539 if (SubStmtInvalid)
7540 return StmtError();
7542 if (!getDerived().AlwaysRebuild() &&
7543 !SubStmtChanged)
7544 return S;
7546 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
7547 Statements,
7548 S->getRBracLoc(),
7549 IsStmtExpr);
7552 template<typename Derived>
7553 StmtResult
7554 TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
7555 ExprResult LHS, RHS;
7557 EnterExpressionEvaluationContext Unevaluated(
7558 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7560 // Transform the left-hand case value.
7561 LHS = getDerived().TransformExpr(S->getLHS());
7562 LHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), LHS);
7563 if (LHS.isInvalid())
7564 return StmtError();
7566 // Transform the right-hand case value (for the GNU case-range extension).
7567 RHS = getDerived().TransformExpr(S->getRHS());
7568 RHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), RHS);
7569 if (RHS.isInvalid())
7570 return StmtError();
7573 // Build the case statement.
7574 // Case statements are always rebuilt so that they will attached to their
7575 // transformed switch statement.
7576 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
7577 LHS.get(),
7578 S->getEllipsisLoc(),
7579 RHS.get(),
7580 S->getColonLoc());
7581 if (Case.isInvalid())
7582 return StmtError();
7584 // Transform the statement following the case
7585 StmtResult SubStmt =
7586 getDerived().TransformStmt(S->getSubStmt());
7587 if (SubStmt.isInvalid())
7588 return StmtError();
7590 // Attach the body to the case statement
7591 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
7594 template <typename Derived>
7595 StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
7596 // Transform the statement following the default case
7597 StmtResult SubStmt =
7598 getDerived().TransformStmt(S->getSubStmt());
7599 if (SubStmt.isInvalid())
7600 return StmtError();
7602 // Default statements are always rebuilt
7603 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
7604 SubStmt.get());
7607 template<typename Derived>
7608 StmtResult
7609 TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
7610 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7611 if (SubStmt.isInvalid())
7612 return StmtError();
7614 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
7615 S->getDecl());
7616 if (!LD)
7617 return StmtError();
7619 // If we're transforming "in-place" (we're not creating new local
7620 // declarations), assume we're replacing the old label statement
7621 // and clear out the reference to it.
7622 if (LD == S->getDecl())
7623 S->getDecl()->setStmt(nullptr);
7625 // FIXME: Pass the real colon location in.
7626 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
7627 cast<LabelDecl>(LD), SourceLocation(),
7628 SubStmt.get());
7631 template <typename Derived>
7632 const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
7633 if (!R)
7634 return R;
7636 switch (R->getKind()) {
7637 // Transform attributes by calling TransformXXXAttr.
7638 #define ATTR(X) \
7639 case attr::X: \
7640 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
7641 #include "clang/Basic/AttrList.inc"
7643 return R;
7646 template <typename Derived>
7647 const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
7648 const Stmt *InstS,
7649 const Attr *R) {
7650 if (!R)
7651 return R;
7653 switch (R->getKind()) {
7654 // Transform attributes by calling TransformStmtXXXAttr.
7655 #define ATTR(X) \
7656 case attr::X: \
7657 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
7658 #include "clang/Basic/AttrList.inc"
7660 return TransformAttr(R);
7663 template <typename Derived>
7664 StmtResult
7665 TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
7666 StmtDiscardKind SDK) {
7667 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7668 if (SubStmt.isInvalid())
7669 return StmtError();
7671 bool AttrsChanged = false;
7672 SmallVector<const Attr *, 1> Attrs;
7674 // Visit attributes and keep track if any are transformed.
7675 for (const auto *I : S->getAttrs()) {
7676 const Attr *R =
7677 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
7678 AttrsChanged |= (I != R);
7679 if (R)
7680 Attrs.push_back(R);
7683 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
7684 return S;
7686 // If transforming the attributes failed for all of the attributes in the
7687 // statement, don't make an AttributedStmt without attributes.
7688 if (Attrs.empty())
7689 return SubStmt;
7691 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
7692 SubStmt.get());
7695 template<typename Derived>
7696 StmtResult
7697 TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
7698 // Transform the initialization statement
7699 StmtResult Init = getDerived().TransformStmt(S->getInit());
7700 if (Init.isInvalid())
7701 return StmtError();
7703 Sema::ConditionResult Cond;
7704 if (!S->isConsteval()) {
7705 // Transform the condition
7706 Cond = getDerived().TransformCondition(
7707 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
7708 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
7709 : Sema::ConditionKind::Boolean);
7710 if (Cond.isInvalid())
7711 return StmtError();
7714 // If this is a constexpr if, determine which arm we should instantiate.
7715 std::optional<bool> ConstexprConditionValue;
7716 if (S->isConstexpr())
7717 ConstexprConditionValue = Cond.getKnownValue();
7719 // Transform the "then" branch.
7720 StmtResult Then;
7721 if (!ConstexprConditionValue || *ConstexprConditionValue) {
7722 Then = getDerived().TransformStmt(S->getThen());
7723 if (Then.isInvalid())
7724 return StmtError();
7725 } else {
7726 Then = new (getSema().Context) NullStmt(S->getThen()->getBeginLoc());
7729 // Transform the "else" branch.
7730 StmtResult Else;
7731 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
7732 Else = getDerived().TransformStmt(S->getElse());
7733 if (Else.isInvalid())
7734 return StmtError();
7737 if (!getDerived().AlwaysRebuild() &&
7738 Init.get() == S->getInit() &&
7739 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7740 Then.get() == S->getThen() &&
7741 Else.get() == S->getElse())
7742 return S;
7744 return getDerived().RebuildIfStmt(
7745 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
7746 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
7749 template<typename Derived>
7750 StmtResult
7751 TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
7752 // Transform the initialization statement
7753 StmtResult Init = getDerived().TransformStmt(S->getInit());
7754 if (Init.isInvalid())
7755 return StmtError();
7757 // Transform the condition.
7758 Sema::ConditionResult Cond = getDerived().TransformCondition(
7759 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
7760 Sema::ConditionKind::Switch);
7761 if (Cond.isInvalid())
7762 return StmtError();
7764 // Rebuild the switch statement.
7765 StmtResult Switch =
7766 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
7767 Init.get(), Cond, S->getRParenLoc());
7768 if (Switch.isInvalid())
7769 return StmtError();
7771 // Transform the body of the switch statement.
7772 StmtResult Body = getDerived().TransformStmt(S->getBody());
7773 if (Body.isInvalid())
7774 return StmtError();
7776 // Complete the switch statement.
7777 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
7778 Body.get());
7781 template<typename Derived>
7782 StmtResult
7783 TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
7784 // Transform the condition
7785 Sema::ConditionResult Cond = getDerived().TransformCondition(
7786 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
7787 Sema::ConditionKind::Boolean);
7788 if (Cond.isInvalid())
7789 return StmtError();
7791 // Transform the body
7792 StmtResult Body = getDerived().TransformStmt(S->getBody());
7793 if (Body.isInvalid())
7794 return StmtError();
7796 if (!getDerived().AlwaysRebuild() &&
7797 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7798 Body.get() == S->getBody())
7799 return Owned(S);
7801 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
7802 Cond, S->getRParenLoc(), Body.get());
7805 template<typename Derived>
7806 StmtResult
7807 TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
7808 // Transform the body
7809 StmtResult Body = getDerived().TransformStmt(S->getBody());
7810 if (Body.isInvalid())
7811 return StmtError();
7813 // Transform the condition
7814 ExprResult Cond = getDerived().TransformExpr(S->getCond());
7815 if (Cond.isInvalid())
7816 return StmtError();
7818 if (!getDerived().AlwaysRebuild() &&
7819 Cond.get() == S->getCond() &&
7820 Body.get() == S->getBody())
7821 return S;
7823 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
7824 /*FIXME:*/S->getWhileLoc(), Cond.get(),
7825 S->getRParenLoc());
7828 template<typename Derived>
7829 StmtResult
7830 TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
7831 if (getSema().getLangOpts().OpenMP)
7832 getSema().startOpenMPLoop();
7834 // Transform the initialization statement
7835 StmtResult Init = getDerived().TransformStmt(S->getInit());
7836 if (Init.isInvalid())
7837 return StmtError();
7839 // In OpenMP loop region loop control variable must be captured and be
7840 // private. Perform analysis of first part (if any).
7841 if (getSema().getLangOpts().OpenMP && Init.isUsable())
7842 getSema().ActOnOpenMPLoopInitialization(S->getForLoc(), Init.get());
7844 // Transform the condition
7845 Sema::ConditionResult Cond = getDerived().TransformCondition(
7846 S->getForLoc(), S->getConditionVariable(), S->getCond(),
7847 Sema::ConditionKind::Boolean);
7848 if (Cond.isInvalid())
7849 return StmtError();
7851 // Transform the increment
7852 ExprResult Inc = getDerived().TransformExpr(S->getInc());
7853 if (Inc.isInvalid())
7854 return StmtError();
7856 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
7857 if (S->getInc() && !FullInc.get())
7858 return StmtError();
7860 // Transform the body
7861 StmtResult Body = getDerived().TransformStmt(S->getBody());
7862 if (Body.isInvalid())
7863 return StmtError();
7865 if (!getDerived().AlwaysRebuild() &&
7866 Init.get() == S->getInit() &&
7867 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7868 Inc.get() == S->getInc() &&
7869 Body.get() == S->getBody())
7870 return S;
7872 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
7873 Init.get(), Cond, FullInc,
7874 S->getRParenLoc(), Body.get());
7877 template<typename Derived>
7878 StmtResult
7879 TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
7880 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
7881 S->getLabel());
7882 if (!LD)
7883 return StmtError();
7885 // Goto statements must always be rebuilt, to resolve the label.
7886 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
7887 cast<LabelDecl>(LD));
7890 template<typename Derived>
7891 StmtResult
7892 TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
7893 ExprResult Target = getDerived().TransformExpr(S->getTarget());
7894 if (Target.isInvalid())
7895 return StmtError();
7896 Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());
7898 if (!getDerived().AlwaysRebuild() &&
7899 Target.get() == S->getTarget())
7900 return S;
7902 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
7903 Target.get());
7906 template<typename Derived>
7907 StmtResult
7908 TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
7909 return S;
7912 template<typename Derived>
7913 StmtResult
7914 TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
7915 return S;
7918 template<typename Derived>
7919 StmtResult
7920 TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
7921 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
7922 /*NotCopyInit*/false);
7923 if (Result.isInvalid())
7924 return StmtError();
7926 // FIXME: We always rebuild the return statement because there is no way
7927 // to tell whether the return type of the function has changed.
7928 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
7931 template<typename Derived>
7932 StmtResult
7933 TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
7934 bool DeclChanged = false;
7935 SmallVector<Decl *, 4> Decls;
7936 for (auto *D : S->decls()) {
7937 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
7938 if (!Transformed)
7939 return StmtError();
7941 if (Transformed != D)
7942 DeclChanged = true;
7944 Decls.push_back(Transformed);
7947 if (!getDerived().AlwaysRebuild() && !DeclChanged)
7948 return S;
7950 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
7953 template<typename Derived>
7954 StmtResult
7955 TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
7957 SmallVector<Expr*, 8> Constraints;
7958 SmallVector<Expr*, 8> Exprs;
7959 SmallVector<IdentifierInfo *, 4> Names;
7961 ExprResult AsmString;
7962 SmallVector<Expr*, 8> Clobbers;
7964 bool ExprsChanged = false;
7966 // Go through the outputs.
7967 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
7968 Names.push_back(S->getOutputIdentifier(I));
7970 // No need to transform the constraint literal.
7971 Constraints.push_back(S->getOutputConstraintLiteral(I));
7973 // Transform the output expr.
7974 Expr *OutputExpr = S->getOutputExpr(I);
7975 ExprResult Result = getDerived().TransformExpr(OutputExpr);
7976 if (Result.isInvalid())
7977 return StmtError();
7979 ExprsChanged |= Result.get() != OutputExpr;
7981 Exprs.push_back(Result.get());
7984 // Go through the inputs.
7985 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
7986 Names.push_back(S->getInputIdentifier(I));
7988 // No need to transform the constraint literal.
7989 Constraints.push_back(S->getInputConstraintLiteral(I));
7991 // Transform the input expr.
7992 Expr *InputExpr = S->getInputExpr(I);
7993 ExprResult Result = getDerived().TransformExpr(InputExpr);
7994 if (Result.isInvalid())
7995 return StmtError();
7997 ExprsChanged |= Result.get() != InputExpr;
7999 Exprs.push_back(Result.get());
8002 // Go through the Labels.
8003 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8004 Names.push_back(S->getLabelIdentifier(I));
8006 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(I));
8007 if (Result.isInvalid())
8008 return StmtError();
8009 ExprsChanged |= Result.get() != S->getLabelExpr(I);
8010 Exprs.push_back(Result.get());
8012 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8013 return S;
8015 // Go through the clobbers.
8016 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
8017 Clobbers.push_back(S->getClobberStringLiteral(I));
8019 // No need to transform the asm string literal.
8020 AsmString = S->getAsmString();
8021 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8022 S->isVolatile(), S->getNumOutputs(),
8023 S->getNumInputs(), Names.data(),
8024 Constraints, Exprs, AsmString.get(),
8025 Clobbers, S->getNumLabels(),
8026 S->getRParenLoc());
8029 template<typename Derived>
8030 StmtResult
8031 TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8032 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8034 bool HadError = false, HadChange = false;
8036 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8037 SmallVector<Expr*, 8> TransformedExprs;
8038 TransformedExprs.reserve(SrcExprs.size());
8039 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8040 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8041 if (!Result.isUsable()) {
8042 HadError = true;
8043 } else {
8044 HadChange |= (Result.get() != SrcExprs[i]);
8045 TransformedExprs.push_back(Result.get());
8049 if (HadError) return StmtError();
8050 if (!HadChange && !getDerived().AlwaysRebuild())
8051 return Owned(S);
8053 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8054 AsmToks, S->getAsmString(),
8055 S->getNumOutputs(), S->getNumInputs(),
8056 S->getAllConstraints(), S->getClobbers(),
8057 TransformedExprs, S->getEndLoc());
8060 // C++ Coroutines
8061 template<typename Derived>
8062 StmtResult
8063 TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8064 auto *ScopeInfo = SemaRef.getCurFunction();
8065 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
8066 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8067 ScopeInfo->NeedsCoroutineSuspends &&
8068 ScopeInfo->CoroutineSuspends.first == nullptr &&
8069 ScopeInfo->CoroutineSuspends.second == nullptr &&
8070 "expected clean scope info");
8072 // Set that we have (possibly-invalid) suspend points before we do anything
8073 // that may fail.
8074 ScopeInfo->setNeedsCoroutineSuspends(false);
8076 // We re-build the coroutine promise object (and the coroutine parameters its
8077 // type and constructor depend on) based on the types used in our current
8078 // function. We must do so, and set it on the current FunctionScopeInfo,
8079 // before attempting to transform the other parts of the coroutine body
8080 // statement, such as the implicit suspend statements (because those
8081 // statements reference the FunctionScopeInfo::CoroutinePromise).
8082 if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation()))
8083 return StmtError();
8084 auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());
8085 if (!Promise)
8086 return StmtError();
8087 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8088 ScopeInfo->CoroutinePromise = Promise;
8090 // Transform the implicit coroutine statements constructed using dependent
8091 // types during the previous parse: initial and final suspensions, the return
8092 // object, and others. We also transform the coroutine function's body.
8093 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8094 if (InitSuspend.isInvalid())
8095 return StmtError();
8096 StmtResult FinalSuspend =
8097 getDerived().TransformStmt(S->getFinalSuspendStmt());
8098 if (FinalSuspend.isInvalid() ||
8099 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get()))
8100 return StmtError();
8101 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
8102 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8104 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8105 if (BodyRes.isInvalid())
8106 return StmtError();
8108 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8109 if (Builder.isInvalid())
8110 return StmtError();
8112 Expr *ReturnObject = S->getReturnValueInit();
8113 assert(ReturnObject && "the return object is expected to be valid");
8114 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8115 /*NoCopyInit*/ false);
8116 if (Res.isInvalid())
8117 return StmtError();
8118 Builder.ReturnValue = Res.get();
8120 // If during the previous parse the coroutine still had a dependent promise
8121 // statement, we may need to build some implicit coroutine statements
8122 // (such as exception and fallthrough handlers) for the first time.
8123 if (S->hasDependentPromiseType()) {
8124 // We can only build these statements, however, if the current promise type
8125 // is not dependent.
8126 if (!Promise->getType()->isDependentType()) {
8127 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8128 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8129 "these nodes should not have been built yet");
8130 if (!Builder.buildDependentStatements())
8131 return StmtError();
8133 } else {
8134 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8135 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8136 if (Res.isInvalid())
8137 return StmtError();
8138 Builder.OnFallthrough = Res.get();
8141 if (auto *OnException = S->getExceptionHandler()) {
8142 StmtResult Res = getDerived().TransformStmt(OnException);
8143 if (Res.isInvalid())
8144 return StmtError();
8145 Builder.OnException = Res.get();
8148 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8149 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8150 if (Res.isInvalid())
8151 return StmtError();
8152 Builder.ReturnStmtOnAllocFailure = Res.get();
8155 // Transform any additional statements we may have already built
8156 assert(S->getAllocate() && S->getDeallocate() &&
8157 "allocation and deallocation calls must already be built");
8158 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8159 if (AllocRes.isInvalid())
8160 return StmtError();
8161 Builder.Allocate = AllocRes.get();
8163 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8164 if (DeallocRes.isInvalid())
8165 return StmtError();
8166 Builder.Deallocate = DeallocRes.get();
8168 if (auto *ResultDecl = S->getResultDecl()) {
8169 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8170 if (Res.isInvalid())
8171 return StmtError();
8172 Builder.ResultDecl = Res.get();
8175 if (auto *ReturnStmt = S->getReturnStmt()) {
8176 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8177 if (Res.isInvalid())
8178 return StmtError();
8179 Builder.ReturnStmt = Res.get();
8183 return getDerived().RebuildCoroutineBodyStmt(Builder);
8186 template<typename Derived>
8187 StmtResult
8188 TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8189 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8190 /*NotCopyInit*/false);
8191 if (Result.isInvalid())
8192 return StmtError();
8194 // Always rebuild; we don't know if this needs to be injected into a new
8195 // context or if the promise type has changed.
8196 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8197 S->isImplicit());
8200 template <typename Derived>
8201 ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8202 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8203 /*NotCopyInit*/ false);
8204 if (Operand.isInvalid())
8205 return ExprError();
8207 // Rebuild the common-expr from the operand rather than transforming it
8208 // separately.
8210 // FIXME: getCurScope() should not be used during template instantiation.
8211 // We should pick up the set of unqualified lookup results for operator
8212 // co_await during the initial parse.
8213 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8214 getSema().getCurScope(), E->getKeywordLoc());
8216 // Always rebuild; we don't know if this needs to be injected into a new
8217 // context or if the promise type has changed.
8218 return getDerived().RebuildCoawaitExpr(
8219 E->getKeywordLoc(), Operand.get(),
8220 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());
8223 template <typename Derived>
8224 ExprResult
8225 TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8226 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8227 /*NotCopyInit*/ false);
8228 if (OperandResult.isInvalid())
8229 return ExprError();
8231 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8232 E->getOperatorCoawaitLookup());
8234 if (LookupResult.isInvalid())
8235 return ExprError();
8237 // Always rebuild; we don't know if this needs to be injected into a new
8238 // context or if the promise type has changed.
8239 return getDerived().RebuildDependentCoawaitExpr(
8240 E->getKeywordLoc(), OperandResult.get(),
8241 cast<UnresolvedLookupExpr>(LookupResult.get()));
8244 template<typename Derived>
8245 ExprResult
8246 TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8247 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8248 /*NotCopyInit*/false);
8249 if (Result.isInvalid())
8250 return ExprError();
8252 // Always rebuild; we don't know if this needs to be injected into a new
8253 // context or if the promise type has changed.
8254 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8257 // Objective-C Statements.
8259 template<typename Derived>
8260 StmtResult
8261 TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8262 // Transform the body of the @try.
8263 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8264 if (TryBody.isInvalid())
8265 return StmtError();
8267 // Transform the @catch statements (if present).
8268 bool AnyCatchChanged = false;
8269 SmallVector<Stmt*, 8> CatchStmts;
8270 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8271 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8272 if (Catch.isInvalid())
8273 return StmtError();
8274 if (Catch.get() != S->getCatchStmt(I))
8275 AnyCatchChanged = true;
8276 CatchStmts.push_back(Catch.get());
8279 // Transform the @finally statement (if present).
8280 StmtResult Finally;
8281 if (S->getFinallyStmt()) {
8282 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8283 if (Finally.isInvalid())
8284 return StmtError();
8287 // If nothing changed, just retain this statement.
8288 if (!getDerived().AlwaysRebuild() &&
8289 TryBody.get() == S->getTryBody() &&
8290 !AnyCatchChanged &&
8291 Finally.get() == S->getFinallyStmt())
8292 return S;
8294 // Build a new statement.
8295 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8296 CatchStmts, Finally.get());
8299 template<typename Derived>
8300 StmtResult
8301 TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8302 // Transform the @catch parameter, if there is one.
8303 VarDecl *Var = nullptr;
8304 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8305 TypeSourceInfo *TSInfo = nullptr;
8306 if (FromVar->getTypeSourceInfo()) {
8307 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8308 if (!TSInfo)
8309 return StmtError();
8312 QualType T;
8313 if (TSInfo)
8314 T = TSInfo->getType();
8315 else {
8316 T = getDerived().TransformType(FromVar->getType());
8317 if (T.isNull())
8318 return StmtError();
8321 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8322 if (!Var)
8323 return StmtError();
8326 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8327 if (Body.isInvalid())
8328 return StmtError();
8330 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
8331 S->getRParenLoc(),
8332 Var, Body.get());
8335 template<typename Derived>
8336 StmtResult
8337 TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
8338 // Transform the body.
8339 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
8340 if (Body.isInvalid())
8341 return StmtError();
8343 // If nothing changed, just retain this statement.
8344 if (!getDerived().AlwaysRebuild() &&
8345 Body.get() == S->getFinallyBody())
8346 return S;
8348 // Build a new statement.
8349 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
8350 Body.get());
8353 template<typename Derived>
8354 StmtResult
8355 TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
8356 ExprResult Operand;
8357 if (S->getThrowExpr()) {
8358 Operand = getDerived().TransformExpr(S->getThrowExpr());
8359 if (Operand.isInvalid())
8360 return StmtError();
8363 if (!getDerived().AlwaysRebuild() &&
8364 Operand.get() == S->getThrowExpr())
8365 return S;
8367 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
8370 template<typename Derived>
8371 StmtResult
8372 TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
8373 ObjCAtSynchronizedStmt *S) {
8374 // Transform the object we are locking.
8375 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
8376 if (Object.isInvalid())
8377 return StmtError();
8378 Object =
8379 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
8380 Object.get());
8381 if (Object.isInvalid())
8382 return StmtError();
8384 // Transform the body.
8385 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
8386 if (Body.isInvalid())
8387 return StmtError();
8389 // If nothing change, just retain the current statement.
8390 if (!getDerived().AlwaysRebuild() &&
8391 Object.get() == S->getSynchExpr() &&
8392 Body.get() == S->getSynchBody())
8393 return S;
8395 // Build a new statement.
8396 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
8397 Object.get(), Body.get());
8400 template<typename Derived>
8401 StmtResult
8402 TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
8403 ObjCAutoreleasePoolStmt *S) {
8404 // Transform the body.
8405 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
8406 if (Body.isInvalid())
8407 return StmtError();
8409 // If nothing changed, just retain this statement.
8410 if (!getDerived().AlwaysRebuild() &&
8411 Body.get() == S->getSubStmt())
8412 return S;
8414 // Build a new statement.
8415 return getDerived().RebuildObjCAutoreleasePoolStmt(
8416 S->getAtLoc(), Body.get());
8419 template<typename Derived>
8420 StmtResult
8421 TreeTransform<Derived>::TransformObjCForCollectionStmt(
8422 ObjCForCollectionStmt *S) {
8423 // Transform the element statement.
8424 StmtResult Element =
8425 getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded);
8426 if (Element.isInvalid())
8427 return StmtError();
8429 // Transform the collection expression.
8430 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
8431 if (Collection.isInvalid())
8432 return StmtError();
8434 // Transform the body.
8435 StmtResult Body = getDerived().TransformStmt(S->getBody());
8436 if (Body.isInvalid())
8437 return StmtError();
8439 // If nothing changed, just retain this statement.
8440 if (!getDerived().AlwaysRebuild() &&
8441 Element.get() == S->getElement() &&
8442 Collection.get() == S->getCollection() &&
8443 Body.get() == S->getBody())
8444 return S;
8446 // Build a new statement.
8447 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
8448 Element.get(),
8449 Collection.get(),
8450 S->getRParenLoc(),
8451 Body.get());
8454 template <typename Derived>
8455 StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
8456 // Transform the exception declaration, if any.
8457 VarDecl *Var = nullptr;
8458 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
8459 TypeSourceInfo *T =
8460 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
8461 if (!T)
8462 return StmtError();
8464 Var = getDerived().RebuildExceptionDecl(
8465 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
8466 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
8467 if (!Var || Var->isInvalidDecl())
8468 return StmtError();
8471 // Transform the actual exception handler.
8472 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
8473 if (Handler.isInvalid())
8474 return StmtError();
8476 if (!getDerived().AlwaysRebuild() && !Var &&
8477 Handler.get() == S->getHandlerBlock())
8478 return S;
8480 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
8483 template <typename Derived>
8484 StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
8485 // Transform the try block itself.
8486 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8487 if (TryBlock.isInvalid())
8488 return StmtError();
8490 // Transform the handlers.
8491 bool HandlerChanged = false;
8492 SmallVector<Stmt *, 8> Handlers;
8493 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
8494 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I));
8495 if (Handler.isInvalid())
8496 return StmtError();
8498 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
8499 Handlers.push_back(Handler.getAs<Stmt>());
8502 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8503 !HandlerChanged)
8504 return S;
8506 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
8507 Handlers);
8510 template<typename Derived>
8511 StmtResult
8512 TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
8513 StmtResult Init =
8514 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
8515 if (Init.isInvalid())
8516 return StmtError();
8518 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
8519 if (Range.isInvalid())
8520 return StmtError();
8522 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
8523 if (Begin.isInvalid())
8524 return StmtError();
8525 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
8526 if (End.isInvalid())
8527 return StmtError();
8529 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8530 if (Cond.isInvalid())
8531 return StmtError();
8532 if (Cond.get())
8533 Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());
8534 if (Cond.isInvalid())
8535 return StmtError();
8536 if (Cond.get())
8537 Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());
8539 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8540 if (Inc.isInvalid())
8541 return StmtError();
8542 if (Inc.get())
8543 Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());
8545 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
8546 if (LoopVar.isInvalid())
8547 return StmtError();
8549 StmtResult NewStmt = S;
8550 if (getDerived().AlwaysRebuild() ||
8551 Init.get() != S->getInit() ||
8552 Range.get() != S->getRangeStmt() ||
8553 Begin.get() != S->getBeginStmt() ||
8554 End.get() != S->getEndStmt() ||
8555 Cond.get() != S->getCond() ||
8556 Inc.get() != S->getInc() ||
8557 LoopVar.get() != S->getLoopVarStmt()) {
8558 NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
8559 S->getCoawaitLoc(), Init.get(),
8560 S->getColonLoc(), Range.get(),
8561 Begin.get(), End.get(),
8562 Cond.get(),
8563 Inc.get(), LoopVar.get(),
8564 S->getRParenLoc());
8565 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
8566 // Might not have attached any initializer to the loop variable.
8567 getSema().ActOnInitializerError(
8568 cast<DeclStmt>(LoopVar.get())->getSingleDecl());
8569 return StmtError();
8573 StmtResult Body = getDerived().TransformStmt(S->getBody());
8574 if (Body.isInvalid())
8575 return StmtError();
8577 // Body has changed but we didn't rebuild the for-range statement. Rebuild
8578 // it now so we have a new statement to attach the body to.
8579 if (Body.get() != S->getBody() && NewStmt.get() == S) {
8580 NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
8581 S->getCoawaitLoc(), Init.get(),
8582 S->getColonLoc(), Range.get(),
8583 Begin.get(), End.get(),
8584 Cond.get(),
8585 Inc.get(), LoopVar.get(),
8586 S->getRParenLoc());
8587 if (NewStmt.isInvalid())
8588 return StmtError();
8591 if (NewStmt.get() == S)
8592 return S;
8594 return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
8597 template<typename Derived>
8598 StmtResult
8599 TreeTransform<Derived>::TransformMSDependentExistsStmt(
8600 MSDependentExistsStmt *S) {
8601 // Transform the nested-name-specifier, if any.
8602 NestedNameSpecifierLoc QualifierLoc;
8603 if (S->getQualifierLoc()) {
8604 QualifierLoc
8605 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
8606 if (!QualifierLoc)
8607 return StmtError();
8610 // Transform the declaration name.
8611 DeclarationNameInfo NameInfo = S->getNameInfo();
8612 if (NameInfo.getName()) {
8613 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
8614 if (!NameInfo.getName())
8615 return StmtError();
8618 // Check whether anything changed.
8619 if (!getDerived().AlwaysRebuild() &&
8620 QualifierLoc == S->getQualifierLoc() &&
8621 NameInfo.getName() == S->getNameInfo().getName())
8622 return S;
8624 // Determine whether this name exists, if we can.
8625 CXXScopeSpec SS;
8626 SS.Adopt(QualifierLoc);
8627 bool Dependent = false;
8628 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
8629 case Sema::IER_Exists:
8630 if (S->isIfExists())
8631 break;
8633 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8635 case Sema::IER_DoesNotExist:
8636 if (S->isIfNotExists())
8637 break;
8639 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8641 case Sema::IER_Dependent:
8642 Dependent = true;
8643 break;
8645 case Sema::IER_Error:
8646 return StmtError();
8649 // We need to continue with the instantiation, so do so now.
8650 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
8651 if (SubStmt.isInvalid())
8652 return StmtError();
8654 // If we have resolved the name, just transform to the substatement.
8655 if (!Dependent)
8656 return SubStmt;
8658 // The name is still dependent, so build a dependent expression again.
8659 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
8660 S->isIfExists(),
8661 QualifierLoc,
8662 NameInfo,
8663 SubStmt.get());
8666 template<typename Derived>
8667 ExprResult
8668 TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
8669 NestedNameSpecifierLoc QualifierLoc;
8670 if (E->getQualifierLoc()) {
8671 QualifierLoc
8672 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
8673 if (!QualifierLoc)
8674 return ExprError();
8677 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
8678 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
8679 if (!PD)
8680 return ExprError();
8682 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
8683 if (Base.isInvalid())
8684 return ExprError();
8686 return new (SemaRef.getASTContext())
8687 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
8688 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
8689 QualifierLoc, E->getMemberLoc());
8692 template <typename Derived>
8693 ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
8694 MSPropertySubscriptExpr *E) {
8695 auto BaseRes = getDerived().TransformExpr(E->getBase());
8696 if (BaseRes.isInvalid())
8697 return ExprError();
8698 auto IdxRes = getDerived().TransformExpr(E->getIdx());
8699 if (IdxRes.isInvalid())
8700 return ExprError();
8702 if (!getDerived().AlwaysRebuild() &&
8703 BaseRes.get() == E->getBase() &&
8704 IdxRes.get() == E->getIdx())
8705 return E;
8707 return getDerived().RebuildArraySubscriptExpr(
8708 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
8711 template <typename Derived>
8712 StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
8713 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8714 if (TryBlock.isInvalid())
8715 return StmtError();
8717 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
8718 if (Handler.isInvalid())
8719 return StmtError();
8721 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8722 Handler.get() == S->getHandler())
8723 return S;
8725 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
8726 TryBlock.get(), Handler.get());
8729 template <typename Derived>
8730 StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
8731 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
8732 if (Block.isInvalid())
8733 return StmtError();
8735 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
8738 template <typename Derived>
8739 StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
8740 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
8741 if (FilterExpr.isInvalid())
8742 return StmtError();
8744 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
8745 if (Block.isInvalid())
8746 return StmtError();
8748 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
8749 Block.get());
8752 template <typename Derived>
8753 StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
8754 if (isa<SEHFinallyStmt>(Handler))
8755 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
8756 else
8757 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
8760 template<typename Derived>
8761 StmtResult
8762 TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
8763 return S;
8766 //===----------------------------------------------------------------------===//
8767 // OpenMP directive transformation
8768 //===----------------------------------------------------------------------===//
8770 template <typename Derived>
8771 StmtResult
8772 TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
8773 // OMPCanonicalLoops are eliminated during transformation, since they will be
8774 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
8775 // after transformation.
8776 return getDerived().TransformStmt(L->getLoopStmt());
8779 template <typename Derived>
8780 StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
8781 OMPExecutableDirective *D) {
8783 // Transform the clauses
8784 llvm::SmallVector<OMPClause *, 16> TClauses;
8785 ArrayRef<OMPClause *> Clauses = D->clauses();
8786 TClauses.reserve(Clauses.size());
8787 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
8788 I != E; ++I) {
8789 if (*I) {
8790 getDerived().getSema().StartOpenMPClause((*I)->getClauseKind());
8791 OMPClause *Clause = getDerived().TransformOMPClause(*I);
8792 getDerived().getSema().EndOpenMPClause();
8793 if (Clause)
8794 TClauses.push_back(Clause);
8795 } else {
8796 TClauses.push_back(nullptr);
8799 StmtResult AssociatedStmt;
8800 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
8801 getDerived().getSema().ActOnOpenMPRegionStart(D->getDirectiveKind(),
8802 /*CurScope=*/nullptr);
8803 StmtResult Body;
8805 Sema::CompoundScopeRAII CompoundScope(getSema());
8806 Stmt *CS;
8807 if (D->getDirectiveKind() == OMPD_atomic ||
8808 D->getDirectiveKind() == OMPD_critical ||
8809 D->getDirectiveKind() == OMPD_section ||
8810 D->getDirectiveKind() == OMPD_master)
8811 CS = D->getAssociatedStmt();
8812 else
8813 CS = D->getRawStmt();
8814 Body = getDerived().TransformStmt(CS);
8815 if (Body.isUsable() && isOpenMPLoopDirective(D->getDirectiveKind()) &&
8816 getSema().getLangOpts().OpenMPIRBuilder)
8817 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
8819 AssociatedStmt =
8820 getDerived().getSema().ActOnOpenMPRegionEnd(Body, TClauses);
8821 if (AssociatedStmt.isInvalid()) {
8822 return StmtError();
8825 if (TClauses.size() != Clauses.size()) {
8826 return StmtError();
8829 // Transform directive name for 'omp critical' directive.
8830 DeclarationNameInfo DirName;
8831 if (D->getDirectiveKind() == OMPD_critical) {
8832 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
8833 DirName = getDerived().TransformDeclarationNameInfo(DirName);
8835 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
8836 if (D->getDirectiveKind() == OMPD_cancellation_point) {
8837 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();
8838 } else if (D->getDirectiveKind() == OMPD_cancel) {
8839 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();
8842 return getDerived().RebuildOMPExecutableDirective(
8843 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
8844 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc(),
8845 D->getMappedDirective());
8848 template <typename Derived>
8849 StmtResult
8850 TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
8851 // TODO: Fix This
8852 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)
8853 << getOpenMPDirectiveName(D->getDirectiveKind());
8854 return StmtError();
8857 template <typename Derived>
8858 StmtResult
8859 TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
8860 DeclarationNameInfo DirName;
8861 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr,
8862 D->getBeginLoc());
8863 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8864 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8865 return Res;
8868 template <typename Derived>
8869 StmtResult
8870 TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
8871 DeclarationNameInfo DirName;
8872 getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr,
8873 D->getBeginLoc());
8874 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8875 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8876 return Res;
8879 template <typename Derived>
8880 StmtResult
8881 TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
8882 DeclarationNameInfo DirName;
8883 getDerived().getSema().StartOpenMPDSABlock(D->getDirectiveKind(), DirName,
8884 nullptr, D->getBeginLoc());
8885 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8886 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8887 return Res;
8890 template <typename Derived>
8891 StmtResult
8892 TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
8893 DeclarationNameInfo DirName;
8894 getDerived().getSema().StartOpenMPDSABlock(D->getDirectiveKind(), DirName,
8895 nullptr, D->getBeginLoc());
8896 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8897 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8898 return Res;
8901 template <typename Derived>
8902 StmtResult
8903 TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
8904 DeclarationNameInfo DirName;
8905 getDerived().getSema().StartOpenMPDSABlock(OMPD_for, DirName, nullptr,
8906 D->getBeginLoc());
8907 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8908 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8909 return Res;
8912 template <typename Derived>
8913 StmtResult
8914 TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
8915 DeclarationNameInfo DirName;
8916 getDerived().getSema().StartOpenMPDSABlock(OMPD_for_simd, DirName, nullptr,
8917 D->getBeginLoc());
8918 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8919 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8920 return Res;
8923 template <typename Derived>
8924 StmtResult
8925 TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
8926 DeclarationNameInfo DirName;
8927 getDerived().getSema().StartOpenMPDSABlock(OMPD_sections, DirName, nullptr,
8928 D->getBeginLoc());
8929 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8930 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8931 return Res;
8934 template <typename Derived>
8935 StmtResult
8936 TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
8937 DeclarationNameInfo DirName;
8938 getDerived().getSema().StartOpenMPDSABlock(OMPD_section, DirName, nullptr,
8939 D->getBeginLoc());
8940 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8941 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8942 return Res;
8945 template <typename Derived>
8946 StmtResult
8947 TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
8948 DeclarationNameInfo DirName;
8949 getDerived().getSema().StartOpenMPDSABlock(OMPD_scope, DirName, nullptr,
8950 D->getBeginLoc());
8951 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8952 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8953 return Res;
8956 template <typename Derived>
8957 StmtResult
8958 TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
8959 DeclarationNameInfo DirName;
8960 getDerived().getSema().StartOpenMPDSABlock(OMPD_single, DirName, nullptr,
8961 D->getBeginLoc());
8962 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8963 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8964 return Res;
8967 template <typename Derived>
8968 StmtResult
8969 TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
8970 DeclarationNameInfo DirName;
8971 getDerived().getSema().StartOpenMPDSABlock(OMPD_master, DirName, nullptr,
8972 D->getBeginLoc());
8973 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8974 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8975 return Res;
8978 template <typename Derived>
8979 StmtResult
8980 TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
8981 getDerived().getSema().StartOpenMPDSABlock(
8982 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
8983 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8984 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8985 return Res;
8988 template <typename Derived>
8989 StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
8990 OMPParallelForDirective *D) {
8991 DeclarationNameInfo DirName;
8992 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for, DirName,
8993 nullptr, D->getBeginLoc());
8994 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8995 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8996 return Res;
8999 template <typename Derived>
9000 StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9001 OMPParallelForSimdDirective *D) {
9002 DeclarationNameInfo DirName;
9003 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for_simd, DirName,
9004 nullptr, D->getBeginLoc());
9005 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9006 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9007 return Res;
9010 template <typename Derived>
9011 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9012 OMPParallelMasterDirective *D) {
9013 DeclarationNameInfo DirName;
9014 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_master, DirName,
9015 nullptr, D->getBeginLoc());
9016 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9017 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9018 return Res;
9021 template <typename Derived>
9022 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9023 OMPParallelMaskedDirective *D) {
9024 DeclarationNameInfo DirName;
9025 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_masked, DirName,
9026 nullptr, D->getBeginLoc());
9027 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9028 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9029 return Res;
9032 template <typename Derived>
9033 StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9034 OMPParallelSectionsDirective *D) {
9035 DeclarationNameInfo DirName;
9036 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_sections, DirName,
9037 nullptr, D->getBeginLoc());
9038 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9039 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9040 return Res;
9043 template <typename Derived>
9044 StmtResult
9045 TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9046 DeclarationNameInfo DirName;
9047 getDerived().getSema().StartOpenMPDSABlock(OMPD_task, DirName, nullptr,
9048 D->getBeginLoc());
9049 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9050 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9051 return Res;
9054 template <typename Derived>
9055 StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9056 OMPTaskyieldDirective *D) {
9057 DeclarationNameInfo DirName;
9058 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskyield, DirName, nullptr,
9059 D->getBeginLoc());
9060 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9061 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9062 return Res;
9065 template <typename Derived>
9066 StmtResult
9067 TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9068 DeclarationNameInfo DirName;
9069 getDerived().getSema().StartOpenMPDSABlock(OMPD_barrier, DirName, nullptr,
9070 D->getBeginLoc());
9071 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9072 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9073 return Res;
9076 template <typename Derived>
9077 StmtResult
9078 TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9079 DeclarationNameInfo DirName;
9080 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskwait, DirName, nullptr,
9081 D->getBeginLoc());
9082 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9083 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9084 return Res;
9087 template <typename Derived>
9088 StmtResult
9089 TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9090 DeclarationNameInfo DirName;
9091 getDerived().getSema().StartOpenMPDSABlock(OMPD_error, DirName, nullptr,
9092 D->getBeginLoc());
9093 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9094 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9095 return Res;
9098 template <typename Derived>
9099 StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9100 OMPTaskgroupDirective *D) {
9101 DeclarationNameInfo DirName;
9102 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskgroup, DirName, nullptr,
9103 D->getBeginLoc());
9104 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9105 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9106 return Res;
9109 template <typename Derived>
9110 StmtResult
9111 TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9112 DeclarationNameInfo DirName;
9113 getDerived().getSema().StartOpenMPDSABlock(OMPD_flush, DirName, nullptr,
9114 D->getBeginLoc());
9115 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9116 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9117 return Res;
9120 template <typename Derived>
9121 StmtResult
9122 TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9123 DeclarationNameInfo DirName;
9124 getDerived().getSema().StartOpenMPDSABlock(OMPD_depobj, DirName, nullptr,
9125 D->getBeginLoc());
9126 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9127 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9128 return Res;
9131 template <typename Derived>
9132 StmtResult
9133 TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9134 DeclarationNameInfo DirName;
9135 getDerived().getSema().StartOpenMPDSABlock(OMPD_scan, DirName, nullptr,
9136 D->getBeginLoc());
9137 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9138 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9139 return Res;
9142 template <typename Derived>
9143 StmtResult
9144 TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9145 DeclarationNameInfo DirName;
9146 getDerived().getSema().StartOpenMPDSABlock(OMPD_ordered, DirName, nullptr,
9147 D->getBeginLoc());
9148 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9149 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9150 return Res;
9153 template <typename Derived>
9154 StmtResult
9155 TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9156 DeclarationNameInfo DirName;
9157 getDerived().getSema().StartOpenMPDSABlock(OMPD_atomic, DirName, nullptr,
9158 D->getBeginLoc());
9159 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9160 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9161 return Res;
9164 template <typename Derived>
9165 StmtResult
9166 TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9167 DeclarationNameInfo DirName;
9168 getDerived().getSema().StartOpenMPDSABlock(OMPD_target, DirName, nullptr,
9169 D->getBeginLoc());
9170 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9171 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9172 return Res;
9175 template <typename Derived>
9176 StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9177 OMPTargetDataDirective *D) {
9178 DeclarationNameInfo DirName;
9179 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_data, DirName, nullptr,
9180 D->getBeginLoc());
9181 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9182 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9183 return Res;
9186 template <typename Derived>
9187 StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9188 OMPTargetEnterDataDirective *D) {
9189 DeclarationNameInfo DirName;
9190 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_enter_data, DirName,
9191 nullptr, D->getBeginLoc());
9192 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9193 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9194 return Res;
9197 template <typename Derived>
9198 StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9199 OMPTargetExitDataDirective *D) {
9200 DeclarationNameInfo DirName;
9201 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_exit_data, DirName,
9202 nullptr, D->getBeginLoc());
9203 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9204 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9205 return Res;
9208 template <typename Derived>
9209 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
9210 OMPTargetParallelDirective *D) {
9211 DeclarationNameInfo DirName;
9212 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel, DirName,
9213 nullptr, D->getBeginLoc());
9214 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9215 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9216 return Res;
9219 template <typename Derived>
9220 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
9221 OMPTargetParallelForDirective *D) {
9222 DeclarationNameInfo DirName;
9223 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_for, DirName,
9224 nullptr, D->getBeginLoc());
9225 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9226 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9227 return Res;
9230 template <typename Derived>
9231 StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
9232 OMPTargetUpdateDirective *D) {
9233 DeclarationNameInfo DirName;
9234 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_update, DirName,
9235 nullptr, D->getBeginLoc());
9236 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9237 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9238 return Res;
9241 template <typename Derived>
9242 StmtResult
9243 TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
9244 DeclarationNameInfo DirName;
9245 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams, DirName, nullptr,
9246 D->getBeginLoc());
9247 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9248 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9249 return Res;
9252 template <typename Derived>
9253 StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
9254 OMPCancellationPointDirective *D) {
9255 DeclarationNameInfo DirName;
9256 getDerived().getSema().StartOpenMPDSABlock(OMPD_cancellation_point, DirName,
9257 nullptr, D->getBeginLoc());
9258 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9259 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9260 return Res;
9263 template <typename Derived>
9264 StmtResult
9265 TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
9266 DeclarationNameInfo DirName;
9267 getDerived().getSema().StartOpenMPDSABlock(OMPD_cancel, DirName, nullptr,
9268 D->getBeginLoc());
9269 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9270 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9271 return Res;
9274 template <typename Derived>
9275 StmtResult
9276 TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
9277 DeclarationNameInfo DirName;
9278 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop, DirName, nullptr,
9279 D->getBeginLoc());
9280 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9281 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9282 return Res;
9285 template <typename Derived>
9286 StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
9287 OMPTaskLoopSimdDirective *D) {
9288 DeclarationNameInfo DirName;
9289 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop_simd, DirName,
9290 nullptr, D->getBeginLoc());
9291 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9292 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9293 return Res;
9296 template <typename Derived>
9297 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
9298 OMPMasterTaskLoopDirective *D) {
9299 DeclarationNameInfo DirName;
9300 getDerived().getSema().StartOpenMPDSABlock(OMPD_master_taskloop, DirName,
9301 nullptr, D->getBeginLoc());
9302 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9303 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9304 return Res;
9307 template <typename Derived>
9308 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
9309 OMPMaskedTaskLoopDirective *D) {
9310 DeclarationNameInfo DirName;
9311 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked_taskloop, DirName,
9312 nullptr, D->getBeginLoc());
9313 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9314 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9315 return Res;
9318 template <typename Derived>
9319 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
9320 OMPMasterTaskLoopSimdDirective *D) {
9321 DeclarationNameInfo DirName;
9322 getDerived().getSema().StartOpenMPDSABlock(OMPD_master_taskloop_simd, DirName,
9323 nullptr, D->getBeginLoc());
9324 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9325 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9326 return Res;
9329 template <typename Derived>
9330 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
9331 OMPMaskedTaskLoopSimdDirective *D) {
9332 DeclarationNameInfo DirName;
9333 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked_taskloop_simd, DirName,
9334 nullptr, D->getBeginLoc());
9335 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9336 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9337 return Res;
9340 template <typename Derived>
9341 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
9342 OMPParallelMasterTaskLoopDirective *D) {
9343 DeclarationNameInfo DirName;
9344 getDerived().getSema().StartOpenMPDSABlock(
9345 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
9346 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9347 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9348 return Res;
9351 template <typename Derived>
9352 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
9353 OMPParallelMaskedTaskLoopDirective *D) {
9354 DeclarationNameInfo DirName;
9355 getDerived().getSema().StartOpenMPDSABlock(
9356 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9357 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9358 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9359 return Res;
9362 template <typename Derived>
9363 StmtResult
9364 TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
9365 OMPParallelMasterTaskLoopSimdDirective *D) {
9366 DeclarationNameInfo DirName;
9367 getDerived().getSema().StartOpenMPDSABlock(
9368 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9369 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9370 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9371 return Res;
9374 template <typename Derived>
9375 StmtResult
9376 TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
9377 OMPParallelMaskedTaskLoopSimdDirective *D) {
9378 DeclarationNameInfo DirName;
9379 getDerived().getSema().StartOpenMPDSABlock(
9380 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9381 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9382 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9383 return Res;
9386 template <typename Derived>
9387 StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
9388 OMPDistributeDirective *D) {
9389 DeclarationNameInfo DirName;
9390 getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute, DirName, nullptr,
9391 D->getBeginLoc());
9392 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9393 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9394 return Res;
9397 template <typename Derived>
9398 StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
9399 OMPDistributeParallelForDirective *D) {
9400 DeclarationNameInfo DirName;
9401 getDerived().getSema().StartOpenMPDSABlock(
9402 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9403 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9404 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9405 return Res;
9408 template <typename Derived>
9409 StmtResult
9410 TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
9411 OMPDistributeParallelForSimdDirective *D) {
9412 DeclarationNameInfo DirName;
9413 getDerived().getSema().StartOpenMPDSABlock(
9414 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9415 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9416 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9417 return Res;
9420 template <typename Derived>
9421 StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
9422 OMPDistributeSimdDirective *D) {
9423 DeclarationNameInfo DirName;
9424 getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute_simd, DirName,
9425 nullptr, D->getBeginLoc());
9426 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9427 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9428 return Res;
9431 template <typename Derived>
9432 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
9433 OMPTargetParallelForSimdDirective *D) {
9434 DeclarationNameInfo DirName;
9435 getDerived().getSema().StartOpenMPDSABlock(
9436 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9437 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9438 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9439 return Res;
9442 template <typename Derived>
9443 StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
9444 OMPTargetSimdDirective *D) {
9445 DeclarationNameInfo DirName;
9446 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_simd, DirName, nullptr,
9447 D->getBeginLoc());
9448 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9449 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9450 return Res;
9453 template <typename Derived>
9454 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
9455 OMPTeamsDistributeDirective *D) {
9456 DeclarationNameInfo DirName;
9457 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams_distribute, DirName,
9458 nullptr, D->getBeginLoc());
9459 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9460 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9461 return Res;
9464 template <typename Derived>
9465 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
9466 OMPTeamsDistributeSimdDirective *D) {
9467 DeclarationNameInfo DirName;
9468 getDerived().getSema().StartOpenMPDSABlock(
9469 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9470 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9471 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9472 return Res;
9475 template <typename Derived>
9476 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
9477 OMPTeamsDistributeParallelForSimdDirective *D) {
9478 DeclarationNameInfo DirName;
9479 getDerived().getSema().StartOpenMPDSABlock(
9480 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
9481 D->getBeginLoc());
9482 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9483 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9484 return Res;
9487 template <typename Derived>
9488 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
9489 OMPTeamsDistributeParallelForDirective *D) {
9490 DeclarationNameInfo DirName;
9491 getDerived().getSema().StartOpenMPDSABlock(
9492 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9493 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9494 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9495 return Res;
9498 template <typename Derived>
9499 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
9500 OMPTargetTeamsDirective *D) {
9501 DeclarationNameInfo DirName;
9502 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams, DirName,
9503 nullptr, D->getBeginLoc());
9504 auto Res = getDerived().TransformOMPExecutableDirective(D);
9505 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9506 return Res;
9509 template <typename Derived>
9510 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
9511 OMPTargetTeamsDistributeDirective *D) {
9512 DeclarationNameInfo DirName;
9513 getDerived().getSema().StartOpenMPDSABlock(
9514 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
9515 auto Res = getDerived().TransformOMPExecutableDirective(D);
9516 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9517 return Res;
9520 template <typename Derived>
9521 StmtResult
9522 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
9523 OMPTargetTeamsDistributeParallelForDirective *D) {
9524 DeclarationNameInfo DirName;
9525 getDerived().getSema().StartOpenMPDSABlock(
9526 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
9527 D->getBeginLoc());
9528 auto Res = getDerived().TransformOMPExecutableDirective(D);
9529 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9530 return Res;
9533 template <typename Derived>
9534 StmtResult TreeTransform<Derived>::
9535 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
9536 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
9537 DeclarationNameInfo DirName;
9538 getDerived().getSema().StartOpenMPDSABlock(
9539 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
9540 D->getBeginLoc());
9541 auto Res = getDerived().TransformOMPExecutableDirective(D);
9542 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9543 return Res;
9546 template <typename Derived>
9547 StmtResult
9548 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
9549 OMPTargetTeamsDistributeSimdDirective *D) {
9550 DeclarationNameInfo DirName;
9551 getDerived().getSema().StartOpenMPDSABlock(
9552 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9553 auto Res = getDerived().TransformOMPExecutableDirective(D);
9554 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9555 return Res;
9558 template <typename Derived>
9559 StmtResult
9560 TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
9561 DeclarationNameInfo DirName;
9562 getDerived().getSema().StartOpenMPDSABlock(OMPD_interop, DirName, nullptr,
9563 D->getBeginLoc());
9564 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9565 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9566 return Res;
9569 template <typename Derived>
9570 StmtResult
9571 TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
9572 DeclarationNameInfo DirName;
9573 getDerived().getSema().StartOpenMPDSABlock(OMPD_dispatch, DirName, nullptr,
9574 D->getBeginLoc());
9575 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9576 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9577 return Res;
9580 template <typename Derived>
9581 StmtResult
9582 TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
9583 DeclarationNameInfo DirName;
9584 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked, DirName, nullptr,
9585 D->getBeginLoc());
9586 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9587 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9588 return Res;
9591 template <typename Derived>
9592 StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
9593 OMPGenericLoopDirective *D) {
9594 DeclarationNameInfo DirName;
9595 getDerived().getSema().StartOpenMPDSABlock(OMPD_loop, DirName, nullptr,
9596 D->getBeginLoc());
9597 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9598 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9599 return Res;
9602 template <typename Derived>
9603 StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
9604 OMPTeamsGenericLoopDirective *D) {
9605 DeclarationNameInfo DirName;
9606 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams_loop, DirName, nullptr,
9607 D->getBeginLoc());
9608 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9609 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9610 return Res;
9613 template <typename Derived>
9614 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
9615 OMPTargetTeamsGenericLoopDirective *D) {
9616 DeclarationNameInfo DirName;
9617 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams_loop, DirName,
9618 nullptr, D->getBeginLoc());
9619 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9620 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9621 return Res;
9624 template <typename Derived>
9625 StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
9626 OMPParallelGenericLoopDirective *D) {
9627 DeclarationNameInfo DirName;
9628 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_loop, DirName,
9629 nullptr, D->getBeginLoc());
9630 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9631 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9632 return Res;
9635 template <typename Derived>
9636 StmtResult
9637 TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
9638 OMPTargetParallelGenericLoopDirective *D) {
9639 DeclarationNameInfo DirName;
9640 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_loop, DirName,
9641 nullptr, D->getBeginLoc());
9642 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9643 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9644 return Res;
9647 //===----------------------------------------------------------------------===//
9648 // OpenMP clause transformation
9649 //===----------------------------------------------------------------------===//
9650 template <typename Derived>
9651 OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
9652 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9653 if (Cond.isInvalid())
9654 return nullptr;
9655 return getDerived().RebuildOMPIfClause(
9656 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
9657 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
9660 template <typename Derived>
9661 OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
9662 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9663 if (Cond.isInvalid())
9664 return nullptr;
9665 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
9666 C->getLParenLoc(), C->getEndLoc());
9669 template <typename Derived>
9670 OMPClause *
9671 TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
9672 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
9673 if (NumThreads.isInvalid())
9674 return nullptr;
9675 return getDerived().RebuildOMPNumThreadsClause(
9676 NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9679 template <typename Derived>
9680 OMPClause *
9681 TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
9682 ExprResult E = getDerived().TransformExpr(C->getSafelen());
9683 if (E.isInvalid())
9684 return nullptr;
9685 return getDerived().RebuildOMPSafelenClause(
9686 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9689 template <typename Derived>
9690 OMPClause *
9691 TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
9692 ExprResult E = getDerived().TransformExpr(C->getAllocator());
9693 if (E.isInvalid())
9694 return nullptr;
9695 return getDerived().RebuildOMPAllocatorClause(
9696 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9699 template <typename Derived>
9700 OMPClause *
9701 TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
9702 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
9703 if (E.isInvalid())
9704 return nullptr;
9705 return getDerived().RebuildOMPSimdlenClause(
9706 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9709 template <typename Derived>
9710 OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
9711 SmallVector<Expr *, 4> TransformedSizes;
9712 TransformedSizes.reserve(C->getNumSizes());
9713 bool Changed = false;
9714 for (Expr *E : C->getSizesRefs()) {
9715 if (!E) {
9716 TransformedSizes.push_back(nullptr);
9717 continue;
9720 ExprResult T = getDerived().TransformExpr(E);
9721 if (T.isInvalid())
9722 return nullptr;
9723 if (E != T.get())
9724 Changed = true;
9725 TransformedSizes.push_back(T.get());
9728 if (!Changed && !getDerived().AlwaysRebuild())
9729 return C;
9730 return RebuildOMPSizesClause(TransformedSizes, C->getBeginLoc(),
9731 C->getLParenLoc(), C->getEndLoc());
9734 template <typename Derived>
9735 OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
9736 if (!getDerived().AlwaysRebuild())
9737 return C;
9738 return RebuildOMPFullClause(C->getBeginLoc(), C->getEndLoc());
9741 template <typename Derived>
9742 OMPClause *
9743 TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
9744 ExprResult T = getDerived().TransformExpr(C->getFactor());
9745 if (T.isInvalid())
9746 return nullptr;
9747 Expr *Factor = T.get();
9748 bool Changed = Factor != C->getFactor();
9750 if (!Changed && !getDerived().AlwaysRebuild())
9751 return C;
9752 return RebuildOMPPartialClause(Factor, C->getBeginLoc(), C->getLParenLoc(),
9753 C->getEndLoc());
9756 template <typename Derived>
9757 OMPClause *
9758 TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
9759 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
9760 if (E.isInvalid())
9761 return nullptr;
9762 return getDerived().RebuildOMPCollapseClause(
9763 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9766 template <typename Derived>
9767 OMPClause *
9768 TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
9769 return getDerived().RebuildOMPDefaultClause(
9770 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
9771 C->getLParenLoc(), C->getEndLoc());
9774 template <typename Derived>
9775 OMPClause *
9776 TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
9777 return getDerived().RebuildOMPProcBindClause(
9778 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
9779 C->getLParenLoc(), C->getEndLoc());
9782 template <typename Derived>
9783 OMPClause *
9784 TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
9785 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
9786 if (E.isInvalid())
9787 return nullptr;
9788 return getDerived().RebuildOMPScheduleClause(
9789 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
9790 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
9791 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
9792 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
9795 template <typename Derived>
9796 OMPClause *
9797 TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
9798 ExprResult E;
9799 if (auto *Num = C->getNumForLoops()) {
9800 E = getDerived().TransformExpr(Num);
9801 if (E.isInvalid())
9802 return nullptr;
9804 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
9805 C->getLParenLoc(), E.get());
9808 template <typename Derived>
9809 OMPClause *
9810 TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
9811 ExprResult E;
9812 if (Expr *Evt = C->getEventHandler()) {
9813 E = getDerived().TransformExpr(Evt);
9814 if (E.isInvalid())
9815 return nullptr;
9817 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
9818 C->getLParenLoc(), C->getEndLoc());
9821 template <typename Derived>
9822 OMPClause *
9823 TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
9824 // No need to rebuild this clause, no template-dependent parameters.
9825 return C;
9828 template <typename Derived>
9829 OMPClause *
9830 TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
9831 // No need to rebuild this clause, no template-dependent parameters.
9832 return C;
9835 template <typename Derived>
9836 OMPClause *
9837 TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
9838 // No need to rebuild this clause, no template-dependent parameters.
9839 return C;
9842 template <typename Derived>
9843 OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
9844 // No need to rebuild this clause, no template-dependent parameters.
9845 return C;
9848 template <typename Derived>
9849 OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
9850 // No need to rebuild this clause, no template-dependent parameters.
9851 return C;
9854 template <typename Derived>
9855 OMPClause *
9856 TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
9857 // No need to rebuild this clause, no template-dependent parameters.
9858 return C;
9861 template <typename Derived>
9862 OMPClause *
9863 TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
9864 // No need to rebuild this clause, no template-dependent parameters.
9865 return C;
9868 template <typename Derived>
9869 OMPClause *
9870 TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
9871 // No need to rebuild this clause, no template-dependent parameters.
9872 return C;
9875 template <typename Derived>
9876 OMPClause *
9877 TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
9878 // No need to rebuild this clause, no template-dependent parameters.
9879 return C;
9882 template <typename Derived>
9883 OMPClause *
9884 TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
9885 // No need to rebuild this clause, no template-dependent parameters.
9886 return C;
9889 template <typename Derived>
9890 OMPClause *
9891 TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
9892 // No need to rebuild this clause, no template-dependent parameters.
9893 return C;
9896 template <typename Derived>
9897 OMPClause *
9898 TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
9899 // No need to rebuild this clause, no template-dependent parameters.
9900 return C;
9903 template <typename Derived>
9904 OMPClause *
9905 TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
9906 // No need to rebuild this clause, no template-dependent parameters.
9907 return C;
9910 template <typename Derived>
9911 OMPClause *
9912 TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
9913 // No need to rebuild this clause, no template-dependent parameters.
9914 return C;
9917 template <typename Derived>
9918 OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
9919 // No need to rebuild this clause, no template-dependent parameters.
9920 return C;
9923 template <typename Derived>
9924 OMPClause *
9925 TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
9926 // No need to rebuild this clause, no template-dependent parameters.
9927 return C;
9930 template <typename Derived>
9931 OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
9932 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
9933 if (IVR.isInvalid())
9934 return nullptr;
9936 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
9937 InteropInfo.PreferTypes.reserve(C->varlist_size() - 1);
9938 for (Expr *E : llvm::drop_begin(C->varlists())) {
9939 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
9940 if (ER.isInvalid())
9941 return nullptr;
9942 InteropInfo.PreferTypes.push_back(ER.get());
9944 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
9945 C->getBeginLoc(), C->getLParenLoc(),
9946 C->getVarLoc(), C->getEndLoc());
9949 template <typename Derived>
9950 OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
9951 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
9952 if (ER.isInvalid())
9953 return nullptr;
9954 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
9955 C->getLParenLoc(), C->getVarLoc(),
9956 C->getEndLoc());
9959 template <typename Derived>
9960 OMPClause *
9961 TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
9962 ExprResult ER;
9963 if (Expr *IV = C->getInteropVar()) {
9964 ER = getDerived().TransformExpr(IV);
9965 if (ER.isInvalid())
9966 return nullptr;
9968 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
9969 C->getLParenLoc(), C->getVarLoc(),
9970 C->getEndLoc());
9973 template <typename Derived>
9974 OMPClause *
9975 TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
9976 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9977 if (Cond.isInvalid())
9978 return nullptr;
9979 return getDerived().RebuildOMPNovariantsClause(
9980 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9983 template <typename Derived>
9984 OMPClause *
9985 TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
9986 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9987 if (Cond.isInvalid())
9988 return nullptr;
9989 return getDerived().RebuildOMPNocontextClause(
9990 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9993 template <typename Derived>
9994 OMPClause *
9995 TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
9996 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
9997 if (ThreadID.isInvalid())
9998 return nullptr;
9999 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10000 C->getLParenLoc(), C->getEndLoc());
10003 template <typename Derived>
10004 OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10005 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10006 if (E.isInvalid())
10007 return nullptr;
10008 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10009 C->getLParenLoc(), C->getEndLoc());
10012 template <typename Derived>
10013 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10014 OMPUnifiedAddressClause *C) {
10015 llvm_unreachable("unified_address clause cannot appear in dependent context");
10018 template <typename Derived>
10019 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10020 OMPUnifiedSharedMemoryClause *C) {
10021 llvm_unreachable(
10022 "unified_shared_memory clause cannot appear in dependent context");
10025 template <typename Derived>
10026 OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10027 OMPReverseOffloadClause *C) {
10028 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10031 template <typename Derived>
10032 OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10033 OMPDynamicAllocatorsClause *C) {
10034 llvm_unreachable(
10035 "dynamic_allocators clause cannot appear in dependent context");
10038 template <typename Derived>
10039 OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10040 OMPAtomicDefaultMemOrderClause *C) {
10041 llvm_unreachable(
10042 "atomic_default_mem_order clause cannot appear in dependent context");
10045 template <typename Derived>
10046 OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10047 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10048 C->getBeginLoc(), C->getLParenLoc(),
10049 C->getEndLoc());
10052 template <typename Derived>
10053 OMPClause *
10054 TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10055 return getDerived().RebuildOMPSeverityClause(
10056 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10057 C->getLParenLoc(), C->getEndLoc());
10060 template <typename Derived>
10061 OMPClause *
10062 TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10063 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10064 if (E.isInvalid())
10065 return nullptr;
10066 return getDerived().RebuildOMPMessageClause(
10067 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10068 C->getEndLoc());
10071 template <typename Derived>
10072 OMPClause *
10073 TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10074 llvm::SmallVector<Expr *, 16> Vars;
10075 Vars.reserve(C->varlist_size());
10076 for (auto *VE : C->varlists()) {
10077 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10078 if (EVar.isInvalid())
10079 return nullptr;
10080 Vars.push_back(EVar.get());
10082 return getDerived().RebuildOMPPrivateClause(
10083 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10086 template <typename Derived>
10087 OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10088 OMPFirstprivateClause *C) {
10089 llvm::SmallVector<Expr *, 16> Vars;
10090 Vars.reserve(C->varlist_size());
10091 for (auto *VE : C->varlists()) {
10092 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10093 if (EVar.isInvalid())
10094 return nullptr;
10095 Vars.push_back(EVar.get());
10097 return getDerived().RebuildOMPFirstprivateClause(
10098 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10101 template <typename Derived>
10102 OMPClause *
10103 TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10104 llvm::SmallVector<Expr *, 16> Vars;
10105 Vars.reserve(C->varlist_size());
10106 for (auto *VE : C->varlists()) {
10107 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10108 if (EVar.isInvalid())
10109 return nullptr;
10110 Vars.push_back(EVar.get());
10112 return getDerived().RebuildOMPLastprivateClause(
10113 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10114 C->getLParenLoc(), C->getEndLoc());
10117 template <typename Derived>
10118 OMPClause *
10119 TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
10120 llvm::SmallVector<Expr *, 16> Vars;
10121 Vars.reserve(C->varlist_size());
10122 for (auto *VE : C->varlists()) {
10123 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10124 if (EVar.isInvalid())
10125 return nullptr;
10126 Vars.push_back(EVar.get());
10128 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
10129 C->getLParenLoc(), C->getEndLoc());
10132 template <typename Derived>
10133 OMPClause *
10134 TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
10135 llvm::SmallVector<Expr *, 16> Vars;
10136 Vars.reserve(C->varlist_size());
10137 for (auto *VE : C->varlists()) {
10138 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10139 if (EVar.isInvalid())
10140 return nullptr;
10141 Vars.push_back(EVar.get());
10143 CXXScopeSpec ReductionIdScopeSpec;
10144 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10146 DeclarationNameInfo NameInfo = C->getNameInfo();
10147 if (NameInfo.getName()) {
10148 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10149 if (!NameInfo.getName())
10150 return nullptr;
10152 // Build a list of all UDR decls with the same names ranged by the Scopes.
10153 // The Scope boundary is a duplication of the previous decl.
10154 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10155 for (auto *E : C->reduction_ops()) {
10156 // Transform all the decls.
10157 if (E) {
10158 auto *ULE = cast<UnresolvedLookupExpr>(E);
10159 UnresolvedSet<8> Decls;
10160 for (auto *D : ULE->decls()) {
10161 NamedDecl *InstD =
10162 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10163 Decls.addDecl(InstD, InstD->getAccess());
10165 UnresolvedReductions.push_back(
10166 UnresolvedLookupExpr::Create(
10167 SemaRef.Context, /*NamingClass=*/nullptr,
10168 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context),
10169 NameInfo, /*ADL=*/true, ULE->isOverloaded(),
10170 Decls.begin(), Decls.end()));
10171 } else
10172 UnresolvedReductions.push_back(nullptr);
10174 return getDerived().RebuildOMPReductionClause(
10175 Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(),
10176 C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
10177 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10180 template <typename Derived>
10181 OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
10182 OMPTaskReductionClause *C) {
10183 llvm::SmallVector<Expr *, 16> Vars;
10184 Vars.reserve(C->varlist_size());
10185 for (auto *VE : C->varlists()) {
10186 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10187 if (EVar.isInvalid())
10188 return nullptr;
10189 Vars.push_back(EVar.get());
10191 CXXScopeSpec ReductionIdScopeSpec;
10192 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10194 DeclarationNameInfo NameInfo = C->getNameInfo();
10195 if (NameInfo.getName()) {
10196 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10197 if (!NameInfo.getName())
10198 return nullptr;
10200 // Build a list of all UDR decls with the same names ranged by the Scopes.
10201 // The Scope boundary is a duplication of the previous decl.
10202 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10203 for (auto *E : C->reduction_ops()) {
10204 // Transform all the decls.
10205 if (E) {
10206 auto *ULE = cast<UnresolvedLookupExpr>(E);
10207 UnresolvedSet<8> Decls;
10208 for (auto *D : ULE->decls()) {
10209 NamedDecl *InstD =
10210 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10211 Decls.addDecl(InstD, InstD->getAccess());
10213 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10214 SemaRef.Context, /*NamingClass=*/nullptr,
10215 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10216 /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end()));
10217 } else
10218 UnresolvedReductions.push_back(nullptr);
10220 return getDerived().RebuildOMPTaskReductionClause(
10221 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10222 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10225 template <typename Derived>
10226 OMPClause *
10227 TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
10228 llvm::SmallVector<Expr *, 16> Vars;
10229 Vars.reserve(C->varlist_size());
10230 for (auto *VE : C->varlists()) {
10231 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10232 if (EVar.isInvalid())
10233 return nullptr;
10234 Vars.push_back(EVar.get());
10236 CXXScopeSpec ReductionIdScopeSpec;
10237 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10239 DeclarationNameInfo NameInfo = C->getNameInfo();
10240 if (NameInfo.getName()) {
10241 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10242 if (!NameInfo.getName())
10243 return nullptr;
10245 // Build a list of all UDR decls with the same names ranged by the Scopes.
10246 // The Scope boundary is a duplication of the previous decl.
10247 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10248 for (auto *E : C->reduction_ops()) {
10249 // Transform all the decls.
10250 if (E) {
10251 auto *ULE = cast<UnresolvedLookupExpr>(E);
10252 UnresolvedSet<8> Decls;
10253 for (auto *D : ULE->decls()) {
10254 NamedDecl *InstD =
10255 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10256 Decls.addDecl(InstD, InstD->getAccess());
10258 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10259 SemaRef.Context, /*NamingClass=*/nullptr,
10260 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10261 /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end()));
10262 } else
10263 UnresolvedReductions.push_back(nullptr);
10265 return getDerived().RebuildOMPInReductionClause(
10266 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10267 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10270 template <typename Derived>
10271 OMPClause *
10272 TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
10273 llvm::SmallVector<Expr *, 16> Vars;
10274 Vars.reserve(C->varlist_size());
10275 for (auto *VE : C->varlists()) {
10276 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10277 if (EVar.isInvalid())
10278 return nullptr;
10279 Vars.push_back(EVar.get());
10281 ExprResult Step = getDerived().TransformExpr(C->getStep());
10282 if (Step.isInvalid())
10283 return nullptr;
10284 return getDerived().RebuildOMPLinearClause(
10285 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
10286 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
10287 C->getEndLoc());
10290 template <typename Derived>
10291 OMPClause *
10292 TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
10293 llvm::SmallVector<Expr *, 16> Vars;
10294 Vars.reserve(C->varlist_size());
10295 for (auto *VE : C->varlists()) {
10296 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10297 if (EVar.isInvalid())
10298 return nullptr;
10299 Vars.push_back(EVar.get());
10301 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
10302 if (Alignment.isInvalid())
10303 return nullptr;
10304 return getDerived().RebuildOMPAlignedClause(
10305 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
10306 C->getColonLoc(), C->getEndLoc());
10309 template <typename Derived>
10310 OMPClause *
10311 TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
10312 llvm::SmallVector<Expr *, 16> Vars;
10313 Vars.reserve(C->varlist_size());
10314 for (auto *VE : C->varlists()) {
10315 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10316 if (EVar.isInvalid())
10317 return nullptr;
10318 Vars.push_back(EVar.get());
10320 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
10321 C->getLParenLoc(), C->getEndLoc());
10324 template <typename Derived>
10325 OMPClause *
10326 TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
10327 llvm::SmallVector<Expr *, 16> Vars;
10328 Vars.reserve(C->varlist_size());
10329 for (auto *VE : C->varlists()) {
10330 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10331 if (EVar.isInvalid())
10332 return nullptr;
10333 Vars.push_back(EVar.get());
10335 return getDerived().RebuildOMPCopyprivateClause(
10336 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10339 template <typename Derived>
10340 OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
10341 llvm::SmallVector<Expr *, 16> Vars;
10342 Vars.reserve(C->varlist_size());
10343 for (auto *VE : C->varlists()) {
10344 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10345 if (EVar.isInvalid())
10346 return nullptr;
10347 Vars.push_back(EVar.get());
10349 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
10350 C->getLParenLoc(), C->getEndLoc());
10353 template <typename Derived>
10354 OMPClause *
10355 TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
10356 ExprResult E = getDerived().TransformExpr(C->getDepobj());
10357 if (E.isInvalid())
10358 return nullptr;
10359 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
10360 C->getLParenLoc(), C->getEndLoc());
10363 template <typename Derived>
10364 OMPClause *
10365 TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
10366 llvm::SmallVector<Expr *, 16> Vars;
10367 Expr *DepModifier = C->getModifier();
10368 if (DepModifier) {
10369 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
10370 if (DepModRes.isInvalid())
10371 return nullptr;
10372 DepModifier = DepModRes.get();
10374 Vars.reserve(C->varlist_size());
10375 for (auto *VE : C->varlists()) {
10376 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10377 if (EVar.isInvalid())
10378 return nullptr;
10379 Vars.push_back(EVar.get());
10381 return getDerived().RebuildOMPDependClause(
10382 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
10383 C->getOmpAllMemoryLoc()},
10384 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10387 template <typename Derived>
10388 OMPClause *
10389 TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
10390 ExprResult E = getDerived().TransformExpr(C->getDevice());
10391 if (E.isInvalid())
10392 return nullptr;
10393 return getDerived().RebuildOMPDeviceClause(
10394 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10395 C->getModifierLoc(), C->getEndLoc());
10398 template <typename Derived, class T>
10399 bool transformOMPMappableExprListClause(
10400 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
10401 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
10402 DeclarationNameInfo &MapperIdInfo,
10403 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
10404 // Transform expressions in the list.
10405 Vars.reserve(C->varlist_size());
10406 for (auto *VE : C->varlists()) {
10407 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
10408 if (EVar.isInvalid())
10409 return true;
10410 Vars.push_back(EVar.get());
10412 // Transform mapper scope specifier and identifier.
10413 NestedNameSpecifierLoc QualifierLoc;
10414 if (C->getMapperQualifierLoc()) {
10415 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
10416 C->getMapperQualifierLoc());
10417 if (!QualifierLoc)
10418 return true;
10420 MapperIdScopeSpec.Adopt(QualifierLoc);
10421 MapperIdInfo = C->getMapperIdInfo();
10422 if (MapperIdInfo.getName()) {
10423 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
10424 if (!MapperIdInfo.getName())
10425 return true;
10427 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
10428 // the previous user-defined mapper lookup in dependent environment.
10429 for (auto *E : C->mapperlists()) {
10430 // Transform all the decls.
10431 if (E) {
10432 auto *ULE = cast<UnresolvedLookupExpr>(E);
10433 UnresolvedSet<8> Decls;
10434 for (auto *D : ULE->decls()) {
10435 NamedDecl *InstD =
10436 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
10437 Decls.addDecl(InstD, InstD->getAccess());
10439 UnresolvedMappers.push_back(UnresolvedLookupExpr::Create(
10440 TT.getSema().Context, /*NamingClass=*/nullptr,
10441 MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
10442 MapperIdInfo, /*ADL=*/true, ULE->isOverloaded(), Decls.begin(),
10443 Decls.end()));
10444 } else {
10445 UnresolvedMappers.push_back(nullptr);
10448 return false;
10451 template <typename Derived>
10452 OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
10453 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10454 llvm::SmallVector<Expr *, 16> Vars;
10455 Expr *IteratorModifier = C->getIteratorModifier();
10456 if (IteratorModifier) {
10457 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
10458 if (MapModRes.isInvalid())
10459 return nullptr;
10460 IteratorModifier = MapModRes.get();
10462 CXXScopeSpec MapperIdScopeSpec;
10463 DeclarationNameInfo MapperIdInfo;
10464 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10465 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
10466 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10467 return nullptr;
10468 return getDerived().RebuildOMPMapClause(
10469 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
10470 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
10471 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10474 template <typename Derived>
10475 OMPClause *
10476 TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
10477 Expr *Allocator = C->getAllocator();
10478 if (Allocator) {
10479 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
10480 if (AllocatorRes.isInvalid())
10481 return nullptr;
10482 Allocator = AllocatorRes.get();
10484 llvm::SmallVector<Expr *, 16> Vars;
10485 Vars.reserve(C->varlist_size());
10486 for (auto *VE : C->varlists()) {
10487 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10488 if (EVar.isInvalid())
10489 return nullptr;
10490 Vars.push_back(EVar.get());
10492 return getDerived().RebuildOMPAllocateClause(
10493 Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10494 C->getEndLoc());
10497 template <typename Derived>
10498 OMPClause *
10499 TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
10500 ExprResult E = getDerived().TransformExpr(C->getNumTeams());
10501 if (E.isInvalid())
10502 return nullptr;
10503 return getDerived().RebuildOMPNumTeamsClause(
10504 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10507 template <typename Derived>
10508 OMPClause *
10509 TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
10510 ExprResult E = getDerived().TransformExpr(C->getThreadLimit());
10511 if (E.isInvalid())
10512 return nullptr;
10513 return getDerived().RebuildOMPThreadLimitClause(
10514 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10517 template <typename Derived>
10518 OMPClause *
10519 TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
10520 ExprResult E = getDerived().TransformExpr(C->getPriority());
10521 if (E.isInvalid())
10522 return nullptr;
10523 return getDerived().RebuildOMPPriorityClause(
10524 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10527 template <typename Derived>
10528 OMPClause *
10529 TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
10530 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
10531 if (E.isInvalid())
10532 return nullptr;
10533 return getDerived().RebuildOMPGrainsizeClause(
10534 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10535 C->getModifierLoc(), C->getEndLoc());
10538 template <typename Derived>
10539 OMPClause *
10540 TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
10541 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
10542 if (E.isInvalid())
10543 return nullptr;
10544 return getDerived().RebuildOMPNumTasksClause(
10545 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10546 C->getModifierLoc(), C->getEndLoc());
10549 template <typename Derived>
10550 OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
10551 ExprResult E = getDerived().TransformExpr(C->getHint());
10552 if (E.isInvalid())
10553 return nullptr;
10554 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
10555 C->getLParenLoc(), C->getEndLoc());
10558 template <typename Derived>
10559 OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
10560 OMPDistScheduleClause *C) {
10561 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10562 if (E.isInvalid())
10563 return nullptr;
10564 return getDerived().RebuildOMPDistScheduleClause(
10565 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10566 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10569 template <typename Derived>
10570 OMPClause *
10571 TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
10572 // Rebuild Defaultmap Clause since we need to invoke the checking of
10573 // defaultmap(none:variable-category) after template initialization.
10574 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
10575 C->getDefaultmapKind(),
10576 C->getBeginLoc(),
10577 C->getLParenLoc(),
10578 C->getDefaultmapModifierLoc(),
10579 C->getDefaultmapKindLoc(),
10580 C->getEndLoc());
10583 template <typename Derived>
10584 OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
10585 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10586 llvm::SmallVector<Expr *, 16> Vars;
10587 CXXScopeSpec MapperIdScopeSpec;
10588 DeclarationNameInfo MapperIdInfo;
10589 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10590 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
10591 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10592 return nullptr;
10593 return getDerived().RebuildOMPToClause(
10594 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10595 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10598 template <typename Derived>
10599 OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
10600 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10601 llvm::SmallVector<Expr *, 16> Vars;
10602 CXXScopeSpec MapperIdScopeSpec;
10603 DeclarationNameInfo MapperIdInfo;
10604 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10605 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
10606 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10607 return nullptr;
10608 return getDerived().RebuildOMPFromClause(
10609 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10610 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10613 template <typename Derived>
10614 OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
10615 OMPUseDevicePtrClause *C) {
10616 llvm::SmallVector<Expr *, 16> Vars;
10617 Vars.reserve(C->varlist_size());
10618 for (auto *VE : C->varlists()) {
10619 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10620 if (EVar.isInvalid())
10621 return nullptr;
10622 Vars.push_back(EVar.get());
10624 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10625 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
10628 template <typename Derived>
10629 OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
10630 OMPUseDeviceAddrClause *C) {
10631 llvm::SmallVector<Expr *, 16> Vars;
10632 Vars.reserve(C->varlist_size());
10633 for (auto *VE : C->varlists()) {
10634 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10635 if (EVar.isInvalid())
10636 return nullptr;
10637 Vars.push_back(EVar.get());
10639 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10640 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
10643 template <typename Derived>
10644 OMPClause *
10645 TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
10646 llvm::SmallVector<Expr *, 16> Vars;
10647 Vars.reserve(C->varlist_size());
10648 for (auto *VE : C->varlists()) {
10649 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10650 if (EVar.isInvalid())
10651 return nullptr;
10652 Vars.push_back(EVar.get());
10654 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10655 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
10658 template <typename Derived>
10659 OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
10660 OMPHasDeviceAddrClause *C) {
10661 llvm::SmallVector<Expr *, 16> Vars;
10662 Vars.reserve(C->varlist_size());
10663 for (auto *VE : C->varlists()) {
10664 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10665 if (EVar.isInvalid())
10666 return nullptr;
10667 Vars.push_back(EVar.get());
10669 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10670 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
10673 template <typename Derived>
10674 OMPClause *
10675 TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
10676 llvm::SmallVector<Expr *, 16> Vars;
10677 Vars.reserve(C->varlist_size());
10678 for (auto *VE : C->varlists()) {
10679 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10680 if (EVar.isInvalid())
10681 return nullptr;
10682 Vars.push_back(EVar.get());
10684 return getDerived().RebuildOMPNontemporalClause(
10685 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10688 template <typename Derived>
10689 OMPClause *
10690 TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
10691 llvm::SmallVector<Expr *, 16> Vars;
10692 Vars.reserve(C->varlist_size());
10693 for (auto *VE : C->varlists()) {
10694 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10695 if (EVar.isInvalid())
10696 return nullptr;
10697 Vars.push_back(EVar.get());
10699 return getDerived().RebuildOMPInclusiveClause(
10700 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10703 template <typename Derived>
10704 OMPClause *
10705 TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
10706 llvm::SmallVector<Expr *, 16> Vars;
10707 Vars.reserve(C->varlist_size());
10708 for (auto *VE : C->varlists()) {
10709 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10710 if (EVar.isInvalid())
10711 return nullptr;
10712 Vars.push_back(EVar.get());
10714 return getDerived().RebuildOMPExclusiveClause(
10715 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10718 template <typename Derived>
10719 OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
10720 OMPUsesAllocatorsClause *C) {
10721 SmallVector<Sema::UsesAllocatorsData, 16> Data;
10722 Data.reserve(C->getNumberOfAllocators());
10723 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
10724 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
10725 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
10726 if (Allocator.isInvalid())
10727 continue;
10728 ExprResult AllocatorTraits;
10729 if (Expr *AT = D.AllocatorTraits) {
10730 AllocatorTraits = getDerived().TransformExpr(AT);
10731 if (AllocatorTraits.isInvalid())
10732 continue;
10734 Sema::UsesAllocatorsData &NewD = Data.emplace_back();
10735 NewD.Allocator = Allocator.get();
10736 NewD.AllocatorTraits = AllocatorTraits.get();
10737 NewD.LParenLoc = D.LParenLoc;
10738 NewD.RParenLoc = D.RParenLoc;
10740 return getDerived().RebuildOMPUsesAllocatorsClause(
10741 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10744 template <typename Derived>
10745 OMPClause *
10746 TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
10747 SmallVector<Expr *, 4> Locators;
10748 Locators.reserve(C->varlist_size());
10749 ExprResult ModifierRes;
10750 if (Expr *Modifier = C->getModifier()) {
10751 ModifierRes = getDerived().TransformExpr(Modifier);
10752 if (ModifierRes.isInvalid())
10753 return nullptr;
10755 for (Expr *E : C->varlists()) {
10756 ExprResult Locator = getDerived().TransformExpr(E);
10757 if (Locator.isInvalid())
10758 continue;
10759 Locators.push_back(Locator.get());
10761 return getDerived().RebuildOMPAffinityClause(
10762 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
10763 ModifierRes.get(), Locators);
10766 template <typename Derived>
10767 OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
10768 return getDerived().RebuildOMPOrderClause(
10769 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
10770 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
10773 template <typename Derived>
10774 OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
10775 return getDerived().RebuildOMPBindClause(
10776 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
10777 C->getLParenLoc(), C->getEndLoc());
10780 template <typename Derived>
10781 OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
10782 OMPXDynCGroupMemClause *C) {
10783 ExprResult Size = getDerived().TransformExpr(C->getSize());
10784 if (Size.isInvalid())
10785 return nullptr;
10786 return getDerived().RebuildOMPXDynCGroupMemClause(
10787 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10790 template <typename Derived>
10791 OMPClause *
10792 TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
10793 llvm::SmallVector<Expr *, 16> Vars;
10794 Vars.reserve(C->varlist_size());
10795 for (auto *VE : C->varlists()) {
10796 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10797 if (EVar.isInvalid())
10798 return nullptr;
10799 Vars.push_back(EVar.get());
10801 return getDerived().RebuildOMPDoacrossClause(
10802 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
10803 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10806 template <typename Derived>
10807 OMPClause *
10808 TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
10809 SmallVector<const Attr *> NewAttrs;
10810 for (auto *A : C->getAttrs())
10811 NewAttrs.push_back(getDerived().TransformAttr(A));
10812 return getDerived().RebuildOMPXAttributeClause(
10813 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10816 template <typename Derived>
10817 OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
10818 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
10821 //===----------------------------------------------------------------------===//
10822 // Expression transformation
10823 //===----------------------------------------------------------------------===//
10824 template<typename Derived>
10825 ExprResult
10826 TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
10827 return TransformExpr(E->getSubExpr());
10830 template <typename Derived>
10831 ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
10832 SYCLUniqueStableNameExpr *E) {
10833 if (!E->isTypeDependent())
10834 return E;
10836 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
10838 if (!NewT)
10839 return ExprError();
10841 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
10842 return E;
10844 return getDerived().RebuildSYCLUniqueStableNameExpr(
10845 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
10848 template<typename Derived>
10849 ExprResult
10850 TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
10851 if (!E->isTypeDependent())
10852 return E;
10854 return getDerived().RebuildPredefinedExpr(E->getLocation(),
10855 E->getIdentKind());
10858 template<typename Derived>
10859 ExprResult
10860 TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
10861 NestedNameSpecifierLoc QualifierLoc;
10862 if (E->getQualifierLoc()) {
10863 QualifierLoc
10864 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
10865 if (!QualifierLoc)
10866 return ExprError();
10869 ValueDecl *ND
10870 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
10871 E->getDecl()));
10872 if (!ND)
10873 return ExprError();
10875 NamedDecl *Found = ND;
10876 if (E->getFoundDecl() != E->getDecl()) {
10877 Found = cast_or_null<NamedDecl>(
10878 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
10879 if (!Found)
10880 return ExprError();
10883 DeclarationNameInfo NameInfo = E->getNameInfo();
10884 if (NameInfo.getName()) {
10885 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10886 if (!NameInfo.getName())
10887 return ExprError();
10890 if (!getDerived().AlwaysRebuild() &&
10891 QualifierLoc == E->getQualifierLoc() &&
10892 ND == E->getDecl() &&
10893 Found == E->getFoundDecl() &&
10894 NameInfo.getName() == E->getDecl()->getDeclName() &&
10895 !E->hasExplicitTemplateArgs()) {
10897 // Mark it referenced in the new context regardless.
10898 // FIXME: this is a bit instantiation-specific.
10899 SemaRef.MarkDeclRefReferenced(E);
10901 return E;
10904 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
10905 if (E->hasExplicitTemplateArgs()) {
10906 TemplateArgs = &TransArgs;
10907 TransArgs.setLAngleLoc(E->getLAngleLoc());
10908 TransArgs.setRAngleLoc(E->getRAngleLoc());
10909 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
10910 E->getNumTemplateArgs(),
10911 TransArgs))
10912 return ExprError();
10915 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
10916 Found, TemplateArgs);
10919 template<typename Derived>
10920 ExprResult
10921 TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
10922 return E;
10925 template <typename Derived>
10926 ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
10927 FixedPointLiteral *E) {
10928 return E;
10931 template<typename Derived>
10932 ExprResult
10933 TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
10934 return E;
10937 template<typename Derived>
10938 ExprResult
10939 TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
10940 return E;
10943 template<typename Derived>
10944 ExprResult
10945 TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
10946 return E;
10949 template<typename Derived>
10950 ExprResult
10951 TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
10952 return E;
10955 template<typename Derived>
10956 ExprResult
10957 TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
10958 return getDerived().TransformCallExpr(E);
10961 template<typename Derived>
10962 ExprResult
10963 TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
10964 ExprResult ControllingExpr;
10965 TypeSourceInfo *ControllingType = nullptr;
10966 if (E->isExprPredicate())
10967 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
10968 else
10969 ControllingType = getDerived().TransformType(E->getControllingType());
10971 if (ControllingExpr.isInvalid() && !ControllingType)
10972 return ExprError();
10974 SmallVector<Expr *, 4> AssocExprs;
10975 SmallVector<TypeSourceInfo *, 4> AssocTypes;
10976 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
10977 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
10978 if (TSI) {
10979 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
10980 if (!AssocType)
10981 return ExprError();
10982 AssocTypes.push_back(AssocType);
10983 } else {
10984 AssocTypes.push_back(nullptr);
10987 ExprResult AssocExpr =
10988 getDerived().TransformExpr(Assoc.getAssociationExpr());
10989 if (AssocExpr.isInvalid())
10990 return ExprError();
10991 AssocExprs.push_back(AssocExpr.get());
10994 if (!ControllingType)
10995 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
10996 E->getDefaultLoc(),
10997 E->getRParenLoc(),
10998 ControllingExpr.get(),
10999 AssocTypes,
11000 AssocExprs);
11001 return getDerived().RebuildGenericSelectionExpr(
11002 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
11003 ControllingType, AssocTypes, AssocExprs);
11006 template<typename Derived>
11007 ExprResult
11008 TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
11009 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
11010 if (SubExpr.isInvalid())
11011 return ExprError();
11013 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11014 return E;
11016 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
11017 E->getRParen());
11020 /// The operand of a unary address-of operator has special rules: it's
11021 /// allowed to refer to a non-static member of a class even if there's no 'this'
11022 /// object available.
11023 template<typename Derived>
11024 ExprResult
11025 TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
11026 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
11027 return getDerived().TransformDependentScopeDeclRefExpr(DRE, true, nullptr);
11028 else
11029 return getDerived().TransformExpr(E);
11032 template<typename Derived>
11033 ExprResult
11034 TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
11035 ExprResult SubExpr;
11036 if (E->getOpcode() == UO_AddrOf)
11037 SubExpr = TransformAddressOfOperand(E->getSubExpr());
11038 else
11039 SubExpr = TransformExpr(E->getSubExpr());
11040 if (SubExpr.isInvalid())
11041 return ExprError();
11043 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11044 return E;
11046 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
11047 E->getOpcode(),
11048 SubExpr.get());
11051 template<typename Derived>
11052 ExprResult
11053 TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
11054 // Transform the type.
11055 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
11056 if (!Type)
11057 return ExprError();
11059 // Transform all of the components into components similar to what the
11060 // parser uses.
11061 // FIXME: It would be slightly more efficient in the non-dependent case to
11062 // just map FieldDecls, rather than requiring the rebuilder to look for
11063 // the fields again. However, __builtin_offsetof is rare enough in
11064 // template code that we don't care.
11065 bool ExprChanged = false;
11066 typedef Sema::OffsetOfComponent Component;
11067 SmallVector<Component, 4> Components;
11068 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
11069 const OffsetOfNode &ON = E->getComponent(I);
11070 Component Comp;
11071 Comp.isBrackets = true;
11072 Comp.LocStart = ON.getSourceRange().getBegin();
11073 Comp.LocEnd = ON.getSourceRange().getEnd();
11074 switch (ON.getKind()) {
11075 case OffsetOfNode::Array: {
11076 Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
11077 ExprResult Index = getDerived().TransformExpr(FromIndex);
11078 if (Index.isInvalid())
11079 return ExprError();
11081 ExprChanged = ExprChanged || Index.get() != FromIndex;
11082 Comp.isBrackets = true;
11083 Comp.U.E = Index.get();
11084 break;
11087 case OffsetOfNode::Field:
11088 case OffsetOfNode::Identifier:
11089 Comp.isBrackets = false;
11090 Comp.U.IdentInfo = ON.getFieldName();
11091 if (!Comp.U.IdentInfo)
11092 continue;
11094 break;
11096 case OffsetOfNode::Base:
11097 // Will be recomputed during the rebuild.
11098 continue;
11101 Components.push_back(Comp);
11104 // If nothing changed, retain the existing expression.
11105 if (!getDerived().AlwaysRebuild() &&
11106 Type == E->getTypeSourceInfo() &&
11107 !ExprChanged)
11108 return E;
11110 // Build a new offsetof expression.
11111 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
11112 Components, E->getRParenLoc());
11115 template<typename Derived>
11116 ExprResult
11117 TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
11118 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
11119 "opaque value expression requires transformation");
11120 return E;
11123 template<typename Derived>
11124 ExprResult
11125 TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
11126 return E;
11129 template <typename Derived>
11130 ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
11131 llvm::SmallVector<Expr *, 8> Children;
11132 bool Changed = false;
11133 for (Expr *C : E->subExpressions()) {
11134 ExprResult NewC = getDerived().TransformExpr(C);
11135 if (NewC.isInvalid())
11136 return ExprError();
11137 Children.push_back(NewC.get());
11139 Changed |= NewC.get() != C;
11141 if (!getDerived().AlwaysRebuild() && !Changed)
11142 return E;
11143 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
11144 Children, E->getType());
11147 template<typename Derived>
11148 ExprResult
11149 TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
11150 // Rebuild the syntactic form. The original syntactic form has
11151 // opaque-value expressions in it, so strip those away and rebuild
11152 // the result. This is a really awful way of doing this, but the
11153 // better solution (rebuilding the semantic expressions and
11154 // rebinding OVEs as necessary) doesn't work; we'd need
11155 // TreeTransform to not strip away implicit conversions.
11156 Expr *newSyntacticForm = SemaRef.recreateSyntacticForm(E);
11157 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
11158 if (result.isInvalid()) return ExprError();
11160 // If that gives us a pseudo-object result back, the pseudo-object
11161 // expression must have been an lvalue-to-rvalue conversion which we
11162 // should reapply.
11163 if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
11164 result = SemaRef.checkPseudoObjectRValue(result.get());
11166 return result;
11169 template<typename Derived>
11170 ExprResult
11171 TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
11172 UnaryExprOrTypeTraitExpr *E) {
11173 if (E->isArgumentType()) {
11174 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
11176 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
11177 if (!NewT)
11178 return ExprError();
11180 if (!getDerived().AlwaysRebuild() && OldT == NewT)
11181 return E;
11183 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
11184 E->getKind(),
11185 E->getSourceRange());
11188 // C++0x [expr.sizeof]p1:
11189 // The operand is either an expression, which is an unevaluated operand
11190 // [...]
11191 EnterExpressionEvaluationContext Unevaluated(
11192 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
11193 Sema::ReuseLambdaContextDecl);
11195 // Try to recover if we have something like sizeof(T::X) where X is a type.
11196 // Notably, there must be *exactly* one set of parens if X is a type.
11197 TypeSourceInfo *RecoveryTSI = nullptr;
11198 ExprResult SubExpr;
11199 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
11200 if (auto *DRE =
11201 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
11202 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
11203 PE, DRE, false, &RecoveryTSI);
11204 else
11205 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
11207 if (RecoveryTSI) {
11208 return getDerived().RebuildUnaryExprOrTypeTrait(
11209 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
11210 } else if (SubExpr.isInvalid())
11211 return ExprError();
11213 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
11214 return E;
11216 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
11217 E->getOperatorLoc(),
11218 E->getKind(),
11219 E->getSourceRange());
11222 template<typename Derived>
11223 ExprResult
11224 TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
11225 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11226 if (LHS.isInvalid())
11227 return ExprError();
11229 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11230 if (RHS.isInvalid())
11231 return ExprError();
11234 if (!getDerived().AlwaysRebuild() &&
11235 LHS.get() == E->getLHS() &&
11236 RHS.get() == E->getRHS())
11237 return E;
11239 return getDerived().RebuildArraySubscriptExpr(
11240 LHS.get(),
11241 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
11244 template <typename Derived>
11245 ExprResult
11246 TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
11247 ExprResult Base = getDerived().TransformExpr(E->getBase());
11248 if (Base.isInvalid())
11249 return ExprError();
11251 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
11252 if (RowIdx.isInvalid())
11253 return ExprError();
11255 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
11256 if (ColumnIdx.isInvalid())
11257 return ExprError();
11259 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
11260 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
11261 return E;
11263 return getDerived().RebuildMatrixSubscriptExpr(
11264 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
11267 template <typename Derived>
11268 ExprResult
11269 TreeTransform<Derived>::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) {
11270 ExprResult Base = getDerived().TransformExpr(E->getBase());
11271 if (Base.isInvalid())
11272 return ExprError();
11274 ExprResult LowerBound;
11275 if (E->getLowerBound()) {
11276 LowerBound = getDerived().TransformExpr(E->getLowerBound());
11277 if (LowerBound.isInvalid())
11278 return ExprError();
11281 ExprResult Length;
11282 if (E->getLength()) {
11283 Length = getDerived().TransformExpr(E->getLength());
11284 if (Length.isInvalid())
11285 return ExprError();
11288 ExprResult Stride;
11289 if (Expr *Str = E->getStride()) {
11290 Stride = getDerived().TransformExpr(Str);
11291 if (Stride.isInvalid())
11292 return ExprError();
11295 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
11296 LowerBound.get() == E->getLowerBound() && Length.get() == E->getLength())
11297 return E;
11299 return getDerived().RebuildOMPArraySectionExpr(
11300 Base.get(), E->getBase()->getEndLoc(), LowerBound.get(),
11301 E->getColonLocFirst(), E->getColonLocSecond(), Length.get(), Stride.get(),
11302 E->getRBracketLoc());
11305 template <typename Derived>
11306 ExprResult
11307 TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
11308 ExprResult Base = getDerived().TransformExpr(E->getBase());
11309 if (Base.isInvalid())
11310 return ExprError();
11312 SmallVector<Expr *, 4> Dims;
11313 bool ErrorFound = false;
11314 for (Expr *Dim : E->getDimensions()) {
11315 ExprResult DimRes = getDerived().TransformExpr(Dim);
11316 if (DimRes.isInvalid()) {
11317 ErrorFound = true;
11318 continue;
11320 Dims.push_back(DimRes.get());
11323 if (ErrorFound)
11324 return ExprError();
11325 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
11326 E->getRParenLoc(), Dims,
11327 E->getBracketsRanges());
11330 template <typename Derived>
11331 ExprResult
11332 TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
11333 unsigned NumIterators = E->numOfIterators();
11334 SmallVector<Sema::OMPIteratorData, 4> Data(NumIterators);
11336 bool ErrorFound = false;
11337 bool NeedToRebuild = getDerived().AlwaysRebuild();
11338 for (unsigned I = 0; I < NumIterators; ++I) {
11339 auto *D = cast<VarDecl>(E->getIteratorDecl(I));
11340 Data[I].DeclIdent = D->getIdentifier();
11341 Data[I].DeclIdentLoc = D->getLocation();
11342 if (D->getLocation() == D->getBeginLoc()) {
11343 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
11344 "Implicit type must be int.");
11345 } else {
11346 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
11347 QualType DeclTy = getDerived().TransformType(D->getType());
11348 Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI);
11350 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
11351 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
11352 ExprResult End = getDerived().TransformExpr(Range.End);
11353 ExprResult Step = getDerived().TransformExpr(Range.Step);
11354 ErrorFound = ErrorFound ||
11355 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
11356 !Data[I].Type.get().isNull())) ||
11357 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
11358 if (ErrorFound)
11359 continue;
11360 Data[I].Range.Begin = Begin.get();
11361 Data[I].Range.End = End.get();
11362 Data[I].Range.Step = Step.get();
11363 Data[I].AssignLoc = E->getAssignLoc(I);
11364 Data[I].ColonLoc = E->getColonLoc(I);
11365 Data[I].SecColonLoc = E->getSecondColonLoc(I);
11366 NeedToRebuild =
11367 NeedToRebuild ||
11368 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
11369 D->getType().getTypePtrOrNull()) ||
11370 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
11371 Range.Step != Data[I].Range.Step;
11373 if (ErrorFound)
11374 return ExprError();
11375 if (!NeedToRebuild)
11376 return E;
11378 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
11379 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
11380 if (!Res.isUsable())
11381 return Res;
11382 auto *IE = cast<OMPIteratorExpr>(Res.get());
11383 for (unsigned I = 0; I < NumIterators; ++I)
11384 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
11385 IE->getIteratorDecl(I));
11386 return Res;
11389 template<typename Derived>
11390 ExprResult
11391 TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
11392 // Transform the callee.
11393 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
11394 if (Callee.isInvalid())
11395 return ExprError();
11397 // Transform arguments.
11398 bool ArgChanged = false;
11399 SmallVector<Expr*, 8> Args;
11400 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
11401 &ArgChanged))
11402 return ExprError();
11404 if (!getDerived().AlwaysRebuild() &&
11405 Callee.get() == E->getCallee() &&
11406 !ArgChanged)
11407 return SemaRef.MaybeBindToTemporary(E);
11409 // FIXME: Wrong source location information for the '('.
11410 SourceLocation FakeLParenLoc
11411 = ((Expr *)Callee.get())->getSourceRange().getBegin();
11413 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11414 if (E->hasStoredFPFeatures()) {
11415 FPOptionsOverride NewOverrides = E->getFPFeatures();
11416 getSema().CurFPFeatures =
11417 NewOverrides.applyOverrides(getSema().getLangOpts());
11418 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11421 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
11422 Args,
11423 E->getRParenLoc());
11426 template<typename Derived>
11427 ExprResult
11428 TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
11429 ExprResult Base = getDerived().TransformExpr(E->getBase());
11430 if (Base.isInvalid())
11431 return ExprError();
11433 NestedNameSpecifierLoc QualifierLoc;
11434 if (E->hasQualifier()) {
11435 QualifierLoc
11436 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
11438 if (!QualifierLoc)
11439 return ExprError();
11441 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
11443 ValueDecl *Member
11444 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
11445 E->getMemberDecl()));
11446 if (!Member)
11447 return ExprError();
11449 NamedDecl *FoundDecl = E->getFoundDecl();
11450 if (FoundDecl == E->getMemberDecl()) {
11451 FoundDecl = Member;
11452 } else {
11453 FoundDecl = cast_or_null<NamedDecl>(
11454 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
11455 if (!FoundDecl)
11456 return ExprError();
11459 if (!getDerived().AlwaysRebuild() &&
11460 Base.get() == E->getBase() &&
11461 QualifierLoc == E->getQualifierLoc() &&
11462 Member == E->getMemberDecl() &&
11463 FoundDecl == E->getFoundDecl() &&
11464 !E->hasExplicitTemplateArgs()) {
11466 // Skip for member expression of (this->f), rebuilt thisi->f is needed
11467 // for Openmp where the field need to be privatizized in the case.
11468 if (!(isa<CXXThisExpr>(E->getBase()) &&
11469 getSema().isOpenMPRebuildMemberExpr(cast<ValueDecl>(Member)))) {
11470 // Mark it referenced in the new context regardless.
11471 // FIXME: this is a bit instantiation-specific.
11472 SemaRef.MarkMemberReferenced(E);
11473 return E;
11477 TemplateArgumentListInfo TransArgs;
11478 if (E->hasExplicitTemplateArgs()) {
11479 TransArgs.setLAngleLoc(E->getLAngleLoc());
11480 TransArgs.setRAngleLoc(E->getRAngleLoc());
11481 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
11482 E->getNumTemplateArgs(),
11483 TransArgs))
11484 return ExprError();
11487 // FIXME: Bogus source location for the operator
11488 SourceLocation FakeOperatorLoc =
11489 SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
11491 // FIXME: to do this check properly, we will need to preserve the
11492 // first-qualifier-in-scope here, just in case we had a dependent
11493 // base (and therefore couldn't do the check) and a
11494 // nested-name-qualifier (and therefore could do the lookup).
11495 NamedDecl *FirstQualifierInScope = nullptr;
11496 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
11497 if (MemberNameInfo.getName()) {
11498 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
11499 if (!MemberNameInfo.getName())
11500 return ExprError();
11503 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
11504 E->isArrow(),
11505 QualifierLoc,
11506 TemplateKWLoc,
11507 MemberNameInfo,
11508 Member,
11509 FoundDecl,
11510 (E->hasExplicitTemplateArgs()
11511 ? &TransArgs : nullptr),
11512 FirstQualifierInScope);
11515 template<typename Derived>
11516 ExprResult
11517 TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
11518 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11519 if (LHS.isInvalid())
11520 return ExprError();
11522 ExprResult RHS =
11523 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
11524 if (RHS.isInvalid())
11525 return ExprError();
11527 if (!getDerived().AlwaysRebuild() &&
11528 LHS.get() == E->getLHS() &&
11529 RHS.get() == E->getRHS())
11530 return E;
11532 if (E->isCompoundAssignmentOp())
11533 // FPFeatures has already been established from trailing storage
11534 return getDerived().RebuildBinaryOperator(
11535 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
11536 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11537 FPOptionsOverride NewOverrides(E->getFPFeatures());
11538 getSema().CurFPFeatures =
11539 NewOverrides.applyOverrides(getSema().getLangOpts());
11540 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11541 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
11542 LHS.get(), RHS.get());
11545 template <typename Derived>
11546 ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
11547 CXXRewrittenBinaryOperator *E) {
11548 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
11550 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
11551 if (LHS.isInvalid())
11552 return ExprError();
11554 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
11555 if (RHS.isInvalid())
11556 return ExprError();
11558 // Extract the already-resolved callee declarations so that we can restrict
11559 // ourselves to using them as the unqualified lookup results when rebuilding.
11560 UnresolvedSet<2> UnqualLookups;
11561 bool ChangedAnyLookups = false;
11562 Expr *PossibleBinOps[] = {E->getSemanticForm(),
11563 const_cast<Expr *>(Decomp.InnerBinOp)};
11564 for (Expr *PossibleBinOp : PossibleBinOps) {
11565 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());
11566 if (!Op)
11567 continue;
11568 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());
11569 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))
11570 continue;
11572 // Transform the callee in case we built a call to a local extern
11573 // declaration.
11574 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
11575 E->getOperatorLoc(), Callee->getFoundDecl()));
11576 if (!Found)
11577 return ExprError();
11578 if (Found != Callee->getFoundDecl())
11579 ChangedAnyLookups = true;
11580 UnqualLookups.addDecl(Found);
11583 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
11584 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
11585 // Mark all functions used in the rewrite as referenced. Note that when
11586 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
11587 // function calls, and/or there might be a user-defined conversion sequence
11588 // applied to the operands of the <.
11589 // FIXME: this is a bit instantiation-specific.
11590 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
11591 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);
11592 return E;
11595 return getDerived().RebuildCXXRewrittenBinaryOperator(
11596 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
11599 template<typename Derived>
11600 ExprResult
11601 TreeTransform<Derived>::TransformCompoundAssignOperator(
11602 CompoundAssignOperator *E) {
11603 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11604 FPOptionsOverride NewOverrides(E->getFPFeatures());
11605 getSema().CurFPFeatures =
11606 NewOverrides.applyOverrides(getSema().getLangOpts());
11607 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11608 return getDerived().TransformBinaryOperator(E);
11611 template<typename Derived>
11612 ExprResult TreeTransform<Derived>::
11613 TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
11614 // Just rebuild the common and RHS expressions and see whether we
11615 // get any changes.
11617 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
11618 if (commonExpr.isInvalid())
11619 return ExprError();
11621 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
11622 if (rhs.isInvalid())
11623 return ExprError();
11625 if (!getDerived().AlwaysRebuild() &&
11626 commonExpr.get() == e->getCommon() &&
11627 rhs.get() == e->getFalseExpr())
11628 return e;
11630 return getDerived().RebuildConditionalOperator(commonExpr.get(),
11631 e->getQuestionLoc(),
11632 nullptr,
11633 e->getColonLoc(),
11634 rhs.get());
11637 template<typename Derived>
11638 ExprResult
11639 TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
11640 ExprResult Cond = getDerived().TransformExpr(E->getCond());
11641 if (Cond.isInvalid())
11642 return ExprError();
11644 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11645 if (LHS.isInvalid())
11646 return ExprError();
11648 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11649 if (RHS.isInvalid())
11650 return ExprError();
11652 if (!getDerived().AlwaysRebuild() &&
11653 Cond.get() == E->getCond() &&
11654 LHS.get() == E->getLHS() &&
11655 RHS.get() == E->getRHS())
11656 return E;
11658 return getDerived().RebuildConditionalOperator(Cond.get(),
11659 E->getQuestionLoc(),
11660 LHS.get(),
11661 E->getColonLoc(),
11662 RHS.get());
11665 template<typename Derived>
11666 ExprResult
11667 TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
11668 // Implicit casts are eliminated during transformation, since they
11669 // will be recomputed by semantic analysis after transformation.
11670 return getDerived().TransformExpr(E->getSubExprAsWritten());
11673 template<typename Derived>
11674 ExprResult
11675 TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
11676 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
11677 if (!Type)
11678 return ExprError();
11680 ExprResult SubExpr
11681 = getDerived().TransformExpr(E->getSubExprAsWritten());
11682 if (SubExpr.isInvalid())
11683 return ExprError();
11685 if (!getDerived().AlwaysRebuild() &&
11686 Type == E->getTypeInfoAsWritten() &&
11687 SubExpr.get() == E->getSubExpr())
11688 return E;
11690 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
11691 Type,
11692 E->getRParenLoc(),
11693 SubExpr.get());
11696 template<typename Derived>
11697 ExprResult
11698 TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
11699 TypeSourceInfo *OldT = E->getTypeSourceInfo();
11700 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
11701 if (!NewT)
11702 return ExprError();
11704 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
11705 if (Init.isInvalid())
11706 return ExprError();
11708 if (!getDerived().AlwaysRebuild() &&
11709 OldT == NewT &&
11710 Init.get() == E->getInitializer())
11711 return SemaRef.MaybeBindToTemporary(E);
11713 // Note: the expression type doesn't necessarily match the
11714 // type-as-written, but that's okay, because it should always be
11715 // derivable from the initializer.
11717 return getDerived().RebuildCompoundLiteralExpr(
11718 E->getLParenLoc(), NewT,
11719 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
11722 template<typename Derived>
11723 ExprResult
11724 TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
11725 ExprResult Base = getDerived().TransformExpr(E->getBase());
11726 if (Base.isInvalid())
11727 return ExprError();
11729 if (!getDerived().AlwaysRebuild() &&
11730 Base.get() == E->getBase())
11731 return E;
11733 // FIXME: Bad source location
11734 SourceLocation FakeOperatorLoc =
11735 SemaRef.getLocForEndOfToken(E->getBase()->getEndLoc());
11736 return getDerived().RebuildExtVectorElementExpr(
11737 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
11738 E->getAccessor());
11741 template<typename Derived>
11742 ExprResult
11743 TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
11744 if (InitListExpr *Syntactic = E->getSyntacticForm())
11745 E = Syntactic;
11747 bool InitChanged = false;
11749 EnterExpressionEvaluationContext Context(
11750 getSema(), EnterExpressionEvaluationContext::InitList);
11752 SmallVector<Expr*, 4> Inits;
11753 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
11754 Inits, &InitChanged))
11755 return ExprError();
11757 if (!getDerived().AlwaysRebuild() && !InitChanged) {
11758 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
11759 // in some cases. We can't reuse it in general, because the syntactic and
11760 // semantic forms are linked, and we can't know that semantic form will
11761 // match even if the syntactic form does.
11764 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
11765 E->getRBraceLoc());
11768 template<typename Derived>
11769 ExprResult
11770 TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
11771 Designation Desig;
11773 // transform the initializer value
11774 ExprResult Init = getDerived().TransformExpr(E->getInit());
11775 if (Init.isInvalid())
11776 return ExprError();
11778 // transform the designators.
11779 SmallVector<Expr*, 4> ArrayExprs;
11780 bool ExprChanged = false;
11781 for (const DesignatedInitExpr::Designator &D : E->designators()) {
11782 if (D.isFieldDesignator()) {
11783 if (D.getFieldDecl()) {
11784 FieldDecl *Field = cast_or_null<FieldDecl>(
11785 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
11786 if (Field != D.getFieldDecl())
11787 // Rebuild the expression when the transformed FieldDecl is
11788 // different to the already assigned FieldDecl.
11789 ExprChanged = true;
11790 if (Field->isAnonymousStructOrUnion())
11791 continue;
11792 } else {
11793 // Ensure that the designator expression is rebuilt when there isn't
11794 // a resolved FieldDecl in the designator as we don't want to assign
11795 // a FieldDecl to a pattern designator that will be instantiated again.
11796 ExprChanged = true;
11798 Desig.AddDesignator(Designator::CreateFieldDesignator(
11799 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
11800 continue;
11803 if (D.isArrayDesignator()) {
11804 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
11805 if (Index.isInvalid())
11806 return ExprError();
11808 Desig.AddDesignator(
11809 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
11811 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
11812 ArrayExprs.push_back(Index.get());
11813 continue;
11816 assert(D.isArrayRangeDesignator() && "New kind of designator?");
11817 ExprResult Start
11818 = getDerived().TransformExpr(E->getArrayRangeStart(D));
11819 if (Start.isInvalid())
11820 return ExprError();
11822 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
11823 if (End.isInvalid())
11824 return ExprError();
11826 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
11827 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
11829 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
11830 End.get() != E->getArrayRangeEnd(D);
11832 ArrayExprs.push_back(Start.get());
11833 ArrayExprs.push_back(End.get());
11836 if (!getDerived().AlwaysRebuild() &&
11837 Init.get() == E->getInit() &&
11838 !ExprChanged)
11839 return E;
11841 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
11842 E->getEqualOrColonLoc(),
11843 E->usesGNUSyntax(), Init.get());
11846 // Seems that if TransformInitListExpr() only works on the syntactic form of an
11847 // InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
11848 template<typename Derived>
11849 ExprResult
11850 TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
11851 DesignatedInitUpdateExpr *E) {
11852 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
11853 "initializer");
11854 return ExprError();
11857 template<typename Derived>
11858 ExprResult
11859 TreeTransform<Derived>::TransformNoInitExpr(
11860 NoInitExpr *E) {
11861 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
11862 return ExprError();
11865 template<typename Derived>
11866 ExprResult
11867 TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
11868 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
11869 return ExprError();
11872 template<typename Derived>
11873 ExprResult
11874 TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
11875 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
11876 return ExprError();
11879 template<typename Derived>
11880 ExprResult
11881 TreeTransform<Derived>::TransformImplicitValueInitExpr(
11882 ImplicitValueInitExpr *E) {
11883 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
11885 // FIXME: Will we ever have proper type location here? Will we actually
11886 // need to transform the type?
11887 QualType T = getDerived().TransformType(E->getType());
11888 if (T.isNull())
11889 return ExprError();
11891 if (!getDerived().AlwaysRebuild() &&
11892 T == E->getType())
11893 return E;
11895 return getDerived().RebuildImplicitValueInitExpr(T);
11898 template<typename Derived>
11899 ExprResult
11900 TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
11901 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
11902 if (!TInfo)
11903 return ExprError();
11905 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
11906 if (SubExpr.isInvalid())
11907 return ExprError();
11909 if (!getDerived().AlwaysRebuild() &&
11910 TInfo == E->getWrittenTypeInfo() &&
11911 SubExpr.get() == E->getSubExpr())
11912 return E;
11914 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
11915 TInfo, E->getRParenLoc());
11918 template<typename Derived>
11919 ExprResult
11920 TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
11921 bool ArgumentChanged = false;
11922 SmallVector<Expr*, 4> Inits;
11923 if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits,
11924 &ArgumentChanged))
11925 return ExprError();
11927 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
11928 Inits,
11929 E->getRParenLoc());
11932 /// Transform an address-of-label expression.
11934 /// By default, the transformation of an address-of-label expression always
11935 /// rebuilds the expression, so that the label identifier can be resolved to
11936 /// the corresponding label statement by semantic analysis.
11937 template<typename Derived>
11938 ExprResult
11939 TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
11940 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
11941 E->getLabel());
11942 if (!LD)
11943 return ExprError();
11945 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
11946 cast<LabelDecl>(LD));
11949 template<typename Derived>
11950 ExprResult
11951 TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
11952 SemaRef.ActOnStartStmtExpr();
11953 StmtResult SubStmt
11954 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
11955 if (SubStmt.isInvalid()) {
11956 SemaRef.ActOnStmtExprError();
11957 return ExprError();
11960 unsigned OldDepth = E->getTemplateDepth();
11961 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
11963 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
11964 SubStmt.get() == E->getSubStmt()) {
11965 // Calling this an 'error' is unintuitive, but it does the right thing.
11966 SemaRef.ActOnStmtExprError();
11967 return SemaRef.MaybeBindToTemporary(E);
11970 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
11971 E->getRParenLoc(), NewDepth);
11974 template<typename Derived>
11975 ExprResult
11976 TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
11977 ExprResult Cond = getDerived().TransformExpr(E->getCond());
11978 if (Cond.isInvalid())
11979 return ExprError();
11981 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11982 if (LHS.isInvalid())
11983 return ExprError();
11985 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11986 if (RHS.isInvalid())
11987 return ExprError();
11989 if (!getDerived().AlwaysRebuild() &&
11990 Cond.get() == E->getCond() &&
11991 LHS.get() == E->getLHS() &&
11992 RHS.get() == E->getRHS())
11993 return E;
11995 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
11996 Cond.get(), LHS.get(), RHS.get(),
11997 E->getRParenLoc());
12000 template<typename Derived>
12001 ExprResult
12002 TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
12003 return E;
12006 template<typename Derived>
12007 ExprResult
12008 TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
12009 switch (E->getOperator()) {
12010 case OO_New:
12011 case OO_Delete:
12012 case OO_Array_New:
12013 case OO_Array_Delete:
12014 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
12016 case OO_Subscript:
12017 case OO_Call: {
12018 // This is a call to an object's operator().
12019 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
12021 // Transform the object itself.
12022 ExprResult Object = getDerived().TransformExpr(E->getArg(0));
12023 if (Object.isInvalid())
12024 return ExprError();
12026 // FIXME: Poor location information
12027 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
12028 static_cast<Expr *>(Object.get())->getEndLoc());
12030 // Transform the call arguments.
12031 SmallVector<Expr*, 8> Args;
12032 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
12033 Args))
12034 return ExprError();
12036 if (E->getOperator() == OO_Subscript)
12037 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
12038 Args, E->getEndLoc());
12040 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
12041 E->getEndLoc());
12044 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
12045 case OO_##Name: \
12046 break;
12048 #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
12049 #include "clang/Basic/OperatorKinds.def"
12051 case OO_Conditional:
12052 llvm_unreachable("conditional operator is not actually overloadable");
12054 case OO_None:
12055 case NUM_OVERLOADED_OPERATORS:
12056 llvm_unreachable("not an overloaded operator?");
12059 ExprResult First;
12060 if (E->getOperator() == OO_Amp)
12061 First = getDerived().TransformAddressOfOperand(E->getArg(0));
12062 else
12063 First = getDerived().TransformExpr(E->getArg(0));
12064 if (First.isInvalid())
12065 return ExprError();
12067 ExprResult Second;
12068 if (E->getNumArgs() == 2) {
12069 Second =
12070 getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);
12071 if (Second.isInvalid())
12072 return ExprError();
12075 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12076 FPOptionsOverride NewOverrides(E->getFPFeatures());
12077 getSema().CurFPFeatures =
12078 NewOverrides.applyOverrides(getSema().getLangOpts());
12079 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12081 Expr *Callee = E->getCallee();
12082 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
12083 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
12084 Sema::LookupOrdinaryName);
12085 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
12086 return ExprError();
12088 return getDerived().RebuildCXXOperatorCallExpr(
12089 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
12090 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
12093 UnresolvedSet<1> Functions;
12094 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
12095 Callee = ICE->getSubExprAsWritten();
12096 NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();
12097 ValueDecl *VD = cast_or_null<ValueDecl>(
12098 getDerived().TransformDecl(DR->getLocation(), DR));
12099 if (!VD)
12100 return ExprError();
12102 if (!isa<CXXMethodDecl>(VD))
12103 Functions.addDecl(VD);
12105 return getDerived().RebuildCXXOperatorCallExpr(
12106 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
12107 /*RequiresADL=*/false, Functions, First.get(), Second.get());
12110 template<typename Derived>
12111 ExprResult
12112 TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
12113 return getDerived().TransformCallExpr(E);
12116 template <typename Derived>
12117 ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
12118 bool NeedRebuildFunc = E->getIdentKind() == SourceLocExpr::Function &&
12119 getSema().CurContext != E->getParentContext();
12121 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
12122 return E;
12124 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
12125 E->getBeginLoc(), E->getEndLoc(),
12126 getSema().CurContext);
12129 template<typename Derived>
12130 ExprResult
12131 TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
12132 // Transform the callee.
12133 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
12134 if (Callee.isInvalid())
12135 return ExprError();
12137 // Transform exec config.
12138 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
12139 if (EC.isInvalid())
12140 return ExprError();
12142 // Transform arguments.
12143 bool ArgChanged = false;
12144 SmallVector<Expr*, 8> Args;
12145 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
12146 &ArgChanged))
12147 return ExprError();
12149 if (!getDerived().AlwaysRebuild() &&
12150 Callee.get() == E->getCallee() &&
12151 !ArgChanged)
12152 return SemaRef.MaybeBindToTemporary(E);
12154 // FIXME: Wrong source location information for the '('.
12155 SourceLocation FakeLParenLoc
12156 = ((Expr *)Callee.get())->getSourceRange().getBegin();
12157 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
12158 Args,
12159 E->getRParenLoc(), EC.get());
12162 template<typename Derived>
12163 ExprResult
12164 TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
12165 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
12166 if (!Type)
12167 return ExprError();
12169 ExprResult SubExpr
12170 = getDerived().TransformExpr(E->getSubExprAsWritten());
12171 if (SubExpr.isInvalid())
12172 return ExprError();
12174 if (!getDerived().AlwaysRebuild() &&
12175 Type == E->getTypeInfoAsWritten() &&
12176 SubExpr.get() == E->getSubExpr())
12177 return E;
12178 return getDerived().RebuildCXXNamedCastExpr(
12179 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
12180 Type, E->getAngleBrackets().getEnd(),
12181 // FIXME. this should be '(' location
12182 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
12185 template<typename Derived>
12186 ExprResult
12187 TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
12188 TypeSourceInfo *TSI =
12189 getDerived().TransformType(BCE->getTypeInfoAsWritten());
12190 if (!TSI)
12191 return ExprError();
12193 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
12194 if (Sub.isInvalid())
12195 return ExprError();
12197 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
12198 Sub.get(), BCE->getEndLoc());
12201 template<typename Derived>
12202 ExprResult
12203 TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
12204 return getDerived().TransformCXXNamedCastExpr(E);
12207 template<typename Derived>
12208 ExprResult
12209 TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
12210 return getDerived().TransformCXXNamedCastExpr(E);
12213 template<typename Derived>
12214 ExprResult
12215 TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
12216 CXXReinterpretCastExpr *E) {
12217 return getDerived().TransformCXXNamedCastExpr(E);
12220 template<typename Derived>
12221 ExprResult
12222 TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
12223 return getDerived().TransformCXXNamedCastExpr(E);
12226 template<typename Derived>
12227 ExprResult
12228 TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
12229 return getDerived().TransformCXXNamedCastExpr(E);
12232 template<typename Derived>
12233 ExprResult
12234 TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
12235 CXXFunctionalCastExpr *E) {
12236 TypeSourceInfo *Type =
12237 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
12238 if (!Type)
12239 return ExprError();
12241 ExprResult SubExpr
12242 = getDerived().TransformExpr(E->getSubExprAsWritten());
12243 if (SubExpr.isInvalid())
12244 return ExprError();
12246 if (!getDerived().AlwaysRebuild() &&
12247 Type == E->getTypeInfoAsWritten() &&
12248 SubExpr.get() == E->getSubExpr())
12249 return E;
12251 return getDerived().RebuildCXXFunctionalCastExpr(Type,
12252 E->getLParenLoc(),
12253 SubExpr.get(),
12254 E->getRParenLoc(),
12255 E->isListInitialization());
12258 template<typename Derived>
12259 ExprResult
12260 TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
12261 if (E->isTypeOperand()) {
12262 TypeSourceInfo *TInfo
12263 = getDerived().TransformType(E->getTypeOperandSourceInfo());
12264 if (!TInfo)
12265 return ExprError();
12267 if (!getDerived().AlwaysRebuild() &&
12268 TInfo == E->getTypeOperandSourceInfo())
12269 return E;
12271 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
12272 TInfo, E->getEndLoc());
12275 // Typeid's operand is an unevaluated context, unless it's a polymorphic
12276 // type. We must not unilaterally enter unevaluated context here, as then
12277 // semantic processing can re-transform an already transformed operand.
12278 Expr *Op = E->getExprOperand();
12279 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
12280 if (E->isGLValue())
12281 if (auto *RecordT = Op->getType()->getAs<RecordType>())
12282 if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
12283 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
12285 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
12286 Sema::ReuseLambdaContextDecl);
12288 ExprResult SubExpr = getDerived().TransformExpr(Op);
12289 if (SubExpr.isInvalid())
12290 return ExprError();
12292 if (!getDerived().AlwaysRebuild() &&
12293 SubExpr.get() == E->getExprOperand())
12294 return E;
12296 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
12297 SubExpr.get(), E->getEndLoc());
12300 template<typename Derived>
12301 ExprResult
12302 TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
12303 if (E->isTypeOperand()) {
12304 TypeSourceInfo *TInfo
12305 = getDerived().TransformType(E->getTypeOperandSourceInfo());
12306 if (!TInfo)
12307 return ExprError();
12309 if (!getDerived().AlwaysRebuild() &&
12310 TInfo == E->getTypeOperandSourceInfo())
12311 return E;
12313 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
12314 TInfo, E->getEndLoc());
12317 EnterExpressionEvaluationContext Unevaluated(
12318 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
12320 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
12321 if (SubExpr.isInvalid())
12322 return ExprError();
12324 if (!getDerived().AlwaysRebuild() &&
12325 SubExpr.get() == E->getExprOperand())
12326 return E;
12328 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
12329 SubExpr.get(), E->getEndLoc());
12332 template<typename Derived>
12333 ExprResult
12334 TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
12335 return E;
12338 template<typename Derived>
12339 ExprResult
12340 TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
12341 CXXNullPtrLiteralExpr *E) {
12342 return E;
12345 template<typename Derived>
12346 ExprResult
12347 TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
12349 // In lambdas, the qualifiers of the type depends of where in
12350 // the call operator `this` appear, and we do not have a good way to
12351 // rebuild this information, so we transform the type.
12353 // In other contexts, the type of `this` may be overrided
12354 // for type deduction, so we need to recompute it.
12355 QualType T = getSema().getCurLambda() ?
12356 getDerived().TransformType(E->getType())
12357 : getSema().getCurrentThisType();
12359 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
12360 // Mark it referenced in the new context regardless.
12361 // FIXME: this is a bit instantiation-specific.
12362 getSema().MarkThisReferenced(E);
12363 return E;
12366 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
12369 template<typename Derived>
12370 ExprResult
12371 TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
12372 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12373 if (SubExpr.isInvalid())
12374 return ExprError();
12376 if (!getDerived().AlwaysRebuild() &&
12377 SubExpr.get() == E->getSubExpr())
12378 return E;
12380 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
12381 E->isThrownVariableInScope());
12384 template<typename Derived>
12385 ExprResult
12386 TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
12387 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
12388 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
12389 if (!Param)
12390 return ExprError();
12392 ExprResult InitRes;
12393 if (E->hasRewrittenInit()) {
12394 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
12395 if (InitRes.isInvalid())
12396 return ExprError();
12399 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
12400 E->getUsedContext() == SemaRef.CurContext &&
12401 InitRes.get() == E->getRewrittenExpr())
12402 return E;
12404 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
12405 InitRes.get());
12408 template<typename Derived>
12409 ExprResult
12410 TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
12411 FieldDecl *Field = cast_or_null<FieldDecl>(
12412 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
12413 if (!Field)
12414 return ExprError();
12416 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
12417 E->getUsedContext() == SemaRef.CurContext)
12418 return E;
12420 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
12423 template<typename Derived>
12424 ExprResult
12425 TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
12426 CXXScalarValueInitExpr *E) {
12427 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
12428 if (!T)
12429 return ExprError();
12431 if (!getDerived().AlwaysRebuild() &&
12432 T == E->getTypeSourceInfo())
12433 return E;
12435 return getDerived().RebuildCXXScalarValueInitExpr(T,
12436 /*FIXME:*/T->getTypeLoc().getEndLoc(),
12437 E->getRParenLoc());
12440 template<typename Derived>
12441 ExprResult
12442 TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
12443 // Transform the type that we're allocating
12444 TypeSourceInfo *AllocTypeInfo =
12445 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
12446 if (!AllocTypeInfo)
12447 return ExprError();
12449 // Transform the size of the array we're allocating (if any).
12450 std::optional<Expr *> ArraySize;
12451 if (E->isArray()) {
12452 ExprResult NewArraySize;
12453 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
12454 NewArraySize = getDerived().TransformExpr(*OldArraySize);
12455 if (NewArraySize.isInvalid())
12456 return ExprError();
12458 ArraySize = NewArraySize.get();
12461 // Transform the placement arguments (if any).
12462 bool ArgumentChanged = false;
12463 SmallVector<Expr*, 8> PlacementArgs;
12464 if (getDerived().TransformExprs(E->getPlacementArgs(),
12465 E->getNumPlacementArgs(), true,
12466 PlacementArgs, &ArgumentChanged))
12467 return ExprError();
12469 // Transform the initializer (if any).
12470 Expr *OldInit = E->getInitializer();
12471 ExprResult NewInit;
12472 if (OldInit)
12473 NewInit = getDerived().TransformInitializer(OldInit, true);
12474 if (NewInit.isInvalid())
12475 return ExprError();
12477 // Transform new operator and delete operator.
12478 FunctionDecl *OperatorNew = nullptr;
12479 if (E->getOperatorNew()) {
12480 OperatorNew = cast_or_null<FunctionDecl>(
12481 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
12482 if (!OperatorNew)
12483 return ExprError();
12486 FunctionDecl *OperatorDelete = nullptr;
12487 if (E->getOperatorDelete()) {
12488 OperatorDelete = cast_or_null<FunctionDecl>(
12489 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
12490 if (!OperatorDelete)
12491 return ExprError();
12494 if (!getDerived().AlwaysRebuild() &&
12495 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
12496 ArraySize == E->getArraySize() &&
12497 NewInit.get() == OldInit &&
12498 OperatorNew == E->getOperatorNew() &&
12499 OperatorDelete == E->getOperatorDelete() &&
12500 !ArgumentChanged) {
12501 // Mark any declarations we need as referenced.
12502 // FIXME: instantiation-specific.
12503 if (OperatorNew)
12504 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorNew);
12505 if (OperatorDelete)
12506 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
12508 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
12509 QualType ElementType
12510 = SemaRef.Context.getBaseElementType(E->getAllocatedType());
12511 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
12512 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
12513 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
12514 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor);
12519 return E;
12522 QualType AllocType = AllocTypeInfo->getType();
12523 if (!ArraySize) {
12524 // If no array size was specified, but the new expression was
12525 // instantiated with an array type (e.g., "new T" where T is
12526 // instantiated with "int[4]"), extract the outer bound from the
12527 // array type as our array size. We do this with constant and
12528 // dependently-sized array types.
12529 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);
12530 if (!ArrayT) {
12531 // Do nothing
12532 } else if (const ConstantArrayType *ConsArrayT
12533 = dyn_cast<ConstantArrayType>(ArrayT)) {
12534 ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),
12535 SemaRef.Context.getSizeType(),
12536 /*FIXME:*/ E->getBeginLoc());
12537 AllocType = ConsArrayT->getElementType();
12538 } else if (const DependentSizedArrayType *DepArrayT
12539 = dyn_cast<DependentSizedArrayType>(ArrayT)) {
12540 if (DepArrayT->getSizeExpr()) {
12541 ArraySize = DepArrayT->getSizeExpr();
12542 AllocType = DepArrayT->getElementType();
12547 return getDerived().RebuildCXXNewExpr(
12548 E->getBeginLoc(), E->isGlobalNew(),
12549 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
12550 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
12551 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
12554 template<typename Derived>
12555 ExprResult
12556 TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
12557 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
12558 if (Operand.isInvalid())
12559 return ExprError();
12561 // Transform the delete operator, if known.
12562 FunctionDecl *OperatorDelete = nullptr;
12563 if (E->getOperatorDelete()) {
12564 OperatorDelete = cast_or_null<FunctionDecl>(
12565 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
12566 if (!OperatorDelete)
12567 return ExprError();
12570 if (!getDerived().AlwaysRebuild() &&
12571 Operand.get() == E->getArgument() &&
12572 OperatorDelete == E->getOperatorDelete()) {
12573 // Mark any declarations we need as referenced.
12574 // FIXME: instantiation-specific.
12575 if (OperatorDelete)
12576 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
12578 if (!E->getArgument()->isTypeDependent()) {
12579 QualType Destroyed = SemaRef.Context.getBaseElementType(
12580 E->getDestroyedType());
12581 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
12582 CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
12583 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
12584 SemaRef.LookupDestructor(Record));
12588 return E;
12591 return getDerived().RebuildCXXDeleteExpr(
12592 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
12595 template<typename Derived>
12596 ExprResult
12597 TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
12598 CXXPseudoDestructorExpr *E) {
12599 ExprResult Base = getDerived().TransformExpr(E->getBase());
12600 if (Base.isInvalid())
12601 return ExprError();
12603 ParsedType ObjectTypePtr;
12604 bool MayBePseudoDestructor = false;
12605 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
12606 E->getOperatorLoc(),
12607 E->isArrow()? tok::arrow : tok::period,
12608 ObjectTypePtr,
12609 MayBePseudoDestructor);
12610 if (Base.isInvalid())
12611 return ExprError();
12613 QualType ObjectType = ObjectTypePtr.get();
12614 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
12615 if (QualifierLoc) {
12616 QualifierLoc
12617 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
12618 if (!QualifierLoc)
12619 return ExprError();
12621 CXXScopeSpec SS;
12622 SS.Adopt(QualifierLoc);
12624 PseudoDestructorTypeStorage Destroyed;
12625 if (E->getDestroyedTypeInfo()) {
12626 TypeSourceInfo *DestroyedTypeInfo
12627 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
12628 ObjectType, nullptr, SS);
12629 if (!DestroyedTypeInfo)
12630 return ExprError();
12631 Destroyed = DestroyedTypeInfo;
12632 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
12633 // We aren't likely to be able to resolve the identifier down to a type
12634 // now anyway, so just retain the identifier.
12635 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
12636 E->getDestroyedTypeLoc());
12637 } else {
12638 // Look for a destructor known with the given name.
12639 ParsedType T = SemaRef.getDestructorName(
12640 *E->getDestroyedTypeIdentifier(), E->getDestroyedTypeLoc(),
12641 /*Scope=*/nullptr, SS, ObjectTypePtr, false);
12642 if (!T)
12643 return ExprError();
12645 Destroyed
12646 = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),
12647 E->getDestroyedTypeLoc());
12650 TypeSourceInfo *ScopeTypeInfo = nullptr;
12651 if (E->getScopeTypeInfo()) {
12652 CXXScopeSpec EmptySS;
12653 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
12654 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
12655 if (!ScopeTypeInfo)
12656 return ExprError();
12659 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
12660 E->getOperatorLoc(),
12661 E->isArrow(),
12663 ScopeTypeInfo,
12664 E->getColonColonLoc(),
12665 E->getTildeLoc(),
12666 Destroyed);
12669 template <typename Derived>
12670 bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
12671 bool RequiresADL,
12672 LookupResult &R) {
12673 // Transform all the decls.
12674 bool AllEmptyPacks = true;
12675 for (auto *OldD : Old->decls()) {
12676 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
12677 if (!InstD) {
12678 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
12679 // This can happen because of dependent hiding.
12680 if (isa<UsingShadowDecl>(OldD))
12681 continue;
12682 else {
12683 R.clear();
12684 return true;
12688 // Expand using pack declarations.
12689 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
12690 ArrayRef<NamedDecl*> Decls = SingleDecl;
12691 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
12692 Decls = UPD->expansions();
12694 // Expand using declarations.
12695 for (auto *D : Decls) {
12696 if (auto *UD = dyn_cast<UsingDecl>(D)) {
12697 for (auto *SD : UD->shadows())
12698 R.addDecl(SD);
12699 } else {
12700 R.addDecl(D);
12704 AllEmptyPacks &= Decls.empty();
12707 // C++ [temp.res]/8.4.2:
12708 // The program is ill-formed, no diagnostic required, if [...] lookup for
12709 // a name in the template definition found a using-declaration, but the
12710 // lookup in the corresponding scope in the instantiation odoes not find
12711 // any declarations because the using-declaration was a pack expansion and
12712 // the corresponding pack is empty
12713 if (AllEmptyPacks && !RequiresADL) {
12714 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
12715 << isa<UnresolvedMemberExpr>(Old) << Old->getName();
12716 return true;
12719 // Resolve a kind, but don't do any further analysis. If it's
12720 // ambiguous, the callee needs to deal with it.
12721 R.resolveKind();
12722 return false;
12725 template<typename Derived>
12726 ExprResult
12727 TreeTransform<Derived>::TransformUnresolvedLookupExpr(
12728 UnresolvedLookupExpr *Old) {
12729 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
12730 Sema::LookupOrdinaryName);
12732 // Transform the declaration set.
12733 if (TransformOverloadExprDecls(Old, Old->requiresADL(), R))
12734 return ExprError();
12736 // Rebuild the nested-name qualifier, if present.
12737 CXXScopeSpec SS;
12738 if (Old->getQualifierLoc()) {
12739 NestedNameSpecifierLoc QualifierLoc
12740 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
12741 if (!QualifierLoc)
12742 return ExprError();
12744 SS.Adopt(QualifierLoc);
12747 if (Old->getNamingClass()) {
12748 CXXRecordDecl *NamingClass
12749 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
12750 Old->getNameLoc(),
12751 Old->getNamingClass()));
12752 if (!NamingClass) {
12753 R.clear();
12754 return ExprError();
12757 R.setNamingClass(NamingClass);
12760 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
12762 // If we have neither explicit template arguments, nor the template keyword,
12763 // it's a normal declaration name or member reference.
12764 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) {
12765 NamedDecl *D = R.getAsSingle<NamedDecl>();
12766 // In a C++11 unevaluated context, an UnresolvedLookupExpr might refer to an
12767 // instance member. In other contexts, BuildPossibleImplicitMemberExpr will
12768 // give a good diagnostic.
12769 if (D && D->isCXXInstanceMember()) {
12770 return SemaRef.BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, R,
12771 /*TemplateArgs=*/nullptr,
12772 /*Scope=*/nullptr);
12775 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
12778 // If we have template arguments, rebuild them, then rebuild the
12779 // templateid expression.
12780 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
12781 if (Old->hasExplicitTemplateArgs() &&
12782 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
12783 Old->getNumTemplateArgs(),
12784 TransArgs)) {
12785 R.clear();
12786 return ExprError();
12789 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
12790 Old->requiresADL(), &TransArgs);
12793 template<typename Derived>
12794 ExprResult
12795 TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
12796 bool ArgChanged = false;
12797 SmallVector<TypeSourceInfo *, 4> Args;
12798 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
12799 TypeSourceInfo *From = E->getArg(I);
12800 TypeLoc FromTL = From->getTypeLoc();
12801 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
12802 TypeLocBuilder TLB;
12803 TLB.reserve(FromTL.getFullDataSize());
12804 QualType To = getDerived().TransformType(TLB, FromTL);
12805 if (To.isNull())
12806 return ExprError();
12808 if (To == From->getType())
12809 Args.push_back(From);
12810 else {
12811 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12812 ArgChanged = true;
12814 continue;
12817 ArgChanged = true;
12819 // We have a pack expansion. Instantiate it.
12820 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
12821 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
12822 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
12823 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
12825 // Determine whether the set of unexpanded parameter packs can and should
12826 // be expanded.
12827 bool Expand = true;
12828 bool RetainExpansion = false;
12829 std::optional<unsigned> OrigNumExpansions =
12830 ExpansionTL.getTypePtr()->getNumExpansions();
12831 std::optional<unsigned> NumExpansions = OrigNumExpansions;
12832 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
12833 PatternTL.getSourceRange(),
12834 Unexpanded,
12835 Expand, RetainExpansion,
12836 NumExpansions))
12837 return ExprError();
12839 if (!Expand) {
12840 // The transform has determined that we should perform a simple
12841 // transformation on the pack expansion, producing another pack
12842 // expansion.
12843 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
12845 TypeLocBuilder TLB;
12846 TLB.reserve(From->getTypeLoc().getFullDataSize());
12848 QualType To = getDerived().TransformType(TLB, PatternTL);
12849 if (To.isNull())
12850 return ExprError();
12852 To = getDerived().RebuildPackExpansionType(To,
12853 PatternTL.getSourceRange(),
12854 ExpansionTL.getEllipsisLoc(),
12855 NumExpansions);
12856 if (To.isNull())
12857 return ExprError();
12859 PackExpansionTypeLoc ToExpansionTL
12860 = TLB.push<PackExpansionTypeLoc>(To);
12861 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
12862 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12863 continue;
12866 // Expand the pack expansion by substituting for each argument in the
12867 // pack(s).
12868 for (unsigned I = 0; I != *NumExpansions; ++I) {
12869 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
12870 TypeLocBuilder TLB;
12871 TLB.reserve(PatternTL.getFullDataSize());
12872 QualType To = getDerived().TransformType(TLB, PatternTL);
12873 if (To.isNull())
12874 return ExprError();
12876 if (To->containsUnexpandedParameterPack()) {
12877 To = getDerived().RebuildPackExpansionType(To,
12878 PatternTL.getSourceRange(),
12879 ExpansionTL.getEllipsisLoc(),
12880 NumExpansions);
12881 if (To.isNull())
12882 return ExprError();
12884 PackExpansionTypeLoc ToExpansionTL
12885 = TLB.push<PackExpansionTypeLoc>(To);
12886 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
12889 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12892 if (!RetainExpansion)
12893 continue;
12895 // If we're supposed to retain a pack expansion, do so by temporarily
12896 // forgetting the partially-substituted parameter pack.
12897 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
12899 TypeLocBuilder TLB;
12900 TLB.reserve(From->getTypeLoc().getFullDataSize());
12902 QualType To = getDerived().TransformType(TLB, PatternTL);
12903 if (To.isNull())
12904 return ExprError();
12906 To = getDerived().RebuildPackExpansionType(To,
12907 PatternTL.getSourceRange(),
12908 ExpansionTL.getEllipsisLoc(),
12909 NumExpansions);
12910 if (To.isNull())
12911 return ExprError();
12913 PackExpansionTypeLoc ToExpansionTL
12914 = TLB.push<PackExpansionTypeLoc>(To);
12915 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
12916 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12919 if (!getDerived().AlwaysRebuild() && !ArgChanged)
12920 return E;
12922 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
12923 E->getEndLoc());
12926 template<typename Derived>
12927 ExprResult
12928 TreeTransform<Derived>::TransformConceptSpecializationExpr(
12929 ConceptSpecializationExpr *E) {
12930 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
12931 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
12932 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
12933 Old->NumTemplateArgs, TransArgs))
12934 return ExprError();
12936 return getDerived().RebuildConceptSpecializationExpr(
12937 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
12938 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
12939 &TransArgs);
12942 template<typename Derived>
12943 ExprResult
12944 TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
12945 SmallVector<ParmVarDecl*, 4> TransParams;
12946 SmallVector<QualType, 4> TransParamTypes;
12947 Sema::ExtParameterInfoBuilder ExtParamInfos;
12949 // C++2a [expr.prim.req]p2
12950 // Expressions appearing within a requirement-body are unevaluated operands.
12951 EnterExpressionEvaluationContext Ctx(
12952 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
12953 Sema::ReuseLambdaContextDecl);
12955 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
12956 getSema().Context, getSema().CurContext,
12957 E->getBody()->getBeginLoc());
12959 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
12961 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
12962 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
12963 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
12965 for (ParmVarDecl *Param : TransParams)
12966 if (Param)
12967 Param->setDeclContext(Body);
12969 // On failure to transform, TransformRequiresTypeParams returns an expression
12970 // in the event that the transformation of the type params failed in some way.
12971 // It is expected that this will result in a 'not satisfied' Requires clause
12972 // when instantiating.
12973 if (!TypeParamResult.isUnset())
12974 return TypeParamResult;
12976 SmallVector<concepts::Requirement *, 4> TransReqs;
12977 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
12978 TransReqs))
12979 return ExprError();
12981 for (concepts::Requirement *Req : TransReqs) {
12982 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
12983 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
12984 ER->getReturnTypeRequirement()
12985 .getTypeConstraintTemplateParameterList()->getParam(0)
12986 ->setDeclContext(Body);
12991 return getDerived().RebuildRequiresExpr(
12992 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
12993 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
12996 template<typename Derived>
12997 bool TreeTransform<Derived>::TransformRequiresExprRequirements(
12998 ArrayRef<concepts::Requirement *> Reqs,
12999 SmallVectorImpl<concepts::Requirement *> &Transformed) {
13000 for (concepts::Requirement *Req : Reqs) {
13001 concepts::Requirement *TransReq = nullptr;
13002 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
13003 TransReq = getDerived().TransformTypeRequirement(TypeReq);
13004 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
13005 TransReq = getDerived().TransformExprRequirement(ExprReq);
13006 else
13007 TransReq = getDerived().TransformNestedRequirement(
13008 cast<concepts::NestedRequirement>(Req));
13009 if (!TransReq)
13010 return true;
13011 Transformed.push_back(TransReq);
13013 return false;
13016 template<typename Derived>
13017 concepts::TypeRequirement *
13018 TreeTransform<Derived>::TransformTypeRequirement(
13019 concepts::TypeRequirement *Req) {
13020 if (Req->isSubstitutionFailure()) {
13021 if (getDerived().AlwaysRebuild())
13022 return getDerived().RebuildTypeRequirement(
13023 Req->getSubstitutionDiagnostic());
13024 return Req;
13026 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
13027 if (!TransType)
13028 return nullptr;
13029 return getDerived().RebuildTypeRequirement(TransType);
13032 template<typename Derived>
13033 concepts::ExprRequirement *
13034 TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
13035 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
13036 if (Req->isExprSubstitutionFailure())
13037 TransExpr = Req->getExprSubstitutionDiagnostic();
13038 else {
13039 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
13040 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
13041 TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
13042 if (TransExprRes.isInvalid())
13043 return nullptr;
13044 TransExpr = TransExprRes.get();
13047 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
13048 const auto &RetReq = Req->getReturnTypeRequirement();
13049 if (RetReq.isEmpty())
13050 TransRetReq.emplace();
13051 else if (RetReq.isSubstitutionFailure())
13052 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
13053 else if (RetReq.isTypeConstraint()) {
13054 TemplateParameterList *OrigTPL =
13055 RetReq.getTypeConstraintTemplateParameterList();
13056 TemplateParameterList *TPL =
13057 getDerived().TransformTemplateParameterList(OrigTPL);
13058 if (!TPL)
13059 return nullptr;
13060 TransRetReq.emplace(TPL);
13062 assert(TransRetReq && "All code paths leading here must set TransRetReq");
13063 if (Expr *E = TransExpr.dyn_cast<Expr *>())
13064 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
13065 Req->getNoexceptLoc(),
13066 std::move(*TransRetReq));
13067 return getDerived().RebuildExprRequirement(
13068 TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(),
13069 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
13072 template<typename Derived>
13073 concepts::NestedRequirement *
13074 TreeTransform<Derived>::TransformNestedRequirement(
13075 concepts::NestedRequirement *Req) {
13076 if (Req->hasInvalidConstraint()) {
13077 if (getDerived().AlwaysRebuild())
13078 return getDerived().RebuildNestedRequirement(
13079 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
13080 return Req;
13082 ExprResult TransConstraint =
13083 getDerived().TransformExpr(Req->getConstraintExpr());
13084 if (TransConstraint.isInvalid())
13085 return nullptr;
13086 return getDerived().RebuildNestedRequirement(TransConstraint.get());
13089 template<typename Derived>
13090 ExprResult
13091 TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
13092 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
13093 if (!T)
13094 return ExprError();
13096 if (!getDerived().AlwaysRebuild() &&
13097 T == E->getQueriedTypeSourceInfo())
13098 return E;
13100 ExprResult SubExpr;
13102 EnterExpressionEvaluationContext Unevaluated(
13103 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13104 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
13105 if (SubExpr.isInvalid())
13106 return ExprError();
13108 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
13109 return E;
13112 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
13113 SubExpr.get(), E->getEndLoc());
13116 template<typename Derived>
13117 ExprResult
13118 TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
13119 ExprResult SubExpr;
13121 EnterExpressionEvaluationContext Unevaluated(
13122 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13123 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
13124 if (SubExpr.isInvalid())
13125 return ExprError();
13127 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
13128 return E;
13131 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
13132 SubExpr.get(), E->getEndLoc());
13135 template <typename Derived>
13136 ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
13137 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
13138 TypeSourceInfo **RecoveryTSI) {
13139 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
13140 DRE, AddrTaken, RecoveryTSI);
13142 // Propagate both errors and recovered types, which return ExprEmpty.
13143 if (!NewDRE.isUsable())
13144 return NewDRE;
13146 // We got an expr, wrap it up in parens.
13147 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
13148 return PE;
13149 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
13150 PE->getRParen());
13153 template <typename Derived>
13154 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
13155 DependentScopeDeclRefExpr *E) {
13156 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
13157 nullptr);
13160 template <typename Derived>
13161 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
13162 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
13163 TypeSourceInfo **RecoveryTSI) {
13164 assert(E->getQualifierLoc());
13165 NestedNameSpecifierLoc QualifierLoc =
13166 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13167 if (!QualifierLoc)
13168 return ExprError();
13169 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13171 // TODO: If this is a conversion-function-id, verify that the
13172 // destination type name (if present) resolves the same way after
13173 // instantiation as it did in the local scope.
13175 DeclarationNameInfo NameInfo =
13176 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
13177 if (!NameInfo.getName())
13178 return ExprError();
13180 if (!E->hasExplicitTemplateArgs()) {
13181 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
13182 // Note: it is sufficient to compare the Name component of NameInfo:
13183 // if name has not changed, DNLoc has not changed either.
13184 NameInfo.getName() == E->getDeclName())
13185 return E;
13187 return getDerived().RebuildDependentScopeDeclRefExpr(
13188 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
13189 IsAddressOfOperand, RecoveryTSI);
13192 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
13193 if (getDerived().TransformTemplateArguments(
13194 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
13195 return ExprError();
13197 return getDerived().RebuildDependentScopeDeclRefExpr(
13198 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
13199 RecoveryTSI);
13202 template<typename Derived>
13203 ExprResult
13204 TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
13205 // CXXConstructExprs other than for list-initialization and
13206 // CXXTemporaryObjectExpr are always implicit, so when we have
13207 // a 1-argument construction we just transform that argument.
13208 if (getDerived().AllowSkippingCXXConstructExpr() &&
13209 ((E->getNumArgs() == 1 ||
13210 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) &&
13211 (!getDerived().DropCallArgument(E->getArg(0))) &&
13212 !E->isListInitialization()))
13213 return getDerived().TransformInitializer(E->getArg(0),
13214 /*DirectInit*/ false);
13216 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
13218 QualType T = getDerived().TransformType(E->getType());
13219 if (T.isNull())
13220 return ExprError();
13222 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13223 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13224 if (!Constructor)
13225 return ExprError();
13227 bool ArgumentChanged = false;
13228 SmallVector<Expr*, 8> Args;
13230 EnterExpressionEvaluationContext Context(
13231 getSema(), EnterExpressionEvaluationContext::InitList,
13232 E->isListInitialization());
13233 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13234 &ArgumentChanged))
13235 return ExprError();
13238 if (!getDerived().AlwaysRebuild() &&
13239 T == E->getType() &&
13240 Constructor == E->getConstructor() &&
13241 !ArgumentChanged) {
13242 // Mark the constructor as referenced.
13243 // FIXME: Instantiation-specific
13244 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13245 return E;
13248 return getDerived().RebuildCXXConstructExpr(
13249 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
13250 E->hadMultipleCandidates(), E->isListInitialization(),
13251 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
13252 E->getConstructionKind(), E->getParenOrBraceRange());
13255 template<typename Derived>
13256 ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
13257 CXXInheritedCtorInitExpr *E) {
13258 QualType T = getDerived().TransformType(E->getType());
13259 if (T.isNull())
13260 return ExprError();
13262 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13263 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13264 if (!Constructor)
13265 return ExprError();
13267 if (!getDerived().AlwaysRebuild() &&
13268 T == E->getType() &&
13269 Constructor == E->getConstructor()) {
13270 // Mark the constructor as referenced.
13271 // FIXME: Instantiation-specific
13272 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13273 return E;
13276 return getDerived().RebuildCXXInheritedCtorInitExpr(
13277 T, E->getLocation(), Constructor,
13278 E->constructsVBase(), E->inheritedFromVBase());
13281 /// Transform a C++ temporary-binding expression.
13283 /// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
13284 /// transform the subexpression and return that.
13285 template<typename Derived>
13286 ExprResult
13287 TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
13288 if (auto *Dtor = E->getTemporary()->getDestructor())
13289 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
13290 const_cast<CXXDestructorDecl *>(Dtor));
13291 return getDerived().TransformExpr(E->getSubExpr());
13294 /// Transform a C++ expression that contains cleanups that should
13295 /// be run after the expression is evaluated.
13297 /// Since ExprWithCleanups nodes are implicitly generated, we
13298 /// just transform the subexpression and return that.
13299 template<typename Derived>
13300 ExprResult
13301 TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
13302 return getDerived().TransformExpr(E->getSubExpr());
13305 template<typename Derived>
13306 ExprResult
13307 TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
13308 CXXTemporaryObjectExpr *E) {
13309 TypeSourceInfo *T =
13310 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
13311 if (!T)
13312 return ExprError();
13314 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13315 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13316 if (!Constructor)
13317 return ExprError();
13319 bool ArgumentChanged = false;
13320 SmallVector<Expr*, 8> Args;
13321 Args.reserve(E->getNumArgs());
13323 EnterExpressionEvaluationContext Context(
13324 getSema(), EnterExpressionEvaluationContext::InitList,
13325 E->isListInitialization());
13326 if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13327 &ArgumentChanged))
13328 return ExprError();
13331 if (!getDerived().AlwaysRebuild() &&
13332 T == E->getTypeSourceInfo() &&
13333 Constructor == E->getConstructor() &&
13334 !ArgumentChanged) {
13335 // FIXME: Instantiation-specific
13336 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13337 return SemaRef.MaybeBindToTemporary(E);
13340 // FIXME: We should just pass E->isListInitialization(), but we're not
13341 // prepared to handle list-initialization without a child InitListExpr.
13342 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
13343 return getDerived().RebuildCXXTemporaryObjectExpr(
13344 T, LParenLoc, Args, E->getEndLoc(),
13345 /*ListInitialization=*/LParenLoc.isInvalid());
13348 template<typename Derived>
13349 ExprResult
13350 TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
13351 // Transform any init-capture expressions before entering the scope of the
13352 // lambda body, because they are not semantically within that scope.
13353 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
13354 struct TransformedInitCapture {
13355 // The location of the ... if the result is retaining a pack expansion.
13356 SourceLocation EllipsisLoc;
13357 // Zero or more expansions of the init-capture.
13358 SmallVector<InitCaptureInfoTy, 4> Expansions;
13360 SmallVector<TransformedInitCapture, 4> InitCaptures;
13361 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
13362 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13363 CEnd = E->capture_end();
13364 C != CEnd; ++C) {
13365 if (!E->isInitCapture(C))
13366 continue;
13368 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
13369 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
13371 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
13372 std::optional<unsigned> NumExpansions) {
13373 ExprResult NewExprInitResult = getDerived().TransformInitializer(
13374 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
13376 if (NewExprInitResult.isInvalid()) {
13377 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
13378 return;
13380 Expr *NewExprInit = NewExprInitResult.get();
13382 QualType NewInitCaptureType =
13383 getSema().buildLambdaInitCaptureInitialization(
13384 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
13385 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
13386 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=
13387 VarDecl::CInit,
13388 NewExprInit);
13389 Result.Expansions.push_back(
13390 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
13393 // If this is an init-capture pack, consider expanding the pack now.
13394 if (OldVD->isParameterPack()) {
13395 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
13396 ->getTypeLoc()
13397 .castAs<PackExpansionTypeLoc>();
13398 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
13399 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
13401 // Determine whether the set of unexpanded parameter packs can and should
13402 // be expanded.
13403 bool Expand = true;
13404 bool RetainExpansion = false;
13405 std::optional<unsigned> OrigNumExpansions =
13406 ExpansionTL.getTypePtr()->getNumExpansions();
13407 std::optional<unsigned> NumExpansions = OrigNumExpansions;
13408 if (getDerived().TryExpandParameterPacks(
13409 ExpansionTL.getEllipsisLoc(),
13410 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
13411 RetainExpansion, NumExpansions))
13412 return ExprError();
13413 if (Expand) {
13414 for (unsigned I = 0; I != *NumExpansions; ++I) {
13415 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
13416 SubstInitCapture(SourceLocation(), std::nullopt);
13419 if (!Expand || RetainExpansion) {
13420 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
13421 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
13422 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
13424 } else {
13425 SubstInitCapture(SourceLocation(), std::nullopt);
13429 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
13430 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
13432 // Create the local class that will describe the lambda.
13434 // FIXME: DependencyKind below is wrong when substituting inside a templated
13435 // context that isn't a DeclContext (such as a variable template), or when
13436 // substituting an unevaluated lambda inside of a function's parameter's type
13437 // - as parameter types are not instantiated from within a function's DC. We
13438 // use evaluation contexts to distinguish the function parameter case.
13439 CXXRecordDecl::LambdaDependencyKind DependencyKind =
13440 CXXRecordDecl::LDK_Unknown;
13441 if ((getSema().isUnevaluatedContext() ||
13442 getSema().isConstantEvaluatedContext()) &&
13443 (getSema().CurContext->isFileContext() ||
13444 !getSema().CurContext->getParent()->isDependentContext()))
13445 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
13447 CXXRecordDecl *OldClass = E->getLambdaClass();
13448 CXXRecordDecl *Class = getSema().createLambdaClosureType(
13449 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
13450 E->getCaptureDefault());
13451 getDerived().transformedLocalDecl(OldClass, {Class});
13453 CXXMethodDecl *NewCallOperator =
13454 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
13455 NewCallOperator->setLexicalDeclContext(getSema().CurContext);
13457 // Enter the scope of the lambda.
13458 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
13459 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
13460 E->hasExplicitParameters(), E->isMutable());
13462 // Introduce the context of the call operator.
13463 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
13464 /*NewThisContext*/false);
13466 bool Invalid = false;
13468 // Transform captures.
13469 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13470 CEnd = E->capture_end();
13471 C != CEnd; ++C) {
13472 // When we hit the first implicit capture, tell Sema that we've finished
13473 // the list of explicit captures.
13474 if (C->isImplicit())
13475 break;
13477 // Capturing 'this' is trivial.
13478 if (C->capturesThis()) {
13479 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
13480 /*BuildAndDiagnose*/ true, nullptr,
13481 C->getCaptureKind() == LCK_StarThis);
13482 continue;
13484 // Captured expression will be recaptured during captured variables
13485 // rebuilding.
13486 if (C->capturesVLAType())
13487 continue;
13489 // Rebuild init-captures, including the implied field declaration.
13490 if (E->isInitCapture(C)) {
13491 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
13493 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
13494 llvm::SmallVector<Decl*, 4> NewVDs;
13496 for (InitCaptureInfoTy &Info : NewC.Expansions) {
13497 ExprResult Init = Info.first;
13498 QualType InitQualType = Info.second;
13499 if (Init.isInvalid() || InitQualType.isNull()) {
13500 Invalid = true;
13501 break;
13503 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
13504 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
13505 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
13506 getSema().CurContext);
13507 if (!NewVD) {
13508 Invalid = true;
13509 break;
13511 NewVDs.push_back(NewVD);
13512 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
13515 if (Invalid)
13516 break;
13518 getDerived().transformedLocalDecl(OldVD, NewVDs);
13519 continue;
13522 assert(C->capturesVariable() && "unexpected kind of lambda capture");
13524 // Determine the capture kind for Sema.
13525 Sema::TryCaptureKind Kind
13526 = C->isImplicit()? Sema::TryCapture_Implicit
13527 : C->getCaptureKind() == LCK_ByCopy
13528 ? Sema::TryCapture_ExplicitByVal
13529 : Sema::TryCapture_ExplicitByRef;
13530 SourceLocation EllipsisLoc;
13531 if (C->isPackExpansion()) {
13532 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
13533 bool ShouldExpand = false;
13534 bool RetainExpansion = false;
13535 std::optional<unsigned> NumExpansions;
13536 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
13537 C->getLocation(),
13538 Unexpanded,
13539 ShouldExpand, RetainExpansion,
13540 NumExpansions)) {
13541 Invalid = true;
13542 continue;
13545 if (ShouldExpand) {
13546 // The transform has determined that we should perform an expansion;
13547 // transform and capture each of the arguments.
13548 // expansion of the pattern. Do so.
13549 auto *Pack = cast<VarDecl>(C->getCapturedVar());
13550 for (unsigned I = 0; I != *NumExpansions; ++I) {
13551 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
13552 VarDecl *CapturedVar
13553 = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
13554 Pack));
13555 if (!CapturedVar) {
13556 Invalid = true;
13557 continue;
13560 // Capture the transformed variable.
13561 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
13564 // FIXME: Retain a pack expansion if RetainExpansion is true.
13566 continue;
13569 EllipsisLoc = C->getEllipsisLoc();
13572 // Transform the captured variable.
13573 auto *CapturedVar = cast_or_null<ValueDecl>(
13574 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
13575 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
13576 Invalid = true;
13577 continue;
13580 // Capture the transformed variable.
13581 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
13582 EllipsisLoc);
13584 getSema().finishLambdaExplicitCaptures(LSI);
13586 // Transform the template parameters, and add them to the current
13587 // instantiation scope. The null case is handled correctly.
13588 auto TPL = getDerived().TransformTemplateParameterList(
13589 E->getTemplateParameterList());
13590 LSI->GLTemplateParameterList = TPL;
13591 if (TPL)
13592 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
13593 TPL);
13595 // Transform the type of the original lambda's call operator.
13596 // The transformation MUST be done in the CurrentInstantiationScope since
13597 // it introduces a mapping of the original to the newly created
13598 // transformed parameters.
13599 TypeSourceInfo *NewCallOpTSI = nullptr;
13601 TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo();
13602 auto OldCallOpFPTL =
13603 OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
13605 TypeLocBuilder NewCallOpTLBuilder;
13606 SmallVector<QualType, 4> ExceptionStorage;
13607 TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
13608 QualType NewCallOpType = TransformFunctionProtoType(
13609 NewCallOpTLBuilder, OldCallOpFPTL, nullptr, Qualifiers(),
13610 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
13611 return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI,
13612 ExceptionStorage, Changed);
13614 if (NewCallOpType.isNull())
13615 return ExprError();
13616 NewCallOpTSI =
13617 NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
13620 getSema().CompleteLambdaCallOperator(
13621 NewCallOperator, E->getCallOperator()->getLocation(),
13622 E->getCallOperator()->getInnerLocStart(),
13623 E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
13624 E->getCallOperator()->getConstexprKind(),
13625 E->getCallOperator()->getStorageClass(),
13626 NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
13627 E->hasExplicitResultType());
13629 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
13630 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
13633 // Number the lambda for linkage purposes if necessary.
13634 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
13636 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
13637 if (getDerived().ReplacingOriginal()) {
13638 Numbering = OldClass->getLambdaNumbering();
13641 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
13644 // FIXME: Sema's lambda-building mechanism expects us to push an expression
13645 // evaluation context even if we're not transforming the function body.
13646 getSema().PushExpressionEvaluationContext(
13647 Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
13649 // Instantiate the body of the lambda expression.
13650 StmtResult Body =
13651 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
13653 // ActOnLambda* will pop the function scope for us.
13654 FuncScopeCleanup.disable();
13656 if (Body.isInvalid()) {
13657 SavedContext.pop();
13658 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
13659 /*IsInstantiation=*/true);
13660 return ExprError();
13663 // Copy the LSI before ActOnFinishFunctionBody removes it.
13664 // FIXME: This is dumb. Store the lambda information somewhere that outlives
13665 // the call operator.
13666 auto LSICopy = *LSI;
13667 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
13668 /*IsInstantiation*/ true);
13669 SavedContext.pop();
13671 return getSema().BuildLambdaExpr(E->getBeginLoc(), Body.get()->getEndLoc(),
13672 &LSICopy);
13675 template<typename Derived>
13676 StmtResult
13677 TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
13678 return TransformStmt(S);
13681 template<typename Derived>
13682 StmtResult
13683 TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
13684 // Transform captures.
13685 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13686 CEnd = E->capture_end();
13687 C != CEnd; ++C) {
13688 // When we hit the first implicit capture, tell Sema that we've finished
13689 // the list of explicit captures.
13690 if (!C->isImplicit())
13691 continue;
13693 // Capturing 'this' is trivial.
13694 if (C->capturesThis()) {
13695 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
13696 /*BuildAndDiagnose*/ true, nullptr,
13697 C->getCaptureKind() == LCK_StarThis);
13698 continue;
13700 // Captured expression will be recaptured during captured variables
13701 // rebuilding.
13702 if (C->capturesVLAType())
13703 continue;
13705 assert(C->capturesVariable() && "unexpected kind of lambda capture");
13706 assert(!E->isInitCapture(C) && "implicit init-capture?");
13708 // Transform the captured variable.
13709 VarDecl *CapturedVar = cast_or_null<VarDecl>(
13710 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
13711 if (!CapturedVar || CapturedVar->isInvalidDecl())
13712 return StmtError();
13714 // Capture the transformed variable.
13715 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
13718 return S;
13721 template<typename Derived>
13722 ExprResult
13723 TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
13724 CXXUnresolvedConstructExpr *E) {
13725 TypeSourceInfo *T =
13726 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
13727 if (!T)
13728 return ExprError();
13730 bool ArgumentChanged = false;
13731 SmallVector<Expr*, 8> Args;
13732 Args.reserve(E->getNumArgs());
13734 EnterExpressionEvaluationContext Context(
13735 getSema(), EnterExpressionEvaluationContext::InitList,
13736 E->isListInitialization());
13737 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
13738 &ArgumentChanged))
13739 return ExprError();
13742 if (!getDerived().AlwaysRebuild() &&
13743 T == E->getTypeSourceInfo() &&
13744 !ArgumentChanged)
13745 return E;
13747 // FIXME: we're faking the locations of the commas
13748 return getDerived().RebuildCXXUnresolvedConstructExpr(
13749 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
13752 template<typename Derived>
13753 ExprResult
13754 TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
13755 CXXDependentScopeMemberExpr *E) {
13756 // Transform the base of the expression.
13757 ExprResult Base((Expr*) nullptr);
13758 Expr *OldBase;
13759 QualType BaseType;
13760 QualType ObjectType;
13761 if (!E->isImplicitAccess()) {
13762 OldBase = E->getBase();
13763 Base = getDerived().TransformExpr(OldBase);
13764 if (Base.isInvalid())
13765 return ExprError();
13767 // Start the member reference and compute the object's type.
13768 ParsedType ObjectTy;
13769 bool MayBePseudoDestructor = false;
13770 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
13771 E->getOperatorLoc(),
13772 E->isArrow()? tok::arrow : tok::period,
13773 ObjectTy,
13774 MayBePseudoDestructor);
13775 if (Base.isInvalid())
13776 return ExprError();
13778 ObjectType = ObjectTy.get();
13779 BaseType = ((Expr*) Base.get())->getType();
13780 } else {
13781 OldBase = nullptr;
13782 BaseType = getDerived().TransformType(E->getBaseType());
13783 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
13786 // Transform the first part of the nested-name-specifier that qualifies
13787 // the member name.
13788 NamedDecl *FirstQualifierInScope
13789 = getDerived().TransformFirstQualifierInScope(
13790 E->getFirstQualifierFoundInScope(),
13791 E->getQualifierLoc().getBeginLoc());
13793 NestedNameSpecifierLoc QualifierLoc;
13794 if (E->getQualifier()) {
13795 QualifierLoc
13796 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
13797 ObjectType,
13798 FirstQualifierInScope);
13799 if (!QualifierLoc)
13800 return ExprError();
13803 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13805 // TODO: If this is a conversion-function-id, verify that the
13806 // destination type name (if present) resolves the same way after
13807 // instantiation as it did in the local scope.
13809 DeclarationNameInfo NameInfo
13810 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
13811 if (!NameInfo.getName())
13812 return ExprError();
13814 if (!E->hasExplicitTemplateArgs()) {
13815 // This is a reference to a member without an explicitly-specified
13816 // template argument list. Optimize for this common case.
13817 if (!getDerived().AlwaysRebuild() &&
13818 Base.get() == OldBase &&
13819 BaseType == E->getBaseType() &&
13820 QualifierLoc == E->getQualifierLoc() &&
13821 NameInfo.getName() == E->getMember() &&
13822 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
13823 return E;
13825 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
13826 BaseType,
13827 E->isArrow(),
13828 E->getOperatorLoc(),
13829 QualifierLoc,
13830 TemplateKWLoc,
13831 FirstQualifierInScope,
13832 NameInfo,
13833 /*TemplateArgs*/nullptr);
13836 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
13837 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13838 E->getNumTemplateArgs(),
13839 TransArgs))
13840 return ExprError();
13842 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
13843 BaseType,
13844 E->isArrow(),
13845 E->getOperatorLoc(),
13846 QualifierLoc,
13847 TemplateKWLoc,
13848 FirstQualifierInScope,
13849 NameInfo,
13850 &TransArgs);
13853 template <typename Derived>
13854 ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
13855 UnresolvedMemberExpr *Old) {
13856 // Transform the base of the expression.
13857 ExprResult Base((Expr *)nullptr);
13858 QualType BaseType;
13859 if (!Old->isImplicitAccess()) {
13860 Base = getDerived().TransformExpr(Old->getBase());
13861 if (Base.isInvalid())
13862 return ExprError();
13863 Base =
13864 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
13865 if (Base.isInvalid())
13866 return ExprError();
13867 BaseType = Base.get()->getType();
13868 } else {
13869 BaseType = getDerived().TransformType(Old->getBaseType());
13872 NestedNameSpecifierLoc QualifierLoc;
13873 if (Old->getQualifierLoc()) {
13874 QualifierLoc =
13875 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
13876 if (!QualifierLoc)
13877 return ExprError();
13880 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
13882 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
13884 // Transform the declaration set.
13885 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ false, R))
13886 return ExprError();
13888 // Determine the naming class.
13889 if (Old->getNamingClass()) {
13890 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
13891 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
13892 if (!NamingClass)
13893 return ExprError();
13895 R.setNamingClass(NamingClass);
13898 TemplateArgumentListInfo TransArgs;
13899 if (Old->hasExplicitTemplateArgs()) {
13900 TransArgs.setLAngleLoc(Old->getLAngleLoc());
13901 TransArgs.setRAngleLoc(Old->getRAngleLoc());
13902 if (getDerived().TransformTemplateArguments(
13903 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
13904 return ExprError();
13907 // FIXME: to do this check properly, we will need to preserve the
13908 // first-qualifier-in-scope here, just in case we had a dependent
13909 // base (and therefore couldn't do the check) and a
13910 // nested-name-qualifier (and therefore could do the lookup).
13911 NamedDecl *FirstQualifierInScope = nullptr;
13913 return getDerived().RebuildUnresolvedMemberExpr(
13914 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
13915 TemplateKWLoc, FirstQualifierInScope, R,
13916 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
13919 template<typename Derived>
13920 ExprResult
13921 TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
13922 EnterExpressionEvaluationContext Unevaluated(
13923 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13924 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
13925 if (SubExpr.isInvalid())
13926 return ExprError();
13928 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
13929 return E;
13931 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
13934 template<typename Derived>
13935 ExprResult
13936 TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
13937 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
13938 if (Pattern.isInvalid())
13939 return ExprError();
13941 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
13942 return E;
13944 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
13945 E->getNumExpansions());
13948 template<typename Derived>
13949 ExprResult
13950 TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
13951 // If E is not value-dependent, then nothing will change when we transform it.
13952 // Note: This is an instantiation-centric view.
13953 if (!E->isValueDependent())
13954 return E;
13956 EnterExpressionEvaluationContext Unevaluated(
13957 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
13959 ArrayRef<TemplateArgument> PackArgs;
13960 TemplateArgument ArgStorage;
13962 // Find the argument list to transform.
13963 if (E->isPartiallySubstituted()) {
13964 PackArgs = E->getPartialArguments();
13965 } else if (E->isValueDependent()) {
13966 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
13967 bool ShouldExpand = false;
13968 bool RetainExpansion = false;
13969 std::optional<unsigned> NumExpansions;
13970 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
13971 Unexpanded,
13972 ShouldExpand, RetainExpansion,
13973 NumExpansions))
13974 return ExprError();
13976 // If we need to expand the pack, build a template argument from it and
13977 // expand that.
13978 if (ShouldExpand) {
13979 auto *Pack = E->getPack();
13980 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) {
13981 ArgStorage = getSema().Context.getPackExpansionType(
13982 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
13983 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {
13984 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
13985 } else {
13986 auto *VD = cast<ValueDecl>(Pack);
13987 ExprResult DRE = getSema().BuildDeclRefExpr(
13988 VD, VD->getType().getNonLValueExprType(getSema().Context),
13989 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
13990 E->getPackLoc());
13991 if (DRE.isInvalid())
13992 return ExprError();
13993 ArgStorage = new (getSema().Context)
13994 PackExpansionExpr(getSema().Context.DependentTy, DRE.get(),
13995 E->getPackLoc(), std::nullopt);
13997 PackArgs = ArgStorage;
14001 // If we're not expanding the pack, just transform the decl.
14002 if (!PackArgs.size()) {
14003 auto *Pack = cast_or_null<NamedDecl>(
14004 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
14005 if (!Pack)
14006 return ExprError();
14007 return getDerived().RebuildSizeOfPackExpr(
14008 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
14009 std::nullopt, std::nullopt);
14012 // Try to compute the result without performing a partial substitution.
14013 std::optional<unsigned> Result = 0;
14014 for (const TemplateArgument &Arg : PackArgs) {
14015 if (!Arg.isPackExpansion()) {
14016 Result = *Result + 1;
14017 continue;
14020 TemplateArgumentLoc ArgLoc;
14021 InventTemplateArgumentLoc(Arg, ArgLoc);
14023 // Find the pattern of the pack expansion.
14024 SourceLocation Ellipsis;
14025 std::optional<unsigned> OrigNumExpansions;
14026 TemplateArgumentLoc Pattern =
14027 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
14028 OrigNumExpansions);
14030 // Substitute under the pack expansion. Do not expand the pack (yet).
14031 TemplateArgumentLoc OutPattern;
14032 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14033 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
14034 /*Uneval*/ true))
14035 return true;
14037 // See if we can determine the number of arguments from the result.
14038 std::optional<unsigned> NumExpansions =
14039 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
14040 if (!NumExpansions) {
14041 // No: we must be in an alias template expansion, and we're going to need
14042 // to actually expand the packs.
14043 Result = std::nullopt;
14044 break;
14047 Result = *Result + *NumExpansions;
14050 // Common case: we could determine the number of expansions without
14051 // substituting.
14052 if (Result)
14053 return getDerived().RebuildSizeOfPackExpr(
14054 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
14055 *Result, std::nullopt);
14057 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
14058 E->getPackLoc());
14060 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
14061 typedef TemplateArgumentLocInventIterator<
14062 Derived, const TemplateArgument*> PackLocIterator;
14063 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
14064 PackLocIterator(*this, PackArgs.end()),
14065 TransformedPackArgs, /*Uneval*/true))
14066 return ExprError();
14069 // Check whether we managed to fully-expand the pack.
14070 // FIXME: Is it possible for us to do so and not hit the early exit path?
14071 SmallVector<TemplateArgument, 8> Args;
14072 bool PartialSubstitution = false;
14073 for (auto &Loc : TransformedPackArgs.arguments()) {
14074 Args.push_back(Loc.getArgument());
14075 if (Loc.getArgument().isPackExpansion())
14076 PartialSubstitution = true;
14079 if (PartialSubstitution)
14080 return getDerived().RebuildSizeOfPackExpr(
14081 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
14082 std::nullopt, Args);
14084 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
14085 E->getPackLoc(), E->getRParenLoc(),
14086 Args.size(), std::nullopt);
14089 template<typename Derived>
14090 ExprResult
14091 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
14092 SubstNonTypeTemplateParmPackExpr *E) {
14093 // Default behavior is to do nothing with this transformation.
14094 return E;
14097 template<typename Derived>
14098 ExprResult
14099 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
14100 SubstNonTypeTemplateParmExpr *E) {
14101 // Default behavior is to do nothing with this transformation.
14102 return E;
14105 template<typename Derived>
14106 ExprResult
14107 TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
14108 // Default behavior is to do nothing with this transformation.
14109 return E;
14112 template<typename Derived>
14113 ExprResult
14114 TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
14115 MaterializeTemporaryExpr *E) {
14116 return getDerived().TransformExpr(E->getSubExpr());
14119 template<typename Derived>
14120 ExprResult
14121 TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
14122 UnresolvedLookupExpr *Callee = nullptr;
14123 if (Expr *OldCallee = E->getCallee()) {
14124 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
14125 if (CalleeResult.isInvalid())
14126 return ExprError();
14127 Callee = cast<UnresolvedLookupExpr>(CalleeResult.get());
14130 Expr *Pattern = E->getPattern();
14132 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14133 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
14134 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
14136 // Determine whether the set of unexpanded parameter packs can and should
14137 // be expanded.
14138 bool Expand = true;
14139 bool RetainExpansion = false;
14140 std::optional<unsigned> OrigNumExpansions = E->getNumExpansions(),
14141 NumExpansions = OrigNumExpansions;
14142 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
14143 Pattern->getSourceRange(),
14144 Unexpanded,
14145 Expand, RetainExpansion,
14146 NumExpansions))
14147 return true;
14149 if (!Expand) {
14150 // Do not expand any packs here, just transform and rebuild a fold
14151 // expression.
14152 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14154 ExprResult LHS =
14155 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
14156 if (LHS.isInvalid())
14157 return true;
14159 ExprResult RHS =
14160 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
14161 if (RHS.isInvalid())
14162 return true;
14164 if (!getDerived().AlwaysRebuild() &&
14165 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
14166 return E;
14168 return getDerived().RebuildCXXFoldExpr(
14169 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
14170 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
14173 // Formally a fold expression expands to nested parenthesized expressions.
14174 // Enforce this limit to avoid creating trees so deep we can't safely traverse
14175 // them.
14176 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) {
14177 SemaRef.Diag(E->getEllipsisLoc(),
14178 clang::diag::err_fold_expression_limit_exceeded)
14179 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
14180 << E->getSourceRange();
14181 SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);
14182 return ExprError();
14185 // The transform has determined that we should perform an elementwise
14186 // expansion of the pattern. Do so.
14187 ExprResult Result = getDerived().TransformExpr(E->getInit());
14188 if (Result.isInvalid())
14189 return true;
14190 bool LeftFold = E->isLeftFold();
14192 // If we're retaining an expansion for a right fold, it is the innermost
14193 // component and takes the init (if any).
14194 if (!LeftFold && RetainExpansion) {
14195 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14197 ExprResult Out = getDerived().TransformExpr(Pattern);
14198 if (Out.isInvalid())
14199 return true;
14201 Result = getDerived().RebuildCXXFoldExpr(
14202 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
14203 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
14204 if (Result.isInvalid())
14205 return true;
14208 for (unsigned I = 0; I != *NumExpansions; ++I) {
14209 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(
14210 getSema(), LeftFold ? I : *NumExpansions - I - 1);
14211 ExprResult Out = getDerived().TransformExpr(Pattern);
14212 if (Out.isInvalid())
14213 return true;
14215 if (Out.get()->containsUnexpandedParameterPack()) {
14216 // We still have a pack; retain a pack expansion for this slice.
14217 Result = getDerived().RebuildCXXFoldExpr(
14218 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
14219 E->getOperator(), E->getEllipsisLoc(),
14220 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
14221 OrigNumExpansions);
14222 } else if (Result.isUsable()) {
14223 // We've got down to a single element; build a binary operator.
14224 Expr *LHS = LeftFold ? Result.get() : Out.get();
14225 Expr *RHS = LeftFold ? Out.get() : Result.get();
14226 if (Callee) {
14227 UnresolvedSet<16> Functions;
14228 Functions.append(Callee->decls_begin(), Callee->decls_end());
14229 Result = getDerived().RebuildCXXOperatorCallExpr(
14230 BinaryOperator::getOverloadedOperator(E->getOperator()),
14231 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
14232 Functions, LHS, RHS);
14233 } else {
14234 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
14235 E->getOperator(), LHS, RHS);
14237 } else
14238 Result = Out;
14240 if (Result.isInvalid())
14241 return true;
14244 // If we're retaining an expansion for a left fold, it is the outermost
14245 // component and takes the complete expansion so far as its init (if any).
14246 if (LeftFold && RetainExpansion) {
14247 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14249 ExprResult Out = getDerived().TransformExpr(Pattern);
14250 if (Out.isInvalid())
14251 return true;
14253 Result = getDerived().RebuildCXXFoldExpr(
14254 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
14255 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
14256 if (Result.isInvalid())
14257 return true;
14260 // If we had no init and an empty pack, and we're not retaining an expansion,
14261 // then produce a fallback value or error.
14262 if (Result.isUnset())
14263 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
14264 E->getOperator());
14266 return Result;
14269 template <typename Derived>
14270 ExprResult
14271 TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
14272 SmallVector<Expr *, 4> TransformedInits;
14273 ArrayRef<Expr *> InitExprs = E->getInitExprs();
14274 if (TransformExprs(InitExprs.data(), InitExprs.size(), true,
14275 TransformedInits))
14276 return ExprError();
14278 return getDerived().RebuildParenListExpr(E->getBeginLoc(), TransformedInits,
14279 E->getEndLoc());
14282 template<typename Derived>
14283 ExprResult
14284 TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
14285 CXXStdInitializerListExpr *E) {
14286 return getDerived().TransformExpr(E->getSubExpr());
14289 template<typename Derived>
14290 ExprResult
14291 TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
14292 return SemaRef.MaybeBindToTemporary(E);
14295 template<typename Derived>
14296 ExprResult
14297 TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
14298 return E;
14301 template<typename Derived>
14302 ExprResult
14303 TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
14304 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14305 if (SubExpr.isInvalid())
14306 return ExprError();
14308 if (!getDerived().AlwaysRebuild() &&
14309 SubExpr.get() == E->getSubExpr())
14310 return E;
14312 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
14315 template<typename Derived>
14316 ExprResult
14317 TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
14318 // Transform each of the elements.
14319 SmallVector<Expr *, 8> Elements;
14320 bool ArgChanged = false;
14321 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
14322 /*IsCall=*/false, Elements, &ArgChanged))
14323 return ExprError();
14325 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14326 return SemaRef.MaybeBindToTemporary(E);
14328 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
14329 Elements.data(),
14330 Elements.size());
14333 template<typename Derived>
14334 ExprResult
14335 TreeTransform<Derived>::TransformObjCDictionaryLiteral(
14336 ObjCDictionaryLiteral *E) {
14337 // Transform each of the elements.
14338 SmallVector<ObjCDictionaryElement, 8> Elements;
14339 bool ArgChanged = false;
14340 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
14341 ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);
14343 if (OrigElement.isPackExpansion()) {
14344 // This key/value element is a pack expansion.
14345 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14346 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
14347 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
14348 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
14350 // Determine whether the set of unexpanded parameter packs can
14351 // and should be expanded.
14352 bool Expand = true;
14353 bool RetainExpansion = false;
14354 std::optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
14355 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14356 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
14357 OrigElement.Value->getEndLoc());
14358 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
14359 PatternRange, Unexpanded, Expand,
14360 RetainExpansion, NumExpansions))
14361 return ExprError();
14363 if (!Expand) {
14364 // The transform has determined that we should perform a simple
14365 // transformation on the pack expansion, producing another pack
14366 // expansion.
14367 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14368 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14369 if (Key.isInvalid())
14370 return ExprError();
14372 if (Key.get() != OrigElement.Key)
14373 ArgChanged = true;
14375 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
14376 if (Value.isInvalid())
14377 return ExprError();
14379 if (Value.get() != OrigElement.Value)
14380 ArgChanged = true;
14382 ObjCDictionaryElement Expansion = {
14383 Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions
14385 Elements.push_back(Expansion);
14386 continue;
14389 // Record right away that the argument was changed. This needs
14390 // to happen even if the array expands to nothing.
14391 ArgChanged = true;
14393 // The transform has determined that we should perform an elementwise
14394 // expansion of the pattern. Do so.
14395 for (unsigned I = 0; I != *NumExpansions; ++I) {
14396 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14397 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14398 if (Key.isInvalid())
14399 return ExprError();
14401 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
14402 if (Value.isInvalid())
14403 return ExprError();
14405 ObjCDictionaryElement Element = {
14406 Key.get(), Value.get(), SourceLocation(), NumExpansions
14409 // If any unexpanded parameter packs remain, we still have a
14410 // pack expansion.
14411 // FIXME: Can this really happen?
14412 if (Key.get()->containsUnexpandedParameterPack() ||
14413 Value.get()->containsUnexpandedParameterPack())
14414 Element.EllipsisLoc = OrigElement.EllipsisLoc;
14416 Elements.push_back(Element);
14419 // FIXME: Retain a pack expansion if RetainExpansion is true.
14421 // We've finished with this pack expansion.
14422 continue;
14425 // Transform and check key.
14426 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14427 if (Key.isInvalid())
14428 return ExprError();
14430 if (Key.get() != OrigElement.Key)
14431 ArgChanged = true;
14433 // Transform and check value.
14434 ExprResult Value
14435 = getDerived().TransformExpr(OrigElement.Value);
14436 if (Value.isInvalid())
14437 return ExprError();
14439 if (Value.get() != OrigElement.Value)
14440 ArgChanged = true;
14442 ObjCDictionaryElement Element = {Key.get(), Value.get(), SourceLocation(),
14443 std::nullopt};
14444 Elements.push_back(Element);
14447 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14448 return SemaRef.MaybeBindToTemporary(E);
14450 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
14451 Elements);
14454 template<typename Derived>
14455 ExprResult
14456 TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
14457 TypeSourceInfo *EncodedTypeInfo
14458 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
14459 if (!EncodedTypeInfo)
14460 return ExprError();
14462 if (!getDerived().AlwaysRebuild() &&
14463 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
14464 return E;
14466 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
14467 EncodedTypeInfo,
14468 E->getRParenLoc());
14471 template<typename Derived>
14472 ExprResult TreeTransform<Derived>::
14473 TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
14474 // This is a kind of implicit conversion, and it needs to get dropped
14475 // and recomputed for the same general reasons that ImplicitCastExprs
14476 // do, as well a more specific one: this expression is only valid when
14477 // it appears *immediately* as an argument expression.
14478 return getDerived().TransformExpr(E->getSubExpr());
14481 template<typename Derived>
14482 ExprResult TreeTransform<Derived>::
14483 TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
14484 TypeSourceInfo *TSInfo
14485 = getDerived().TransformType(E->getTypeInfoAsWritten());
14486 if (!TSInfo)
14487 return ExprError();
14489 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
14490 if (Result.isInvalid())
14491 return ExprError();
14493 if (!getDerived().AlwaysRebuild() &&
14494 TSInfo == E->getTypeInfoAsWritten() &&
14495 Result.get() == E->getSubExpr())
14496 return E;
14498 return SemaRef.BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(),
14499 E->getBridgeKeywordLoc(), TSInfo,
14500 Result.get());
14503 template <typename Derived>
14504 ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
14505 ObjCAvailabilityCheckExpr *E) {
14506 return E;
14509 template<typename Derived>
14510 ExprResult
14511 TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
14512 // Transform arguments.
14513 bool ArgChanged = false;
14514 SmallVector<Expr*, 8> Args;
14515 Args.reserve(E->getNumArgs());
14516 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
14517 &ArgChanged))
14518 return ExprError();
14520 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
14521 // Class message: transform the receiver type.
14522 TypeSourceInfo *ReceiverTypeInfo
14523 = getDerived().TransformType(E->getClassReceiverTypeInfo());
14524 if (!ReceiverTypeInfo)
14525 return ExprError();
14527 // If nothing changed, just retain the existing message send.
14528 if (!getDerived().AlwaysRebuild() &&
14529 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
14530 return SemaRef.MaybeBindToTemporary(E);
14532 // Build a new class message send.
14533 SmallVector<SourceLocation, 16> SelLocs;
14534 E->getSelectorLocs(SelLocs);
14535 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
14536 E->getSelector(),
14537 SelLocs,
14538 E->getMethodDecl(),
14539 E->getLeftLoc(),
14540 Args,
14541 E->getRightLoc());
14543 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
14544 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
14545 if (!E->getMethodDecl())
14546 return ExprError();
14548 // Build a new class message send to 'super'.
14549 SmallVector<SourceLocation, 16> SelLocs;
14550 E->getSelectorLocs(SelLocs);
14551 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
14552 E->getSelector(),
14553 SelLocs,
14554 E->getReceiverType(),
14555 E->getMethodDecl(),
14556 E->getLeftLoc(),
14557 Args,
14558 E->getRightLoc());
14561 // Instance message: transform the receiver
14562 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
14563 "Only class and instance messages may be instantiated");
14564 ExprResult Receiver
14565 = getDerived().TransformExpr(E->getInstanceReceiver());
14566 if (Receiver.isInvalid())
14567 return ExprError();
14569 // If nothing changed, just retain the existing message send.
14570 if (!getDerived().AlwaysRebuild() &&
14571 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
14572 return SemaRef.MaybeBindToTemporary(E);
14574 // Build a new instance message send.
14575 SmallVector<SourceLocation, 16> SelLocs;
14576 E->getSelectorLocs(SelLocs);
14577 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
14578 E->getSelector(),
14579 SelLocs,
14580 E->getMethodDecl(),
14581 E->getLeftLoc(),
14582 Args,
14583 E->getRightLoc());
14586 template<typename Derived>
14587 ExprResult
14588 TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
14589 return E;
14592 template<typename Derived>
14593 ExprResult
14594 TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
14595 return E;
14598 template<typename Derived>
14599 ExprResult
14600 TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
14601 // Transform the base expression.
14602 ExprResult Base = getDerived().TransformExpr(E->getBase());
14603 if (Base.isInvalid())
14604 return ExprError();
14606 // We don't need to transform the ivar; it will never change.
14608 // If nothing changed, just retain the existing expression.
14609 if (!getDerived().AlwaysRebuild() &&
14610 Base.get() == E->getBase())
14611 return E;
14613 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
14614 E->getLocation(),
14615 E->isArrow(), E->isFreeIvar());
14618 template<typename Derived>
14619 ExprResult
14620 TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
14621 // 'super' and types never change. Property never changes. Just
14622 // retain the existing expression.
14623 if (!E->isObjectReceiver())
14624 return E;
14626 // Transform the base expression.
14627 ExprResult Base = getDerived().TransformExpr(E->getBase());
14628 if (Base.isInvalid())
14629 return ExprError();
14631 // We don't need to transform the property; it will never change.
14633 // If nothing changed, just retain the existing expression.
14634 if (!getDerived().AlwaysRebuild() &&
14635 Base.get() == E->getBase())
14636 return E;
14638 if (E->isExplicitProperty())
14639 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
14640 E->getExplicitProperty(),
14641 E->getLocation());
14643 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
14644 SemaRef.Context.PseudoObjectTy,
14645 E->getImplicitPropertyGetter(),
14646 E->getImplicitPropertySetter(),
14647 E->getLocation());
14650 template<typename Derived>
14651 ExprResult
14652 TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
14653 // Transform the base expression.
14654 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
14655 if (Base.isInvalid())
14656 return ExprError();
14658 // Transform the key expression.
14659 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
14660 if (Key.isInvalid())
14661 return ExprError();
14663 // If nothing changed, just retain the existing expression.
14664 if (!getDerived().AlwaysRebuild() &&
14665 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
14666 return E;
14668 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
14669 Base.get(), Key.get(),
14670 E->getAtIndexMethodDecl(),
14671 E->setAtIndexMethodDecl());
14674 template<typename Derived>
14675 ExprResult
14676 TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
14677 // Transform the base expression.
14678 ExprResult Base = getDerived().TransformExpr(E->getBase());
14679 if (Base.isInvalid())
14680 return ExprError();
14682 // If nothing changed, just retain the existing expression.
14683 if (!getDerived().AlwaysRebuild() &&
14684 Base.get() == E->getBase())
14685 return E;
14687 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
14688 E->getOpLoc(),
14689 E->isArrow());
14692 template<typename Derived>
14693 ExprResult
14694 TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
14695 bool ArgumentChanged = false;
14696 SmallVector<Expr*, 8> SubExprs;
14697 SubExprs.reserve(E->getNumSubExprs());
14698 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
14699 SubExprs, &ArgumentChanged))
14700 return ExprError();
14702 if (!getDerived().AlwaysRebuild() &&
14703 !ArgumentChanged)
14704 return E;
14706 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
14707 SubExprs,
14708 E->getRParenLoc());
14711 template<typename Derived>
14712 ExprResult
14713 TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
14714 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
14715 if (SrcExpr.isInvalid())
14716 return ExprError();
14718 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
14719 if (!Type)
14720 return ExprError();
14722 if (!getDerived().AlwaysRebuild() &&
14723 Type == E->getTypeSourceInfo() &&
14724 SrcExpr.get() == E->getSrcExpr())
14725 return E;
14727 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
14728 SrcExpr.get(), Type,
14729 E->getRParenLoc());
14732 template<typename Derived>
14733 ExprResult
14734 TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
14735 BlockDecl *oldBlock = E->getBlockDecl();
14737 SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr);
14738 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
14740 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
14741 blockScope->TheDecl->setBlockMissingReturnType(
14742 oldBlock->blockMissingReturnType());
14744 SmallVector<ParmVarDecl*, 4> params;
14745 SmallVector<QualType, 4> paramTypes;
14747 const FunctionProtoType *exprFunctionType = E->getFunctionType();
14749 // Parameter substitution.
14750 Sema::ExtParameterInfoBuilder extParamInfos;
14751 if (getDerived().TransformFunctionTypeParams(
14752 E->getCaretLocation(), oldBlock->parameters(), nullptr,
14753 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
14754 extParamInfos)) {
14755 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
14756 return ExprError();
14759 QualType exprResultType =
14760 getDerived().TransformType(exprFunctionType->getReturnType());
14762 auto epi = exprFunctionType->getExtProtoInfo();
14763 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size());
14765 QualType functionType =
14766 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
14767 blockScope->FunctionType = functionType;
14769 // Set the parameters on the block decl.
14770 if (!params.empty())
14771 blockScope->TheDecl->setParams(params);
14773 if (!oldBlock->blockMissingReturnType()) {
14774 blockScope->HasImplicitReturnType = false;
14775 blockScope->ReturnType = exprResultType;
14778 // Transform the body
14779 StmtResult body = getDerived().TransformStmt(E->getBody());
14780 if (body.isInvalid()) {
14781 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
14782 return ExprError();
14785 #ifndef NDEBUG
14786 // In builds with assertions, make sure that we captured everything we
14787 // captured before.
14788 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
14789 for (const auto &I : oldBlock->captures()) {
14790 VarDecl *oldCapture = I.getVariable();
14792 // Ignore parameter packs.
14793 if (oldCapture->isParameterPack())
14794 continue;
14796 VarDecl *newCapture =
14797 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
14798 oldCapture));
14799 assert(blockScope->CaptureMap.count(newCapture));
14802 // The this pointer may not be captured by the instantiated block, even when
14803 // it's captured by the original block, if the expression causing the
14804 // capture is in the discarded branch of a constexpr if statement.
14805 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
14806 "this pointer isn't captured in the old block");
14808 #endif
14810 return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(),
14811 /*Scope=*/nullptr);
14814 template<typename Derived>
14815 ExprResult
14816 TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
14817 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
14818 if (SrcExpr.isInvalid())
14819 return ExprError();
14821 QualType Type = getDerived().TransformType(E->getType());
14823 return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(),
14824 E->getRParenLoc());
14827 template<typename Derived>
14828 ExprResult
14829 TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
14830 bool ArgumentChanged = false;
14831 SmallVector<Expr*, 8> SubExprs;
14832 SubExprs.reserve(E->getNumSubExprs());
14833 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
14834 SubExprs, &ArgumentChanged))
14835 return ExprError();
14837 if (!getDerived().AlwaysRebuild() &&
14838 !ArgumentChanged)
14839 return E;
14841 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
14842 E->getOp(), E->getRParenLoc());
14845 //===----------------------------------------------------------------------===//
14846 // Type reconstruction
14847 //===----------------------------------------------------------------------===//
14849 template<typename Derived>
14850 QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
14851 SourceLocation Star) {
14852 return SemaRef.BuildPointerType(PointeeType, Star,
14853 getDerived().getBaseEntity());
14856 template<typename Derived>
14857 QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
14858 SourceLocation Star) {
14859 return SemaRef.BuildBlockPointerType(PointeeType, Star,
14860 getDerived().getBaseEntity());
14863 template<typename Derived>
14864 QualType
14865 TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
14866 bool WrittenAsLValue,
14867 SourceLocation Sigil) {
14868 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue,
14869 Sigil, getDerived().getBaseEntity());
14872 template<typename Derived>
14873 QualType
14874 TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
14875 QualType ClassType,
14876 SourceLocation Sigil) {
14877 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil,
14878 getDerived().getBaseEntity());
14881 template<typename Derived>
14882 QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
14883 const ObjCTypeParamDecl *Decl,
14884 SourceLocation ProtocolLAngleLoc,
14885 ArrayRef<ObjCProtocolDecl *> Protocols,
14886 ArrayRef<SourceLocation> ProtocolLocs,
14887 SourceLocation ProtocolRAngleLoc) {
14888 return SemaRef.BuildObjCTypeParamType(Decl,
14889 ProtocolLAngleLoc, Protocols,
14890 ProtocolLocs, ProtocolRAngleLoc,
14891 /*FailOnError=*/true);
14894 template<typename Derived>
14895 QualType TreeTransform<Derived>::RebuildObjCObjectType(
14896 QualType BaseType,
14897 SourceLocation Loc,
14898 SourceLocation TypeArgsLAngleLoc,
14899 ArrayRef<TypeSourceInfo *> TypeArgs,
14900 SourceLocation TypeArgsRAngleLoc,
14901 SourceLocation ProtocolLAngleLoc,
14902 ArrayRef<ObjCProtocolDecl *> Protocols,
14903 ArrayRef<SourceLocation> ProtocolLocs,
14904 SourceLocation ProtocolRAngleLoc) {
14905 return SemaRef.BuildObjCObjectType(BaseType, Loc, TypeArgsLAngleLoc, TypeArgs,
14906 TypeArgsRAngleLoc, ProtocolLAngleLoc,
14907 Protocols, ProtocolLocs, ProtocolRAngleLoc,
14908 /*FailOnError=*/true,
14909 /*Rebuilding=*/true);
14912 template<typename Derived>
14913 QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
14914 QualType PointeeType,
14915 SourceLocation Star) {
14916 return SemaRef.Context.getObjCObjectPointerType(PointeeType);
14919 template <typename Derived>
14920 QualType TreeTransform<Derived>::RebuildArrayType(
14921 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
14922 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
14923 if (SizeExpr || !Size)
14924 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
14925 IndexTypeQuals, BracketsRange,
14926 getDerived().getBaseEntity());
14928 QualType Types[] = {
14929 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
14930 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
14931 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
14933 QualType SizeType;
14934 for (const auto &T : Types)
14935 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
14936 SizeType = T;
14937 break;
14940 // Note that we can return a VariableArrayType here in the case where
14941 // the element type was a dependent VariableArrayType.
14942 IntegerLiteral *ArraySize
14943 = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType,
14944 /*FIXME*/BracketsRange.getBegin());
14945 return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize,
14946 IndexTypeQuals, BracketsRange,
14947 getDerived().getBaseEntity());
14950 template <typename Derived>
14951 QualType TreeTransform<Derived>::RebuildConstantArrayType(
14952 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
14953 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
14954 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
14955 IndexTypeQuals, BracketsRange);
14958 template <typename Derived>
14959 QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
14960 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
14961 SourceRange BracketsRange) {
14962 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
14963 IndexTypeQuals, BracketsRange);
14966 template <typename Derived>
14967 QualType TreeTransform<Derived>::RebuildVariableArrayType(
14968 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
14969 unsigned IndexTypeQuals, SourceRange BracketsRange) {
14970 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
14971 SizeExpr,
14972 IndexTypeQuals, BracketsRange);
14975 template <typename Derived>
14976 QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
14977 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
14978 unsigned IndexTypeQuals, SourceRange BracketsRange) {
14979 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
14980 SizeExpr,
14981 IndexTypeQuals, BracketsRange);
14984 template <typename Derived>
14985 QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
14986 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
14987 return SemaRef.BuildAddressSpaceAttr(PointeeType, AddrSpaceExpr,
14988 AttributeLoc);
14991 template <typename Derived>
14992 QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
14993 unsigned NumElements,
14994 VectorKind VecKind) {
14995 // FIXME: semantic checking!
14996 return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);
14999 template <typename Derived>
15000 QualType TreeTransform<Derived>::RebuildDependentVectorType(
15001 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
15002 VectorKind VecKind) {
15003 return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc);
15006 template<typename Derived>
15007 QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
15008 unsigned NumElements,
15009 SourceLocation AttributeLoc) {
15010 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
15011 NumElements, true);
15012 IntegerLiteral *VectorSize
15013 = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
15014 AttributeLoc);
15015 return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
15018 template<typename Derived>
15019 QualType
15020 TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
15021 Expr *SizeExpr,
15022 SourceLocation AttributeLoc) {
15023 return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
15026 template <typename Derived>
15027 QualType TreeTransform<Derived>::RebuildConstantMatrixType(
15028 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
15029 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
15030 NumColumns);
15033 template <typename Derived>
15034 QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
15035 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
15036 SourceLocation AttributeLoc) {
15037 return SemaRef.BuildMatrixType(ElementType, RowExpr, ColumnExpr,
15038 AttributeLoc);
15041 template<typename Derived>
15042 QualType TreeTransform<Derived>::RebuildFunctionProtoType(
15043 QualType T,
15044 MutableArrayRef<QualType> ParamTypes,
15045 const FunctionProtoType::ExtProtoInfo &EPI) {
15046 return SemaRef.BuildFunctionType(T, ParamTypes,
15047 getDerived().getBaseLocation(),
15048 getDerived().getBaseEntity(),
15049 EPI);
15052 template<typename Derived>
15053 QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
15054 return SemaRef.Context.getFunctionNoProtoType(T);
15057 template<typename Derived>
15058 QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
15059 Decl *D) {
15060 assert(D && "no decl found");
15061 if (D->isInvalidDecl()) return QualType();
15063 // FIXME: Doesn't account for ObjCInterfaceDecl!
15064 if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
15065 // A valid resolved using typename pack expansion decl can have multiple
15066 // UsingDecls, but they must each have exactly one type, and it must be
15067 // the same type in every case. But we must have at least one expansion!
15068 if (UPD->expansions().empty()) {
15069 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
15070 << UPD->isCXXClassMember() << UPD;
15071 return QualType();
15074 // We might still have some unresolved types. Try to pick a resolved type
15075 // if we can. The final instantiation will check that the remaining
15076 // unresolved types instantiate to the type we pick.
15077 QualType FallbackT;
15078 QualType T;
15079 for (auto *E : UPD->expansions()) {
15080 QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
15081 if (ThisT.isNull())
15082 continue;
15083 else if (ThisT->getAs<UnresolvedUsingType>())
15084 FallbackT = ThisT;
15085 else if (T.isNull())
15086 T = ThisT;
15087 else
15088 assert(getSema().Context.hasSameType(ThisT, T) &&
15089 "mismatched resolved types in using pack expansion");
15091 return T.isNull() ? FallbackT : T;
15092 } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
15093 assert(Using->hasTypename() &&
15094 "UnresolvedUsingTypenameDecl transformed to non-typename using");
15096 // A valid resolved using typename decl points to exactly one type decl.
15097 assert(++Using->shadow_begin() == Using->shadow_end());
15099 UsingShadowDecl *Shadow = *Using->shadow_begin();
15100 if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), Loc))
15101 return QualType();
15102 return SemaRef.Context.getUsingType(
15103 Shadow, SemaRef.Context.getTypeDeclType(
15104 cast<TypeDecl>(Shadow->getTargetDecl())));
15105 } else {
15106 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
15107 "UnresolvedUsingTypenameDecl transformed to non-using decl");
15108 return SemaRef.Context.getTypeDeclType(
15109 cast<UnresolvedUsingTypenameDecl>(D));
15113 template <typename Derived>
15114 QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
15115 TypeOfKind Kind) {
15116 return SemaRef.BuildTypeofExprType(E, Kind);
15119 template<typename Derived>
15120 QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
15121 TypeOfKind Kind) {
15122 return SemaRef.Context.getTypeOfType(Underlying, Kind);
15125 template <typename Derived>
15126 QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
15127 return SemaRef.BuildDecltypeType(E);
15130 template<typename Derived>
15131 QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
15132 UnaryTransformType::UTTKind UKind,
15133 SourceLocation Loc) {
15134 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
15137 template<typename Derived>
15138 QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
15139 TemplateName Template,
15140 SourceLocation TemplateNameLoc,
15141 TemplateArgumentListInfo &TemplateArgs) {
15142 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
15145 template<typename Derived>
15146 QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
15147 SourceLocation KWLoc) {
15148 return SemaRef.BuildAtomicType(ValueType, KWLoc);
15151 template<typename Derived>
15152 QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
15153 SourceLocation KWLoc,
15154 bool isReadPipe) {
15155 return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc)
15156 : SemaRef.BuildWritePipeType(ValueType, KWLoc);
15159 template <typename Derived>
15160 QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
15161 unsigned NumBits,
15162 SourceLocation Loc) {
15163 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
15164 NumBits, true);
15165 IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,
15166 SemaRef.Context.IntTy, Loc);
15167 return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc);
15170 template <typename Derived>
15171 QualType TreeTransform<Derived>::RebuildDependentBitIntType(
15172 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
15173 return SemaRef.BuildBitIntType(IsUnsigned, NumBitsExpr, Loc);
15176 template<typename Derived>
15177 TemplateName
15178 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15179 bool TemplateKW,
15180 TemplateDecl *Template) {
15181 return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW,
15182 TemplateName(Template));
15185 template<typename Derived>
15186 TemplateName
15187 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15188 SourceLocation TemplateKWLoc,
15189 const IdentifierInfo &Name,
15190 SourceLocation NameLoc,
15191 QualType ObjectType,
15192 NamedDecl *FirstQualifierInScope,
15193 bool AllowInjectedClassName) {
15194 UnqualifiedId TemplateName;
15195 TemplateName.setIdentifier(&Name, NameLoc);
15196 Sema::TemplateTy Template;
15197 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
15198 TemplateName, ParsedType::make(ObjectType),
15199 /*EnteringContext=*/false, Template,
15200 AllowInjectedClassName);
15201 return Template.get();
15204 template<typename Derived>
15205 TemplateName
15206 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15207 SourceLocation TemplateKWLoc,
15208 OverloadedOperatorKind Operator,
15209 SourceLocation NameLoc,
15210 QualType ObjectType,
15211 bool AllowInjectedClassName) {
15212 UnqualifiedId Name;
15213 // FIXME: Bogus location information.
15214 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
15215 Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);
15216 Sema::TemplateTy Template;
15217 getSema().ActOnTemplateName(
15218 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(ObjectType),
15219 /*EnteringContext=*/false, Template, AllowInjectedClassName);
15220 return Template.get();
15223 template <typename Derived>
15224 ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
15225 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
15226 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
15227 Expr *Second) {
15228 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
15230 if (First->getObjectKind() == OK_ObjCProperty) {
15231 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
15232 if (BinaryOperator::isAssignmentOp(Opc))
15233 return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc, Opc,
15234 First, Second);
15235 ExprResult Result = SemaRef.CheckPlaceholderExpr(First);
15236 if (Result.isInvalid())
15237 return ExprError();
15238 First = Result.get();
15241 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
15242 ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
15243 if (Result.isInvalid())
15244 return ExprError();
15245 Second = Result.get();
15248 // Determine whether this should be a builtin operation.
15249 if (Op == OO_Subscript) {
15250 if (!First->getType()->isOverloadableType() &&
15251 !Second->getType()->isOverloadableType())
15252 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
15253 OpLoc);
15254 } else if (Op == OO_Arrow) {
15255 // It is possible that the type refers to a RecoveryExpr created earlier
15256 // in the tree transformation.
15257 if (First->getType()->isDependentType())
15258 return ExprError();
15259 // -> is never a builtin operation.
15260 return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);
15261 } else if (Second == nullptr || isPostIncDec) {
15262 if (!First->getType()->isOverloadableType() ||
15263 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
15264 // The argument is not of overloadable type, or this is an expression
15265 // of the form &Class::member, so try to create a built-in unary
15266 // operation.
15267 UnaryOperatorKind Opc
15268 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
15270 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
15272 } else {
15273 if (!First->getType()->isOverloadableType() &&
15274 !Second->getType()->isOverloadableType()) {
15275 // Neither of the arguments is an overloadable type, so try to
15276 // create a built-in binary operation.
15277 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
15278 ExprResult Result
15279 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
15280 if (Result.isInvalid())
15281 return ExprError();
15283 return Result;
15287 // Add any functions found via argument-dependent lookup.
15288 Expr *Args[2] = { First, Second };
15289 unsigned NumArgs = 1 + (Second != nullptr);
15291 // Create the overloaded operator invocation for unary operators.
15292 if (NumArgs == 1 || isPostIncDec) {
15293 UnaryOperatorKind Opc
15294 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
15295 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First,
15296 RequiresADL);
15299 // Create the overloaded operator invocation for binary operators.
15300 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
15301 ExprResult Result = SemaRef.CreateOverloadedBinOp(
15302 OpLoc, Opc, Functions, Args[0], Args[1], RequiresADL);
15303 if (Result.isInvalid())
15304 return ExprError();
15306 return Result;
15309 template<typename Derived>
15310 ExprResult
15311 TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
15312 SourceLocation OperatorLoc,
15313 bool isArrow,
15314 CXXScopeSpec &SS,
15315 TypeSourceInfo *ScopeType,
15316 SourceLocation CCLoc,
15317 SourceLocation TildeLoc,
15318 PseudoDestructorTypeStorage Destroyed) {
15319 QualType BaseType = Base->getType();
15320 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
15321 (!isArrow && !BaseType->getAs<RecordType>()) ||
15322 (isArrow && BaseType->getAs<PointerType>() &&
15323 !BaseType->castAs<PointerType>()->getPointeeType()
15324 ->template getAs<RecordType>())){
15325 // This pseudo-destructor expression is still a pseudo-destructor.
15326 return SemaRef.BuildPseudoDestructorExpr(
15327 Base, OperatorLoc, isArrow ? tok::arrow : tok::period, SS, ScopeType,
15328 CCLoc, TildeLoc, Destroyed);
15331 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
15332 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
15333 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
15334 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
15335 NameInfo.setNamedTypeInfo(DestroyedType);
15337 // The scope type is now known to be a valid nested name specifier
15338 // component. Tack it on to the end of the nested name specifier.
15339 if (ScopeType) {
15340 if (!ScopeType->getType()->getAs<TagType>()) {
15341 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
15342 diag::err_expected_class_or_namespace)
15343 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
15344 return ExprError();
15346 SS.Extend(SemaRef.Context, SourceLocation(), ScopeType->getTypeLoc(),
15347 CCLoc);
15350 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
15351 return getSema().BuildMemberReferenceExpr(Base, BaseType,
15352 OperatorLoc, isArrow,
15353 SS, TemplateKWLoc,
15354 /*FIXME: FirstQualifier*/ nullptr,
15355 NameInfo,
15356 /*TemplateArgs*/ nullptr,
15357 /*S*/nullptr);
15360 template<typename Derived>
15361 StmtResult
15362 TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
15363 SourceLocation Loc = S->getBeginLoc();
15364 CapturedDecl *CD = S->getCapturedDecl();
15365 unsigned NumParams = CD->getNumParams();
15366 unsigned ContextParamPos = CD->getContextParamPosition();
15367 SmallVector<Sema::CapturedParamNameType, 4> Params;
15368 for (unsigned I = 0; I < NumParams; ++I) {
15369 if (I != ContextParamPos) {
15370 Params.push_back(
15371 std::make_pair(
15372 CD->getParam(I)->getName(),
15373 getDerived().TransformType(CD->getParam(I)->getType())));
15374 } else {
15375 Params.push_back(std::make_pair(StringRef(), QualType()));
15378 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
15379 S->getCapturedRegionKind(), Params);
15380 StmtResult Body;
15382 Sema::CompoundScopeRAII CompoundScope(getSema());
15383 Body = getDerived().TransformStmt(S->getCapturedStmt());
15386 if (Body.isInvalid()) {
15387 getSema().ActOnCapturedRegionError();
15388 return StmtError();
15391 return getSema().ActOnCapturedRegionEnd(Body.get());
15394 } // end namespace clang
15396 #endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H