[Flang] remove whole-archive option for AIX linker (#76039)
[llvm-project.git] / clang / lib / Sema / TreeTransform.h
blob7df5bf0cb71370b5e43cf9ba3431b2bd7ebaa58c
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 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1382 return StmtError();
1383 return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt);
1386 /// Build a new "if" statement.
1388 /// By default, performs semantic analysis to build the new statement.
1389 /// Subclasses may override this routine to provide different behavior.
1390 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1391 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1392 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1393 SourceLocation ElseLoc, Stmt *Else) {
1394 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1395 Then, ElseLoc, Else);
1398 /// Start building a new switch statement.
1400 /// By default, performs semantic analysis to build the new statement.
1401 /// Subclasses may override this routine to provide different behavior.
1402 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1403 SourceLocation LParenLoc, Stmt *Init,
1404 Sema::ConditionResult Cond,
1405 SourceLocation RParenLoc) {
1406 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1407 RParenLoc);
1410 /// Attach the body to the switch statement.
1412 /// By default, performs semantic analysis to build the new statement.
1413 /// Subclasses may override this routine to provide different behavior.
1414 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1415 Stmt *Switch, Stmt *Body) {
1416 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1419 /// Build a new while statement.
1421 /// By default, performs semantic analysis to build the new statement.
1422 /// Subclasses may override this routine to provide different behavior.
1423 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1424 Sema::ConditionResult Cond,
1425 SourceLocation RParenLoc, Stmt *Body) {
1426 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1429 /// Build a new do-while statement.
1431 /// By default, performs semantic analysis to build the new statement.
1432 /// Subclasses may override this routine to provide different behavior.
1433 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1434 SourceLocation WhileLoc, SourceLocation LParenLoc,
1435 Expr *Cond, SourceLocation RParenLoc) {
1436 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1437 Cond, RParenLoc);
1440 /// Build a new for statement.
1442 /// By default, performs semantic analysis to build the new statement.
1443 /// Subclasses may override this routine to provide different behavior.
1444 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1445 Stmt *Init, Sema::ConditionResult Cond,
1446 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1447 Stmt *Body) {
1448 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1449 Inc, RParenLoc, Body);
1452 /// Build a new goto statement.
1454 /// By default, performs semantic analysis to build the new statement.
1455 /// Subclasses may override this routine to provide different behavior.
1456 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1457 LabelDecl *Label) {
1458 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1461 /// Build a new indirect goto statement.
1463 /// By default, performs semantic analysis to build the new statement.
1464 /// Subclasses may override this routine to provide different behavior.
1465 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1466 SourceLocation StarLoc,
1467 Expr *Target) {
1468 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1471 /// Build a new return statement.
1473 /// By default, performs semantic analysis to build the new statement.
1474 /// Subclasses may override this routine to provide different behavior.
1475 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1476 return getSema().BuildReturnStmt(ReturnLoc, Result);
1479 /// Build a new declaration statement.
1481 /// By default, performs semantic analysis to build the new statement.
1482 /// Subclasses may override this routine to provide different behavior.
1483 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1484 SourceLocation StartLoc, SourceLocation EndLoc) {
1485 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1486 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1489 /// Build a new inline asm statement.
1491 /// By default, performs semantic analysis to build the new statement.
1492 /// Subclasses may override this routine to provide different behavior.
1493 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1494 bool IsVolatile, unsigned NumOutputs,
1495 unsigned NumInputs, IdentifierInfo **Names,
1496 MultiExprArg Constraints, MultiExprArg Exprs,
1497 Expr *AsmString, MultiExprArg Clobbers,
1498 unsigned NumLabels,
1499 SourceLocation RParenLoc) {
1500 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1501 NumInputs, Names, Constraints, Exprs,
1502 AsmString, Clobbers, NumLabels, RParenLoc);
1505 /// Build a new MS style inline asm statement.
1507 /// By default, performs semantic analysis to build the new statement.
1508 /// Subclasses may override this routine to provide different behavior.
1509 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1510 ArrayRef<Token> AsmToks,
1511 StringRef AsmString,
1512 unsigned NumOutputs, unsigned NumInputs,
1513 ArrayRef<StringRef> Constraints,
1514 ArrayRef<StringRef> Clobbers,
1515 ArrayRef<Expr*> Exprs,
1516 SourceLocation EndLoc) {
1517 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1518 NumOutputs, NumInputs,
1519 Constraints, Clobbers, Exprs, EndLoc);
1522 /// Build a new co_return statement.
1524 /// By default, performs semantic analysis to build the new statement.
1525 /// Subclasses may override this routine to provide different behavior.
1526 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1527 bool IsImplicit) {
1528 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1531 /// Build a new co_await expression.
1533 /// By default, performs semantic analysis to build the new expression.
1534 /// Subclasses may override this routine to provide different behavior.
1535 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1536 UnresolvedLookupExpr *OpCoawaitLookup,
1537 bool IsImplicit) {
1538 // This function rebuilds a coawait-expr given its operator.
1539 // For an explicit coawait-expr, the rebuild involves the full set
1540 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1541 // including calling await_transform().
1542 // For an implicit coawait-expr, we need to rebuild the "operator
1543 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1544 // This mirrors how the implicit CoawaitExpr is originally created
1545 // in Sema::ActOnCoroutineBodyStart().
1546 if (IsImplicit) {
1547 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1548 CoawaitLoc, Operand, OpCoawaitLookup);
1549 if (Suspend.isInvalid())
1550 return ExprError();
1551 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1552 Suspend.get(), true);
1555 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1556 OpCoawaitLookup);
1559 /// Build a new co_await expression.
1561 /// By default, performs semantic analysis to build the new expression.
1562 /// Subclasses may override this routine to provide different behavior.
1563 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1564 Expr *Result,
1565 UnresolvedLookupExpr *Lookup) {
1566 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1569 /// Build a new co_yield expression.
1571 /// By default, performs semantic analysis to build the new expression.
1572 /// Subclasses may override this routine to provide different behavior.
1573 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1574 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1577 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1578 return getSema().BuildCoroutineBodyStmt(Args);
1581 /// Build a new Objective-C \@try statement.
1583 /// By default, performs semantic analysis to build the new statement.
1584 /// Subclasses may override this routine to provide different behavior.
1585 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1586 Stmt *TryBody,
1587 MultiStmtArg CatchStmts,
1588 Stmt *Finally) {
1589 return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1590 Finally);
1593 /// Rebuild an Objective-C exception declaration.
1595 /// By default, performs semantic analysis to build the new declaration.
1596 /// Subclasses may override this routine to provide different behavior.
1597 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1598 TypeSourceInfo *TInfo, QualType T) {
1599 return getSema().BuildObjCExceptionDecl(TInfo, T,
1600 ExceptionDecl->getInnerLocStart(),
1601 ExceptionDecl->getLocation(),
1602 ExceptionDecl->getIdentifier());
1605 /// Build a new Objective-C \@catch statement.
1607 /// By default, performs semantic analysis to build the new statement.
1608 /// Subclasses may override this routine to provide different behavior.
1609 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1610 SourceLocation RParenLoc,
1611 VarDecl *Var,
1612 Stmt *Body) {
1613 return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
1614 Var, Body);
1617 /// Build a new Objective-C \@finally statement.
1619 /// By default, performs semantic analysis to build the new statement.
1620 /// Subclasses may override this routine to provide different behavior.
1621 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1622 Stmt *Body) {
1623 return getSema().ActOnObjCAtFinallyStmt(AtLoc, Body);
1626 /// Build a new Objective-C \@throw statement.
1628 /// By default, performs semantic analysis to build the new statement.
1629 /// Subclasses may override this routine to provide different behavior.
1630 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1631 Expr *Operand) {
1632 return getSema().BuildObjCAtThrowStmt(AtLoc, Operand);
1635 /// Build a new OpenMP Canonical loop.
1637 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1638 /// OMPCanonicalLoop.
1639 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1640 return getSema().ActOnOpenMPCanonicalLoop(LoopStmt);
1643 /// Build a new OpenMP executable directive.
1645 /// By default, performs semantic analysis to build the new statement.
1646 /// Subclasses may override this routine to provide different behavior.
1647 StmtResult RebuildOMPExecutableDirective(
1648 OpenMPDirectiveKind Kind, DeclarationNameInfo DirName,
1649 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
1650 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
1651 OpenMPDirectiveKind PrevMappedDirective = OMPD_unknown) {
1653 return getSema().ActOnOpenMPExecutableDirective(
1654 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc,
1655 PrevMappedDirective);
1658 /// Build a new OpenMP 'if' clause.
1660 /// By default, performs semantic analysis to build the new OpenMP clause.
1661 /// Subclasses may override this routine to provide different behavior.
1662 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1663 Expr *Condition, SourceLocation StartLoc,
1664 SourceLocation LParenLoc,
1665 SourceLocation NameModifierLoc,
1666 SourceLocation ColonLoc,
1667 SourceLocation EndLoc) {
1668 return getSema().ActOnOpenMPIfClause(NameModifier, Condition, StartLoc,
1669 LParenLoc, NameModifierLoc, ColonLoc,
1670 EndLoc);
1673 /// Build a new OpenMP 'final' clause.
1675 /// By default, performs semantic analysis to build the new OpenMP clause.
1676 /// Subclasses may override this routine to provide different behavior.
1677 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1678 SourceLocation LParenLoc,
1679 SourceLocation EndLoc) {
1680 return getSema().ActOnOpenMPFinalClause(Condition, StartLoc, LParenLoc,
1681 EndLoc);
1684 /// Build a new OpenMP 'num_threads' clause.
1686 /// By default, performs semantic analysis to build the new OpenMP clause.
1687 /// Subclasses may override this routine to provide different behavior.
1688 OMPClause *RebuildOMPNumThreadsClause(Expr *NumThreads,
1689 SourceLocation StartLoc,
1690 SourceLocation LParenLoc,
1691 SourceLocation EndLoc) {
1692 return getSema().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc,
1693 LParenLoc, EndLoc);
1696 /// Build a new OpenMP 'safelen' clause.
1698 /// By default, performs semantic analysis to build the new OpenMP clause.
1699 /// Subclasses may override this routine to provide different behavior.
1700 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1701 SourceLocation LParenLoc,
1702 SourceLocation EndLoc) {
1703 return getSema().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc, EndLoc);
1706 /// Build a new OpenMP 'simdlen' clause.
1708 /// By default, performs semantic analysis to build the new OpenMP clause.
1709 /// Subclasses may override this routine to provide different behavior.
1710 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1711 SourceLocation LParenLoc,
1712 SourceLocation EndLoc) {
1713 return getSema().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc, EndLoc);
1716 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1717 SourceLocation StartLoc,
1718 SourceLocation LParenLoc,
1719 SourceLocation EndLoc) {
1720 return getSema().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc, EndLoc);
1723 /// Build a new OpenMP 'full' clause.
1724 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1725 SourceLocation EndLoc) {
1726 return getSema().ActOnOpenMPFullClause(StartLoc, EndLoc);
1729 /// Build a new OpenMP 'partial' clause.
1730 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1731 SourceLocation LParenLoc,
1732 SourceLocation EndLoc) {
1733 return getSema().ActOnOpenMPPartialClause(Factor, StartLoc, LParenLoc,
1734 EndLoc);
1737 /// Build a new OpenMP 'allocator' clause.
1739 /// By default, performs semantic analysis to build the new OpenMP clause.
1740 /// Subclasses may override this routine to provide different behavior.
1741 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1742 SourceLocation LParenLoc,
1743 SourceLocation EndLoc) {
1744 return getSema().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc, EndLoc);
1747 /// Build a new OpenMP 'collapse' clause.
1749 /// By default, performs semantic analysis to build the new OpenMP clause.
1750 /// Subclasses may override this routine to provide different behavior.
1751 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1752 SourceLocation LParenLoc,
1753 SourceLocation EndLoc) {
1754 return getSema().ActOnOpenMPCollapseClause(Num, StartLoc, LParenLoc,
1755 EndLoc);
1758 /// Build a new OpenMP 'default' clause.
1760 /// By default, performs semantic analysis to build the new OpenMP clause.
1761 /// Subclasses may override this routine to provide different behavior.
1762 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1763 SourceLocation StartLoc,
1764 SourceLocation LParenLoc,
1765 SourceLocation EndLoc) {
1766 return getSema().ActOnOpenMPDefaultClause(Kind, KindKwLoc,
1767 StartLoc, LParenLoc, EndLoc);
1770 /// Build a new OpenMP 'proc_bind' clause.
1772 /// By default, performs semantic analysis to build the new OpenMP clause.
1773 /// Subclasses may override this routine to provide different behavior.
1774 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1775 SourceLocation KindKwLoc,
1776 SourceLocation StartLoc,
1777 SourceLocation LParenLoc,
1778 SourceLocation EndLoc) {
1779 return getSema().ActOnOpenMPProcBindClause(Kind, KindKwLoc,
1780 StartLoc, LParenLoc, EndLoc);
1783 /// Build a new OpenMP 'schedule' clause.
1785 /// By default, performs semantic analysis to build the new OpenMP clause.
1786 /// Subclasses may override this routine to provide different behavior.
1787 OMPClause *RebuildOMPScheduleClause(
1788 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1789 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1790 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1791 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1792 return getSema().ActOnOpenMPScheduleClause(
1793 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1794 CommaLoc, EndLoc);
1797 /// Build a new OpenMP 'ordered' clause.
1799 /// By default, performs semantic analysis to build the new OpenMP clause.
1800 /// Subclasses may override this routine to provide different behavior.
1801 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1802 SourceLocation EndLoc,
1803 SourceLocation LParenLoc, Expr *Num) {
1804 return getSema().ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Num);
1807 /// Build a new OpenMP 'private' clause.
1809 /// By default, performs semantic analysis to build the new OpenMP clause.
1810 /// Subclasses may override this routine to provide different behavior.
1811 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1812 SourceLocation StartLoc,
1813 SourceLocation LParenLoc,
1814 SourceLocation EndLoc) {
1815 return getSema().ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc,
1816 EndLoc);
1819 /// Build a new OpenMP 'firstprivate' clause.
1821 /// By default, performs semantic analysis to build the new OpenMP clause.
1822 /// Subclasses may override this routine to provide different behavior.
1823 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1824 SourceLocation StartLoc,
1825 SourceLocation LParenLoc,
1826 SourceLocation EndLoc) {
1827 return getSema().ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc,
1828 EndLoc);
1831 /// Build a new OpenMP 'lastprivate' clause.
1833 /// By default, performs semantic analysis to build the new OpenMP clause.
1834 /// Subclasses may override this routine to provide different behavior.
1835 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1836 OpenMPLastprivateModifier LPKind,
1837 SourceLocation LPKindLoc,
1838 SourceLocation ColonLoc,
1839 SourceLocation StartLoc,
1840 SourceLocation LParenLoc,
1841 SourceLocation EndLoc) {
1842 return getSema().ActOnOpenMPLastprivateClause(
1843 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1846 /// Build a new OpenMP 'shared' clause.
1848 /// By default, performs semantic analysis to build the new OpenMP clause.
1849 /// Subclasses may override this routine to provide different behavior.
1850 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1851 SourceLocation StartLoc,
1852 SourceLocation LParenLoc,
1853 SourceLocation EndLoc) {
1854 return getSema().ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc,
1855 EndLoc);
1858 /// Build a new OpenMP 'reduction' clause.
1860 /// By default, performs semantic analysis to build the new statement.
1861 /// Subclasses may override this routine to provide different behavior.
1862 OMPClause *RebuildOMPReductionClause(
1863 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1864 SourceLocation StartLoc, SourceLocation LParenLoc,
1865 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1866 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1867 const DeclarationNameInfo &ReductionId,
1868 ArrayRef<Expr *> UnresolvedReductions) {
1869 return getSema().ActOnOpenMPReductionClause(
1870 VarList, Modifier, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
1871 ReductionIdScopeSpec, ReductionId, UnresolvedReductions);
1874 /// Build a new OpenMP 'task_reduction' clause.
1876 /// By default, performs semantic analysis to build the new statement.
1877 /// Subclasses may override this routine to provide different behavior.
1878 OMPClause *RebuildOMPTaskReductionClause(
1879 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1880 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1881 CXXScopeSpec &ReductionIdScopeSpec,
1882 const DeclarationNameInfo &ReductionId,
1883 ArrayRef<Expr *> UnresolvedReductions) {
1884 return getSema().ActOnOpenMPTaskReductionClause(
1885 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1886 ReductionId, UnresolvedReductions);
1889 /// Build a new OpenMP 'in_reduction' clause.
1891 /// By default, performs semantic analysis to build the new statement.
1892 /// Subclasses may override this routine to provide different behavior.
1893 OMPClause *
1894 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1895 SourceLocation LParenLoc, SourceLocation ColonLoc,
1896 SourceLocation EndLoc,
1897 CXXScopeSpec &ReductionIdScopeSpec,
1898 const DeclarationNameInfo &ReductionId,
1899 ArrayRef<Expr *> UnresolvedReductions) {
1900 return getSema().ActOnOpenMPInReductionClause(
1901 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1902 ReductionId, UnresolvedReductions);
1905 /// Build a new OpenMP 'linear' clause.
1907 /// By default, performs semantic analysis to build the new OpenMP clause.
1908 /// Subclasses may override this routine to provide different behavior.
1909 OMPClause *RebuildOMPLinearClause(
1910 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1911 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1912 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1913 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
1914 return getSema().ActOnOpenMPLinearClause(VarList, Step, StartLoc, LParenLoc,
1915 Modifier, ModifierLoc, ColonLoc,
1916 StepModifierLoc, EndLoc);
1919 /// Build a new OpenMP 'aligned' clause.
1921 /// By default, performs semantic analysis to build the new OpenMP clause.
1922 /// Subclasses may override this routine to provide different behavior.
1923 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
1924 SourceLocation StartLoc,
1925 SourceLocation LParenLoc,
1926 SourceLocation ColonLoc,
1927 SourceLocation EndLoc) {
1928 return getSema().ActOnOpenMPAlignedClause(VarList, Alignment, StartLoc,
1929 LParenLoc, ColonLoc, EndLoc);
1932 /// Build a new OpenMP 'copyin' clause.
1934 /// By default, performs semantic analysis to build the new OpenMP clause.
1935 /// Subclasses may override this routine to provide different behavior.
1936 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
1937 SourceLocation StartLoc,
1938 SourceLocation LParenLoc,
1939 SourceLocation EndLoc) {
1940 return getSema().ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc,
1941 EndLoc);
1944 /// Build a new OpenMP 'copyprivate' clause.
1946 /// By default, performs semantic analysis to build the new OpenMP clause.
1947 /// Subclasses may override this routine to provide different behavior.
1948 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
1949 SourceLocation StartLoc,
1950 SourceLocation LParenLoc,
1951 SourceLocation EndLoc) {
1952 return getSema().ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc,
1953 EndLoc);
1956 /// Build a new OpenMP 'flush' pseudo clause.
1958 /// By default, performs semantic analysis to build the new OpenMP clause.
1959 /// Subclasses may override this routine to provide different behavior.
1960 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
1961 SourceLocation StartLoc,
1962 SourceLocation LParenLoc,
1963 SourceLocation EndLoc) {
1964 return getSema().ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc,
1965 EndLoc);
1968 /// Build a new OpenMP 'depobj' pseudo clause.
1970 /// By default, performs semantic analysis to build the new OpenMP clause.
1971 /// Subclasses may override this routine to provide different behavior.
1972 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
1973 SourceLocation LParenLoc,
1974 SourceLocation EndLoc) {
1975 return getSema().ActOnOpenMPDepobjClause(Depobj, StartLoc, LParenLoc,
1976 EndLoc);
1979 /// Build a new OpenMP 'depend' pseudo clause.
1981 /// By default, performs semantic analysis to build the new OpenMP clause.
1982 /// Subclasses may override this routine to provide different behavior.
1983 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
1984 Expr *DepModifier, ArrayRef<Expr *> VarList,
1985 SourceLocation StartLoc,
1986 SourceLocation LParenLoc,
1987 SourceLocation EndLoc) {
1988 return getSema().ActOnOpenMPDependClause(Data, DepModifier, VarList,
1989 StartLoc, LParenLoc, EndLoc);
1992 /// Build a new OpenMP 'device' clause.
1994 /// By default, performs semantic analysis to build the new statement.
1995 /// Subclasses may override this routine to provide different behavior.
1996 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
1997 Expr *Device, SourceLocation StartLoc,
1998 SourceLocation LParenLoc,
1999 SourceLocation ModifierLoc,
2000 SourceLocation EndLoc) {
2001 return getSema().ActOnOpenMPDeviceClause(Modifier, Device, StartLoc,
2002 LParenLoc, ModifierLoc, EndLoc);
2005 /// Build a new OpenMP 'map' clause.
2007 /// By default, performs semantic analysis to build the new OpenMP clause.
2008 /// Subclasses may override this routine to provide different behavior.
2009 OMPClause *RebuildOMPMapClause(
2010 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2011 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2012 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2013 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2014 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2015 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2016 return getSema().ActOnOpenMPMapClause(
2017 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2018 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2019 ColonLoc, VarList, Locs,
2020 /*NoDiagnose=*/false, UnresolvedMappers);
2023 /// Build a new OpenMP 'allocate' clause.
2025 /// By default, performs semantic analysis to build the new OpenMP clause.
2026 /// Subclasses may override this routine to provide different behavior.
2027 OMPClause *RebuildOMPAllocateClause(Expr *Allocate, ArrayRef<Expr *> VarList,
2028 SourceLocation StartLoc,
2029 SourceLocation LParenLoc,
2030 SourceLocation ColonLoc,
2031 SourceLocation EndLoc) {
2032 return getSema().ActOnOpenMPAllocateClause(Allocate, VarList, StartLoc,
2033 LParenLoc, ColonLoc, EndLoc);
2036 /// Build a new OpenMP 'num_teams' clause.
2038 /// By default, performs semantic analysis to build the new statement.
2039 /// Subclasses may override this routine to provide different behavior.
2040 OMPClause *RebuildOMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc,
2041 SourceLocation LParenLoc,
2042 SourceLocation EndLoc) {
2043 return getSema().ActOnOpenMPNumTeamsClause(NumTeams, StartLoc, LParenLoc,
2044 EndLoc);
2047 /// Build a new OpenMP 'thread_limit' clause.
2049 /// By default, performs semantic analysis to build the new statement.
2050 /// Subclasses may override this routine to provide different behavior.
2051 OMPClause *RebuildOMPThreadLimitClause(Expr *ThreadLimit,
2052 SourceLocation StartLoc,
2053 SourceLocation LParenLoc,
2054 SourceLocation EndLoc) {
2055 return getSema().ActOnOpenMPThreadLimitClause(ThreadLimit, StartLoc,
2056 LParenLoc, EndLoc);
2059 /// Build a new OpenMP 'priority' clause.
2061 /// By default, performs semantic analysis to build the new statement.
2062 /// Subclasses may override this routine to provide different behavior.
2063 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2064 SourceLocation LParenLoc,
2065 SourceLocation EndLoc) {
2066 return getSema().ActOnOpenMPPriorityClause(Priority, StartLoc, LParenLoc,
2067 EndLoc);
2070 /// Build a new OpenMP 'grainsize' clause.
2072 /// By default, performs semantic analysis to build the new statement.
2073 /// Subclasses may override this routine to provide different behavior.
2074 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2075 Expr *Device, SourceLocation StartLoc,
2076 SourceLocation LParenLoc,
2077 SourceLocation ModifierLoc,
2078 SourceLocation EndLoc) {
2079 return getSema().ActOnOpenMPGrainsizeClause(Modifier, Device, StartLoc,
2080 LParenLoc, ModifierLoc, EndLoc);
2083 /// Build a new OpenMP 'num_tasks' clause.
2085 /// By default, performs semantic analysis to build the new statement.
2086 /// Subclasses may override this routine to provide different behavior.
2087 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2088 Expr *NumTasks, SourceLocation StartLoc,
2089 SourceLocation LParenLoc,
2090 SourceLocation ModifierLoc,
2091 SourceLocation EndLoc) {
2092 return getSema().ActOnOpenMPNumTasksClause(Modifier, NumTasks, StartLoc,
2093 LParenLoc, ModifierLoc, EndLoc);
2096 /// Build a new OpenMP 'hint' clause.
2098 /// By default, performs semantic analysis to build the new statement.
2099 /// Subclasses may override this routine to provide different behavior.
2100 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2101 SourceLocation LParenLoc,
2102 SourceLocation EndLoc) {
2103 return getSema().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc, EndLoc);
2106 /// Build a new OpenMP 'detach' clause.
2108 /// By default, performs semantic analysis to build the new statement.
2109 /// Subclasses may override this routine to provide different behavior.
2110 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2111 SourceLocation LParenLoc,
2112 SourceLocation EndLoc) {
2113 return getSema().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
2116 /// Build a new OpenMP 'dist_schedule' clause.
2118 /// By default, performs semantic analysis to build the new OpenMP clause.
2119 /// Subclasses may override this routine to provide different behavior.
2120 OMPClause *
2121 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2122 Expr *ChunkSize, SourceLocation StartLoc,
2123 SourceLocation LParenLoc, SourceLocation KindLoc,
2124 SourceLocation CommaLoc, SourceLocation EndLoc) {
2125 return getSema().ActOnOpenMPDistScheduleClause(
2126 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2129 /// Build a new OpenMP 'to' clause.
2131 /// By default, performs semantic analysis to build the new statement.
2132 /// Subclasses may override this routine to provide different behavior.
2133 OMPClause *
2134 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2135 ArrayRef<SourceLocation> MotionModifiersLoc,
2136 CXXScopeSpec &MapperIdScopeSpec,
2137 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2138 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2139 ArrayRef<Expr *> UnresolvedMappers) {
2140 return getSema().ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
2141 MapperIdScopeSpec, MapperId, ColonLoc,
2142 VarList, Locs, UnresolvedMappers);
2145 /// Build a new OpenMP 'from' clause.
2147 /// By default, performs semantic analysis to build the new statement.
2148 /// Subclasses may override this routine to provide different behavior.
2149 OMPClause *
2150 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2151 ArrayRef<SourceLocation> MotionModifiersLoc,
2152 CXXScopeSpec &MapperIdScopeSpec,
2153 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2154 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2155 ArrayRef<Expr *> UnresolvedMappers) {
2156 return getSema().ActOnOpenMPFromClause(
2157 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2158 ColonLoc, VarList, Locs, UnresolvedMappers);
2161 /// Build a new OpenMP 'use_device_ptr' clause.
2163 /// By default, performs semantic analysis to build the new OpenMP clause.
2164 /// Subclasses may override this routine to provide different behavior.
2165 OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
2166 const OMPVarListLocTy &Locs) {
2167 return getSema().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2170 /// Build a new OpenMP 'use_device_addr' clause.
2172 /// By default, performs semantic analysis to build the new OpenMP clause.
2173 /// Subclasses may override this routine to provide different behavior.
2174 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2175 const OMPVarListLocTy &Locs) {
2176 return getSema().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2179 /// Build a new OpenMP 'is_device_ptr' clause.
2181 /// By default, performs semantic analysis to build the new OpenMP clause.
2182 /// Subclasses may override this routine to provide different behavior.
2183 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2184 const OMPVarListLocTy &Locs) {
2185 return getSema().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2188 /// Build a new OpenMP 'has_device_addr' clause.
2190 /// By default, performs semantic analysis to build the new OpenMP clause.
2191 /// Subclasses may override this routine to provide different behavior.
2192 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2193 const OMPVarListLocTy &Locs) {
2194 return getSema().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2197 /// Build a new OpenMP 'defaultmap' clause.
2199 /// By default, performs semantic analysis to build the new OpenMP clause.
2200 /// Subclasses may override this routine to provide different behavior.
2201 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2202 OpenMPDefaultmapClauseKind Kind,
2203 SourceLocation StartLoc,
2204 SourceLocation LParenLoc,
2205 SourceLocation MLoc,
2206 SourceLocation KindLoc,
2207 SourceLocation EndLoc) {
2208 return getSema().ActOnOpenMPDefaultmapClause(M, Kind, StartLoc, LParenLoc,
2209 MLoc, KindLoc, EndLoc);
2212 /// Build a new OpenMP 'nontemporal' clause.
2214 /// By default, performs semantic analysis to build the new OpenMP clause.
2215 /// Subclasses may override this routine to provide different behavior.
2216 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2217 SourceLocation StartLoc,
2218 SourceLocation LParenLoc,
2219 SourceLocation EndLoc) {
2220 return getSema().ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc,
2221 EndLoc);
2224 /// Build a new OpenMP 'inclusive' clause.
2226 /// By default, performs semantic analysis to build the new OpenMP clause.
2227 /// Subclasses may override this routine to provide different behavior.
2228 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2229 SourceLocation StartLoc,
2230 SourceLocation LParenLoc,
2231 SourceLocation EndLoc) {
2232 return getSema().ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc,
2233 EndLoc);
2236 /// Build a new OpenMP 'exclusive' clause.
2238 /// By default, performs semantic analysis to build the new OpenMP clause.
2239 /// Subclasses may override this routine to provide different behavior.
2240 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2241 SourceLocation StartLoc,
2242 SourceLocation LParenLoc,
2243 SourceLocation EndLoc) {
2244 return getSema().ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc,
2245 EndLoc);
2248 /// Build a new OpenMP 'uses_allocators' clause.
2250 /// By default, performs semantic analysis to build the new OpenMP clause.
2251 /// Subclasses may override this routine to provide different behavior.
2252 OMPClause *RebuildOMPUsesAllocatorsClause(
2253 ArrayRef<Sema::UsesAllocatorsData> Data, SourceLocation StartLoc,
2254 SourceLocation LParenLoc, SourceLocation EndLoc) {
2255 return getSema().ActOnOpenMPUsesAllocatorClause(StartLoc, LParenLoc, EndLoc,
2256 Data);
2259 /// Build a new OpenMP 'affinity' clause.
2261 /// By default, performs semantic analysis to build the new OpenMP clause.
2262 /// Subclasses may override this routine to provide different behavior.
2263 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2264 SourceLocation LParenLoc,
2265 SourceLocation ColonLoc,
2266 SourceLocation EndLoc, Expr *Modifier,
2267 ArrayRef<Expr *> Locators) {
2268 return getSema().ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc,
2269 EndLoc, Modifier, Locators);
2272 /// Build a new OpenMP 'order' clause.
2274 /// By default, performs semantic analysis to build the new OpenMP clause.
2275 /// Subclasses may override this routine to provide different behavior.
2276 OMPClause *RebuildOMPOrderClause(
2277 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2278 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2279 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2280 return getSema().ActOnOpenMPOrderClause(Modifier, Kind, StartLoc, LParenLoc,
2281 ModifierKwLoc, KindKwLoc, EndLoc);
2284 /// Build a new OpenMP 'init' clause.
2286 /// By default, performs semantic analysis to build the new OpenMP clause.
2287 /// Subclasses may override this routine to provide different behavior.
2288 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2289 SourceLocation StartLoc,
2290 SourceLocation LParenLoc,
2291 SourceLocation VarLoc,
2292 SourceLocation EndLoc) {
2293 return getSema().ActOnOpenMPInitClause(InteropVar, InteropInfo, StartLoc,
2294 LParenLoc, VarLoc, EndLoc);
2297 /// Build a new OpenMP 'use' clause.
2299 /// By default, performs semantic analysis to build the new OpenMP clause.
2300 /// Subclasses may override this routine to provide different behavior.
2301 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2302 SourceLocation LParenLoc,
2303 SourceLocation VarLoc, SourceLocation EndLoc) {
2304 return getSema().ActOnOpenMPUseClause(InteropVar, StartLoc, LParenLoc,
2305 VarLoc, EndLoc);
2308 /// Build a new OpenMP 'destroy' clause.
2310 /// By default, performs semantic analysis to build the new OpenMP clause.
2311 /// Subclasses may override this routine to provide different behavior.
2312 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2313 SourceLocation LParenLoc,
2314 SourceLocation VarLoc,
2315 SourceLocation EndLoc) {
2316 return getSema().ActOnOpenMPDestroyClause(InteropVar, StartLoc, LParenLoc,
2317 VarLoc, EndLoc);
2320 /// Build a new OpenMP 'novariants' clause.
2322 /// By default, performs semantic analysis to build the new OpenMP clause.
2323 /// Subclasses may override this routine to provide different behavior.
2324 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2325 SourceLocation StartLoc,
2326 SourceLocation LParenLoc,
2327 SourceLocation EndLoc) {
2328 return getSema().ActOnOpenMPNovariantsClause(Condition, StartLoc, LParenLoc,
2329 EndLoc);
2332 /// Build a new OpenMP 'nocontext' clause.
2334 /// By default, performs semantic analysis to build the new OpenMP clause.
2335 /// Subclasses may override this routine to provide different behavior.
2336 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2337 SourceLocation LParenLoc,
2338 SourceLocation EndLoc) {
2339 return getSema().ActOnOpenMPNocontextClause(Condition, StartLoc, LParenLoc,
2340 EndLoc);
2343 /// Build a new OpenMP 'filter' clause.
2345 /// By default, performs semantic analysis to build the new OpenMP clause.
2346 /// Subclasses may override this routine to provide different behavior.
2347 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2348 SourceLocation LParenLoc,
2349 SourceLocation EndLoc) {
2350 return getSema().ActOnOpenMPFilterClause(ThreadID, StartLoc, LParenLoc,
2351 EndLoc);
2354 /// Build a new OpenMP 'bind' clause.
2356 /// By default, performs semantic analysis to build the new OpenMP clause.
2357 /// Subclasses may override this routine to provide different behavior.
2358 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2359 SourceLocation KindLoc,
2360 SourceLocation StartLoc,
2361 SourceLocation LParenLoc,
2362 SourceLocation EndLoc) {
2363 return getSema().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc, LParenLoc,
2364 EndLoc);
2367 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2369 /// By default, performs semantic analysis to build the new OpenMP clause.
2370 /// Subclasses may override this routine to provide different behavior.
2371 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2372 SourceLocation LParenLoc,
2373 SourceLocation EndLoc) {
2374 return getSema().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc, LParenLoc,
2375 EndLoc);
2378 /// Build a new OpenMP 'ompx_attribute' clause.
2380 /// By default, performs semantic analysis to build the new OpenMP clause.
2381 /// Subclasses may override this routine to provide different behavior.
2382 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2383 SourceLocation StartLoc,
2384 SourceLocation LParenLoc,
2385 SourceLocation EndLoc) {
2386 return getSema().ActOnOpenMPXAttributeClause(Attrs, StartLoc, LParenLoc,
2387 EndLoc);
2390 /// Build a new OpenMP 'ompx_bare' clause.
2392 /// By default, performs semantic analysis to build the new OpenMP clause.
2393 /// Subclasses may override this routine to provide different behavior.
2394 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2395 SourceLocation EndLoc) {
2396 return getSema().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2399 /// Build a new OpenMP 'align' clause.
2401 /// By default, performs semantic analysis to build the new OpenMP clause.
2402 /// Subclasses may override this routine to provide different behavior.
2403 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2404 SourceLocation LParenLoc,
2405 SourceLocation EndLoc) {
2406 return getSema().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc, EndLoc);
2409 /// Build a new OpenMP 'at' clause.
2411 /// By default, performs semantic analysis to build the new OpenMP clause.
2412 /// Subclasses may override this routine to provide different behavior.
2413 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2414 SourceLocation StartLoc,
2415 SourceLocation LParenLoc,
2416 SourceLocation EndLoc) {
2417 return getSema().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc, LParenLoc,
2418 EndLoc);
2421 /// Build a new OpenMP 'severity' clause.
2423 /// By default, performs semantic analysis to build the new OpenMP clause.
2424 /// Subclasses may override this routine to provide different behavior.
2425 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2426 SourceLocation KwLoc,
2427 SourceLocation StartLoc,
2428 SourceLocation LParenLoc,
2429 SourceLocation EndLoc) {
2430 return getSema().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc, LParenLoc,
2431 EndLoc);
2434 /// Build a new OpenMP 'message' clause.
2436 /// By default, performs semantic analysis to build the new OpenMP clause.
2437 /// Subclasses may override this routine to provide different behavior.
2438 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2439 SourceLocation LParenLoc,
2440 SourceLocation EndLoc) {
2441 return getSema().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc, EndLoc);
2444 /// Build a new OpenMP 'doacross' clause.
2446 /// By default, performs semantic analysis to build the new OpenMP clause.
2447 /// Subclasses may override this routine to provide different behavior.
2448 OMPClause *
2449 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2450 SourceLocation DepLoc, SourceLocation ColonLoc,
2451 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2452 SourceLocation LParenLoc, SourceLocation EndLoc) {
2453 return getSema().ActOnOpenMPDoacrossClause(
2454 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2457 /// Rebuild the operand to an Objective-C \@synchronized statement.
2459 /// By default, performs semantic analysis to build the new statement.
2460 /// Subclasses may override this routine to provide different behavior.
2461 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2462 Expr *object) {
2463 return getSema().ActOnObjCAtSynchronizedOperand(atLoc, object);
2466 /// Build a new Objective-C \@synchronized statement.
2468 /// By default, performs semantic analysis to build the new statement.
2469 /// Subclasses may override this routine to provide different behavior.
2470 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2471 Expr *Object, Stmt *Body) {
2472 return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2475 /// Build a new Objective-C \@autoreleasepool statement.
2477 /// By default, performs semantic analysis to build the new statement.
2478 /// Subclasses may override this routine to provide different behavior.
2479 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2480 Stmt *Body) {
2481 return getSema().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2484 /// Build a new Objective-C fast enumeration statement.
2486 /// By default, performs semantic analysis to build the new statement.
2487 /// Subclasses may override this routine to provide different behavior.
2488 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2489 Stmt *Element,
2490 Expr *Collection,
2491 SourceLocation RParenLoc,
2492 Stmt *Body) {
2493 StmtResult ForEachStmt = getSema().ActOnObjCForCollectionStmt(ForLoc,
2494 Element,
2495 Collection,
2496 RParenLoc);
2497 if (ForEachStmt.isInvalid())
2498 return StmtError();
2500 return getSema().FinishObjCForCollectionStmt(ForEachStmt.get(), Body);
2503 /// Build a new C++ exception declaration.
2505 /// By default, performs semantic analysis to build the new decaration.
2506 /// Subclasses may override this routine to provide different behavior.
2507 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2508 TypeSourceInfo *Declarator,
2509 SourceLocation StartLoc,
2510 SourceLocation IdLoc,
2511 IdentifierInfo *Id) {
2512 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2513 StartLoc, IdLoc, Id);
2514 if (Var)
2515 getSema().CurContext->addDecl(Var);
2516 return Var;
2519 /// Build a new C++ catch statement.
2521 /// By default, performs semantic analysis to build the new statement.
2522 /// Subclasses may override this routine to provide different behavior.
2523 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2524 VarDecl *ExceptionDecl,
2525 Stmt *Handler) {
2526 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2527 Handler));
2530 /// Build a new C++ try statement.
2532 /// By default, performs semantic analysis to build the new statement.
2533 /// Subclasses may override this routine to provide different behavior.
2534 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2535 ArrayRef<Stmt *> Handlers) {
2536 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2539 /// Build a new C++0x range-based for statement.
2541 /// By default, performs semantic analysis to build the new statement.
2542 /// Subclasses may override this routine to provide different behavior.
2543 StmtResult RebuildCXXForRangeStmt(SourceLocation ForLoc,
2544 SourceLocation CoawaitLoc, Stmt *Init,
2545 SourceLocation ColonLoc, Stmt *Range,
2546 Stmt *Begin, Stmt *End, Expr *Cond,
2547 Expr *Inc, Stmt *LoopVar,
2548 SourceLocation RParenLoc) {
2549 // If we've just learned that the range is actually an Objective-C
2550 // collection, treat this as an Objective-C fast enumeration loop.
2551 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
2552 if (RangeStmt->isSingleDecl()) {
2553 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
2554 if (RangeVar->isInvalidDecl())
2555 return StmtError();
2557 Expr *RangeExpr = RangeVar->getInit();
2558 if (!RangeExpr->isTypeDependent() &&
2559 RangeExpr->getType()->isObjCObjectPointerType()) {
2560 // FIXME: Support init-statements in Objective-C++20 ranged for
2561 // statement.
2562 if (Init) {
2563 return SemaRef.Diag(Init->getBeginLoc(),
2564 diag::err_objc_for_range_init_stmt)
2565 << Init->getSourceRange();
2567 return getSema().ActOnObjCForCollectionStmt(ForLoc, LoopVar,
2568 RangeExpr, RParenLoc);
2574 return getSema().BuildCXXForRangeStmt(ForLoc, CoawaitLoc, Init, ColonLoc,
2575 Range, Begin, End, Cond, Inc, LoopVar,
2576 RParenLoc, Sema::BFRK_Rebuild);
2579 /// Build a new C++0x range-based for statement.
2581 /// By default, performs semantic analysis to build the new statement.
2582 /// Subclasses may override this routine to provide different behavior.
2583 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2584 bool IsIfExists,
2585 NestedNameSpecifierLoc QualifierLoc,
2586 DeclarationNameInfo NameInfo,
2587 Stmt *Nested) {
2588 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2589 QualifierLoc, NameInfo, Nested);
2592 /// Attach body to a C++0x range-based for statement.
2594 /// By default, performs semantic analysis to finish the new statement.
2595 /// Subclasses may override this routine to provide different behavior.
2596 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2597 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2600 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2601 Stmt *TryBlock, Stmt *Handler) {
2602 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2605 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2606 Stmt *Block) {
2607 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2610 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2611 return SEHFinallyStmt::Create(getSema().getASTContext(), Loc, Block);
2614 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2615 SourceLocation LParen,
2616 SourceLocation RParen,
2617 TypeSourceInfo *TSI) {
2618 return getSema().BuildSYCLUniqueStableNameExpr(OpLoc, LParen, RParen, TSI);
2621 /// Build a new predefined expression.
2623 /// By default, performs semantic analysis to build the new expression.
2624 /// Subclasses may override this routine to provide different behavior.
2625 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2626 return getSema().BuildPredefinedExpr(Loc, IK);
2629 /// Build a new expression that references a declaration.
2631 /// By default, performs semantic analysis to build the new expression.
2632 /// Subclasses may override this routine to provide different behavior.
2633 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2634 LookupResult &R,
2635 bool RequiresADL) {
2636 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2640 /// Build a new expression that references a declaration.
2642 /// By default, performs semantic analysis to build the new expression.
2643 /// Subclasses may override this routine to provide different behavior.
2644 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2645 ValueDecl *VD,
2646 const DeclarationNameInfo &NameInfo,
2647 NamedDecl *Found,
2648 TemplateArgumentListInfo *TemplateArgs) {
2649 CXXScopeSpec SS;
2650 SS.Adopt(QualifierLoc);
2651 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2652 TemplateArgs);
2655 /// Build a new expression in parentheses.
2657 /// By default, performs semantic analysis to build the new expression.
2658 /// Subclasses may override this routine to provide different behavior.
2659 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2660 SourceLocation RParen) {
2661 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2664 /// Build a new pseudo-destructor expression.
2666 /// By default, performs semantic analysis to build the new expression.
2667 /// Subclasses may override this routine to provide different behavior.
2668 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2669 SourceLocation OperatorLoc,
2670 bool isArrow,
2671 CXXScopeSpec &SS,
2672 TypeSourceInfo *ScopeType,
2673 SourceLocation CCLoc,
2674 SourceLocation TildeLoc,
2675 PseudoDestructorTypeStorage Destroyed);
2677 /// Build a new unary operator expression.
2679 /// By default, performs semantic analysis to build the new expression.
2680 /// Subclasses may override this routine to provide different behavior.
2681 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2682 UnaryOperatorKind Opc,
2683 Expr *SubExpr) {
2684 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2687 /// Build a new builtin offsetof expression.
2689 /// By default, performs semantic analysis to build the new expression.
2690 /// Subclasses may override this routine to provide different behavior.
2691 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2692 TypeSourceInfo *Type,
2693 ArrayRef<Sema::OffsetOfComponent> Components,
2694 SourceLocation RParenLoc) {
2695 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2696 RParenLoc);
2699 /// Build a new sizeof, alignof or vec_step expression with a
2700 /// type argument.
2702 /// By default, performs semantic analysis to build the new expression.
2703 /// Subclasses may override this routine to provide different behavior.
2704 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2705 SourceLocation OpLoc,
2706 UnaryExprOrTypeTrait ExprKind,
2707 SourceRange R) {
2708 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2711 /// Build a new sizeof, alignof or vec step expression with an
2712 /// expression argument.
2714 /// By default, performs semantic analysis to build the new expression.
2715 /// Subclasses may override this routine to provide different behavior.
2716 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2717 UnaryExprOrTypeTrait ExprKind,
2718 SourceRange R) {
2719 ExprResult Result
2720 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2721 if (Result.isInvalid())
2722 return ExprError();
2724 return Result;
2727 /// Build a new array subscript expression.
2729 /// By default, performs semantic analysis to build the new expression.
2730 /// Subclasses may override this routine to provide different behavior.
2731 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2732 SourceLocation LBracketLoc,
2733 Expr *RHS,
2734 SourceLocation RBracketLoc) {
2735 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2736 LBracketLoc, RHS,
2737 RBracketLoc);
2740 /// Build a new matrix subscript expression.
2742 /// By default, performs semantic analysis to build the new expression.
2743 /// Subclasses may override this routine to provide different behavior.
2744 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2745 Expr *ColumnIdx,
2746 SourceLocation RBracketLoc) {
2747 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2748 RBracketLoc);
2751 /// Build a new array section expression.
2753 /// By default, performs semantic analysis to build the new expression.
2754 /// Subclasses may override this routine to provide different behavior.
2755 ExprResult RebuildOMPArraySectionExpr(Expr *Base, SourceLocation LBracketLoc,
2756 Expr *LowerBound,
2757 SourceLocation ColonLocFirst,
2758 SourceLocation ColonLocSecond,
2759 Expr *Length, Expr *Stride,
2760 SourceLocation RBracketLoc) {
2761 return getSema().ActOnOMPArraySectionExpr(Base, LBracketLoc, LowerBound,
2762 ColonLocFirst, ColonLocSecond,
2763 Length, Stride, RBracketLoc);
2766 /// Build a new array shaping expression.
2768 /// By default, performs semantic analysis to build the new expression.
2769 /// Subclasses may override this routine to provide different behavior.
2770 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2771 SourceLocation RParenLoc,
2772 ArrayRef<Expr *> Dims,
2773 ArrayRef<SourceRange> BracketsRanges) {
2774 return getSema().ActOnOMPArrayShapingExpr(Base, LParenLoc, RParenLoc, Dims,
2775 BracketsRanges);
2778 /// Build a new iterator expression.
2780 /// By default, performs semantic analysis to build the new expression.
2781 /// Subclasses may override this routine to provide different behavior.
2782 ExprResult RebuildOMPIteratorExpr(
2783 SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc,
2784 ArrayRef<Sema::OMPIteratorData> Data) {
2785 return getSema().ActOnOMPIteratorExpr(/*Scope=*/nullptr, IteratorKwLoc,
2786 LLoc, RLoc, Data);
2789 /// Build a new call expression.
2791 /// By default, performs semantic analysis to build the new expression.
2792 /// Subclasses may override this routine to provide different behavior.
2793 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2794 MultiExprArg Args,
2795 SourceLocation RParenLoc,
2796 Expr *ExecConfig = nullptr) {
2797 return getSema().ActOnCallExpr(
2798 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2801 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2802 MultiExprArg Args,
2803 SourceLocation RParenLoc) {
2804 return getSema().ActOnArraySubscriptExpr(
2805 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2808 /// Build a new member access expression.
2810 /// By default, performs semantic analysis to build the new expression.
2811 /// Subclasses may override this routine to provide different behavior.
2812 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2813 bool isArrow,
2814 NestedNameSpecifierLoc QualifierLoc,
2815 SourceLocation TemplateKWLoc,
2816 const DeclarationNameInfo &MemberNameInfo,
2817 ValueDecl *Member,
2818 NamedDecl *FoundDecl,
2819 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2820 NamedDecl *FirstQualifierInScope) {
2821 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2822 isArrow);
2823 if (!Member->getDeclName()) {
2824 // We have a reference to an unnamed field. This is always the
2825 // base of an anonymous struct/union member access, i.e. the
2826 // field is always of record type.
2827 assert(Member->getType()->isRecordType() &&
2828 "unnamed member not of record type?");
2830 BaseResult =
2831 getSema().PerformObjectMemberConversion(BaseResult.get(),
2832 QualifierLoc.getNestedNameSpecifier(),
2833 FoundDecl, Member);
2834 if (BaseResult.isInvalid())
2835 return ExprError();
2836 Base = BaseResult.get();
2838 CXXScopeSpec EmptySS;
2839 return getSema().BuildFieldReferenceExpr(
2840 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
2841 DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()), MemberNameInfo);
2844 CXXScopeSpec SS;
2845 SS.Adopt(QualifierLoc);
2847 Base = BaseResult.get();
2848 QualType BaseType = Base->getType();
2850 if (isArrow && !BaseType->isPointerType())
2851 return ExprError();
2853 // FIXME: this involves duplicating earlier analysis in a lot of
2854 // cases; we should avoid this when possible.
2855 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2856 R.addDecl(FoundDecl);
2857 R.resolveKind();
2859 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2860 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {
2861 if (auto *ThisClass = cast<CXXThisExpr>(Base)
2862 ->getType()
2863 ->getPointeeType()
2864 ->getAsCXXRecordDecl()) {
2865 auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());
2866 // In unevaluated contexts, an expression supposed to be a member access
2867 // might reference a member in an unrelated class.
2868 if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))
2869 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2870 VK_LValue, Member->getLocation());
2874 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2875 SS, TemplateKWLoc,
2876 FirstQualifierInScope,
2877 R, ExplicitTemplateArgs,
2878 /*S*/nullptr);
2881 /// Build a new binary operator expression.
2883 /// By default, performs semantic analysis to build the new expression.
2884 /// Subclasses may override this routine to provide different behavior.
2885 ExprResult RebuildBinaryOperator(SourceLocation OpLoc,
2886 BinaryOperatorKind Opc,
2887 Expr *LHS, Expr *RHS) {
2888 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS);
2891 /// Build a new rewritten operator expression.
2893 /// By default, performs semantic analysis to build the new expression.
2894 /// Subclasses may override this routine to provide different behavior.
2895 ExprResult RebuildCXXRewrittenBinaryOperator(
2896 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2897 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2898 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2899 RHS, /*RequiresADL*/false);
2902 /// Build a new conditional operator expression.
2904 /// By default, performs semantic analysis to build the new expression.
2905 /// Subclasses may override this routine to provide different behavior.
2906 ExprResult RebuildConditionalOperator(Expr *Cond,
2907 SourceLocation QuestionLoc,
2908 Expr *LHS,
2909 SourceLocation ColonLoc,
2910 Expr *RHS) {
2911 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
2912 LHS, RHS);
2915 /// Build a new C-style cast expression.
2917 /// By default, performs semantic analysis to build the new expression.
2918 /// Subclasses may override this routine to provide different behavior.
2919 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
2920 TypeSourceInfo *TInfo,
2921 SourceLocation RParenLoc,
2922 Expr *SubExpr) {
2923 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
2924 SubExpr);
2927 /// Build a new compound literal expression.
2929 /// By default, performs semantic analysis to build the new expression.
2930 /// Subclasses may override this routine to provide different behavior.
2931 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
2932 TypeSourceInfo *TInfo,
2933 SourceLocation RParenLoc,
2934 Expr *Init) {
2935 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
2936 Init);
2939 /// Build a new extended vector element access expression.
2941 /// By default, performs semantic analysis to build the new expression.
2942 /// Subclasses may override this routine to provide different behavior.
2943 ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,
2944 bool IsArrow,
2945 SourceLocation AccessorLoc,
2946 IdentifierInfo &Accessor) {
2948 CXXScopeSpec SS;
2949 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
2950 return getSema().BuildMemberReferenceExpr(
2951 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
2952 /*FirstQualifierInScope*/ nullptr, NameInfo,
2953 /* TemplateArgs */ nullptr,
2954 /*S*/ nullptr);
2957 /// Build a new initializer list expression.
2959 /// By default, performs semantic analysis to build the new expression.
2960 /// Subclasses may override this routine to provide different behavior.
2961 ExprResult RebuildInitList(SourceLocation LBraceLoc,
2962 MultiExprArg Inits,
2963 SourceLocation RBraceLoc) {
2964 return SemaRef.BuildInitList(LBraceLoc, Inits, RBraceLoc);
2967 /// Build a new designated initializer expression.
2969 /// By default, performs semantic analysis to build the new expression.
2970 /// Subclasses may override this routine to provide different behavior.
2971 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
2972 MultiExprArg ArrayExprs,
2973 SourceLocation EqualOrColonLoc,
2974 bool GNUSyntax,
2975 Expr *Init) {
2976 ExprResult Result
2977 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
2978 Init);
2979 if (Result.isInvalid())
2980 return ExprError();
2982 return Result;
2985 /// Build a new value-initialized expression.
2987 /// By default, builds the implicit value initialization without performing
2988 /// any semantic analysis. Subclasses may override this routine to provide
2989 /// different behavior.
2990 ExprResult RebuildImplicitValueInitExpr(QualType T) {
2991 return new (SemaRef.Context) ImplicitValueInitExpr(T);
2994 /// Build a new \c va_arg expression.
2996 /// By default, performs semantic analysis to build the new expression.
2997 /// Subclasses may override this routine to provide different behavior.
2998 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
2999 Expr *SubExpr, TypeSourceInfo *TInfo,
3000 SourceLocation RParenLoc) {
3001 return getSema().BuildVAArgExpr(BuiltinLoc,
3002 SubExpr, TInfo,
3003 RParenLoc);
3006 /// Build a new expression list in parentheses.
3008 /// By default, performs semantic analysis to build the new expression.
3009 /// Subclasses may override this routine to provide different behavior.
3010 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3011 MultiExprArg SubExprs,
3012 SourceLocation RParenLoc) {
3013 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3016 /// Build a new address-of-label expression.
3018 /// By default, performs semantic analysis, using the name of the label
3019 /// rather than attempting to map the label statement itself.
3020 /// Subclasses may override this routine to provide different behavior.
3021 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3022 SourceLocation LabelLoc, LabelDecl *Label) {
3023 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3026 /// Build a new GNU statement expression.
3028 /// By default, performs semantic analysis to build the new expression.
3029 /// Subclasses may override this routine to provide different behavior.
3030 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3031 SourceLocation RParenLoc, unsigned TemplateDepth) {
3032 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3033 TemplateDepth);
3036 /// Build a new __builtin_choose_expr expression.
3038 /// By default, performs semantic analysis to build the new expression.
3039 /// Subclasses may override this routine to provide different behavior.
3040 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3041 Expr *Cond, Expr *LHS, Expr *RHS,
3042 SourceLocation RParenLoc) {
3043 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3044 Cond, LHS, RHS,
3045 RParenLoc);
3048 /// Build a new generic selection expression with an expression predicate.
3050 /// By default, performs semantic analysis to build the new expression.
3051 /// Subclasses may override this routine to provide different behavior.
3052 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3053 SourceLocation DefaultLoc,
3054 SourceLocation RParenLoc,
3055 Expr *ControllingExpr,
3056 ArrayRef<TypeSourceInfo *> Types,
3057 ArrayRef<Expr *> Exprs) {
3058 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3059 /*PredicateIsExpr=*/true,
3060 ControllingExpr, Types, Exprs);
3063 /// Build a new generic selection expression with a type predicate.
3065 /// By default, performs semantic analysis to build the new expression.
3066 /// Subclasses may override this routine to provide different behavior.
3067 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3068 SourceLocation DefaultLoc,
3069 SourceLocation RParenLoc,
3070 TypeSourceInfo *ControllingType,
3071 ArrayRef<TypeSourceInfo *> Types,
3072 ArrayRef<Expr *> Exprs) {
3073 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3074 /*PredicateIsExpr=*/false,
3075 ControllingType, Types, Exprs);
3078 /// Build a new overloaded operator call expression.
3080 /// By default, performs semantic analysis to build the new expression.
3081 /// The semantic analysis provides the behavior of template instantiation,
3082 /// copying with transformations that turn what looks like an overloaded
3083 /// operator call into a use of a builtin operator, performing
3084 /// argument-dependent lookup, etc. Subclasses may override this routine to
3085 /// provide different behavior.
3086 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3087 SourceLocation OpLoc,
3088 SourceLocation CalleeLoc,
3089 bool RequiresADL,
3090 const UnresolvedSetImpl &Functions,
3091 Expr *First, Expr *Second);
3093 /// Build a new C++ "named" cast expression, such as static_cast or
3094 /// reinterpret_cast.
3096 /// By default, this routine dispatches to one of the more-specific routines
3097 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3098 /// Subclasses may override this routine to provide different behavior.
3099 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3100 Stmt::StmtClass Class,
3101 SourceLocation LAngleLoc,
3102 TypeSourceInfo *TInfo,
3103 SourceLocation RAngleLoc,
3104 SourceLocation LParenLoc,
3105 Expr *SubExpr,
3106 SourceLocation RParenLoc) {
3107 switch (Class) {
3108 case Stmt::CXXStaticCastExprClass:
3109 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3110 RAngleLoc, LParenLoc,
3111 SubExpr, RParenLoc);
3113 case Stmt::CXXDynamicCastExprClass:
3114 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3115 RAngleLoc, LParenLoc,
3116 SubExpr, RParenLoc);
3118 case Stmt::CXXReinterpretCastExprClass:
3119 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3120 RAngleLoc, LParenLoc,
3121 SubExpr,
3122 RParenLoc);
3124 case Stmt::CXXConstCastExprClass:
3125 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3126 RAngleLoc, LParenLoc,
3127 SubExpr, RParenLoc);
3129 case Stmt::CXXAddrspaceCastExprClass:
3130 return getDerived().RebuildCXXAddrspaceCastExpr(
3131 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3133 default:
3134 llvm_unreachable("Invalid C++ named cast");
3138 /// Build a new C++ static_cast expression.
3140 /// By default, performs semantic analysis to build the new expression.
3141 /// Subclasses may override this routine to provide different behavior.
3142 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3143 SourceLocation LAngleLoc,
3144 TypeSourceInfo *TInfo,
3145 SourceLocation RAngleLoc,
3146 SourceLocation LParenLoc,
3147 Expr *SubExpr,
3148 SourceLocation RParenLoc) {
3149 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3150 TInfo, SubExpr,
3151 SourceRange(LAngleLoc, RAngleLoc),
3152 SourceRange(LParenLoc, RParenLoc));
3155 /// Build a new C++ dynamic_cast expression.
3157 /// By default, performs semantic analysis to build the new expression.
3158 /// Subclasses may override this routine to provide different behavior.
3159 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3160 SourceLocation LAngleLoc,
3161 TypeSourceInfo *TInfo,
3162 SourceLocation RAngleLoc,
3163 SourceLocation LParenLoc,
3164 Expr *SubExpr,
3165 SourceLocation RParenLoc) {
3166 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3167 TInfo, SubExpr,
3168 SourceRange(LAngleLoc, RAngleLoc),
3169 SourceRange(LParenLoc, RParenLoc));
3172 /// Build a new C++ reinterpret_cast expression.
3174 /// By default, performs semantic analysis to build the new expression.
3175 /// Subclasses may override this routine to provide different behavior.
3176 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3177 SourceLocation LAngleLoc,
3178 TypeSourceInfo *TInfo,
3179 SourceLocation RAngleLoc,
3180 SourceLocation LParenLoc,
3181 Expr *SubExpr,
3182 SourceLocation RParenLoc) {
3183 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3184 TInfo, SubExpr,
3185 SourceRange(LAngleLoc, RAngleLoc),
3186 SourceRange(LParenLoc, RParenLoc));
3189 /// Build a new C++ const_cast expression.
3191 /// By default, performs semantic analysis to build the new expression.
3192 /// Subclasses may override this routine to provide different behavior.
3193 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3194 SourceLocation LAngleLoc,
3195 TypeSourceInfo *TInfo,
3196 SourceLocation RAngleLoc,
3197 SourceLocation LParenLoc,
3198 Expr *SubExpr,
3199 SourceLocation RParenLoc) {
3200 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3201 TInfo, SubExpr,
3202 SourceRange(LAngleLoc, RAngleLoc),
3203 SourceRange(LParenLoc, RParenLoc));
3206 ExprResult
3207 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3208 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3209 SourceLocation LParenLoc, Expr *SubExpr,
3210 SourceLocation RParenLoc) {
3211 return getSema().BuildCXXNamedCast(
3212 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3213 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3216 /// Build a new C++ functional-style cast expression.
3218 /// By default, performs semantic analysis to build the new expression.
3219 /// Subclasses may override this routine to provide different behavior.
3220 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3221 SourceLocation LParenLoc,
3222 Expr *Sub,
3223 SourceLocation RParenLoc,
3224 bool ListInitialization) {
3225 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3226 // CXXParenListInitExpr. Pass its expanded arguments so that the
3227 // CXXParenListInitExpr can be rebuilt.
3228 if (auto *PLE = dyn_cast<ParenListExpr>(Sub))
3229 return getSema().BuildCXXTypeConstructExpr(
3230 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3231 RParenLoc, ListInitialization);
3232 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3233 MultiExprArg(&Sub, 1), RParenLoc,
3234 ListInitialization);
3237 /// Build a new C++ __builtin_bit_cast expression.
3239 /// By default, performs semantic analysis to build the new expression.
3240 /// Subclasses may override this routine to provide different behavior.
3241 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3242 TypeSourceInfo *TSI, Expr *Sub,
3243 SourceLocation RParenLoc) {
3244 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3247 /// Build a new C++ typeid(type) expression.
3249 /// By default, performs semantic analysis to build the new expression.
3250 /// Subclasses may override this routine to provide different behavior.
3251 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3252 SourceLocation TypeidLoc,
3253 TypeSourceInfo *Operand,
3254 SourceLocation RParenLoc) {
3255 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3256 RParenLoc);
3260 /// Build a new C++ typeid(expr) expression.
3262 /// By default, performs semantic analysis to build the new expression.
3263 /// Subclasses may override this routine to provide different behavior.
3264 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3265 SourceLocation TypeidLoc,
3266 Expr *Operand,
3267 SourceLocation RParenLoc) {
3268 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3269 RParenLoc);
3272 /// Build a new C++ __uuidof(type) expression.
3274 /// By default, performs semantic analysis to build the new expression.
3275 /// Subclasses may override this routine to provide different behavior.
3276 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3277 TypeSourceInfo *Operand,
3278 SourceLocation RParenLoc) {
3279 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3282 /// Build a new C++ __uuidof(expr) expression.
3284 /// By default, performs semantic analysis to build the new expression.
3285 /// Subclasses may override this routine to provide different behavior.
3286 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3287 Expr *Operand, SourceLocation RParenLoc) {
3288 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3291 /// Build a new C++ "this" expression.
3293 /// By default, builds a new "this" expression without performing any
3294 /// semantic analysis. Subclasses may override this routine to provide
3295 /// different behavior.
3296 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3297 QualType ThisType,
3298 bool isImplicit) {
3299 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3302 /// Build a new C++ throw expression.
3304 /// By default, performs semantic analysis to build the new expression.
3305 /// Subclasses may override this routine to provide different behavior.
3306 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3307 bool IsThrownVariableInScope) {
3308 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3311 /// Build a new C++ default-argument expression.
3313 /// By default, builds a new default-argument expression, which does not
3314 /// require any semantic analysis. Subclasses may override this routine to
3315 /// provide different behavior.
3316 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3317 Expr *RewrittenExpr) {
3318 return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param,
3319 RewrittenExpr, getSema().CurContext);
3322 /// Build a new C++11 default-initialization expression.
3324 /// By default, builds a new default field initialization expression, which
3325 /// does not require any semantic analysis. Subclasses may override this
3326 /// routine to provide different behavior.
3327 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3328 FieldDecl *Field) {
3329 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3332 /// Build a new C++ zero-initialization expression.
3334 /// By default, performs semantic analysis to build the new expression.
3335 /// Subclasses may override this routine to provide different behavior.
3336 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3337 SourceLocation LParenLoc,
3338 SourceLocation RParenLoc) {
3339 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, std::nullopt,
3340 RParenLoc,
3341 /*ListInitialization=*/false);
3344 /// Build a new C++ "new" expression.
3346 /// By default, performs semantic analysis to build the new expression.
3347 /// Subclasses may override this routine to provide different behavior.
3348 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3349 SourceLocation PlacementLParen,
3350 MultiExprArg PlacementArgs,
3351 SourceLocation PlacementRParen,
3352 SourceRange TypeIdParens, QualType AllocatedType,
3353 TypeSourceInfo *AllocatedTypeInfo,
3354 std::optional<Expr *> ArraySize,
3355 SourceRange DirectInitRange, Expr *Initializer) {
3356 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3357 PlacementLParen,
3358 PlacementArgs,
3359 PlacementRParen,
3360 TypeIdParens,
3361 AllocatedType,
3362 AllocatedTypeInfo,
3363 ArraySize,
3364 DirectInitRange,
3365 Initializer);
3368 /// Build a new C++ "delete" expression.
3370 /// By default, performs semantic analysis to build the new expression.
3371 /// Subclasses may override this routine to provide different behavior.
3372 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3373 bool IsGlobalDelete,
3374 bool IsArrayForm,
3375 Expr *Operand) {
3376 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3377 Operand);
3380 /// Build a new type trait expression.
3382 /// By default, performs semantic analysis to build the new expression.
3383 /// Subclasses may override this routine to provide different behavior.
3384 ExprResult RebuildTypeTrait(TypeTrait Trait,
3385 SourceLocation StartLoc,
3386 ArrayRef<TypeSourceInfo *> Args,
3387 SourceLocation RParenLoc) {
3388 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3391 /// Build a new array type trait expression.
3393 /// By default, performs semantic analysis to build the new expression.
3394 /// Subclasses may override this routine to provide different behavior.
3395 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3396 SourceLocation StartLoc,
3397 TypeSourceInfo *TSInfo,
3398 Expr *DimExpr,
3399 SourceLocation RParenLoc) {
3400 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3403 /// Build a new expression trait expression.
3405 /// By default, performs semantic analysis to build the new expression.
3406 /// Subclasses may override this routine to provide different behavior.
3407 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3408 SourceLocation StartLoc,
3409 Expr *Queried,
3410 SourceLocation RParenLoc) {
3411 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3414 /// Build a new (previously unresolved) declaration reference
3415 /// expression.
3417 /// By default, performs semantic analysis to build the new expression.
3418 /// Subclasses may override this routine to provide different behavior.
3419 ExprResult RebuildDependentScopeDeclRefExpr(
3420 NestedNameSpecifierLoc QualifierLoc,
3421 SourceLocation TemplateKWLoc,
3422 const DeclarationNameInfo &NameInfo,
3423 const TemplateArgumentListInfo *TemplateArgs,
3424 bool IsAddressOfOperand,
3425 TypeSourceInfo **RecoveryTSI) {
3426 CXXScopeSpec SS;
3427 SS.Adopt(QualifierLoc);
3429 if (TemplateArgs || TemplateKWLoc.isValid())
3430 return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, NameInfo,
3431 TemplateArgs);
3433 return getSema().BuildQualifiedDeclarationNameExpr(
3434 SS, NameInfo, IsAddressOfOperand, /*S*/nullptr, RecoveryTSI);
3437 /// Build a new template-id expression.
3439 /// By default, performs semantic analysis to build the new expression.
3440 /// Subclasses may override this routine to provide different behavior.
3441 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3442 SourceLocation TemplateKWLoc,
3443 LookupResult &R,
3444 bool RequiresADL,
3445 const TemplateArgumentListInfo *TemplateArgs) {
3446 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3447 TemplateArgs);
3450 /// Build a new object-construction expression.
3452 /// By default, performs semantic analysis to build the new expression.
3453 /// Subclasses may override this routine to provide different behavior.
3454 ExprResult RebuildCXXConstructExpr(
3455 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3456 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3457 bool ListInitialization, bool StdInitListInitialization,
3458 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3459 SourceRange ParenRange) {
3460 // Reconstruct the constructor we originally found, which might be
3461 // different if this is a call to an inherited constructor.
3462 CXXConstructorDecl *FoundCtor = Constructor;
3463 if (Constructor->isInheritingConstructor())
3464 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3466 SmallVector<Expr *, 8> ConvertedArgs;
3467 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3468 ConvertedArgs))
3469 return ExprError();
3471 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3472 IsElidable,
3473 ConvertedArgs,
3474 HadMultipleCandidates,
3475 ListInitialization,
3476 StdInitListInitialization,
3477 RequiresZeroInit, ConstructKind,
3478 ParenRange);
3481 /// Build a new implicit construction via inherited constructor
3482 /// expression.
3483 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3484 CXXConstructorDecl *Constructor,
3485 bool ConstructsVBase,
3486 bool InheritedFromVBase) {
3487 return new (getSema().Context) CXXInheritedCtorInitExpr(
3488 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3491 /// Build a new object-construction expression.
3493 /// By default, performs semantic analysis to build the new expression.
3494 /// Subclasses may override this routine to provide different behavior.
3495 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3496 SourceLocation LParenOrBraceLoc,
3497 MultiExprArg Args,
3498 SourceLocation RParenOrBraceLoc,
3499 bool ListInitialization) {
3500 return getSema().BuildCXXTypeConstructExpr(
3501 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3504 /// Build a new object-construction expression.
3506 /// By default, performs semantic analysis to build the new expression.
3507 /// Subclasses may override this routine to provide different behavior.
3508 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3509 SourceLocation LParenLoc,
3510 MultiExprArg Args,
3511 SourceLocation RParenLoc,
3512 bool ListInitialization) {
3513 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3514 RParenLoc, ListInitialization);
3517 /// Build a new member reference expression.
3519 /// By default, performs semantic analysis to build the new expression.
3520 /// Subclasses may override this routine to provide different behavior.
3521 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3522 QualType BaseType,
3523 bool IsArrow,
3524 SourceLocation OperatorLoc,
3525 NestedNameSpecifierLoc QualifierLoc,
3526 SourceLocation TemplateKWLoc,
3527 NamedDecl *FirstQualifierInScope,
3528 const DeclarationNameInfo &MemberNameInfo,
3529 const TemplateArgumentListInfo *TemplateArgs) {
3530 CXXScopeSpec SS;
3531 SS.Adopt(QualifierLoc);
3533 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3534 OperatorLoc, IsArrow,
3535 SS, TemplateKWLoc,
3536 FirstQualifierInScope,
3537 MemberNameInfo,
3538 TemplateArgs, /*S*/nullptr);
3541 /// Build a new member reference expression.
3543 /// By default, performs semantic analysis to build the new expression.
3544 /// Subclasses may override this routine to provide different behavior.
3545 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3546 SourceLocation OperatorLoc,
3547 bool IsArrow,
3548 NestedNameSpecifierLoc QualifierLoc,
3549 SourceLocation TemplateKWLoc,
3550 NamedDecl *FirstQualifierInScope,
3551 LookupResult &R,
3552 const TemplateArgumentListInfo *TemplateArgs) {
3553 CXXScopeSpec SS;
3554 SS.Adopt(QualifierLoc);
3556 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3557 OperatorLoc, IsArrow,
3558 SS, TemplateKWLoc,
3559 FirstQualifierInScope,
3560 R, TemplateArgs, /*S*/nullptr);
3563 /// Build a new noexcept expression.
3565 /// By default, performs semantic analysis to build the new expression.
3566 /// Subclasses may override this routine to provide different behavior.
3567 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3568 return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd());
3571 /// Build a new expression to compute the length of a parameter pack.
3572 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3573 SourceLocation PackLoc,
3574 SourceLocation RParenLoc,
3575 std::optional<unsigned> Length,
3576 ArrayRef<TemplateArgument> PartialArgs) {
3577 return SizeOfPackExpr::Create(SemaRef.Context, OperatorLoc, Pack, PackLoc,
3578 RParenLoc, Length, PartialArgs);
3581 /// Build a new expression representing a call to a source location
3582 /// builtin.
3584 /// By default, performs semantic analysis to build the new expression.
3585 /// Subclasses may override this routine to provide different behavior.
3586 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3587 SourceLocation BuiltinLoc,
3588 SourceLocation RPLoc,
3589 DeclContext *ParentContext) {
3590 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3591 ParentContext);
3594 /// Build a new Objective-C boxed expression.
3596 /// By default, performs semantic analysis to build the new expression.
3597 /// Subclasses may override this routine to provide different behavior.
3598 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3599 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3600 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3601 TemplateArgumentListInfo *TALI) {
3602 CXXScopeSpec SS;
3603 SS.Adopt(NNS);
3604 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3605 ConceptNameInfo,
3606 FoundDecl,
3607 NamedConcept, TALI);
3608 if (Result.isInvalid())
3609 return ExprError();
3610 return Result;
3613 /// \brief Build a new requires expression.
3615 /// By default, performs semantic analysis to build the new expression.
3616 /// Subclasses may override this routine to provide different behavior.
3617 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3618 RequiresExprBodyDecl *Body,
3619 SourceLocation LParenLoc,
3620 ArrayRef<ParmVarDecl *> LocalParameters,
3621 SourceLocation RParenLoc,
3622 ArrayRef<concepts::Requirement *> Requirements,
3623 SourceLocation ClosingBraceLoc) {
3624 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3625 LocalParameters, RParenLoc, Requirements,
3626 ClosingBraceLoc);
3629 concepts::TypeRequirement *
3630 RebuildTypeRequirement(
3631 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3632 return SemaRef.BuildTypeRequirement(SubstDiag);
3635 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3636 return SemaRef.BuildTypeRequirement(T);
3639 concepts::ExprRequirement *
3640 RebuildExprRequirement(
3641 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3642 SourceLocation NoexceptLoc,
3643 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3644 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
3645 std::move(Ret));
3648 concepts::ExprRequirement *
3649 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3650 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3651 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
3652 std::move(Ret));
3655 concepts::NestedRequirement *
3656 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3657 const ASTConstraintSatisfaction &Satisfaction) {
3658 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3659 Satisfaction);
3662 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3663 return SemaRef.BuildNestedRequirement(Constraint);
3666 /// \brief Build a new Objective-C boxed expression.
3668 /// By default, performs semantic analysis to build the new expression.
3669 /// Subclasses may override this routine to provide different behavior.
3670 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3671 return getSema().BuildObjCBoxedExpr(SR, ValueExpr);
3674 /// Build a new Objective-C array literal.
3676 /// By default, performs semantic analysis to build the new expression.
3677 /// Subclasses may override this routine to provide different behavior.
3678 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3679 Expr **Elements, unsigned NumElements) {
3680 return getSema().BuildObjCArrayLiteral(Range,
3681 MultiExprArg(Elements, NumElements));
3684 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3685 Expr *Base, Expr *Key,
3686 ObjCMethodDecl *getterMethod,
3687 ObjCMethodDecl *setterMethod) {
3688 return getSema().BuildObjCSubscriptExpression(RB, Base, Key,
3689 getterMethod, setterMethod);
3692 /// Build a new Objective-C dictionary literal.
3694 /// By default, performs semantic analysis to build the new expression.
3695 /// Subclasses may override this routine to provide different behavior.
3696 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3697 MutableArrayRef<ObjCDictionaryElement> Elements) {
3698 return getSema().BuildObjCDictionaryLiteral(Range, Elements);
3701 /// Build a new Objective-C \@encode expression.
3703 /// By default, performs semantic analysis to build the new expression.
3704 /// Subclasses may override this routine to provide different behavior.
3705 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3706 TypeSourceInfo *EncodeTypeInfo,
3707 SourceLocation RParenLoc) {
3708 return SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, RParenLoc);
3711 /// Build a new Objective-C class message.
3712 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3713 Selector Sel,
3714 ArrayRef<SourceLocation> SelectorLocs,
3715 ObjCMethodDecl *Method,
3716 SourceLocation LBracLoc,
3717 MultiExprArg Args,
3718 SourceLocation RBracLoc) {
3719 return SemaRef.BuildClassMessage(ReceiverTypeInfo,
3720 ReceiverTypeInfo->getType(),
3721 /*SuperLoc=*/SourceLocation(),
3722 Sel, Method, LBracLoc, SelectorLocs,
3723 RBracLoc, Args);
3726 /// Build a new Objective-C instance message.
3727 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3728 Selector Sel,
3729 ArrayRef<SourceLocation> SelectorLocs,
3730 ObjCMethodDecl *Method,
3731 SourceLocation LBracLoc,
3732 MultiExprArg Args,
3733 SourceLocation RBracLoc) {
3734 return SemaRef.BuildInstanceMessage(Receiver,
3735 Receiver->getType(),
3736 /*SuperLoc=*/SourceLocation(),
3737 Sel, Method, LBracLoc, SelectorLocs,
3738 RBracLoc, Args);
3741 /// Build a new Objective-C instance/class message to 'super'.
3742 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3743 Selector Sel,
3744 ArrayRef<SourceLocation> SelectorLocs,
3745 QualType SuperType,
3746 ObjCMethodDecl *Method,
3747 SourceLocation LBracLoc,
3748 MultiExprArg Args,
3749 SourceLocation RBracLoc) {
3750 return Method->isInstanceMethod() ? SemaRef.BuildInstanceMessage(nullptr,
3751 SuperType,
3752 SuperLoc,
3753 Sel, Method, LBracLoc, SelectorLocs,
3754 RBracLoc, Args)
3755 : SemaRef.BuildClassMessage(nullptr,
3756 SuperType,
3757 SuperLoc,
3758 Sel, Method, LBracLoc, SelectorLocs,
3759 RBracLoc, Args);
3764 /// Build a new Objective-C ivar reference expression.
3766 /// By default, performs semantic analysis to build the new expression.
3767 /// Subclasses may override this routine to provide different behavior.
3768 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3769 SourceLocation IvarLoc,
3770 bool IsArrow, bool IsFreeIvar) {
3771 CXXScopeSpec SS;
3772 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3773 ExprResult Result = getSema().BuildMemberReferenceExpr(
3774 BaseArg, BaseArg->getType(),
3775 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3776 /*FirstQualifierInScope=*/nullptr, NameInfo,
3777 /*TemplateArgs=*/nullptr,
3778 /*S=*/nullptr);
3779 if (IsFreeIvar && Result.isUsable())
3780 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
3781 return Result;
3784 /// Build a new Objective-C property reference expression.
3786 /// By default, performs semantic analysis to build the new expression.
3787 /// Subclasses may override this routine to provide different behavior.
3788 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3789 ObjCPropertyDecl *Property,
3790 SourceLocation PropertyLoc) {
3791 CXXScopeSpec SS;
3792 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3793 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3794 /*FIXME:*/PropertyLoc,
3795 /*IsArrow=*/false,
3796 SS, SourceLocation(),
3797 /*FirstQualifierInScope=*/nullptr,
3798 NameInfo,
3799 /*TemplateArgs=*/nullptr,
3800 /*S=*/nullptr);
3803 /// Build a new Objective-C property reference expression.
3805 /// By default, performs semantic analysis to build the new expression.
3806 /// Subclasses may override this routine to provide different behavior.
3807 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3808 ObjCMethodDecl *Getter,
3809 ObjCMethodDecl *Setter,
3810 SourceLocation PropertyLoc) {
3811 // Since these expressions can only be value-dependent, we do not
3812 // need to perform semantic analysis again.
3813 return Owned(
3814 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3815 VK_LValue, OK_ObjCProperty,
3816 PropertyLoc, Base));
3819 /// Build a new Objective-C "isa" expression.
3821 /// By default, performs semantic analysis to build the new expression.
3822 /// Subclasses may override this routine to provide different behavior.
3823 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
3824 SourceLocation OpLoc, bool IsArrow) {
3825 CXXScopeSpec SS;
3826 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3827 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3828 OpLoc, IsArrow,
3829 SS, SourceLocation(),
3830 /*FirstQualifierInScope=*/nullptr,
3831 NameInfo,
3832 /*TemplateArgs=*/nullptr,
3833 /*S=*/nullptr);
3836 /// Build a new shuffle vector expression.
3838 /// By default, performs semantic analysis to build the new expression.
3839 /// Subclasses may override this routine to provide different behavior.
3840 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
3841 MultiExprArg SubExprs,
3842 SourceLocation RParenLoc) {
3843 // Find the declaration for __builtin_shufflevector
3844 const IdentifierInfo &Name
3845 = SemaRef.Context.Idents.get("__builtin_shufflevector");
3846 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
3847 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
3848 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3850 // Build a reference to the __builtin_shufflevector builtin
3851 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
3852 Expr *Callee = new (SemaRef.Context)
3853 DeclRefExpr(SemaRef.Context, Builtin, false,
3854 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3855 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
3856 Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
3857 CK_BuiltinFnToFnPtr).get();
3859 // Build the CallExpr
3860 ExprResult TheCall = CallExpr::Create(
3861 SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
3862 Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc,
3863 FPOptionsOverride());
3865 // Type-check the __builtin_shufflevector expression.
3866 return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
3869 /// Build a new convert vector expression.
3870 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
3871 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3872 SourceLocation RParenLoc) {
3873 return SemaRef.SemaConvertVectorExpr(SrcExpr, DstTInfo,
3874 BuiltinLoc, RParenLoc);
3877 /// Build a new template argument pack expansion.
3879 /// By default, performs semantic analysis to build a new pack expansion
3880 /// for a template argument. Subclasses may override this routine to provide
3881 /// different behavior.
3882 TemplateArgumentLoc
3883 RebuildPackExpansion(TemplateArgumentLoc Pattern, SourceLocation EllipsisLoc,
3884 std::optional<unsigned> NumExpansions) {
3885 switch (Pattern.getArgument().getKind()) {
3886 case TemplateArgument::Expression: {
3887 ExprResult Result
3888 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
3889 EllipsisLoc, NumExpansions);
3890 if (Result.isInvalid())
3891 return TemplateArgumentLoc();
3893 return TemplateArgumentLoc(Result.get(), Result.get());
3896 case TemplateArgument::Template:
3897 return TemplateArgumentLoc(
3898 SemaRef.Context,
3899 TemplateArgument(Pattern.getArgument().getAsTemplate(),
3900 NumExpansions),
3901 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
3902 EllipsisLoc);
3904 case TemplateArgument::Null:
3905 case TemplateArgument::Integral:
3906 case TemplateArgument::Declaration:
3907 case TemplateArgument::Pack:
3908 case TemplateArgument::TemplateExpansion:
3909 case TemplateArgument::NullPtr:
3910 llvm_unreachable("Pack expansion pattern has no parameter packs");
3912 case TemplateArgument::Type:
3913 if (TypeSourceInfo *Expansion
3914 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
3915 EllipsisLoc,
3916 NumExpansions))
3917 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
3918 Expansion);
3919 break;
3922 return TemplateArgumentLoc();
3925 /// Build a new expression pack expansion.
3927 /// By default, performs semantic analysis to build a new pack expansion
3928 /// for an expression. Subclasses may override this routine to provide
3929 /// different behavior.
3930 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
3931 std::optional<unsigned> NumExpansions) {
3932 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
3935 /// Build a new C++1z fold-expression.
3937 /// By default, performs semantic analysis in order to build a new fold
3938 /// expression.
3939 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
3940 SourceLocation LParenLoc, Expr *LHS,
3941 BinaryOperatorKind Operator,
3942 SourceLocation EllipsisLoc, Expr *RHS,
3943 SourceLocation RParenLoc,
3944 std::optional<unsigned> NumExpansions) {
3945 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
3946 EllipsisLoc, RHS, RParenLoc,
3947 NumExpansions);
3950 /// Build an empty C++1z fold-expression with the given operator.
3952 /// By default, produces the fallback value for the fold-expression, or
3953 /// produce an error if there is no fallback value.
3954 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
3955 BinaryOperatorKind Operator) {
3956 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
3959 /// Build a new atomic operation expression.
3961 /// By default, performs semantic analysis to build the new expression.
3962 /// Subclasses may override this routine to provide different behavior.
3963 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
3964 AtomicExpr::AtomicOp Op,
3965 SourceLocation RParenLoc) {
3966 // Use this for all of the locations, since we don't know the difference
3967 // between the call and the expr at this point.
3968 SourceRange Range{BuiltinLoc, RParenLoc};
3969 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
3970 Sema::AtomicArgumentOrder::AST);
3973 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
3974 ArrayRef<Expr *> SubExprs, QualType Type) {
3975 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
3978 private:
3979 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
3980 QualType ObjectType,
3981 NamedDecl *FirstQualifierInScope,
3982 CXXScopeSpec &SS);
3984 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
3985 QualType ObjectType,
3986 NamedDecl *FirstQualifierInScope,
3987 CXXScopeSpec &SS);
3989 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
3990 NamedDecl *FirstQualifierInScope,
3991 CXXScopeSpec &SS);
3993 QualType TransformDependentNameType(TypeLocBuilder &TLB,
3994 DependentNameTypeLoc TL,
3995 bool DeducibleTSTContext);
3998 template <typename Derived>
3999 StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4000 if (!S)
4001 return S;
4003 switch (S->getStmtClass()) {
4004 case Stmt::NoStmtClass: break;
4006 // Transform individual statement nodes
4007 // Pass SDK into statements that can produce a value
4008 #define STMT(Node, Parent) \
4009 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4010 #define VALUESTMT(Node, Parent) \
4011 case Stmt::Node##Class: \
4012 return getDerived().Transform##Node(cast<Node>(S), SDK);
4013 #define ABSTRACT_STMT(Node)
4014 #define EXPR(Node, Parent)
4015 #include "clang/AST/StmtNodes.inc"
4017 // Transform expressions by calling TransformExpr.
4018 #define STMT(Node, Parent)
4019 #define ABSTRACT_STMT(Stmt)
4020 #define EXPR(Node, Parent) case Stmt::Node##Class:
4021 #include "clang/AST/StmtNodes.inc"
4023 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
4025 if (SDK == SDK_StmtExprResult)
4026 E = getSema().ActOnStmtExprResult(E);
4027 return getSema().ActOnExprStmt(E, SDK == SDK_Discarded);
4031 return S;
4034 template<typename Derived>
4035 OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4036 if (!S)
4037 return S;
4039 switch (S->getClauseKind()) {
4040 default: break;
4041 // Transform individual clause nodes
4042 #define GEN_CLANG_CLAUSE_CLASS
4043 #define CLAUSE_CLASS(Enum, Str, Class) \
4044 case Enum: \
4045 return getDerived().Transform##Class(cast<Class>(S));
4046 #include "llvm/Frontend/OpenMP/OMP.inc"
4049 return S;
4053 template<typename Derived>
4054 ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4055 if (!E)
4056 return E;
4058 switch (E->getStmtClass()) {
4059 case Stmt::NoStmtClass: break;
4060 #define STMT(Node, Parent) case Stmt::Node##Class: break;
4061 #define ABSTRACT_STMT(Stmt)
4062 #define EXPR(Node, Parent) \
4063 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4064 #include "clang/AST/StmtNodes.inc"
4067 return E;
4070 template<typename Derived>
4071 ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4072 bool NotCopyInit) {
4073 // Initializers are instantiated like expressions, except that various outer
4074 // layers are stripped.
4075 if (!Init)
4076 return Init;
4078 if (auto *FE = dyn_cast<FullExpr>(Init))
4079 Init = FE->getSubExpr();
4081 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {
4082 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4083 Init = OVE->getSourceExpr();
4086 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
4087 Init = MTE->getSubExpr();
4089 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
4090 Init = Binder->getSubExpr();
4092 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
4093 Init = ICE->getSubExprAsWritten();
4095 if (CXXStdInitializerListExpr *ILE =
4096 dyn_cast<CXXStdInitializerListExpr>(Init))
4097 return TransformInitializer(ILE->getSubExpr(), NotCopyInit);
4099 // If this is copy-initialization, we only need to reconstruct
4100 // InitListExprs. Other forms of copy-initialization will be a no-op if
4101 // the initializer is already the right type.
4102 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
4103 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4104 return getDerived().TransformExpr(Init);
4106 // Revert value-initialization back to empty parens.
4107 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
4108 SourceRange Parens = VIE->getSourceRange();
4109 return getDerived().RebuildParenListExpr(Parens.getBegin(), std::nullopt,
4110 Parens.getEnd());
4113 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4114 if (isa<ImplicitValueInitExpr>(Init))
4115 return getDerived().RebuildParenListExpr(SourceLocation(), std::nullopt,
4116 SourceLocation());
4118 // Revert initialization by constructor back to a parenthesized or braced list
4119 // of expressions. Any other form of initializer can just be reused directly.
4120 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
4121 return getDerived().TransformExpr(Init);
4123 // If the initialization implicitly converted an initializer list to a
4124 // std::initializer_list object, unwrap the std::initializer_list too.
4125 if (Construct && Construct->isStdInitListInitialization())
4126 return TransformInitializer(Construct->getArg(0), NotCopyInit);
4128 // Enter a list-init context if this was list initialization.
4129 EnterExpressionEvaluationContext Context(
4130 getSema(), EnterExpressionEvaluationContext::InitList,
4131 Construct->isListInitialization());
4133 SmallVector<Expr*, 8> NewArgs;
4134 bool ArgChanged = false;
4135 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4136 /*IsCall*/true, NewArgs, &ArgChanged))
4137 return ExprError();
4139 // If this was list initialization, revert to syntactic list form.
4140 if (Construct->isListInitialization())
4141 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4142 Construct->getEndLoc());
4144 // Build a ParenListExpr to represent anything else.
4145 SourceRange Parens = Construct->getParenOrBraceRange();
4146 if (Parens.isInvalid()) {
4147 // This was a variable declaration's initialization for which no initializer
4148 // was specified.
4149 assert(NewArgs.empty() &&
4150 "no parens or braces but have direct init with arguments?");
4151 return ExprEmpty();
4153 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4154 Parens.getEnd());
4157 template<typename Derived>
4158 bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4159 unsigned NumInputs,
4160 bool IsCall,
4161 SmallVectorImpl<Expr *> &Outputs,
4162 bool *ArgChanged) {
4163 for (unsigned I = 0; I != NumInputs; ++I) {
4164 // If requested, drop call arguments that need to be dropped.
4165 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4166 if (ArgChanged)
4167 *ArgChanged = true;
4169 break;
4172 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
4173 Expr *Pattern = Expansion->getPattern();
4175 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4176 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4177 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4179 // Determine whether the set of unexpanded parameter packs can and should
4180 // be expanded.
4181 bool Expand = true;
4182 bool RetainExpansion = false;
4183 std::optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions();
4184 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4185 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4186 Pattern->getSourceRange(),
4187 Unexpanded,
4188 Expand, RetainExpansion,
4189 NumExpansions))
4190 return true;
4192 if (!Expand) {
4193 // The transform has determined that we should perform a simple
4194 // transformation on the pack expansion, producing another pack
4195 // expansion.
4196 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4197 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4198 if (OutPattern.isInvalid())
4199 return true;
4201 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4202 Expansion->getEllipsisLoc(),
4203 NumExpansions);
4204 if (Out.isInvalid())
4205 return true;
4207 if (ArgChanged)
4208 *ArgChanged = true;
4209 Outputs.push_back(Out.get());
4210 continue;
4213 // Record right away that the argument was changed. This needs
4214 // to happen even if the array expands to nothing.
4215 if (ArgChanged) *ArgChanged = true;
4217 // The transform has determined that we should perform an elementwise
4218 // expansion of the pattern. Do so.
4219 for (unsigned I = 0; I != *NumExpansions; ++I) {
4220 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4221 ExprResult Out = getDerived().TransformExpr(Pattern);
4222 if (Out.isInvalid())
4223 return true;
4225 if (Out.get()->containsUnexpandedParameterPack()) {
4226 Out = getDerived().RebuildPackExpansion(
4227 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4228 if (Out.isInvalid())
4229 return true;
4232 Outputs.push_back(Out.get());
4235 // If we're supposed to retain a pack expansion, do so by temporarily
4236 // forgetting the partially-substituted parameter pack.
4237 if (RetainExpansion) {
4238 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4240 ExprResult Out = getDerived().TransformExpr(Pattern);
4241 if (Out.isInvalid())
4242 return true;
4244 Out = getDerived().RebuildPackExpansion(
4245 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4246 if (Out.isInvalid())
4247 return true;
4249 Outputs.push_back(Out.get());
4252 continue;
4255 ExprResult Result =
4256 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4257 : getDerived().TransformExpr(Inputs[I]);
4258 if (Result.isInvalid())
4259 return true;
4261 if (Result.get() != Inputs[I] && ArgChanged)
4262 *ArgChanged = true;
4264 Outputs.push_back(Result.get());
4267 return false;
4270 template <typename Derived>
4271 Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4272 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4273 if (Var) {
4274 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4275 getDerived().TransformDefinition(Var->getLocation(), Var));
4277 if (!ConditionVar)
4278 return Sema::ConditionError();
4280 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4283 if (Expr) {
4284 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4286 if (CondExpr.isInvalid())
4287 return Sema::ConditionError();
4289 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4290 /*MissingOK=*/true);
4293 return Sema::ConditionResult();
4296 template <typename Derived>
4297 NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4298 NestedNameSpecifierLoc NNS, QualType ObjectType,
4299 NamedDecl *FirstQualifierInScope) {
4300 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4302 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4303 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4304 Qualifier = Qualifier.getPrefix())
4305 Qualifiers.push_back(Qualifier);
4307 insertNNS(NNS);
4309 CXXScopeSpec SS;
4310 while (!Qualifiers.empty()) {
4311 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4312 NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
4314 switch (QNNS->getKind()) {
4315 case NestedNameSpecifier::Identifier: {
4316 Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
4317 Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
4318 ObjectType);
4319 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false,
4320 SS, FirstQualifierInScope, false))
4321 return NestedNameSpecifierLoc();
4322 break;
4325 case NestedNameSpecifier::Namespace: {
4326 NamespaceDecl *NS =
4327 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4328 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4329 SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
4330 break;
4333 case NestedNameSpecifier::NamespaceAlias: {
4334 NamespaceAliasDecl *Alias =
4335 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4336 Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
4337 SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
4338 Q.getLocalEndLoc());
4339 break;
4342 case NestedNameSpecifier::Global:
4343 // There is no meaningful transformation that one could perform on the
4344 // global scope.
4345 SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
4346 break;
4348 case NestedNameSpecifier::Super: {
4349 CXXRecordDecl *RD =
4350 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4351 SourceLocation(), QNNS->getAsRecordDecl()));
4352 SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc());
4353 break;
4356 case NestedNameSpecifier::TypeSpecWithTemplate:
4357 case NestedNameSpecifier::TypeSpec: {
4358 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4359 FirstQualifierInScope, SS);
4361 if (!TL)
4362 return NestedNameSpecifierLoc();
4364 QualType T = TL.getType();
4365 if (T->isDependentType() || T->isRecordType() ||
4366 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4367 if (T->isEnumeralType())
4368 SemaRef.Diag(TL.getBeginLoc(),
4369 diag::warn_cxx98_compat_enum_nested_name_spec);
4371 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4372 SS.Adopt(ETL.getQualifierLoc());
4373 TL = ETL.getNamedTypeLoc();
4375 SS.Extend(SemaRef.Context, /*FIXME:*/ SourceLocation(), TL,
4376 Q.getLocalEndLoc());
4377 break;
4379 // If the nested-name-specifier is an invalid type def, don't emit an
4380 // error because a previous error should have already been emitted.
4381 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4382 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4383 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
4384 << T << SS.getRange();
4386 return NestedNameSpecifierLoc();
4390 // The qualifier-in-scope and object type only apply to the leftmost entity.
4391 FirstQualifierInScope = nullptr;
4392 ObjectType = QualType();
4395 // Don't rebuild the nested-name-specifier if we don't have to.
4396 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4397 !getDerived().AlwaysRebuild())
4398 return NNS;
4400 // If we can re-use the source-location data from the original
4401 // nested-name-specifier, do so.
4402 if (SS.location_size() == NNS.getDataLength() &&
4403 memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)
4404 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4406 // Allocate new nested-name-specifier location information.
4407 return SS.getWithLocInContext(SemaRef.Context);
4410 template<typename Derived>
4411 DeclarationNameInfo
4412 TreeTransform<Derived>
4413 ::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4414 DeclarationName Name = NameInfo.getName();
4415 if (!Name)
4416 return DeclarationNameInfo();
4418 switch (Name.getNameKind()) {
4419 case DeclarationName::Identifier:
4420 case DeclarationName::ObjCZeroArgSelector:
4421 case DeclarationName::ObjCOneArgSelector:
4422 case DeclarationName::ObjCMultiArgSelector:
4423 case DeclarationName::CXXOperatorName:
4424 case DeclarationName::CXXLiteralOperatorName:
4425 case DeclarationName::CXXUsingDirective:
4426 return NameInfo;
4428 case DeclarationName::CXXDeductionGuideName: {
4429 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4430 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4431 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4432 if (!NewTemplate)
4433 return DeclarationNameInfo();
4435 DeclarationNameInfo NewNameInfo(NameInfo);
4436 NewNameInfo.setName(
4437 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(NewTemplate));
4438 return NewNameInfo;
4441 case DeclarationName::CXXConstructorName:
4442 case DeclarationName::CXXDestructorName:
4443 case DeclarationName::CXXConversionFunctionName: {
4444 TypeSourceInfo *NewTInfo;
4445 CanQualType NewCanTy;
4446 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4447 NewTInfo = getDerived().TransformType(OldTInfo);
4448 if (!NewTInfo)
4449 return DeclarationNameInfo();
4450 NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
4452 else {
4453 NewTInfo = nullptr;
4454 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4455 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4456 if (NewT.isNull())
4457 return DeclarationNameInfo();
4458 NewCanTy = SemaRef.Context.getCanonicalType(NewT);
4461 DeclarationName NewName
4462 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
4463 NewCanTy);
4464 DeclarationNameInfo NewNameInfo(NameInfo);
4465 NewNameInfo.setName(NewName);
4466 NewNameInfo.setNamedTypeInfo(NewTInfo);
4467 return NewNameInfo;
4471 llvm_unreachable("Unknown name kind.");
4474 template<typename Derived>
4475 TemplateName
4476 TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
4477 TemplateName Name,
4478 SourceLocation NameLoc,
4479 QualType ObjectType,
4480 NamedDecl *FirstQualifierInScope,
4481 bool AllowInjectedClassName) {
4482 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4483 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4484 assert(Template && "qualified template name must refer to a template");
4486 TemplateDecl *TransTemplate
4487 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4488 Template));
4489 if (!TransTemplate)
4490 return TemplateName();
4492 if (!getDerived().AlwaysRebuild() &&
4493 SS.getScopeRep() == QTN->getQualifier() &&
4494 TransTemplate == Template)
4495 return Name;
4497 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4498 TransTemplate);
4501 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4502 if (SS.getScopeRep()) {
4503 // These apply to the scope specifier, not the template.
4504 ObjectType = QualType();
4505 FirstQualifierInScope = nullptr;
4508 if (!getDerived().AlwaysRebuild() &&
4509 SS.getScopeRep() == DTN->getQualifier() &&
4510 ObjectType.isNull())
4511 return Name;
4513 // FIXME: Preserve the location of the "template" keyword.
4514 SourceLocation TemplateKWLoc = NameLoc;
4516 if (DTN->isIdentifier()) {
4517 return getDerived().RebuildTemplateName(SS,
4518 TemplateKWLoc,
4519 *DTN->getIdentifier(),
4520 NameLoc,
4521 ObjectType,
4522 FirstQualifierInScope,
4523 AllowInjectedClassName);
4526 return getDerived().RebuildTemplateName(SS, TemplateKWLoc,
4527 DTN->getOperator(), NameLoc,
4528 ObjectType, AllowInjectedClassName);
4531 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4532 TemplateDecl *TransTemplate
4533 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4534 Template));
4535 if (!TransTemplate)
4536 return TemplateName();
4538 if (!getDerived().AlwaysRebuild() &&
4539 TransTemplate == Template)
4540 return Name;
4542 return TemplateName(TransTemplate);
4545 if (SubstTemplateTemplateParmPackStorage *SubstPack
4546 = Name.getAsSubstTemplateTemplateParmPack()) {
4547 return getDerived().RebuildTemplateName(
4548 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4549 SubstPack->getIndex(), SubstPack->getFinal());
4552 // These should be getting filtered out before they reach the AST.
4553 llvm_unreachable("overloaded function decl survived to here");
4556 template<typename Derived>
4557 void TreeTransform<Derived>::InventTemplateArgumentLoc(
4558 const TemplateArgument &Arg,
4559 TemplateArgumentLoc &Output) {
4560 Output = getSema().getTrivialTemplateArgumentLoc(
4561 Arg, QualType(), getDerived().getBaseLocation());
4564 template <typename Derived>
4565 bool TreeTransform<Derived>::TransformTemplateArgument(
4566 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4567 bool Uneval) {
4568 const TemplateArgument &Arg = Input.getArgument();
4569 switch (Arg.getKind()) {
4570 case TemplateArgument::Null:
4571 case TemplateArgument::Pack:
4572 llvm_unreachable("Unexpected TemplateArgument");
4574 case TemplateArgument::Integral:
4575 case TemplateArgument::NullPtr:
4576 case TemplateArgument::Declaration: {
4577 // Transform a resolved template argument straight to a resolved template
4578 // argument. We get here when substituting into an already-substituted
4579 // template type argument during concept satisfaction checking.
4580 QualType T = Arg.getNonTypeTemplateArgumentType();
4581 QualType NewT = getDerived().TransformType(T);
4582 if (NewT.isNull())
4583 return true;
4585 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
4586 ? Arg.getAsDecl()
4587 : nullptr;
4588 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4589 getDerived().getBaseLocation(), D))
4590 : nullptr;
4591 if (D && !NewD)
4592 return true;
4594 if (NewT == T && D == NewD)
4595 Output = Input;
4596 else if (Arg.getKind() == TemplateArgument::Integral)
4597 Output = TemplateArgumentLoc(
4598 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4599 TemplateArgumentLocInfo());
4600 else if (Arg.getKind() == TemplateArgument::NullPtr)
4601 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4602 TemplateArgumentLocInfo());
4603 else
4604 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4605 TemplateArgumentLocInfo());
4607 return false;
4610 case TemplateArgument::Type: {
4611 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4612 if (!DI)
4613 DI = InventTypeSourceInfo(Input.getArgument().getAsType());
4615 DI = getDerived().TransformType(DI);
4616 if (!DI)
4617 return true;
4619 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4620 return false;
4623 case TemplateArgument::Template: {
4624 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4625 if (QualifierLoc) {
4626 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4627 if (!QualifierLoc)
4628 return true;
4631 CXXScopeSpec SS;
4632 SS.Adopt(QualifierLoc);
4633 TemplateName Template = getDerived().TransformTemplateName(
4634 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4635 if (Template.isNull())
4636 return true;
4638 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4639 QualifierLoc, Input.getTemplateNameLoc());
4640 return false;
4643 case TemplateArgument::TemplateExpansion:
4644 llvm_unreachable("Caller should expand pack expansions");
4646 case TemplateArgument::Expression: {
4647 // Template argument expressions are constant expressions.
4648 EnterExpressionEvaluationContext Unevaluated(
4649 getSema(),
4650 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
4651 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
4652 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4653 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
4655 Expr *InputExpr = Input.getSourceExpression();
4656 if (!InputExpr)
4657 InputExpr = Input.getArgument().getAsExpr();
4659 ExprResult E = getDerived().TransformExpr(InputExpr);
4660 E = SemaRef.ActOnConstantExpression(E);
4661 if (E.isInvalid())
4662 return true;
4663 Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
4664 return false;
4668 // Work around bogus GCC warning
4669 return true;
4672 /// Iterator adaptor that invents template argument location information
4673 /// for each of the template arguments in its underlying iterator.
4674 template<typename Derived, typename InputIterator>
4675 class TemplateArgumentLocInventIterator {
4676 TreeTransform<Derived> &Self;
4677 InputIterator Iter;
4679 public:
4680 typedef TemplateArgumentLoc value_type;
4681 typedef TemplateArgumentLoc reference;
4682 typedef typename std::iterator_traits<InputIterator>::difference_type
4683 difference_type;
4684 typedef std::input_iterator_tag iterator_category;
4686 class pointer {
4687 TemplateArgumentLoc Arg;
4689 public:
4690 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4692 const TemplateArgumentLoc *operator->() const { return &Arg; }
4695 TemplateArgumentLocInventIterator() { }
4697 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
4698 InputIterator Iter)
4699 : Self(Self), Iter(Iter) { }
4701 TemplateArgumentLocInventIterator &operator++() {
4702 ++Iter;
4703 return *this;
4706 TemplateArgumentLocInventIterator operator++(int) {
4707 TemplateArgumentLocInventIterator Old(*this);
4708 ++(*this);
4709 return Old;
4712 reference operator*() const {
4713 TemplateArgumentLoc Result;
4714 Self.InventTemplateArgumentLoc(*Iter, Result);
4715 return Result;
4718 pointer operator->() const { return pointer(**this); }
4720 friend bool operator==(const TemplateArgumentLocInventIterator &X,
4721 const TemplateArgumentLocInventIterator &Y) {
4722 return X.Iter == Y.Iter;
4725 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
4726 const TemplateArgumentLocInventIterator &Y) {
4727 return X.Iter != Y.Iter;
4731 template<typename Derived>
4732 template<typename InputIterator>
4733 bool TreeTransform<Derived>::TransformTemplateArguments(
4734 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
4735 bool Uneval) {
4736 for (; First != Last; ++First) {
4737 TemplateArgumentLoc Out;
4738 TemplateArgumentLoc In = *First;
4740 if (In.getArgument().getKind() == TemplateArgument::Pack) {
4741 // Unpack argument packs, which we translate them into separate
4742 // arguments.
4743 // FIXME: We could do much better if we could guarantee that the
4744 // TemplateArgumentLocInfo for the pack expansion would be usable for
4745 // all of the template arguments in the argument pack.
4746 typedef TemplateArgumentLocInventIterator<Derived,
4747 TemplateArgument::pack_iterator>
4748 PackLocIterator;
4749 if (TransformTemplateArguments(PackLocIterator(*this,
4750 In.getArgument().pack_begin()),
4751 PackLocIterator(*this,
4752 In.getArgument().pack_end()),
4753 Outputs, Uneval))
4754 return true;
4756 continue;
4759 if (In.getArgument().isPackExpansion()) {
4760 // We have a pack expansion, for which we will be substituting into
4761 // the pattern.
4762 SourceLocation Ellipsis;
4763 std::optional<unsigned> OrigNumExpansions;
4764 TemplateArgumentLoc Pattern
4765 = getSema().getTemplateArgumentPackExpansionPattern(
4766 In, Ellipsis, OrigNumExpansions);
4768 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4769 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4770 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4772 // Determine whether the set of unexpanded parameter packs can and should
4773 // be expanded.
4774 bool Expand = true;
4775 bool RetainExpansion = false;
4776 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4777 if (getDerived().TryExpandParameterPacks(Ellipsis,
4778 Pattern.getSourceRange(),
4779 Unexpanded,
4780 Expand,
4781 RetainExpansion,
4782 NumExpansions))
4783 return true;
4785 if (!Expand) {
4786 // The transform has determined that we should perform a simple
4787 // transformation on the pack expansion, producing another pack
4788 // expansion.
4789 TemplateArgumentLoc OutPattern;
4790 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4791 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
4792 return true;
4794 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
4795 NumExpansions);
4796 if (Out.getArgument().isNull())
4797 return true;
4799 Outputs.addArgument(Out);
4800 continue;
4803 // The transform has determined that we should perform an elementwise
4804 // expansion of the pattern. Do so.
4805 for (unsigned I = 0; I != *NumExpansions; ++I) {
4806 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4808 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4809 return true;
4811 if (Out.getArgument().containsUnexpandedParameterPack()) {
4812 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4813 OrigNumExpansions);
4814 if (Out.getArgument().isNull())
4815 return true;
4818 Outputs.addArgument(Out);
4821 // If we're supposed to retain a pack expansion, do so by temporarily
4822 // forgetting the partially-substituted parameter pack.
4823 if (RetainExpansion) {
4824 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4826 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4827 return true;
4829 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4830 OrigNumExpansions);
4831 if (Out.getArgument().isNull())
4832 return true;
4834 Outputs.addArgument(Out);
4837 continue;
4840 // The simple case:
4841 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
4842 return true;
4844 Outputs.addArgument(Out);
4847 return false;
4851 //===----------------------------------------------------------------------===//
4852 // Type transformation
4853 //===----------------------------------------------------------------------===//
4855 template<typename Derived>
4856 QualType TreeTransform<Derived>::TransformType(QualType T) {
4857 if (getDerived().AlreadyTransformed(T))
4858 return T;
4860 // Temporary workaround. All of these transformations should
4861 // eventually turn into transformations on TypeLocs.
4862 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4863 getDerived().getBaseLocation());
4865 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
4867 if (!NewDI)
4868 return QualType();
4870 return NewDI->getType();
4873 template<typename Derived>
4874 TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
4875 // Refine the base location to the type's location.
4876 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
4877 getDerived().getBaseEntity());
4878 if (getDerived().AlreadyTransformed(DI->getType()))
4879 return DI;
4881 TypeLocBuilder TLB;
4883 TypeLoc TL = DI->getTypeLoc();
4884 TLB.reserve(TL.getFullDataSize());
4886 QualType Result = getDerived().TransformType(TLB, TL);
4887 if (Result.isNull())
4888 return nullptr;
4890 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
4893 template<typename Derived>
4894 QualType
4895 TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
4896 switch (T.getTypeLocClass()) {
4897 #define ABSTRACT_TYPELOC(CLASS, PARENT)
4898 #define TYPELOC(CLASS, PARENT) \
4899 case TypeLoc::CLASS: \
4900 return getDerived().Transform##CLASS##Type(TLB, \
4901 T.castAs<CLASS##TypeLoc>());
4902 #include "clang/AST/TypeLocNodes.def"
4905 llvm_unreachable("unhandled type loc!");
4908 template<typename Derived>
4909 QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
4910 if (!isa<DependentNameType>(T))
4911 return TransformType(T);
4913 if (getDerived().AlreadyTransformed(T))
4914 return T;
4915 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4916 getDerived().getBaseLocation());
4917 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
4918 return NewDI ? NewDI->getType() : QualType();
4921 template<typename Derived>
4922 TypeSourceInfo *
4923 TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
4924 if (!isa<DependentNameType>(DI->getType()))
4925 return TransformType(DI);
4927 // Refine the base location to the type's location.
4928 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
4929 getDerived().getBaseEntity());
4930 if (getDerived().AlreadyTransformed(DI->getType()))
4931 return DI;
4933 TypeLocBuilder TLB;
4935 TypeLoc TL = DI->getTypeLoc();
4936 TLB.reserve(TL.getFullDataSize());
4938 auto QTL = TL.getAs<QualifiedTypeLoc>();
4939 if (QTL)
4940 TL = QTL.getUnqualifiedLoc();
4942 auto DNTL = TL.castAs<DependentNameTypeLoc>();
4944 QualType Result = getDerived().TransformDependentNameType(
4945 TLB, DNTL, /*DeducedTSTContext*/true);
4946 if (Result.isNull())
4947 return nullptr;
4949 if (QTL) {
4950 Result = getDerived().RebuildQualifiedType(Result, QTL);
4951 if (Result.isNull())
4952 return nullptr;
4953 TLB.TypeWasModifiedSafely(Result);
4956 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
4959 template<typename Derived>
4960 QualType
4961 TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
4962 QualifiedTypeLoc T) {
4963 QualType Result;
4964 TypeLoc UnqualTL = T.getUnqualifiedLoc();
4965 auto SuppressObjCLifetime =
4966 T.getType().getLocalQualifiers().hasObjCLifetime();
4967 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
4968 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
4969 SuppressObjCLifetime);
4970 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
4971 Result = getDerived().TransformSubstTemplateTypeParmPackType(
4972 TLB, STTP, SuppressObjCLifetime);
4973 } else {
4974 Result = getDerived().TransformType(TLB, UnqualTL);
4977 if (Result.isNull())
4978 return QualType();
4980 Result = getDerived().RebuildQualifiedType(Result, T);
4982 if (Result.isNull())
4983 return QualType();
4985 // RebuildQualifiedType might have updated the type, but not in a way
4986 // that invalidates the TypeLoc. (There's no location information for
4987 // qualifiers.)
4988 TLB.TypeWasModifiedSafely(Result);
4990 return Result;
4993 template <typename Derived>
4994 QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
4995 QualifiedTypeLoc TL) {
4997 SourceLocation Loc = TL.getBeginLoc();
4998 Qualifiers Quals = TL.getType().getLocalQualifiers();
5000 if ((T.getAddressSpace() != LangAS::Default &&
5001 Quals.getAddressSpace() != LangAS::Default) &&
5002 T.getAddressSpace() != Quals.getAddressSpace()) {
5003 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)
5004 << TL.getType() << T;
5005 return QualType();
5008 // C++ [dcl.fct]p7:
5009 // [When] adding cv-qualifications on top of the function type [...] the
5010 // cv-qualifiers are ignored.
5011 if (T->isFunctionType()) {
5012 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5013 Quals.getAddressSpace());
5014 return T;
5017 // C++ [dcl.ref]p1:
5018 // when the cv-qualifiers are introduced through the use of a typedef-name
5019 // or decltype-specifier [...] the cv-qualifiers are ignored.
5020 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5021 // applied to a reference type.
5022 if (T->isReferenceType()) {
5023 // The only qualifier that applies to a reference type is restrict.
5024 if (!Quals.hasRestrict())
5025 return T;
5026 Quals = Qualifiers::fromCVRMask(Qualifiers::Restrict);
5029 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5030 // resulting type.
5031 if (Quals.hasObjCLifetime()) {
5032 if (!T->isObjCLifetimeType() && !T->isDependentType())
5033 Quals.removeObjCLifetime();
5034 else if (T.getObjCLifetime()) {
5035 // Objective-C ARC:
5036 // A lifetime qualifier applied to a substituted template parameter
5037 // overrides the lifetime qualifier from the template argument.
5038 const AutoType *AutoTy;
5039 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
5040 // 'auto' types behave the same way as template parameters.
5041 QualType Deduced = AutoTy->getDeducedType();
5042 Qualifiers Qs = Deduced.getQualifiers();
5043 Qs.removeObjCLifetime();
5044 Deduced =
5045 SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);
5046 T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),
5047 AutoTy->isDependentType(),
5048 /*isPack=*/false,
5049 AutoTy->getTypeConstraintConcept(),
5050 AutoTy->getTypeConstraintArguments());
5051 } else {
5052 // Otherwise, complain about the addition of a qualifier to an
5053 // already-qualified type.
5054 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5055 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
5056 Quals.removeObjCLifetime();
5061 return SemaRef.BuildQualifiedType(T, Loc, Quals);
5064 template<typename Derived>
5065 TypeLoc
5066 TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
5067 QualType ObjectType,
5068 NamedDecl *UnqualLookup,
5069 CXXScopeSpec &SS) {
5070 if (getDerived().AlreadyTransformed(TL.getType()))
5071 return TL;
5073 TypeSourceInfo *TSI =
5074 TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS);
5075 if (TSI)
5076 return TSI->getTypeLoc();
5077 return TypeLoc();
5080 template<typename Derived>
5081 TypeSourceInfo *
5082 TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5083 QualType ObjectType,
5084 NamedDecl *UnqualLookup,
5085 CXXScopeSpec &SS) {
5086 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5087 return TSInfo;
5089 return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType,
5090 UnqualLookup, SS);
5093 template <typename Derived>
5094 TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5095 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5096 CXXScopeSpec &SS) {
5097 QualType T = TL.getType();
5098 assert(!getDerived().AlreadyTransformed(T));
5100 TypeLocBuilder TLB;
5101 QualType Result;
5103 if (isa<TemplateSpecializationType>(T)) {
5104 TemplateSpecializationTypeLoc SpecTL =
5105 TL.castAs<TemplateSpecializationTypeLoc>();
5107 TemplateName Template = getDerived().TransformTemplateName(
5108 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5109 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5110 if (Template.isNull())
5111 return nullptr;
5113 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5114 Template);
5115 } else if (isa<DependentTemplateSpecializationType>(T)) {
5116 DependentTemplateSpecializationTypeLoc SpecTL =
5117 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5119 TemplateName Template
5120 = getDerived().RebuildTemplateName(SS,
5121 SpecTL.getTemplateKeywordLoc(),
5122 *SpecTL.getTypePtr()->getIdentifier(),
5123 SpecTL.getTemplateNameLoc(),
5124 ObjectType, UnqualLookup,
5125 /*AllowInjectedClassName*/true);
5126 if (Template.isNull())
5127 return nullptr;
5129 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5130 SpecTL,
5131 Template,
5132 SS);
5133 } else {
5134 // Nothing special needs to be done for these.
5135 Result = getDerived().TransformType(TLB, TL);
5138 if (Result.isNull())
5139 return nullptr;
5141 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5144 template <class TyLoc> static inline
5145 QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5146 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5147 NewT.setNameLoc(T.getNameLoc());
5148 return T.getType();
5151 template<typename Derived>
5152 QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5153 BuiltinTypeLoc T) {
5154 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
5155 NewT.setBuiltinLoc(T.getBuiltinLoc());
5156 if (T.needsExtraLocalData())
5157 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5158 return T.getType();
5161 template<typename Derived>
5162 QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5163 ComplexTypeLoc T) {
5164 // FIXME: recurse?
5165 return TransformTypeSpecType(TLB, T);
5168 template <typename Derived>
5169 QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5170 AdjustedTypeLoc TL) {
5171 // Adjustments applied during transformation are handled elsewhere.
5172 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5175 template<typename Derived>
5176 QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5177 DecayedTypeLoc TL) {
5178 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5179 if (OriginalType.isNull())
5180 return QualType();
5182 QualType Result = TL.getType();
5183 if (getDerived().AlwaysRebuild() ||
5184 OriginalType != TL.getOriginalLoc().getType())
5185 Result = SemaRef.Context.getDecayedType(OriginalType);
5186 TLB.push<DecayedTypeLoc>(Result);
5187 // Nothing to set for DecayedTypeLoc.
5188 return Result;
5191 template<typename Derived>
5192 QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5193 PointerTypeLoc TL) {
5194 QualType PointeeType
5195 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5196 if (PointeeType.isNull())
5197 return QualType();
5199 QualType Result = TL.getType();
5200 if (PointeeType->getAs<ObjCObjectType>()) {
5201 // A dependent pointer type 'T *' has is being transformed such
5202 // that an Objective-C class type is being replaced for 'T'. The
5203 // resulting pointer type is an ObjCObjectPointerType, not a
5204 // PointerType.
5205 Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
5207 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
5208 NewT.setStarLoc(TL.getStarLoc());
5209 return Result;
5212 if (getDerived().AlwaysRebuild() ||
5213 PointeeType != TL.getPointeeLoc().getType()) {
5214 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5215 if (Result.isNull())
5216 return QualType();
5219 // Objective-C ARC can add lifetime qualifiers to the type that we're
5220 // pointing to.
5221 TLB.TypeWasModifiedSafely(Result->getPointeeType());
5223 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
5224 NewT.setSigilLoc(TL.getSigilLoc());
5225 return Result;
5228 template<typename Derived>
5229 QualType
5230 TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5231 BlockPointerTypeLoc TL) {
5232 QualType PointeeType
5233 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5234 if (PointeeType.isNull())
5235 return QualType();
5237 QualType Result = TL.getType();
5238 if (getDerived().AlwaysRebuild() ||
5239 PointeeType != TL.getPointeeLoc().getType()) {
5240 Result = getDerived().RebuildBlockPointerType(PointeeType,
5241 TL.getSigilLoc());
5242 if (Result.isNull())
5243 return QualType();
5246 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
5247 NewT.setSigilLoc(TL.getSigilLoc());
5248 return Result;
5251 /// Transforms a reference type. Note that somewhat paradoxically we
5252 /// don't care whether the type itself is an l-value type or an r-value
5253 /// type; we only care if the type was *written* as an l-value type
5254 /// or an r-value type.
5255 template<typename Derived>
5256 QualType
5257 TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5258 ReferenceTypeLoc TL) {
5259 const ReferenceType *T = TL.getTypePtr();
5261 // Note that this works with the pointee-as-written.
5262 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5263 if (PointeeType.isNull())
5264 return QualType();
5266 QualType Result = TL.getType();
5267 if (getDerived().AlwaysRebuild() ||
5268 PointeeType != T->getPointeeTypeAsWritten()) {
5269 Result = getDerived().RebuildReferenceType(PointeeType,
5270 T->isSpelledAsLValue(),
5271 TL.getSigilLoc());
5272 if (Result.isNull())
5273 return QualType();
5276 // Objective-C ARC can add lifetime qualifiers to the type that we're
5277 // referring to.
5278 TLB.TypeWasModifiedSafely(
5279 Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5281 // r-value references can be rebuilt as l-value references.
5282 ReferenceTypeLoc NewTL;
5283 if (isa<LValueReferenceType>(Result))
5284 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
5285 else
5286 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
5287 NewTL.setSigilLoc(TL.getSigilLoc());
5289 return Result;
5292 template<typename Derived>
5293 QualType
5294 TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5295 LValueReferenceTypeLoc TL) {
5296 return TransformReferenceType(TLB, TL);
5299 template<typename Derived>
5300 QualType
5301 TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5302 RValueReferenceTypeLoc TL) {
5303 return TransformReferenceType(TLB, TL);
5306 template<typename Derived>
5307 QualType
5308 TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5309 MemberPointerTypeLoc TL) {
5310 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5311 if (PointeeType.isNull())
5312 return QualType();
5314 TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
5315 TypeSourceInfo *NewClsTInfo = nullptr;
5316 if (OldClsTInfo) {
5317 NewClsTInfo = getDerived().TransformType(OldClsTInfo);
5318 if (!NewClsTInfo)
5319 return QualType();
5322 const MemberPointerType *T = TL.getTypePtr();
5323 QualType OldClsType = QualType(T->getClass(), 0);
5324 QualType NewClsType;
5325 if (NewClsTInfo)
5326 NewClsType = NewClsTInfo->getType();
5327 else {
5328 NewClsType = getDerived().TransformType(OldClsType);
5329 if (NewClsType.isNull())
5330 return QualType();
5333 QualType Result = TL.getType();
5334 if (getDerived().AlwaysRebuild() ||
5335 PointeeType != T->getPointeeType() ||
5336 NewClsType != OldClsType) {
5337 Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
5338 TL.getStarLoc());
5339 if (Result.isNull())
5340 return QualType();
5343 // If we had to adjust the pointee type when building a member pointer, make
5344 // sure to push TypeLoc info for it.
5345 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5346 if (MPT && PointeeType != MPT->getPointeeType()) {
5347 assert(isa<AdjustedType>(MPT->getPointeeType()));
5348 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
5351 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
5352 NewTL.setSigilLoc(TL.getSigilLoc());
5353 NewTL.setClassTInfo(NewClsTInfo);
5355 return Result;
5358 template<typename Derived>
5359 QualType
5360 TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5361 ConstantArrayTypeLoc TL) {
5362 const ConstantArrayType *T = TL.getTypePtr();
5363 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5364 if (ElementType.isNull())
5365 return QualType();
5367 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5368 Expr *OldSize = TL.getSizeExpr();
5369 if (!OldSize)
5370 OldSize = const_cast<Expr*>(T->getSizeExpr());
5371 Expr *NewSize = nullptr;
5372 if (OldSize) {
5373 EnterExpressionEvaluationContext Unevaluated(
5374 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5375 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5376 NewSize = SemaRef.ActOnConstantExpression(NewSize).get();
5379 QualType Result = TL.getType();
5380 if (getDerived().AlwaysRebuild() ||
5381 ElementType != T->getElementType() ||
5382 (T->getSizeExpr() && NewSize != OldSize)) {
5383 Result = getDerived().RebuildConstantArrayType(ElementType,
5384 T->getSizeModifier(),
5385 T->getSize(), NewSize,
5386 T->getIndexTypeCVRQualifiers(),
5387 TL.getBracketsRange());
5388 if (Result.isNull())
5389 return QualType();
5392 // We might have either a ConstantArrayType or a VariableArrayType now:
5393 // a ConstantArrayType is allowed to have an element type which is a
5394 // VariableArrayType if the type is dependent. Fortunately, all array
5395 // types have the same location layout.
5396 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5397 NewTL.setLBracketLoc(TL.getLBracketLoc());
5398 NewTL.setRBracketLoc(TL.getRBracketLoc());
5399 NewTL.setSizeExpr(NewSize);
5401 return Result;
5404 template<typename Derived>
5405 QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5406 TypeLocBuilder &TLB,
5407 IncompleteArrayTypeLoc TL) {
5408 const IncompleteArrayType *T = TL.getTypePtr();
5409 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5410 if (ElementType.isNull())
5411 return QualType();
5413 QualType Result = TL.getType();
5414 if (getDerived().AlwaysRebuild() ||
5415 ElementType != T->getElementType()) {
5416 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5417 T->getSizeModifier(),
5418 T->getIndexTypeCVRQualifiers(),
5419 TL.getBracketsRange());
5420 if (Result.isNull())
5421 return QualType();
5424 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
5425 NewTL.setLBracketLoc(TL.getLBracketLoc());
5426 NewTL.setRBracketLoc(TL.getRBracketLoc());
5427 NewTL.setSizeExpr(nullptr);
5429 return Result;
5432 template<typename Derived>
5433 QualType
5434 TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5435 VariableArrayTypeLoc TL) {
5436 const VariableArrayType *T = TL.getTypePtr();
5437 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5438 if (ElementType.isNull())
5439 return QualType();
5441 ExprResult SizeResult;
5443 EnterExpressionEvaluationContext Context(
5444 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5445 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5447 if (SizeResult.isInvalid())
5448 return QualType();
5449 SizeResult =
5450 SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);
5451 if (SizeResult.isInvalid())
5452 return QualType();
5454 Expr *Size = SizeResult.get();
5456 QualType Result = TL.getType();
5457 if (getDerived().AlwaysRebuild() ||
5458 ElementType != T->getElementType() ||
5459 Size != T->getSizeExpr()) {
5460 Result = getDerived().RebuildVariableArrayType(ElementType,
5461 T->getSizeModifier(),
5462 Size,
5463 T->getIndexTypeCVRQualifiers(),
5464 TL.getBracketsRange());
5465 if (Result.isNull())
5466 return QualType();
5469 // We might have constant size array now, but fortunately it has the same
5470 // location layout.
5471 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5472 NewTL.setLBracketLoc(TL.getLBracketLoc());
5473 NewTL.setRBracketLoc(TL.getRBracketLoc());
5474 NewTL.setSizeExpr(Size);
5476 return Result;
5479 template<typename Derived>
5480 QualType
5481 TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5482 DependentSizedArrayTypeLoc TL) {
5483 const DependentSizedArrayType *T = TL.getTypePtr();
5484 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5485 if (ElementType.isNull())
5486 return QualType();
5488 // Array bounds are constant expressions.
5489 EnterExpressionEvaluationContext Unevaluated(
5490 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5492 // If we have a VLA then it won't be a constant.
5493 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5495 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5496 Expr *origSize = TL.getSizeExpr();
5497 if (!origSize) origSize = T->getSizeExpr();
5499 ExprResult sizeResult
5500 = getDerived().TransformExpr(origSize);
5501 sizeResult = SemaRef.ActOnConstantExpression(sizeResult);
5502 if (sizeResult.isInvalid())
5503 return QualType();
5505 Expr *size = sizeResult.get();
5507 QualType Result = TL.getType();
5508 if (getDerived().AlwaysRebuild() ||
5509 ElementType != T->getElementType() ||
5510 size != origSize) {
5511 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5512 T->getSizeModifier(),
5513 size,
5514 T->getIndexTypeCVRQualifiers(),
5515 TL.getBracketsRange());
5516 if (Result.isNull())
5517 return QualType();
5520 // We might have any sort of array type now, but fortunately they
5521 // all have the same location layout.
5522 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5523 NewTL.setLBracketLoc(TL.getLBracketLoc());
5524 NewTL.setRBracketLoc(TL.getRBracketLoc());
5525 NewTL.setSizeExpr(size);
5527 return Result;
5530 template <typename Derived>
5531 QualType TreeTransform<Derived>::TransformDependentVectorType(
5532 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5533 const DependentVectorType *T = TL.getTypePtr();
5534 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5535 if (ElementType.isNull())
5536 return QualType();
5538 EnterExpressionEvaluationContext Unevaluated(
5539 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5541 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5542 Size = SemaRef.ActOnConstantExpression(Size);
5543 if (Size.isInvalid())
5544 return QualType();
5546 QualType Result = TL.getType();
5547 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5548 Size.get() != T->getSizeExpr()) {
5549 Result = getDerived().RebuildDependentVectorType(
5550 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5551 if (Result.isNull())
5552 return QualType();
5555 // Result might be dependent or not.
5556 if (isa<DependentVectorType>(Result)) {
5557 DependentVectorTypeLoc NewTL =
5558 TLB.push<DependentVectorTypeLoc>(Result);
5559 NewTL.setNameLoc(TL.getNameLoc());
5560 } else {
5561 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5562 NewTL.setNameLoc(TL.getNameLoc());
5565 return Result;
5568 template<typename Derived>
5569 QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5570 TypeLocBuilder &TLB,
5571 DependentSizedExtVectorTypeLoc TL) {
5572 const DependentSizedExtVectorType *T = TL.getTypePtr();
5574 // FIXME: ext vector locs should be nested
5575 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5576 if (ElementType.isNull())
5577 return QualType();
5579 // Vector sizes are constant expressions.
5580 EnterExpressionEvaluationContext Unevaluated(
5581 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5583 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5584 Size = SemaRef.ActOnConstantExpression(Size);
5585 if (Size.isInvalid())
5586 return QualType();
5588 QualType Result = TL.getType();
5589 if (getDerived().AlwaysRebuild() ||
5590 ElementType != T->getElementType() ||
5591 Size.get() != T->getSizeExpr()) {
5592 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5593 Size.get(),
5594 T->getAttributeLoc());
5595 if (Result.isNull())
5596 return QualType();
5599 // Result might be dependent or not.
5600 if (isa<DependentSizedExtVectorType>(Result)) {
5601 DependentSizedExtVectorTypeLoc NewTL
5602 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
5603 NewTL.setNameLoc(TL.getNameLoc());
5604 } else {
5605 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5606 NewTL.setNameLoc(TL.getNameLoc());
5609 return Result;
5612 template <typename Derived>
5613 QualType
5614 TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5615 ConstantMatrixTypeLoc TL) {
5616 const ConstantMatrixType *T = TL.getTypePtr();
5617 QualType ElementType = getDerived().TransformType(T->getElementType());
5618 if (ElementType.isNull())
5619 return QualType();
5621 QualType Result = TL.getType();
5622 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5623 Result = getDerived().RebuildConstantMatrixType(
5624 ElementType, T->getNumRows(), T->getNumColumns());
5625 if (Result.isNull())
5626 return QualType();
5629 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);
5630 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5631 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5632 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5633 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5635 return Result;
5638 template <typename Derived>
5639 QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5640 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5641 const DependentSizedMatrixType *T = TL.getTypePtr();
5643 QualType ElementType = getDerived().TransformType(T->getElementType());
5644 if (ElementType.isNull()) {
5645 return QualType();
5648 // Matrix dimensions are constant expressions.
5649 EnterExpressionEvaluationContext Unevaluated(
5650 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5652 Expr *origRows = TL.getAttrRowOperand();
5653 if (!origRows)
5654 origRows = T->getRowExpr();
5655 Expr *origColumns = TL.getAttrColumnOperand();
5656 if (!origColumns)
5657 origColumns = T->getColumnExpr();
5659 ExprResult rowResult = getDerived().TransformExpr(origRows);
5660 rowResult = SemaRef.ActOnConstantExpression(rowResult);
5661 if (rowResult.isInvalid())
5662 return QualType();
5664 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5665 columnResult = SemaRef.ActOnConstantExpression(columnResult);
5666 if (columnResult.isInvalid())
5667 return QualType();
5669 Expr *rows = rowResult.get();
5670 Expr *columns = columnResult.get();
5672 QualType Result = TL.getType();
5673 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5674 rows != origRows || columns != origColumns) {
5675 Result = getDerived().RebuildDependentSizedMatrixType(
5676 ElementType, rows, columns, T->getAttributeLoc());
5678 if (Result.isNull())
5679 return QualType();
5682 // We might have any sort of matrix type now, but fortunately they
5683 // all have the same location layout.
5684 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);
5685 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5686 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5687 NewTL.setAttrRowOperand(rows);
5688 NewTL.setAttrColumnOperand(columns);
5689 return Result;
5692 template <typename Derived>
5693 QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
5694 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
5695 const DependentAddressSpaceType *T = TL.getTypePtr();
5697 QualType pointeeType = getDerived().TransformType(T->getPointeeType());
5699 if (pointeeType.isNull())
5700 return QualType();
5702 // Address spaces are constant expressions.
5703 EnterExpressionEvaluationContext Unevaluated(
5704 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5706 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
5707 AddrSpace = SemaRef.ActOnConstantExpression(AddrSpace);
5708 if (AddrSpace.isInvalid())
5709 return QualType();
5711 QualType Result = TL.getType();
5712 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
5713 AddrSpace.get() != T->getAddrSpaceExpr()) {
5714 Result = getDerived().RebuildDependentAddressSpaceType(
5715 pointeeType, AddrSpace.get(), T->getAttributeLoc());
5716 if (Result.isNull())
5717 return QualType();
5720 // Result might be dependent or not.
5721 if (isa<DependentAddressSpaceType>(Result)) {
5722 DependentAddressSpaceTypeLoc NewTL =
5723 TLB.push<DependentAddressSpaceTypeLoc>(Result);
5725 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5726 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
5727 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5729 } else {
5730 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(
5731 Result, getDerived().getBaseLocation());
5732 TransformType(TLB, DI->getTypeLoc());
5735 return Result;
5738 template <typename Derived>
5739 QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
5740 VectorTypeLoc TL) {
5741 const VectorType *T = TL.getTypePtr();
5742 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5743 if (ElementType.isNull())
5744 return QualType();
5746 QualType Result = TL.getType();
5747 if (getDerived().AlwaysRebuild() ||
5748 ElementType != T->getElementType()) {
5749 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
5750 T->getVectorKind());
5751 if (Result.isNull())
5752 return QualType();
5755 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5756 NewTL.setNameLoc(TL.getNameLoc());
5758 return Result;
5761 template<typename Derived>
5762 QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
5763 ExtVectorTypeLoc TL) {
5764 const VectorType *T = TL.getTypePtr();
5765 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5766 if (ElementType.isNull())
5767 return QualType();
5769 QualType Result = TL.getType();
5770 if (getDerived().AlwaysRebuild() ||
5771 ElementType != T->getElementType()) {
5772 Result = getDerived().RebuildExtVectorType(ElementType,
5773 T->getNumElements(),
5774 /*FIXME*/ SourceLocation());
5775 if (Result.isNull())
5776 return QualType();
5779 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5780 NewTL.setNameLoc(TL.getNameLoc());
5782 return Result;
5785 template <typename Derived>
5786 ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
5787 ParmVarDecl *OldParm, int indexAdjustment,
5788 std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
5789 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
5790 TypeSourceInfo *NewDI = nullptr;
5792 if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
5793 // If we're substituting into a pack expansion type and we know the
5794 // length we want to expand to, just substitute for the pattern.
5795 TypeLoc OldTL = OldDI->getTypeLoc();
5796 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
5798 TypeLocBuilder TLB;
5799 TypeLoc NewTL = OldDI->getTypeLoc();
5800 TLB.reserve(NewTL.getFullDataSize());
5802 QualType Result = getDerived().TransformType(TLB,
5803 OldExpansionTL.getPatternLoc());
5804 if (Result.isNull())
5805 return nullptr;
5807 Result = RebuildPackExpansionType(Result,
5808 OldExpansionTL.getPatternLoc().getSourceRange(),
5809 OldExpansionTL.getEllipsisLoc(),
5810 NumExpansions);
5811 if (Result.isNull())
5812 return nullptr;
5814 PackExpansionTypeLoc NewExpansionTL
5815 = TLB.push<PackExpansionTypeLoc>(Result);
5816 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
5817 NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result);
5818 } else
5819 NewDI = getDerived().TransformType(OldDI);
5820 if (!NewDI)
5821 return nullptr;
5823 if (NewDI == OldDI && indexAdjustment == 0)
5824 return OldParm;
5826 ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context,
5827 OldParm->getDeclContext(),
5828 OldParm->getInnerLocStart(),
5829 OldParm->getLocation(),
5830 OldParm->getIdentifier(),
5831 NewDI->getType(),
5832 NewDI,
5833 OldParm->getStorageClass(),
5834 /* DefArg */ nullptr);
5835 newParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
5836 OldParm->getFunctionScopeIndex() + indexAdjustment);
5837 transformedLocalDecl(OldParm, {newParm});
5838 return newParm;
5841 template <typename Derived>
5842 bool TreeTransform<Derived>::TransformFunctionTypeParams(
5843 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
5844 const QualType *ParamTypes,
5845 const FunctionProtoType::ExtParameterInfo *ParamInfos,
5846 SmallVectorImpl<QualType> &OutParamTypes,
5847 SmallVectorImpl<ParmVarDecl *> *PVars,
5848 Sema::ExtParameterInfoBuilder &PInfos,
5849 unsigned *LastParamTransformed) {
5850 int indexAdjustment = 0;
5852 unsigned NumParams = Params.size();
5853 for (unsigned i = 0; i != NumParams; ++i) {
5854 if (LastParamTransformed)
5855 *LastParamTransformed = i;
5856 if (ParmVarDecl *OldParm = Params[i]) {
5857 assert(OldParm->getFunctionScopeIndex() == i);
5859 std::optional<unsigned> NumExpansions;
5860 ParmVarDecl *NewParm = nullptr;
5861 if (OldParm->isParameterPack()) {
5862 // We have a function parameter pack that may need to be expanded.
5863 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5865 // Find the parameter packs that could be expanded.
5866 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
5867 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
5868 TypeLoc Pattern = ExpansionTL.getPatternLoc();
5869 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
5871 // Determine whether we should expand the parameter packs.
5872 bool ShouldExpand = false;
5873 bool RetainExpansion = false;
5874 std::optional<unsigned> OrigNumExpansions;
5875 if (Unexpanded.size() > 0) {
5876 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
5877 NumExpansions = OrigNumExpansions;
5878 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
5879 Pattern.getSourceRange(),
5880 Unexpanded,
5881 ShouldExpand,
5882 RetainExpansion,
5883 NumExpansions)) {
5884 return true;
5886 } else {
5887 #ifndef NDEBUG
5888 const AutoType *AT =
5889 Pattern.getType().getTypePtr()->getContainedAutoType();
5890 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
5891 "Could not find parameter packs or undeduced auto type!");
5892 #endif
5895 if (ShouldExpand) {
5896 // Expand the function parameter pack into multiple, separate
5897 // parameters.
5898 getDerived().ExpandingFunctionParameterPack(OldParm);
5899 for (unsigned I = 0; I != *NumExpansions; ++I) {
5900 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
5901 ParmVarDecl *NewParm
5902 = getDerived().TransformFunctionTypeParam(OldParm,
5903 indexAdjustment++,
5904 OrigNumExpansions,
5905 /*ExpectParameterPack=*/false);
5906 if (!NewParm)
5907 return true;
5909 if (ParamInfos)
5910 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5911 OutParamTypes.push_back(NewParm->getType());
5912 if (PVars)
5913 PVars->push_back(NewParm);
5916 // If we're supposed to retain a pack expansion, do so by temporarily
5917 // forgetting the partially-substituted parameter pack.
5918 if (RetainExpansion) {
5919 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5920 ParmVarDecl *NewParm
5921 = getDerived().TransformFunctionTypeParam(OldParm,
5922 indexAdjustment++,
5923 OrigNumExpansions,
5924 /*ExpectParameterPack=*/false);
5925 if (!NewParm)
5926 return true;
5928 if (ParamInfos)
5929 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5930 OutParamTypes.push_back(NewParm->getType());
5931 if (PVars)
5932 PVars->push_back(NewParm);
5935 // The next parameter should have the same adjustment as the
5936 // last thing we pushed, but we post-incremented indexAdjustment
5937 // on every push. Also, if we push nothing, the adjustment should
5938 // go down by one.
5939 indexAdjustment--;
5941 // We're done with the pack expansion.
5942 continue;
5945 // We'll substitute the parameter now without expanding the pack
5946 // expansion.
5947 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
5948 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
5949 indexAdjustment,
5950 NumExpansions,
5951 /*ExpectParameterPack=*/true);
5952 assert(NewParm->isParameterPack() &&
5953 "Parameter pack no longer a parameter pack after "
5954 "transformation.");
5955 } else {
5956 NewParm = getDerived().TransformFunctionTypeParam(
5957 OldParm, indexAdjustment, std::nullopt,
5958 /*ExpectParameterPack=*/false);
5961 if (!NewParm)
5962 return true;
5964 if (ParamInfos)
5965 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5966 OutParamTypes.push_back(NewParm->getType());
5967 if (PVars)
5968 PVars->push_back(NewParm);
5969 continue;
5972 // Deal with the possibility that we don't have a parameter
5973 // declaration for this parameter.
5974 assert(ParamTypes);
5975 QualType OldType = ParamTypes[i];
5976 bool IsPackExpansion = false;
5977 std::optional<unsigned> NumExpansions;
5978 QualType NewType;
5979 if (const PackExpansionType *Expansion
5980 = dyn_cast<PackExpansionType>(OldType)) {
5981 // We have a function parameter pack that may need to be expanded.
5982 QualType Pattern = Expansion->getPattern();
5983 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5984 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5986 // Determine whether we should expand the parameter packs.
5987 bool ShouldExpand = false;
5988 bool RetainExpansion = false;
5989 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
5990 Unexpanded,
5991 ShouldExpand,
5992 RetainExpansion,
5993 NumExpansions)) {
5994 return true;
5997 if (ShouldExpand) {
5998 // Expand the function parameter pack into multiple, separate
5999 // parameters.
6000 for (unsigned I = 0; I != *NumExpansions; ++I) {
6001 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6002 QualType NewType = getDerived().TransformType(Pattern);
6003 if (NewType.isNull())
6004 return true;
6006 if (NewType->containsUnexpandedParameterPack()) {
6007 NewType = getSema().getASTContext().getPackExpansionType(
6008 NewType, std::nullopt);
6010 if (NewType.isNull())
6011 return true;
6014 if (ParamInfos)
6015 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6016 OutParamTypes.push_back(NewType);
6017 if (PVars)
6018 PVars->push_back(nullptr);
6021 // We're done with the pack expansion.
6022 continue;
6025 // If we're supposed to retain a pack expansion, do so by temporarily
6026 // forgetting the partially-substituted parameter pack.
6027 if (RetainExpansion) {
6028 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6029 QualType NewType = getDerived().TransformType(Pattern);
6030 if (NewType.isNull())
6031 return true;
6033 if (ParamInfos)
6034 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6035 OutParamTypes.push_back(NewType);
6036 if (PVars)
6037 PVars->push_back(nullptr);
6040 // We'll substitute the parameter now without expanding the pack
6041 // expansion.
6042 OldType = Expansion->getPattern();
6043 IsPackExpansion = true;
6044 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6045 NewType = getDerived().TransformType(OldType);
6046 } else {
6047 NewType = getDerived().TransformType(OldType);
6050 if (NewType.isNull())
6051 return true;
6053 if (IsPackExpansion)
6054 NewType = getSema().Context.getPackExpansionType(NewType,
6055 NumExpansions);
6057 if (ParamInfos)
6058 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6059 OutParamTypes.push_back(NewType);
6060 if (PVars)
6061 PVars->push_back(nullptr);
6064 #ifndef NDEBUG
6065 if (PVars) {
6066 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6067 if (ParmVarDecl *parm = (*PVars)[i])
6068 assert(parm->getFunctionScopeIndex() == i);
6070 #endif
6072 return false;
6075 template<typename Derived>
6076 QualType
6077 TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6078 FunctionProtoTypeLoc TL) {
6079 SmallVector<QualType, 4> ExceptionStorage;
6080 TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
6081 return getDerived().TransformFunctionProtoType(
6082 TLB, TL, nullptr, Qualifiers(),
6083 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6084 return This->getDerived().TransformExceptionSpec(
6085 TL.getBeginLoc(), ESI, ExceptionStorage, Changed);
6089 template<typename Derived> template<typename Fn>
6090 QualType TreeTransform<Derived>::TransformFunctionProtoType(
6091 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6092 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6094 // Transform the parameters and return type.
6096 // We are required to instantiate the params and return type in source order.
6097 // When the function has a trailing return type, we instantiate the
6098 // parameters before the return type, since the return type can then refer
6099 // to the parameters themselves (via decltype, sizeof, etc.).
6101 SmallVector<QualType, 4> ParamTypes;
6102 SmallVector<ParmVarDecl*, 4> ParamDecls;
6103 Sema::ExtParameterInfoBuilder ExtParamInfos;
6104 const FunctionProtoType *T = TL.getTypePtr();
6106 QualType ResultType;
6108 if (T->hasTrailingReturn()) {
6109 if (getDerived().TransformFunctionTypeParams(
6110 TL.getBeginLoc(), TL.getParams(),
6111 TL.getTypePtr()->param_type_begin(),
6112 T->getExtParameterInfosOrNull(),
6113 ParamTypes, &ParamDecls, ExtParamInfos))
6114 return QualType();
6117 // C++11 [expr.prim.general]p3:
6118 // If a declaration declares a member function or member function
6119 // template of a class X, the expression this is a prvalue of type
6120 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6121 // and the end of the function-definition, member-declarator, or
6122 // declarator.
6123 Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals);
6125 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6126 if (ResultType.isNull())
6127 return QualType();
6130 else {
6131 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6132 if (ResultType.isNull())
6133 return QualType();
6135 if (getDerived().TransformFunctionTypeParams(
6136 TL.getBeginLoc(), TL.getParams(),
6137 TL.getTypePtr()->param_type_begin(),
6138 T->getExtParameterInfosOrNull(),
6139 ParamTypes, &ParamDecls, ExtParamInfos))
6140 return QualType();
6143 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6145 bool EPIChanged = false;
6146 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6147 return QualType();
6149 // Handle extended parameter information.
6150 if (auto NewExtParamInfos =
6151 ExtParamInfos.getPointerOrNull(ParamTypes.size())) {
6152 if (!EPI.ExtParameterInfos ||
6153 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6154 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6155 EPIChanged = true;
6157 EPI.ExtParameterInfos = NewExtParamInfos;
6158 } else if (EPI.ExtParameterInfos) {
6159 EPIChanged = true;
6160 EPI.ExtParameterInfos = nullptr;
6163 QualType Result = TL.getType();
6164 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6165 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6166 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6167 if (Result.isNull())
6168 return QualType();
6171 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
6172 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6173 NewTL.setLParenLoc(TL.getLParenLoc());
6174 NewTL.setRParenLoc(TL.getRParenLoc());
6175 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6176 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6177 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6178 NewTL.setParam(i, ParamDecls[i]);
6180 return Result;
6183 template<typename Derived>
6184 bool TreeTransform<Derived>::TransformExceptionSpec(
6185 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6186 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6187 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6189 // Instantiate a dynamic noexcept expression, if any.
6190 if (isComputedNoexcept(ESI.Type)) {
6191 EnterExpressionEvaluationContext Unevaluated(
6192 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6193 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6194 if (NoexceptExpr.isInvalid())
6195 return true;
6197 ExceptionSpecificationType EST = ESI.Type;
6198 NoexceptExpr =
6199 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6200 if (NoexceptExpr.isInvalid())
6201 return true;
6203 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6204 Changed = true;
6205 ESI.NoexceptExpr = NoexceptExpr.get();
6206 ESI.Type = EST;
6209 if (ESI.Type != EST_Dynamic)
6210 return false;
6212 // Instantiate a dynamic exception specification's type.
6213 for (QualType T : ESI.Exceptions) {
6214 if (const PackExpansionType *PackExpansion =
6215 T->getAs<PackExpansionType>()) {
6216 Changed = true;
6218 // We have a pack expansion. Instantiate it.
6219 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6220 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
6221 Unexpanded);
6222 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6224 // Determine whether the set of unexpanded parameter packs can and
6225 // should
6226 // be expanded.
6227 bool Expand = false;
6228 bool RetainExpansion = false;
6229 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
6230 // FIXME: Track the location of the ellipsis (and track source location
6231 // information for the types in the exception specification in general).
6232 if (getDerived().TryExpandParameterPacks(
6233 Loc, SourceRange(), Unexpanded, Expand,
6234 RetainExpansion, NumExpansions))
6235 return true;
6237 if (!Expand) {
6238 // We can't expand this pack expansion into separate arguments yet;
6239 // just substitute into the pattern and create a new pack expansion
6240 // type.
6241 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6242 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6243 if (U.isNull())
6244 return true;
6246 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
6247 Exceptions.push_back(U);
6248 continue;
6251 // Substitute into the pack expansion pattern for each slice of the
6252 // pack.
6253 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6254 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
6256 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6257 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6258 return true;
6260 Exceptions.push_back(U);
6262 } else {
6263 QualType U = getDerived().TransformType(T);
6264 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6265 return true;
6266 if (T != U)
6267 Changed = true;
6269 Exceptions.push_back(U);
6273 ESI.Exceptions = Exceptions;
6274 if (ESI.Exceptions.empty())
6275 ESI.Type = EST_DynamicNone;
6276 return false;
6279 template<typename Derived>
6280 QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6281 TypeLocBuilder &TLB,
6282 FunctionNoProtoTypeLoc TL) {
6283 const FunctionNoProtoType *T = TL.getTypePtr();
6284 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6285 if (ResultType.isNull())
6286 return QualType();
6288 QualType Result = TL.getType();
6289 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6290 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6292 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
6293 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6294 NewTL.setLParenLoc(TL.getLParenLoc());
6295 NewTL.setRParenLoc(TL.getRParenLoc());
6296 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6298 return Result;
6301 template <typename Derived>
6302 QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6303 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6304 const UnresolvedUsingType *T = TL.getTypePtr();
6305 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6306 if (!D)
6307 return QualType();
6309 QualType Result = TL.getType();
6310 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6311 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6312 if (Result.isNull())
6313 return QualType();
6316 // We might get an arbitrary type spec type back. We should at
6317 // least always get a type spec type, though.
6318 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result);
6319 NewTL.setNameLoc(TL.getNameLoc());
6321 return Result;
6324 template <typename Derived>
6325 QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6326 UsingTypeLoc TL) {
6327 const UsingType *T = TL.getTypePtr();
6329 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6330 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6331 if (!Found)
6332 return QualType();
6334 QualType Underlying = getDerived().TransformType(T->desugar());
6335 if (Underlying.isNull())
6336 return QualType();
6338 QualType Result = TL.getType();
6339 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6340 Underlying != T->getUnderlyingType()) {
6341 Result = getDerived().RebuildUsingType(Found, Underlying);
6342 if (Result.isNull())
6343 return QualType();
6346 TLB.pushTypeSpec(Result).setNameLoc(TL.getNameLoc());
6347 return Result;
6350 template<typename Derived>
6351 QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6352 TypedefTypeLoc TL) {
6353 const TypedefType *T = TL.getTypePtr();
6354 TypedefNameDecl *Typedef
6355 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6356 T->getDecl()));
6357 if (!Typedef)
6358 return QualType();
6360 QualType Result = TL.getType();
6361 if (getDerived().AlwaysRebuild() ||
6362 Typedef != T->getDecl()) {
6363 Result = getDerived().RebuildTypedefType(Typedef);
6364 if (Result.isNull())
6365 return QualType();
6368 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
6369 NewTL.setNameLoc(TL.getNameLoc());
6371 return Result;
6374 template<typename Derived>
6375 QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6376 TypeOfExprTypeLoc TL) {
6377 // typeof expressions are not potentially evaluated contexts
6378 EnterExpressionEvaluationContext Unevaluated(
6379 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6380 Sema::ReuseLambdaContextDecl);
6382 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6383 if (E.isInvalid())
6384 return QualType();
6386 E = SemaRef.HandleExprEvaluationContextForTypeof(E.get());
6387 if (E.isInvalid())
6388 return QualType();
6390 QualType Result = TL.getType();
6391 TypeOfKind Kind = Result->getAs<TypeOfExprType>()->getKind();
6392 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6393 Result =
6394 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6395 if (Result.isNull())
6396 return QualType();
6399 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
6400 NewTL.setTypeofLoc(TL.getTypeofLoc());
6401 NewTL.setLParenLoc(TL.getLParenLoc());
6402 NewTL.setRParenLoc(TL.getRParenLoc());
6404 return Result;
6407 template<typename Derived>
6408 QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6409 TypeOfTypeLoc TL) {
6410 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6411 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6412 if (!New_Under_TI)
6413 return QualType();
6415 QualType Result = TL.getType();
6416 TypeOfKind Kind = Result->getAs<TypeOfType>()->getKind();
6417 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6418 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6419 if (Result.isNull())
6420 return QualType();
6423 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
6424 NewTL.setTypeofLoc(TL.getTypeofLoc());
6425 NewTL.setLParenLoc(TL.getLParenLoc());
6426 NewTL.setRParenLoc(TL.getRParenLoc());
6427 NewTL.setUnmodifiedTInfo(New_Under_TI);
6429 return Result;
6432 template<typename Derived>
6433 QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6434 DecltypeTypeLoc TL) {
6435 const DecltypeType *T = TL.getTypePtr();
6437 // decltype expressions are not potentially evaluated contexts
6438 EnterExpressionEvaluationContext Unevaluated(
6439 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
6440 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
6442 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6443 if (E.isInvalid())
6444 return QualType();
6446 E = getSema().ActOnDecltypeExpression(E.get());
6447 if (E.isInvalid())
6448 return QualType();
6450 QualType Result = TL.getType();
6451 if (getDerived().AlwaysRebuild() ||
6452 E.get() != T->getUnderlyingExpr()) {
6453 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6454 if (Result.isNull())
6455 return QualType();
6457 else E.get();
6459 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
6460 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6461 NewTL.setRParenLoc(TL.getRParenLoc());
6462 return Result;
6465 template<typename Derived>
6466 QualType TreeTransform<Derived>::TransformUnaryTransformType(
6467 TypeLocBuilder &TLB,
6468 UnaryTransformTypeLoc TL) {
6469 QualType Result = TL.getType();
6470 if (Result->isDependentType()) {
6471 const UnaryTransformType *T = TL.getTypePtr();
6472 QualType NewBase =
6473 getDerived().TransformType(TL.getUnderlyingTInfo())->getType();
6474 Result = getDerived().RebuildUnaryTransformType(NewBase,
6475 T->getUTTKind(),
6476 TL.getKWLoc());
6477 if (Result.isNull())
6478 return QualType();
6481 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
6482 NewTL.setKWLoc(TL.getKWLoc());
6483 NewTL.setParensRange(TL.getParensRange());
6484 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6485 return Result;
6488 template<typename Derived>
6489 QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6490 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6491 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6493 CXXScopeSpec SS;
6494 TemplateName TemplateName = getDerived().TransformTemplateName(
6495 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6496 if (TemplateName.isNull())
6497 return QualType();
6499 QualType OldDeduced = T->getDeducedType();
6500 QualType NewDeduced;
6501 if (!OldDeduced.isNull()) {
6502 NewDeduced = getDerived().TransformType(OldDeduced);
6503 if (NewDeduced.isNull())
6504 return QualType();
6507 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
6508 TemplateName, NewDeduced);
6509 if (Result.isNull())
6510 return QualType();
6512 DeducedTemplateSpecializationTypeLoc NewTL =
6513 TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
6514 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6516 return Result;
6519 template<typename Derived>
6520 QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
6521 RecordTypeLoc TL) {
6522 const RecordType *T = TL.getTypePtr();
6523 RecordDecl *Record
6524 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6525 T->getDecl()));
6526 if (!Record)
6527 return QualType();
6529 QualType Result = TL.getType();
6530 if (getDerived().AlwaysRebuild() ||
6531 Record != T->getDecl()) {
6532 Result = getDerived().RebuildRecordType(Record);
6533 if (Result.isNull())
6534 return QualType();
6537 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
6538 NewTL.setNameLoc(TL.getNameLoc());
6540 return Result;
6543 template<typename Derived>
6544 QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
6545 EnumTypeLoc TL) {
6546 const EnumType *T = TL.getTypePtr();
6547 EnumDecl *Enum
6548 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6549 T->getDecl()));
6550 if (!Enum)
6551 return QualType();
6553 QualType Result = TL.getType();
6554 if (getDerived().AlwaysRebuild() ||
6555 Enum != T->getDecl()) {
6556 Result = getDerived().RebuildEnumType(Enum);
6557 if (Result.isNull())
6558 return QualType();
6561 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
6562 NewTL.setNameLoc(TL.getNameLoc());
6564 return Result;
6567 template<typename Derived>
6568 QualType TreeTransform<Derived>::TransformInjectedClassNameType(
6569 TypeLocBuilder &TLB,
6570 InjectedClassNameTypeLoc TL) {
6571 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
6572 TL.getTypePtr()->getDecl());
6573 if (!D) return QualType();
6575 QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
6576 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
6577 return T;
6580 template<typename Derived>
6581 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6582 TypeLocBuilder &TLB,
6583 TemplateTypeParmTypeLoc TL) {
6584 return getDerived().TransformTemplateTypeParmType(
6585 TLB, TL,
6586 /*SuppressObjCLifetime=*/false);
6589 template <typename Derived>
6590 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6591 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
6592 return TransformTypeSpecType(TLB, TL);
6595 template<typename Derived>
6596 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
6597 TypeLocBuilder &TLB,
6598 SubstTemplateTypeParmTypeLoc TL) {
6599 const SubstTemplateTypeParmType *T = TL.getTypePtr();
6601 Decl *NewReplaced =
6602 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
6604 // Substitute into the replacement type, which itself might involve something
6605 // that needs to be transformed. This only tends to occur with default
6606 // template arguments of template template parameters.
6607 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
6608 QualType Replacement = getDerived().TransformType(T->getReplacementType());
6609 if (Replacement.isNull())
6610 return QualType();
6612 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
6613 Replacement, NewReplaced, T->getIndex(), T->getPackIndex());
6615 // Propagate type-source information.
6616 SubstTemplateTypeParmTypeLoc NewTL
6617 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
6618 NewTL.setNameLoc(TL.getNameLoc());
6619 return Result;
6623 template<typename Derived>
6624 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6625 TypeLocBuilder &TLB,
6626 SubstTemplateTypeParmPackTypeLoc TL) {
6627 return getDerived().TransformSubstTemplateTypeParmPackType(
6628 TLB, TL, /*SuppressObjCLifetime=*/false);
6631 template <typename Derived>
6632 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6633 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
6634 return TransformTypeSpecType(TLB, TL);
6637 template<typename Derived>
6638 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
6639 TypeLocBuilder &TLB,
6640 TemplateSpecializationTypeLoc TL) {
6641 const TemplateSpecializationType *T = TL.getTypePtr();
6643 // The nested-name-specifier never matters in a TemplateSpecializationType,
6644 // because we can't have a dependent nested-name-specifier anyway.
6645 CXXScopeSpec SS;
6646 TemplateName Template
6647 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
6648 TL.getTemplateNameLoc());
6649 if (Template.isNull())
6650 return QualType();
6652 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
6655 template<typename Derived>
6656 QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
6657 AtomicTypeLoc TL) {
6658 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6659 if (ValueType.isNull())
6660 return QualType();
6662 QualType Result = TL.getType();
6663 if (getDerived().AlwaysRebuild() ||
6664 ValueType != TL.getValueLoc().getType()) {
6665 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
6666 if (Result.isNull())
6667 return QualType();
6670 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
6671 NewTL.setKWLoc(TL.getKWLoc());
6672 NewTL.setLParenLoc(TL.getLParenLoc());
6673 NewTL.setRParenLoc(TL.getRParenLoc());
6675 return Result;
6678 template <typename Derived>
6679 QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
6680 PipeTypeLoc TL) {
6681 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6682 if (ValueType.isNull())
6683 return QualType();
6685 QualType Result = TL.getType();
6686 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
6687 const PipeType *PT = Result->castAs<PipeType>();
6688 bool isReadPipe = PT->isReadOnly();
6689 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
6690 if (Result.isNull())
6691 return QualType();
6694 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);
6695 NewTL.setKWLoc(TL.getKWLoc());
6697 return Result;
6700 template <typename Derived>
6701 QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
6702 BitIntTypeLoc TL) {
6703 const BitIntType *EIT = TL.getTypePtr();
6704 QualType Result = TL.getType();
6706 if (getDerived().AlwaysRebuild()) {
6707 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
6708 EIT->getNumBits(), TL.getNameLoc());
6709 if (Result.isNull())
6710 return QualType();
6713 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6714 NewTL.setNameLoc(TL.getNameLoc());
6715 return Result;
6718 template <typename Derived>
6719 QualType TreeTransform<Derived>::TransformDependentBitIntType(
6720 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
6721 const DependentBitIntType *EIT = TL.getTypePtr();
6723 EnterExpressionEvaluationContext Unevaluated(
6724 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6725 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
6726 BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr);
6728 if (BitsExpr.isInvalid())
6729 return QualType();
6731 QualType Result = TL.getType();
6733 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
6734 Result = getDerived().RebuildDependentBitIntType(
6735 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
6737 if (Result.isNull())
6738 return QualType();
6741 if (isa<DependentBitIntType>(Result)) {
6742 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);
6743 NewTL.setNameLoc(TL.getNameLoc());
6744 } else {
6745 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6746 NewTL.setNameLoc(TL.getNameLoc());
6748 return Result;
6751 /// Simple iterator that traverses the template arguments in a
6752 /// container that provides a \c getArgLoc() member function.
6754 /// This iterator is intended to be used with the iterator form of
6755 /// \c TreeTransform<Derived>::TransformTemplateArguments().
6756 template<typename ArgLocContainer>
6757 class TemplateArgumentLocContainerIterator {
6758 ArgLocContainer *Container;
6759 unsigned Index;
6761 public:
6762 typedef TemplateArgumentLoc value_type;
6763 typedef TemplateArgumentLoc reference;
6764 typedef int difference_type;
6765 typedef std::input_iterator_tag iterator_category;
6767 class pointer {
6768 TemplateArgumentLoc Arg;
6770 public:
6771 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
6773 const TemplateArgumentLoc *operator->() const {
6774 return &Arg;
6779 TemplateArgumentLocContainerIterator() {}
6781 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
6782 unsigned Index)
6783 : Container(&Container), Index(Index) { }
6785 TemplateArgumentLocContainerIterator &operator++() {
6786 ++Index;
6787 return *this;
6790 TemplateArgumentLocContainerIterator operator++(int) {
6791 TemplateArgumentLocContainerIterator Old(*this);
6792 ++(*this);
6793 return Old;
6796 TemplateArgumentLoc operator*() const {
6797 return Container->getArgLoc(Index);
6800 pointer operator->() const {
6801 return pointer(Container->getArgLoc(Index));
6804 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
6805 const TemplateArgumentLocContainerIterator &Y) {
6806 return X.Container == Y.Container && X.Index == Y.Index;
6809 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
6810 const TemplateArgumentLocContainerIterator &Y) {
6811 return !(X == Y);
6815 template<typename Derived>
6816 QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
6817 AutoTypeLoc TL) {
6818 const AutoType *T = TL.getTypePtr();
6819 QualType OldDeduced = T->getDeducedType();
6820 QualType NewDeduced;
6821 if (!OldDeduced.isNull()) {
6822 NewDeduced = getDerived().TransformType(OldDeduced);
6823 if (NewDeduced.isNull())
6824 return QualType();
6827 ConceptDecl *NewCD = nullptr;
6828 TemplateArgumentListInfo NewTemplateArgs;
6829 NestedNameSpecifierLoc NewNestedNameSpec;
6830 if (T->isConstrained()) {
6831 assert(TL.getConceptReference());
6832 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
6833 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
6835 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
6836 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
6837 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
6838 if (getDerived().TransformTemplateArguments(
6839 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
6840 NewTemplateArgs))
6841 return QualType();
6843 if (TL.getNestedNameSpecifierLoc()) {
6844 NewNestedNameSpec
6845 = getDerived().TransformNestedNameSpecifierLoc(
6846 TL.getNestedNameSpecifierLoc());
6847 if (!NewNestedNameSpec)
6848 return QualType();
6852 QualType Result = TL.getType();
6853 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
6854 T->isDependentType() || T->isConstrained()) {
6855 // FIXME: Maybe don't rebuild if all template arguments are the same.
6856 llvm::SmallVector<TemplateArgument, 4> NewArgList;
6857 NewArgList.reserve(NewTemplateArgs.size());
6858 for (const auto &ArgLoc : NewTemplateArgs.arguments())
6859 NewArgList.push_back(ArgLoc.getArgument());
6860 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
6861 NewArgList);
6862 if (Result.isNull())
6863 return QualType();
6866 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
6867 NewTL.setNameLoc(TL.getNameLoc());
6868 NewTL.setRParenLoc(TL.getRParenLoc());
6869 NewTL.setConceptReference(nullptr);
6871 if (T->isConstrained()) {
6872 DeclarationNameInfo DNI = DeclarationNameInfo(
6873 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
6874 TL.getConceptNameLoc(),
6875 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
6876 auto *CR = ConceptReference::Create(
6877 SemaRef.Context, NewNestedNameSpec, TL.getTemplateKWLoc(), DNI,
6878 TL.getFoundDecl(), TL.getTypePtr()->getTypeConstraintConcept(),
6879 ASTTemplateArgumentListInfo::Create(SemaRef.Context, NewTemplateArgs));
6880 NewTL.setConceptReference(CR);
6883 return Result;
6886 template <typename Derived>
6887 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
6888 TypeLocBuilder &TLB,
6889 TemplateSpecializationTypeLoc TL,
6890 TemplateName Template) {
6891 TemplateArgumentListInfo NewTemplateArgs;
6892 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
6893 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
6894 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
6895 ArgIterator;
6896 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
6897 ArgIterator(TL, TL.getNumArgs()),
6898 NewTemplateArgs))
6899 return QualType();
6901 // FIXME: maybe don't rebuild if all the template arguments are the same.
6903 QualType Result =
6904 getDerived().RebuildTemplateSpecializationType(Template,
6905 TL.getTemplateNameLoc(),
6906 NewTemplateArgs);
6908 if (!Result.isNull()) {
6909 // Specializations of template template parameters are represented as
6910 // TemplateSpecializationTypes, and substitution of type alias templates
6911 // within a dependent context can transform them into
6912 // DependentTemplateSpecializationTypes.
6913 if (isa<DependentTemplateSpecializationType>(Result)) {
6914 DependentTemplateSpecializationTypeLoc NewTL
6915 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
6916 NewTL.setElaboratedKeywordLoc(SourceLocation());
6917 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
6918 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6919 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6920 NewTL.setLAngleLoc(TL.getLAngleLoc());
6921 NewTL.setRAngleLoc(TL.getRAngleLoc());
6922 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6923 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6924 return Result;
6927 TemplateSpecializationTypeLoc NewTL
6928 = TLB.push<TemplateSpecializationTypeLoc>(Result);
6929 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6930 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6931 NewTL.setLAngleLoc(TL.getLAngleLoc());
6932 NewTL.setRAngleLoc(TL.getRAngleLoc());
6933 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6934 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6937 return Result;
6940 template <typename Derived>
6941 QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
6942 TypeLocBuilder &TLB,
6943 DependentTemplateSpecializationTypeLoc TL,
6944 TemplateName Template,
6945 CXXScopeSpec &SS) {
6946 TemplateArgumentListInfo NewTemplateArgs;
6947 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
6948 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
6949 typedef TemplateArgumentLocContainerIterator<
6950 DependentTemplateSpecializationTypeLoc> ArgIterator;
6951 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
6952 ArgIterator(TL, TL.getNumArgs()),
6953 NewTemplateArgs))
6954 return QualType();
6956 // FIXME: maybe don't rebuild if all the template arguments are the same.
6958 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
6959 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
6960 TL.getTypePtr()->getKeyword(), DTN->getQualifier(),
6961 DTN->getIdentifier(), NewTemplateArgs.arguments());
6963 DependentTemplateSpecializationTypeLoc NewTL
6964 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
6965 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
6966 NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
6967 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6968 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6969 NewTL.setLAngleLoc(TL.getLAngleLoc());
6970 NewTL.setRAngleLoc(TL.getRAngleLoc());
6971 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6972 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6973 return Result;
6976 QualType Result
6977 = getDerived().RebuildTemplateSpecializationType(Template,
6978 TL.getTemplateNameLoc(),
6979 NewTemplateArgs);
6981 if (!Result.isNull()) {
6982 /// FIXME: Wrap this in an elaborated-type-specifier?
6983 TemplateSpecializationTypeLoc NewTL
6984 = TLB.push<TemplateSpecializationTypeLoc>(Result);
6985 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6986 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6987 NewTL.setLAngleLoc(TL.getLAngleLoc());
6988 NewTL.setRAngleLoc(TL.getRAngleLoc());
6989 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6990 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6993 return Result;
6996 template<typename Derived>
6997 QualType
6998 TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
6999 ElaboratedTypeLoc TL) {
7000 const ElaboratedType *T = TL.getTypePtr();
7002 NestedNameSpecifierLoc QualifierLoc;
7003 // NOTE: the qualifier in an ElaboratedType is optional.
7004 if (TL.getQualifierLoc()) {
7005 QualifierLoc
7006 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7007 if (!QualifierLoc)
7008 return QualType();
7011 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7012 if (NamedT.isNull())
7013 return QualType();
7015 // C++0x [dcl.type.elab]p2:
7016 // If the identifier resolves to a typedef-name or the simple-template-id
7017 // resolves to an alias template specialization, the
7018 // elaborated-type-specifier is ill-formed.
7019 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7020 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7021 if (const TemplateSpecializationType *TST =
7022 NamedT->getAs<TemplateSpecializationType>()) {
7023 TemplateName Template = TST->getTemplateName();
7024 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7025 Template.getAsTemplateDecl())) {
7026 SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
7027 diag::err_tag_reference_non_tag)
7028 << TAT << Sema::NTK_TypeAliasTemplate
7029 << llvm::to_underlying(
7030 ElaboratedType::getTagTypeKindForKeyword(T->getKeyword()));
7031 SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
7036 QualType Result = TL.getType();
7037 if (getDerived().AlwaysRebuild() ||
7038 QualifierLoc != TL.getQualifierLoc() ||
7039 NamedT != T->getNamedType()) {
7040 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7041 T->getKeyword(),
7042 QualifierLoc, NamedT);
7043 if (Result.isNull())
7044 return QualType();
7047 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7048 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7049 NewTL.setQualifierLoc(QualifierLoc);
7050 return Result;
7053 template<typename Derived>
7054 QualType TreeTransform<Derived>::TransformAttributedType(
7055 TypeLocBuilder &TLB,
7056 AttributedTypeLoc TL) {
7057 const AttributedType *oldType = TL.getTypePtr();
7058 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7059 if (modifiedType.isNull())
7060 return QualType();
7062 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7063 const Attr *oldAttr = TL.getAttr();
7064 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7065 if (oldAttr && !newAttr)
7066 return QualType();
7068 QualType result = TL.getType();
7070 // FIXME: dependent operand expressions?
7071 if (getDerived().AlwaysRebuild() ||
7072 modifiedType != oldType->getModifiedType()) {
7073 // TODO: this is really lame; we should really be rebuilding the
7074 // equivalent type from first principles.
7075 QualType equivalentType
7076 = getDerived().TransformType(oldType->getEquivalentType());
7077 if (equivalentType.isNull())
7078 return QualType();
7080 // Check whether we can add nullability; it is only represented as
7081 // type sugar, and therefore cannot be diagnosed in any other way.
7082 if (auto nullability = oldType->getImmediateNullability()) {
7083 if (!modifiedType->canHaveNullability()) {
7084 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
7085 : TL.getModifiedLoc().getBeginLoc()),
7086 diag::err_nullability_nonpointer)
7087 << DiagNullabilityKind(*nullability, false) << modifiedType;
7088 return QualType();
7092 result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
7093 modifiedType,
7094 equivalentType);
7097 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
7098 newTL.setAttr(newAttr);
7099 return result;
7102 template <typename Derived>
7103 QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7104 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7105 // The BTFTagAttributedType is available for C only.
7106 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7109 template<typename Derived>
7110 QualType
7111 TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7112 ParenTypeLoc TL) {
7113 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7114 if (Inner.isNull())
7115 return QualType();
7117 QualType Result = TL.getType();
7118 if (getDerived().AlwaysRebuild() ||
7119 Inner != TL.getInnerLoc().getType()) {
7120 Result = getDerived().RebuildParenType(Inner);
7121 if (Result.isNull())
7122 return QualType();
7125 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
7126 NewTL.setLParenLoc(TL.getLParenLoc());
7127 NewTL.setRParenLoc(TL.getRParenLoc());
7128 return Result;
7131 template <typename Derived>
7132 QualType
7133 TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7134 MacroQualifiedTypeLoc TL) {
7135 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7136 if (Inner.isNull())
7137 return QualType();
7139 QualType Result = TL.getType();
7140 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7141 Result =
7142 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7143 if (Result.isNull())
7144 return QualType();
7147 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
7148 NewTL.setExpansionLoc(TL.getExpansionLoc());
7149 return Result;
7152 template<typename Derived>
7153 QualType TreeTransform<Derived>::TransformDependentNameType(
7154 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7155 return TransformDependentNameType(TLB, TL, false);
7158 template<typename Derived>
7159 QualType TreeTransform<Derived>::TransformDependentNameType(
7160 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7161 const DependentNameType *T = TL.getTypePtr();
7163 NestedNameSpecifierLoc QualifierLoc
7164 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7165 if (!QualifierLoc)
7166 return QualType();
7168 QualType Result
7169 = getDerived().RebuildDependentNameType(T->getKeyword(),
7170 TL.getElaboratedKeywordLoc(),
7171 QualifierLoc,
7172 T->getIdentifier(),
7173 TL.getNameLoc(),
7174 DeducedTSTContext);
7175 if (Result.isNull())
7176 return QualType();
7178 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7179 QualType NamedT = ElabT->getNamedType();
7180 TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
7182 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7183 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7184 NewTL.setQualifierLoc(QualifierLoc);
7185 } else {
7186 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
7187 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7188 NewTL.setQualifierLoc(QualifierLoc);
7189 NewTL.setNameLoc(TL.getNameLoc());
7191 return Result;
7194 template<typename Derived>
7195 QualType TreeTransform<Derived>::
7196 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7197 DependentTemplateSpecializationTypeLoc TL) {
7198 NestedNameSpecifierLoc QualifierLoc;
7199 if (TL.getQualifierLoc()) {
7200 QualifierLoc
7201 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7202 if (!QualifierLoc)
7203 return QualType();
7206 return getDerived()
7207 .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
7210 template<typename Derived>
7211 QualType TreeTransform<Derived>::
7212 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7213 DependentTemplateSpecializationTypeLoc TL,
7214 NestedNameSpecifierLoc QualifierLoc) {
7215 const DependentTemplateSpecializationType *T = TL.getTypePtr();
7217 TemplateArgumentListInfo NewTemplateArgs;
7218 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7219 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7221 typedef TemplateArgumentLocContainerIterator<
7222 DependentTemplateSpecializationTypeLoc> ArgIterator;
7223 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7224 ArgIterator(TL, TL.getNumArgs()),
7225 NewTemplateArgs))
7226 return QualType();
7228 QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
7229 T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(),
7230 T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs,
7231 /*AllowInjectedClassName*/ false);
7232 if (Result.isNull())
7233 return QualType();
7235 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
7236 QualType NamedT = ElabT->getNamedType();
7238 // Copy information relevant to the template specialization.
7239 TemplateSpecializationTypeLoc NamedTL
7240 = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
7241 NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7242 NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7243 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7244 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7245 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7246 NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7248 // Copy information relevant to the elaborated type.
7249 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7250 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7251 NewTL.setQualifierLoc(QualifierLoc);
7252 } else if (isa<DependentTemplateSpecializationType>(Result)) {
7253 DependentTemplateSpecializationTypeLoc SpecTL
7254 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7255 SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7256 SpecTL.setQualifierLoc(QualifierLoc);
7257 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7258 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7259 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7260 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7261 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7262 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7263 } else {
7264 TemplateSpecializationTypeLoc SpecTL
7265 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7266 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7267 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7268 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7269 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7270 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7271 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7273 return Result;
7276 template<typename Derived>
7277 QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7278 PackExpansionTypeLoc TL) {
7279 QualType Pattern
7280 = getDerived().TransformType(TLB, TL.getPatternLoc());
7281 if (Pattern.isNull())
7282 return QualType();
7284 QualType Result = TL.getType();
7285 if (getDerived().AlwaysRebuild() ||
7286 Pattern != TL.getPatternLoc().getType()) {
7287 Result = getDerived().RebuildPackExpansionType(Pattern,
7288 TL.getPatternLoc().getSourceRange(),
7289 TL.getEllipsisLoc(),
7290 TL.getTypePtr()->getNumExpansions());
7291 if (Result.isNull())
7292 return QualType();
7295 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
7296 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7297 return Result;
7300 template<typename Derived>
7301 QualType
7302 TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7303 ObjCInterfaceTypeLoc TL) {
7304 // ObjCInterfaceType is never dependent.
7305 TLB.pushFullCopy(TL);
7306 return TL.getType();
7309 template<typename Derived>
7310 QualType
7311 TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7312 ObjCTypeParamTypeLoc TL) {
7313 const ObjCTypeParamType *T = TL.getTypePtr();
7314 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7315 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7316 if (!OTP)
7317 return QualType();
7319 QualType Result = TL.getType();
7320 if (getDerived().AlwaysRebuild() ||
7321 OTP != T->getDecl()) {
7322 Result = getDerived().RebuildObjCTypeParamType(
7323 OTP, TL.getProtocolLAngleLoc(),
7324 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7325 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7326 if (Result.isNull())
7327 return QualType();
7330 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
7331 if (TL.getNumProtocols()) {
7332 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7333 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7334 NewTL.setProtocolLoc(i, TL.getProtocolLoc(i));
7335 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7337 return Result;
7340 template<typename Derived>
7341 QualType
7342 TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7343 ObjCObjectTypeLoc TL) {
7344 // Transform base type.
7345 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7346 if (BaseType.isNull())
7347 return QualType();
7349 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7351 // Transform type arguments.
7352 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7353 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7354 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7355 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7356 QualType TypeArg = TypeArgInfo->getType();
7357 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7358 AnyChanged = true;
7360 // We have a pack expansion. Instantiate it.
7361 const auto *PackExpansion = PackExpansionLoc.getType()
7362 ->castAs<PackExpansionType>();
7363 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7364 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
7365 Unexpanded);
7366 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7368 // Determine whether the set of unexpanded parameter packs can
7369 // and should be expanded.
7370 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7371 bool Expand = false;
7372 bool RetainExpansion = false;
7373 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
7374 if (getDerived().TryExpandParameterPacks(
7375 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7376 Unexpanded, Expand, RetainExpansion, NumExpansions))
7377 return QualType();
7379 if (!Expand) {
7380 // We can't expand this pack expansion into separate arguments yet;
7381 // just substitute into the pattern and create a new pack expansion
7382 // type.
7383 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
7385 TypeLocBuilder TypeArgBuilder;
7386 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7387 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7388 PatternLoc);
7389 if (NewPatternType.isNull())
7390 return QualType();
7392 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7393 NewPatternType, NumExpansions);
7394 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);
7395 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7396 NewTypeArgInfos.push_back(
7397 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewExpansionType));
7398 continue;
7401 // Substitute into the pack expansion pattern for each slice of the
7402 // pack.
7403 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
7404 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
7406 TypeLocBuilder TypeArgBuilder;
7407 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7409 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
7410 PatternLoc);
7411 if (NewTypeArg.isNull())
7412 return QualType();
7414 NewTypeArgInfos.push_back(
7415 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7418 continue;
7421 TypeLocBuilder TypeArgBuilder;
7422 TypeArgBuilder.reserve(TypeArgLoc.getFullDataSize());
7423 QualType NewTypeArg =
7424 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
7425 if (NewTypeArg.isNull())
7426 return QualType();
7428 // If nothing changed, just keep the old TypeSourceInfo.
7429 if (NewTypeArg == TypeArg) {
7430 NewTypeArgInfos.push_back(TypeArgInfo);
7431 continue;
7434 NewTypeArgInfos.push_back(
7435 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7436 AnyChanged = true;
7439 QualType Result = TL.getType();
7440 if (getDerived().AlwaysRebuild() || AnyChanged) {
7441 // Rebuild the type.
7442 Result = getDerived().RebuildObjCObjectType(
7443 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
7444 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
7445 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7446 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7448 if (Result.isNull())
7449 return QualType();
7452 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);
7453 NewT.setHasBaseTypeAsWritten(true);
7454 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
7455 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
7456 NewT.setTypeArgTInfo(i, NewTypeArgInfos[i]);
7457 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
7458 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7459 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7460 NewT.setProtocolLoc(i, TL.getProtocolLoc(i));
7461 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7462 return Result;
7465 template<typename Derived>
7466 QualType
7467 TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
7468 ObjCObjectPointerTypeLoc TL) {
7469 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
7470 if (PointeeType.isNull())
7471 return QualType();
7473 QualType Result = TL.getType();
7474 if (getDerived().AlwaysRebuild() ||
7475 PointeeType != TL.getPointeeLoc().getType()) {
7476 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
7477 TL.getStarLoc());
7478 if (Result.isNull())
7479 return QualType();
7482 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
7483 NewT.setStarLoc(TL.getStarLoc());
7484 return Result;
7487 //===----------------------------------------------------------------------===//
7488 // Statement transformation
7489 //===----------------------------------------------------------------------===//
7490 template<typename Derived>
7491 StmtResult
7492 TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
7493 return S;
7496 template<typename Derived>
7497 StmtResult
7498 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
7499 return getDerived().TransformCompoundStmt(S, false);
7502 template<typename Derived>
7503 StmtResult
7504 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
7505 bool IsStmtExpr) {
7506 Sema::CompoundScopeRAII CompoundScope(getSema());
7507 Sema::FPFeaturesStateRAII FPSave(getSema());
7508 if (S->hasStoredFPFeatures())
7509 getSema().resetFPOptions(
7510 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
7512 const Stmt *ExprResult = S->getStmtExprResult();
7513 bool SubStmtInvalid = false;
7514 bool SubStmtChanged = false;
7515 SmallVector<Stmt*, 8> Statements;
7516 for (auto *B : S->body()) {
7517 StmtResult Result = getDerived().TransformStmt(
7518 B, IsStmtExpr && B == ExprResult ? SDK_StmtExprResult : SDK_Discarded);
7520 if (Result.isInvalid()) {
7521 // Immediately fail if this was a DeclStmt, since it's very
7522 // likely that this will cause problems for future statements.
7523 if (isa<DeclStmt>(B))
7524 return StmtError();
7526 // Otherwise, just keep processing substatements and fail later.
7527 SubStmtInvalid = true;
7528 continue;
7531 SubStmtChanged = SubStmtChanged || Result.get() != B;
7532 Statements.push_back(Result.getAs<Stmt>());
7535 if (SubStmtInvalid)
7536 return StmtError();
7538 if (!getDerived().AlwaysRebuild() &&
7539 !SubStmtChanged)
7540 return S;
7542 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
7543 Statements,
7544 S->getRBracLoc(),
7545 IsStmtExpr);
7548 template<typename Derived>
7549 StmtResult
7550 TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
7551 ExprResult LHS, RHS;
7553 EnterExpressionEvaluationContext Unevaluated(
7554 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7556 // Transform the left-hand case value.
7557 LHS = getDerived().TransformExpr(S->getLHS());
7558 LHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), LHS);
7559 if (LHS.isInvalid())
7560 return StmtError();
7562 // Transform the right-hand case value (for the GNU case-range extension).
7563 RHS = getDerived().TransformExpr(S->getRHS());
7564 RHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), RHS);
7565 if (RHS.isInvalid())
7566 return StmtError();
7569 // Build the case statement.
7570 // Case statements are always rebuilt so that they will attached to their
7571 // transformed switch statement.
7572 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
7573 LHS.get(),
7574 S->getEllipsisLoc(),
7575 RHS.get(),
7576 S->getColonLoc());
7577 if (Case.isInvalid())
7578 return StmtError();
7580 // Transform the statement following the case
7581 StmtResult SubStmt =
7582 getDerived().TransformStmt(S->getSubStmt());
7583 if (SubStmt.isInvalid())
7584 return StmtError();
7586 // Attach the body to the case statement
7587 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
7590 template <typename Derived>
7591 StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
7592 // Transform the statement following the default case
7593 StmtResult SubStmt =
7594 getDerived().TransformStmt(S->getSubStmt());
7595 if (SubStmt.isInvalid())
7596 return StmtError();
7598 // Default statements are always rebuilt
7599 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
7600 SubStmt.get());
7603 template<typename Derived>
7604 StmtResult
7605 TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
7606 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7607 if (SubStmt.isInvalid())
7608 return StmtError();
7610 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
7611 S->getDecl());
7612 if (!LD)
7613 return StmtError();
7615 // If we're transforming "in-place" (we're not creating new local
7616 // declarations), assume we're replacing the old label statement
7617 // and clear out the reference to it.
7618 if (LD == S->getDecl())
7619 S->getDecl()->setStmt(nullptr);
7621 // FIXME: Pass the real colon location in.
7622 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
7623 cast<LabelDecl>(LD), SourceLocation(),
7624 SubStmt.get());
7627 template <typename Derived>
7628 const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
7629 if (!R)
7630 return R;
7632 switch (R->getKind()) {
7633 // Transform attributes by calling TransformXXXAttr.
7634 #define ATTR(X) \
7635 case attr::X: \
7636 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
7637 #include "clang/Basic/AttrList.inc"
7639 return R;
7642 template <typename Derived>
7643 const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
7644 const Stmt *InstS,
7645 const Attr *R) {
7646 if (!R)
7647 return R;
7649 switch (R->getKind()) {
7650 // Transform attributes by calling TransformStmtXXXAttr.
7651 #define ATTR(X) \
7652 case attr::X: \
7653 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
7654 #include "clang/Basic/AttrList.inc"
7656 return TransformAttr(R);
7659 template <typename Derived>
7660 StmtResult
7661 TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
7662 StmtDiscardKind SDK) {
7663 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7664 if (SubStmt.isInvalid())
7665 return StmtError();
7667 bool AttrsChanged = false;
7668 SmallVector<const Attr *, 1> Attrs;
7670 // Visit attributes and keep track if any are transformed.
7671 for (const auto *I : S->getAttrs()) {
7672 const Attr *R =
7673 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
7674 AttrsChanged |= (I != R);
7675 if (R)
7676 Attrs.push_back(R);
7679 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
7680 return S;
7682 // If transforming the attributes failed for all of the attributes in the
7683 // statement, don't make an AttributedStmt without attributes.
7684 if (Attrs.empty())
7685 return SubStmt;
7687 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
7688 SubStmt.get());
7691 template<typename Derived>
7692 StmtResult
7693 TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
7694 // Transform the initialization statement
7695 StmtResult Init = getDerived().TransformStmt(S->getInit());
7696 if (Init.isInvalid())
7697 return StmtError();
7699 Sema::ConditionResult Cond;
7700 if (!S->isConsteval()) {
7701 // Transform the condition
7702 Cond = getDerived().TransformCondition(
7703 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
7704 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
7705 : Sema::ConditionKind::Boolean);
7706 if (Cond.isInvalid())
7707 return StmtError();
7710 // If this is a constexpr if, determine which arm we should instantiate.
7711 std::optional<bool> ConstexprConditionValue;
7712 if (S->isConstexpr())
7713 ConstexprConditionValue = Cond.getKnownValue();
7715 // Transform the "then" branch.
7716 StmtResult Then;
7717 if (!ConstexprConditionValue || *ConstexprConditionValue) {
7718 Then = getDerived().TransformStmt(S->getThen());
7719 if (Then.isInvalid())
7720 return StmtError();
7721 } else {
7722 Then = new (getSema().Context) NullStmt(S->getThen()->getBeginLoc());
7725 // Transform the "else" branch.
7726 StmtResult Else;
7727 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
7728 Else = getDerived().TransformStmt(S->getElse());
7729 if (Else.isInvalid())
7730 return StmtError();
7733 if (!getDerived().AlwaysRebuild() &&
7734 Init.get() == S->getInit() &&
7735 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7736 Then.get() == S->getThen() &&
7737 Else.get() == S->getElse())
7738 return S;
7740 return getDerived().RebuildIfStmt(
7741 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
7742 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
7745 template<typename Derived>
7746 StmtResult
7747 TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
7748 // Transform the initialization statement
7749 StmtResult Init = getDerived().TransformStmt(S->getInit());
7750 if (Init.isInvalid())
7751 return StmtError();
7753 // Transform the condition.
7754 Sema::ConditionResult Cond = getDerived().TransformCondition(
7755 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
7756 Sema::ConditionKind::Switch);
7757 if (Cond.isInvalid())
7758 return StmtError();
7760 // Rebuild the switch statement.
7761 StmtResult Switch =
7762 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
7763 Init.get(), Cond, S->getRParenLoc());
7764 if (Switch.isInvalid())
7765 return StmtError();
7767 // Transform the body of the switch statement.
7768 StmtResult Body = getDerived().TransformStmt(S->getBody());
7769 if (Body.isInvalid())
7770 return StmtError();
7772 // Complete the switch statement.
7773 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
7774 Body.get());
7777 template<typename Derived>
7778 StmtResult
7779 TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
7780 // Transform the condition
7781 Sema::ConditionResult Cond = getDerived().TransformCondition(
7782 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
7783 Sema::ConditionKind::Boolean);
7784 if (Cond.isInvalid())
7785 return StmtError();
7787 // Transform the body
7788 StmtResult Body = getDerived().TransformStmt(S->getBody());
7789 if (Body.isInvalid())
7790 return StmtError();
7792 if (!getDerived().AlwaysRebuild() &&
7793 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7794 Body.get() == S->getBody())
7795 return Owned(S);
7797 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
7798 Cond, S->getRParenLoc(), Body.get());
7801 template<typename Derived>
7802 StmtResult
7803 TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
7804 // Transform the body
7805 StmtResult Body = getDerived().TransformStmt(S->getBody());
7806 if (Body.isInvalid())
7807 return StmtError();
7809 // Transform the condition
7810 ExprResult Cond = getDerived().TransformExpr(S->getCond());
7811 if (Cond.isInvalid())
7812 return StmtError();
7814 if (!getDerived().AlwaysRebuild() &&
7815 Cond.get() == S->getCond() &&
7816 Body.get() == S->getBody())
7817 return S;
7819 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
7820 /*FIXME:*/S->getWhileLoc(), Cond.get(),
7821 S->getRParenLoc());
7824 template<typename Derived>
7825 StmtResult
7826 TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
7827 if (getSema().getLangOpts().OpenMP)
7828 getSema().startOpenMPLoop();
7830 // Transform the initialization statement
7831 StmtResult Init = getDerived().TransformStmt(S->getInit());
7832 if (Init.isInvalid())
7833 return StmtError();
7835 // In OpenMP loop region loop control variable must be captured and be
7836 // private. Perform analysis of first part (if any).
7837 if (getSema().getLangOpts().OpenMP && Init.isUsable())
7838 getSema().ActOnOpenMPLoopInitialization(S->getForLoc(), Init.get());
7840 // Transform the condition
7841 Sema::ConditionResult Cond = getDerived().TransformCondition(
7842 S->getForLoc(), S->getConditionVariable(), S->getCond(),
7843 Sema::ConditionKind::Boolean);
7844 if (Cond.isInvalid())
7845 return StmtError();
7847 // Transform the increment
7848 ExprResult Inc = getDerived().TransformExpr(S->getInc());
7849 if (Inc.isInvalid())
7850 return StmtError();
7852 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
7853 if (S->getInc() && !FullInc.get())
7854 return StmtError();
7856 // Transform the body
7857 StmtResult Body = getDerived().TransformStmt(S->getBody());
7858 if (Body.isInvalid())
7859 return StmtError();
7861 if (!getDerived().AlwaysRebuild() &&
7862 Init.get() == S->getInit() &&
7863 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7864 Inc.get() == S->getInc() &&
7865 Body.get() == S->getBody())
7866 return S;
7868 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
7869 Init.get(), Cond, FullInc,
7870 S->getRParenLoc(), Body.get());
7873 template<typename Derived>
7874 StmtResult
7875 TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
7876 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
7877 S->getLabel());
7878 if (!LD)
7879 return StmtError();
7881 // Goto statements must always be rebuilt, to resolve the label.
7882 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
7883 cast<LabelDecl>(LD));
7886 template<typename Derived>
7887 StmtResult
7888 TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
7889 ExprResult Target = getDerived().TransformExpr(S->getTarget());
7890 if (Target.isInvalid())
7891 return StmtError();
7892 Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());
7894 if (!getDerived().AlwaysRebuild() &&
7895 Target.get() == S->getTarget())
7896 return S;
7898 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
7899 Target.get());
7902 template<typename Derived>
7903 StmtResult
7904 TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
7905 return S;
7908 template<typename Derived>
7909 StmtResult
7910 TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
7911 return S;
7914 template<typename Derived>
7915 StmtResult
7916 TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
7917 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
7918 /*NotCopyInit*/false);
7919 if (Result.isInvalid())
7920 return StmtError();
7922 // FIXME: We always rebuild the return statement because there is no way
7923 // to tell whether the return type of the function has changed.
7924 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
7927 template<typename Derived>
7928 StmtResult
7929 TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
7930 bool DeclChanged = false;
7931 SmallVector<Decl *, 4> Decls;
7932 for (auto *D : S->decls()) {
7933 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
7934 if (!Transformed)
7935 return StmtError();
7937 if (Transformed != D)
7938 DeclChanged = true;
7940 Decls.push_back(Transformed);
7943 if (!getDerived().AlwaysRebuild() && !DeclChanged)
7944 return S;
7946 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
7949 template<typename Derived>
7950 StmtResult
7951 TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
7953 SmallVector<Expr*, 8> Constraints;
7954 SmallVector<Expr*, 8> Exprs;
7955 SmallVector<IdentifierInfo *, 4> Names;
7957 ExprResult AsmString;
7958 SmallVector<Expr*, 8> Clobbers;
7960 bool ExprsChanged = false;
7962 // Go through the outputs.
7963 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
7964 Names.push_back(S->getOutputIdentifier(I));
7966 // No need to transform the constraint literal.
7967 Constraints.push_back(S->getOutputConstraintLiteral(I));
7969 // Transform the output expr.
7970 Expr *OutputExpr = S->getOutputExpr(I);
7971 ExprResult Result = getDerived().TransformExpr(OutputExpr);
7972 if (Result.isInvalid())
7973 return StmtError();
7975 ExprsChanged |= Result.get() != OutputExpr;
7977 Exprs.push_back(Result.get());
7980 // Go through the inputs.
7981 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
7982 Names.push_back(S->getInputIdentifier(I));
7984 // No need to transform the constraint literal.
7985 Constraints.push_back(S->getInputConstraintLiteral(I));
7987 // Transform the input expr.
7988 Expr *InputExpr = S->getInputExpr(I);
7989 ExprResult Result = getDerived().TransformExpr(InputExpr);
7990 if (Result.isInvalid())
7991 return StmtError();
7993 ExprsChanged |= Result.get() != InputExpr;
7995 Exprs.push_back(Result.get());
7998 // Go through the Labels.
7999 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8000 Names.push_back(S->getLabelIdentifier(I));
8002 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(I));
8003 if (Result.isInvalid())
8004 return StmtError();
8005 ExprsChanged |= Result.get() != S->getLabelExpr(I);
8006 Exprs.push_back(Result.get());
8008 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8009 return S;
8011 // Go through the clobbers.
8012 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
8013 Clobbers.push_back(S->getClobberStringLiteral(I));
8015 // No need to transform the asm string literal.
8016 AsmString = S->getAsmString();
8017 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8018 S->isVolatile(), S->getNumOutputs(),
8019 S->getNumInputs(), Names.data(),
8020 Constraints, Exprs, AsmString.get(),
8021 Clobbers, S->getNumLabels(),
8022 S->getRParenLoc());
8025 template<typename Derived>
8026 StmtResult
8027 TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8028 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8030 bool HadError = false, HadChange = false;
8032 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8033 SmallVector<Expr*, 8> TransformedExprs;
8034 TransformedExprs.reserve(SrcExprs.size());
8035 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8036 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8037 if (!Result.isUsable()) {
8038 HadError = true;
8039 } else {
8040 HadChange |= (Result.get() != SrcExprs[i]);
8041 TransformedExprs.push_back(Result.get());
8045 if (HadError) return StmtError();
8046 if (!HadChange && !getDerived().AlwaysRebuild())
8047 return Owned(S);
8049 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8050 AsmToks, S->getAsmString(),
8051 S->getNumOutputs(), S->getNumInputs(),
8052 S->getAllConstraints(), S->getClobbers(),
8053 TransformedExprs, S->getEndLoc());
8056 // C++ Coroutines
8057 template<typename Derived>
8058 StmtResult
8059 TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8060 auto *ScopeInfo = SemaRef.getCurFunction();
8061 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
8062 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8063 ScopeInfo->NeedsCoroutineSuspends &&
8064 ScopeInfo->CoroutineSuspends.first == nullptr &&
8065 ScopeInfo->CoroutineSuspends.second == nullptr &&
8066 "expected clean scope info");
8068 // Set that we have (possibly-invalid) suspend points before we do anything
8069 // that may fail.
8070 ScopeInfo->setNeedsCoroutineSuspends(false);
8072 // We re-build the coroutine promise object (and the coroutine parameters its
8073 // type and constructor depend on) based on the types used in our current
8074 // function. We must do so, and set it on the current FunctionScopeInfo,
8075 // before attempting to transform the other parts of the coroutine body
8076 // statement, such as the implicit suspend statements (because those
8077 // statements reference the FunctionScopeInfo::CoroutinePromise).
8078 if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation()))
8079 return StmtError();
8080 auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());
8081 if (!Promise)
8082 return StmtError();
8083 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8084 ScopeInfo->CoroutinePromise = Promise;
8086 // Transform the implicit coroutine statements constructed using dependent
8087 // types during the previous parse: initial and final suspensions, the return
8088 // object, and others. We also transform the coroutine function's body.
8089 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8090 if (InitSuspend.isInvalid())
8091 return StmtError();
8092 StmtResult FinalSuspend =
8093 getDerived().TransformStmt(S->getFinalSuspendStmt());
8094 if (FinalSuspend.isInvalid() ||
8095 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get()))
8096 return StmtError();
8097 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
8098 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8100 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8101 if (BodyRes.isInvalid())
8102 return StmtError();
8104 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8105 if (Builder.isInvalid())
8106 return StmtError();
8108 Expr *ReturnObject = S->getReturnValueInit();
8109 assert(ReturnObject && "the return object is expected to be valid");
8110 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8111 /*NoCopyInit*/ false);
8112 if (Res.isInvalid())
8113 return StmtError();
8114 Builder.ReturnValue = Res.get();
8116 // If during the previous parse the coroutine still had a dependent promise
8117 // statement, we may need to build some implicit coroutine statements
8118 // (such as exception and fallthrough handlers) for the first time.
8119 if (S->hasDependentPromiseType()) {
8120 // We can only build these statements, however, if the current promise type
8121 // is not dependent.
8122 if (!Promise->getType()->isDependentType()) {
8123 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8124 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8125 "these nodes should not have been built yet");
8126 if (!Builder.buildDependentStatements())
8127 return StmtError();
8129 } else {
8130 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8131 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8132 if (Res.isInvalid())
8133 return StmtError();
8134 Builder.OnFallthrough = Res.get();
8137 if (auto *OnException = S->getExceptionHandler()) {
8138 StmtResult Res = getDerived().TransformStmt(OnException);
8139 if (Res.isInvalid())
8140 return StmtError();
8141 Builder.OnException = Res.get();
8144 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8145 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8146 if (Res.isInvalid())
8147 return StmtError();
8148 Builder.ReturnStmtOnAllocFailure = Res.get();
8151 // Transform any additional statements we may have already built
8152 assert(S->getAllocate() && S->getDeallocate() &&
8153 "allocation and deallocation calls must already be built");
8154 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8155 if (AllocRes.isInvalid())
8156 return StmtError();
8157 Builder.Allocate = AllocRes.get();
8159 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8160 if (DeallocRes.isInvalid())
8161 return StmtError();
8162 Builder.Deallocate = DeallocRes.get();
8164 if (auto *ResultDecl = S->getResultDecl()) {
8165 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8166 if (Res.isInvalid())
8167 return StmtError();
8168 Builder.ResultDecl = Res.get();
8171 if (auto *ReturnStmt = S->getReturnStmt()) {
8172 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8173 if (Res.isInvalid())
8174 return StmtError();
8175 Builder.ReturnStmt = Res.get();
8179 return getDerived().RebuildCoroutineBodyStmt(Builder);
8182 template<typename Derived>
8183 StmtResult
8184 TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8185 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8186 /*NotCopyInit*/false);
8187 if (Result.isInvalid())
8188 return StmtError();
8190 // Always rebuild; we don't know if this needs to be injected into a new
8191 // context or if the promise type has changed.
8192 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8193 S->isImplicit());
8196 template <typename Derived>
8197 ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8198 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8199 /*NotCopyInit*/ false);
8200 if (Operand.isInvalid())
8201 return ExprError();
8203 // Rebuild the common-expr from the operand rather than transforming it
8204 // separately.
8206 // FIXME: getCurScope() should not be used during template instantiation.
8207 // We should pick up the set of unqualified lookup results for operator
8208 // co_await during the initial parse.
8209 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8210 getSema().getCurScope(), E->getKeywordLoc());
8212 // Always rebuild; we don't know if this needs to be injected into a new
8213 // context or if the promise type has changed.
8214 return getDerived().RebuildCoawaitExpr(
8215 E->getKeywordLoc(), Operand.get(),
8216 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());
8219 template <typename Derived>
8220 ExprResult
8221 TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8222 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8223 /*NotCopyInit*/ false);
8224 if (OperandResult.isInvalid())
8225 return ExprError();
8227 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8228 E->getOperatorCoawaitLookup());
8230 if (LookupResult.isInvalid())
8231 return ExprError();
8233 // Always rebuild; we don't know if this needs to be injected into a new
8234 // context or if the promise type has changed.
8235 return getDerived().RebuildDependentCoawaitExpr(
8236 E->getKeywordLoc(), OperandResult.get(),
8237 cast<UnresolvedLookupExpr>(LookupResult.get()));
8240 template<typename Derived>
8241 ExprResult
8242 TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8243 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8244 /*NotCopyInit*/false);
8245 if (Result.isInvalid())
8246 return ExprError();
8248 // Always rebuild; we don't know if this needs to be injected into a new
8249 // context or if the promise type has changed.
8250 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8253 // Objective-C Statements.
8255 template<typename Derived>
8256 StmtResult
8257 TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8258 // Transform the body of the @try.
8259 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8260 if (TryBody.isInvalid())
8261 return StmtError();
8263 // Transform the @catch statements (if present).
8264 bool AnyCatchChanged = false;
8265 SmallVector<Stmt*, 8> CatchStmts;
8266 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8267 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8268 if (Catch.isInvalid())
8269 return StmtError();
8270 if (Catch.get() != S->getCatchStmt(I))
8271 AnyCatchChanged = true;
8272 CatchStmts.push_back(Catch.get());
8275 // Transform the @finally statement (if present).
8276 StmtResult Finally;
8277 if (S->getFinallyStmt()) {
8278 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8279 if (Finally.isInvalid())
8280 return StmtError();
8283 // If nothing changed, just retain this statement.
8284 if (!getDerived().AlwaysRebuild() &&
8285 TryBody.get() == S->getTryBody() &&
8286 !AnyCatchChanged &&
8287 Finally.get() == S->getFinallyStmt())
8288 return S;
8290 // Build a new statement.
8291 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8292 CatchStmts, Finally.get());
8295 template<typename Derived>
8296 StmtResult
8297 TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8298 // Transform the @catch parameter, if there is one.
8299 VarDecl *Var = nullptr;
8300 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8301 TypeSourceInfo *TSInfo = nullptr;
8302 if (FromVar->getTypeSourceInfo()) {
8303 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8304 if (!TSInfo)
8305 return StmtError();
8308 QualType T;
8309 if (TSInfo)
8310 T = TSInfo->getType();
8311 else {
8312 T = getDerived().TransformType(FromVar->getType());
8313 if (T.isNull())
8314 return StmtError();
8317 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8318 if (!Var)
8319 return StmtError();
8322 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8323 if (Body.isInvalid())
8324 return StmtError();
8326 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
8327 S->getRParenLoc(),
8328 Var, Body.get());
8331 template<typename Derived>
8332 StmtResult
8333 TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
8334 // Transform the body.
8335 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
8336 if (Body.isInvalid())
8337 return StmtError();
8339 // If nothing changed, just retain this statement.
8340 if (!getDerived().AlwaysRebuild() &&
8341 Body.get() == S->getFinallyBody())
8342 return S;
8344 // Build a new statement.
8345 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
8346 Body.get());
8349 template<typename Derived>
8350 StmtResult
8351 TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
8352 ExprResult Operand;
8353 if (S->getThrowExpr()) {
8354 Operand = getDerived().TransformExpr(S->getThrowExpr());
8355 if (Operand.isInvalid())
8356 return StmtError();
8359 if (!getDerived().AlwaysRebuild() &&
8360 Operand.get() == S->getThrowExpr())
8361 return S;
8363 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
8366 template<typename Derived>
8367 StmtResult
8368 TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
8369 ObjCAtSynchronizedStmt *S) {
8370 // Transform the object we are locking.
8371 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
8372 if (Object.isInvalid())
8373 return StmtError();
8374 Object =
8375 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
8376 Object.get());
8377 if (Object.isInvalid())
8378 return StmtError();
8380 // Transform the body.
8381 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
8382 if (Body.isInvalid())
8383 return StmtError();
8385 // If nothing change, just retain the current statement.
8386 if (!getDerived().AlwaysRebuild() &&
8387 Object.get() == S->getSynchExpr() &&
8388 Body.get() == S->getSynchBody())
8389 return S;
8391 // Build a new statement.
8392 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
8393 Object.get(), Body.get());
8396 template<typename Derived>
8397 StmtResult
8398 TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
8399 ObjCAutoreleasePoolStmt *S) {
8400 // Transform the body.
8401 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
8402 if (Body.isInvalid())
8403 return StmtError();
8405 // If nothing changed, just retain this statement.
8406 if (!getDerived().AlwaysRebuild() &&
8407 Body.get() == S->getSubStmt())
8408 return S;
8410 // Build a new statement.
8411 return getDerived().RebuildObjCAutoreleasePoolStmt(
8412 S->getAtLoc(), Body.get());
8415 template<typename Derived>
8416 StmtResult
8417 TreeTransform<Derived>::TransformObjCForCollectionStmt(
8418 ObjCForCollectionStmt *S) {
8419 // Transform the element statement.
8420 StmtResult Element =
8421 getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded);
8422 if (Element.isInvalid())
8423 return StmtError();
8425 // Transform the collection expression.
8426 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
8427 if (Collection.isInvalid())
8428 return StmtError();
8430 // Transform the body.
8431 StmtResult Body = getDerived().TransformStmt(S->getBody());
8432 if (Body.isInvalid())
8433 return StmtError();
8435 // If nothing changed, just retain this statement.
8436 if (!getDerived().AlwaysRebuild() &&
8437 Element.get() == S->getElement() &&
8438 Collection.get() == S->getCollection() &&
8439 Body.get() == S->getBody())
8440 return S;
8442 // Build a new statement.
8443 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
8444 Element.get(),
8445 Collection.get(),
8446 S->getRParenLoc(),
8447 Body.get());
8450 template <typename Derived>
8451 StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
8452 // Transform the exception declaration, if any.
8453 VarDecl *Var = nullptr;
8454 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
8455 TypeSourceInfo *T =
8456 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
8457 if (!T)
8458 return StmtError();
8460 Var = getDerived().RebuildExceptionDecl(
8461 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
8462 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
8463 if (!Var || Var->isInvalidDecl())
8464 return StmtError();
8467 // Transform the actual exception handler.
8468 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
8469 if (Handler.isInvalid())
8470 return StmtError();
8472 if (!getDerived().AlwaysRebuild() && !Var &&
8473 Handler.get() == S->getHandlerBlock())
8474 return S;
8476 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
8479 template <typename Derived>
8480 StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
8481 // Transform the try block itself.
8482 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8483 if (TryBlock.isInvalid())
8484 return StmtError();
8486 // Transform the handlers.
8487 bool HandlerChanged = false;
8488 SmallVector<Stmt *, 8> Handlers;
8489 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
8490 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I));
8491 if (Handler.isInvalid())
8492 return StmtError();
8494 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
8495 Handlers.push_back(Handler.getAs<Stmt>());
8498 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8499 !HandlerChanged)
8500 return S;
8502 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
8503 Handlers);
8506 template<typename Derived>
8507 StmtResult
8508 TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
8509 StmtResult Init =
8510 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
8511 if (Init.isInvalid())
8512 return StmtError();
8514 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
8515 if (Range.isInvalid())
8516 return StmtError();
8518 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
8519 if (Begin.isInvalid())
8520 return StmtError();
8521 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
8522 if (End.isInvalid())
8523 return StmtError();
8525 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8526 if (Cond.isInvalid())
8527 return StmtError();
8528 if (Cond.get())
8529 Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());
8530 if (Cond.isInvalid())
8531 return StmtError();
8532 if (Cond.get())
8533 Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());
8535 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8536 if (Inc.isInvalid())
8537 return StmtError();
8538 if (Inc.get())
8539 Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());
8541 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
8542 if (LoopVar.isInvalid())
8543 return StmtError();
8545 StmtResult NewStmt = S;
8546 if (getDerived().AlwaysRebuild() ||
8547 Init.get() != S->getInit() ||
8548 Range.get() != S->getRangeStmt() ||
8549 Begin.get() != S->getBeginStmt() ||
8550 End.get() != S->getEndStmt() ||
8551 Cond.get() != S->getCond() ||
8552 Inc.get() != S->getInc() ||
8553 LoopVar.get() != S->getLoopVarStmt()) {
8554 NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
8555 S->getCoawaitLoc(), Init.get(),
8556 S->getColonLoc(), Range.get(),
8557 Begin.get(), End.get(),
8558 Cond.get(),
8559 Inc.get(), LoopVar.get(),
8560 S->getRParenLoc());
8561 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
8562 // Might not have attached any initializer to the loop variable.
8563 getSema().ActOnInitializerError(
8564 cast<DeclStmt>(LoopVar.get())->getSingleDecl());
8565 return StmtError();
8569 StmtResult Body = getDerived().TransformStmt(S->getBody());
8570 if (Body.isInvalid())
8571 return StmtError();
8573 // Body has changed but we didn't rebuild the for-range statement. Rebuild
8574 // it now so we have a new statement to attach the body to.
8575 if (Body.get() != S->getBody() && NewStmt.get() == S) {
8576 NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
8577 S->getCoawaitLoc(), Init.get(),
8578 S->getColonLoc(), Range.get(),
8579 Begin.get(), End.get(),
8580 Cond.get(),
8581 Inc.get(), LoopVar.get(),
8582 S->getRParenLoc());
8583 if (NewStmt.isInvalid())
8584 return StmtError();
8587 if (NewStmt.get() == S)
8588 return S;
8590 return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
8593 template<typename Derived>
8594 StmtResult
8595 TreeTransform<Derived>::TransformMSDependentExistsStmt(
8596 MSDependentExistsStmt *S) {
8597 // Transform the nested-name-specifier, if any.
8598 NestedNameSpecifierLoc QualifierLoc;
8599 if (S->getQualifierLoc()) {
8600 QualifierLoc
8601 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
8602 if (!QualifierLoc)
8603 return StmtError();
8606 // Transform the declaration name.
8607 DeclarationNameInfo NameInfo = S->getNameInfo();
8608 if (NameInfo.getName()) {
8609 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
8610 if (!NameInfo.getName())
8611 return StmtError();
8614 // Check whether anything changed.
8615 if (!getDerived().AlwaysRebuild() &&
8616 QualifierLoc == S->getQualifierLoc() &&
8617 NameInfo.getName() == S->getNameInfo().getName())
8618 return S;
8620 // Determine whether this name exists, if we can.
8621 CXXScopeSpec SS;
8622 SS.Adopt(QualifierLoc);
8623 bool Dependent = false;
8624 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
8625 case Sema::IER_Exists:
8626 if (S->isIfExists())
8627 break;
8629 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8631 case Sema::IER_DoesNotExist:
8632 if (S->isIfNotExists())
8633 break;
8635 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8637 case Sema::IER_Dependent:
8638 Dependent = true;
8639 break;
8641 case Sema::IER_Error:
8642 return StmtError();
8645 // We need to continue with the instantiation, so do so now.
8646 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
8647 if (SubStmt.isInvalid())
8648 return StmtError();
8650 // If we have resolved the name, just transform to the substatement.
8651 if (!Dependent)
8652 return SubStmt;
8654 // The name is still dependent, so build a dependent expression again.
8655 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
8656 S->isIfExists(),
8657 QualifierLoc,
8658 NameInfo,
8659 SubStmt.get());
8662 template<typename Derived>
8663 ExprResult
8664 TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
8665 NestedNameSpecifierLoc QualifierLoc;
8666 if (E->getQualifierLoc()) {
8667 QualifierLoc
8668 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
8669 if (!QualifierLoc)
8670 return ExprError();
8673 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
8674 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
8675 if (!PD)
8676 return ExprError();
8678 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
8679 if (Base.isInvalid())
8680 return ExprError();
8682 return new (SemaRef.getASTContext())
8683 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
8684 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
8685 QualifierLoc, E->getMemberLoc());
8688 template <typename Derived>
8689 ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
8690 MSPropertySubscriptExpr *E) {
8691 auto BaseRes = getDerived().TransformExpr(E->getBase());
8692 if (BaseRes.isInvalid())
8693 return ExprError();
8694 auto IdxRes = getDerived().TransformExpr(E->getIdx());
8695 if (IdxRes.isInvalid())
8696 return ExprError();
8698 if (!getDerived().AlwaysRebuild() &&
8699 BaseRes.get() == E->getBase() &&
8700 IdxRes.get() == E->getIdx())
8701 return E;
8703 return getDerived().RebuildArraySubscriptExpr(
8704 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
8707 template <typename Derived>
8708 StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
8709 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8710 if (TryBlock.isInvalid())
8711 return StmtError();
8713 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
8714 if (Handler.isInvalid())
8715 return StmtError();
8717 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8718 Handler.get() == S->getHandler())
8719 return S;
8721 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
8722 TryBlock.get(), Handler.get());
8725 template <typename Derived>
8726 StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
8727 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
8728 if (Block.isInvalid())
8729 return StmtError();
8731 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
8734 template <typename Derived>
8735 StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
8736 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
8737 if (FilterExpr.isInvalid())
8738 return StmtError();
8740 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
8741 if (Block.isInvalid())
8742 return StmtError();
8744 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
8745 Block.get());
8748 template <typename Derived>
8749 StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
8750 if (isa<SEHFinallyStmt>(Handler))
8751 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
8752 else
8753 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
8756 template<typename Derived>
8757 StmtResult
8758 TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
8759 return S;
8762 //===----------------------------------------------------------------------===//
8763 // OpenMP directive transformation
8764 //===----------------------------------------------------------------------===//
8766 template <typename Derived>
8767 StmtResult
8768 TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
8769 // OMPCanonicalLoops are eliminated during transformation, since they will be
8770 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
8771 // after transformation.
8772 return getDerived().TransformStmt(L->getLoopStmt());
8775 template <typename Derived>
8776 StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
8777 OMPExecutableDirective *D) {
8779 // Transform the clauses
8780 llvm::SmallVector<OMPClause *, 16> TClauses;
8781 ArrayRef<OMPClause *> Clauses = D->clauses();
8782 TClauses.reserve(Clauses.size());
8783 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
8784 I != E; ++I) {
8785 if (*I) {
8786 getDerived().getSema().StartOpenMPClause((*I)->getClauseKind());
8787 OMPClause *Clause = getDerived().TransformOMPClause(*I);
8788 getDerived().getSema().EndOpenMPClause();
8789 if (Clause)
8790 TClauses.push_back(Clause);
8791 } else {
8792 TClauses.push_back(nullptr);
8795 StmtResult AssociatedStmt;
8796 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
8797 getDerived().getSema().ActOnOpenMPRegionStart(D->getDirectiveKind(),
8798 /*CurScope=*/nullptr);
8799 StmtResult Body;
8801 Sema::CompoundScopeRAII CompoundScope(getSema());
8802 Stmt *CS;
8803 if (D->getDirectiveKind() == OMPD_atomic ||
8804 D->getDirectiveKind() == OMPD_critical ||
8805 D->getDirectiveKind() == OMPD_section ||
8806 D->getDirectiveKind() == OMPD_master)
8807 CS = D->getAssociatedStmt();
8808 else
8809 CS = D->getRawStmt();
8810 Body = getDerived().TransformStmt(CS);
8811 if (Body.isUsable() && isOpenMPLoopDirective(D->getDirectiveKind()) &&
8812 getSema().getLangOpts().OpenMPIRBuilder)
8813 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
8815 AssociatedStmt =
8816 getDerived().getSema().ActOnOpenMPRegionEnd(Body, TClauses);
8817 if (AssociatedStmt.isInvalid()) {
8818 return StmtError();
8821 if (TClauses.size() != Clauses.size()) {
8822 return StmtError();
8825 // Transform directive name for 'omp critical' directive.
8826 DeclarationNameInfo DirName;
8827 if (D->getDirectiveKind() == OMPD_critical) {
8828 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
8829 DirName = getDerived().TransformDeclarationNameInfo(DirName);
8831 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
8832 if (D->getDirectiveKind() == OMPD_cancellation_point) {
8833 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();
8834 } else if (D->getDirectiveKind() == OMPD_cancel) {
8835 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();
8838 return getDerived().RebuildOMPExecutableDirective(
8839 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
8840 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc(),
8841 D->getMappedDirective());
8844 template <typename Derived>
8845 StmtResult
8846 TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
8847 // TODO: Fix This
8848 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)
8849 << getOpenMPDirectiveName(D->getDirectiveKind());
8850 return StmtError();
8853 template <typename Derived>
8854 StmtResult
8855 TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
8856 DeclarationNameInfo DirName;
8857 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr,
8858 D->getBeginLoc());
8859 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8860 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8861 return Res;
8864 template <typename Derived>
8865 StmtResult
8866 TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
8867 DeclarationNameInfo DirName;
8868 getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr,
8869 D->getBeginLoc());
8870 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8871 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8872 return Res;
8875 template <typename Derived>
8876 StmtResult
8877 TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
8878 DeclarationNameInfo DirName;
8879 getDerived().getSema().StartOpenMPDSABlock(D->getDirectiveKind(), DirName,
8880 nullptr, D->getBeginLoc());
8881 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8882 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8883 return Res;
8886 template <typename Derived>
8887 StmtResult
8888 TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
8889 DeclarationNameInfo DirName;
8890 getDerived().getSema().StartOpenMPDSABlock(D->getDirectiveKind(), DirName,
8891 nullptr, D->getBeginLoc());
8892 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8893 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8894 return Res;
8897 template <typename Derived>
8898 StmtResult
8899 TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
8900 DeclarationNameInfo DirName;
8901 getDerived().getSema().StartOpenMPDSABlock(OMPD_for, DirName, nullptr,
8902 D->getBeginLoc());
8903 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8904 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8905 return Res;
8908 template <typename Derived>
8909 StmtResult
8910 TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
8911 DeclarationNameInfo DirName;
8912 getDerived().getSema().StartOpenMPDSABlock(OMPD_for_simd, DirName, nullptr,
8913 D->getBeginLoc());
8914 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8915 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8916 return Res;
8919 template <typename Derived>
8920 StmtResult
8921 TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
8922 DeclarationNameInfo DirName;
8923 getDerived().getSema().StartOpenMPDSABlock(OMPD_sections, DirName, nullptr,
8924 D->getBeginLoc());
8925 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8926 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8927 return Res;
8930 template <typename Derived>
8931 StmtResult
8932 TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
8933 DeclarationNameInfo DirName;
8934 getDerived().getSema().StartOpenMPDSABlock(OMPD_section, DirName, nullptr,
8935 D->getBeginLoc());
8936 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8937 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8938 return Res;
8941 template <typename Derived>
8942 StmtResult
8943 TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
8944 DeclarationNameInfo DirName;
8945 getDerived().getSema().StartOpenMPDSABlock(OMPD_scope, DirName, nullptr,
8946 D->getBeginLoc());
8947 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8948 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8949 return Res;
8952 template <typename Derived>
8953 StmtResult
8954 TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
8955 DeclarationNameInfo DirName;
8956 getDerived().getSema().StartOpenMPDSABlock(OMPD_single, DirName, nullptr,
8957 D->getBeginLoc());
8958 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8959 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8960 return Res;
8963 template <typename Derived>
8964 StmtResult
8965 TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
8966 DeclarationNameInfo DirName;
8967 getDerived().getSema().StartOpenMPDSABlock(OMPD_master, DirName, nullptr,
8968 D->getBeginLoc());
8969 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8970 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8971 return Res;
8974 template <typename Derived>
8975 StmtResult
8976 TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
8977 getDerived().getSema().StartOpenMPDSABlock(
8978 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
8979 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8980 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8981 return Res;
8984 template <typename Derived>
8985 StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
8986 OMPParallelForDirective *D) {
8987 DeclarationNameInfo DirName;
8988 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for, DirName,
8989 nullptr, D->getBeginLoc());
8990 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8991 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8992 return Res;
8995 template <typename Derived>
8996 StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
8997 OMPParallelForSimdDirective *D) {
8998 DeclarationNameInfo DirName;
8999 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for_simd, DirName,
9000 nullptr, D->getBeginLoc());
9001 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9002 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9003 return Res;
9006 template <typename Derived>
9007 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9008 OMPParallelMasterDirective *D) {
9009 DeclarationNameInfo DirName;
9010 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_master, DirName,
9011 nullptr, D->getBeginLoc());
9012 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9013 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9014 return Res;
9017 template <typename Derived>
9018 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9019 OMPParallelMaskedDirective *D) {
9020 DeclarationNameInfo DirName;
9021 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_masked, DirName,
9022 nullptr, D->getBeginLoc());
9023 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9024 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9025 return Res;
9028 template <typename Derived>
9029 StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9030 OMPParallelSectionsDirective *D) {
9031 DeclarationNameInfo DirName;
9032 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_sections, DirName,
9033 nullptr, D->getBeginLoc());
9034 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9035 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9036 return Res;
9039 template <typename Derived>
9040 StmtResult
9041 TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9042 DeclarationNameInfo DirName;
9043 getDerived().getSema().StartOpenMPDSABlock(OMPD_task, DirName, nullptr,
9044 D->getBeginLoc());
9045 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9046 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9047 return Res;
9050 template <typename Derived>
9051 StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9052 OMPTaskyieldDirective *D) {
9053 DeclarationNameInfo DirName;
9054 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskyield, DirName, nullptr,
9055 D->getBeginLoc());
9056 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9057 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9058 return Res;
9061 template <typename Derived>
9062 StmtResult
9063 TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9064 DeclarationNameInfo DirName;
9065 getDerived().getSema().StartOpenMPDSABlock(OMPD_barrier, DirName, nullptr,
9066 D->getBeginLoc());
9067 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9068 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9069 return Res;
9072 template <typename Derived>
9073 StmtResult
9074 TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9075 DeclarationNameInfo DirName;
9076 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskwait, DirName, nullptr,
9077 D->getBeginLoc());
9078 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9079 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9080 return Res;
9083 template <typename Derived>
9084 StmtResult
9085 TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9086 DeclarationNameInfo DirName;
9087 getDerived().getSema().StartOpenMPDSABlock(OMPD_error, DirName, nullptr,
9088 D->getBeginLoc());
9089 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9090 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9091 return Res;
9094 template <typename Derived>
9095 StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9096 OMPTaskgroupDirective *D) {
9097 DeclarationNameInfo DirName;
9098 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskgroup, DirName, nullptr,
9099 D->getBeginLoc());
9100 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9101 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9102 return Res;
9105 template <typename Derived>
9106 StmtResult
9107 TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9108 DeclarationNameInfo DirName;
9109 getDerived().getSema().StartOpenMPDSABlock(OMPD_flush, DirName, nullptr,
9110 D->getBeginLoc());
9111 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9112 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9113 return Res;
9116 template <typename Derived>
9117 StmtResult
9118 TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9119 DeclarationNameInfo DirName;
9120 getDerived().getSema().StartOpenMPDSABlock(OMPD_depobj, DirName, nullptr,
9121 D->getBeginLoc());
9122 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9123 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9124 return Res;
9127 template <typename Derived>
9128 StmtResult
9129 TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9130 DeclarationNameInfo DirName;
9131 getDerived().getSema().StartOpenMPDSABlock(OMPD_scan, DirName, nullptr,
9132 D->getBeginLoc());
9133 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9134 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9135 return Res;
9138 template <typename Derived>
9139 StmtResult
9140 TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9141 DeclarationNameInfo DirName;
9142 getDerived().getSema().StartOpenMPDSABlock(OMPD_ordered, DirName, nullptr,
9143 D->getBeginLoc());
9144 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9145 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9146 return Res;
9149 template <typename Derived>
9150 StmtResult
9151 TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9152 DeclarationNameInfo DirName;
9153 getDerived().getSema().StartOpenMPDSABlock(OMPD_atomic, DirName, nullptr,
9154 D->getBeginLoc());
9155 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9156 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9157 return Res;
9160 template <typename Derived>
9161 StmtResult
9162 TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9163 DeclarationNameInfo DirName;
9164 getDerived().getSema().StartOpenMPDSABlock(OMPD_target, DirName, nullptr,
9165 D->getBeginLoc());
9166 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9167 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9168 return Res;
9171 template <typename Derived>
9172 StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9173 OMPTargetDataDirective *D) {
9174 DeclarationNameInfo DirName;
9175 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_data, DirName, nullptr,
9176 D->getBeginLoc());
9177 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9178 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9179 return Res;
9182 template <typename Derived>
9183 StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9184 OMPTargetEnterDataDirective *D) {
9185 DeclarationNameInfo DirName;
9186 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_enter_data, DirName,
9187 nullptr, D->getBeginLoc());
9188 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9189 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9190 return Res;
9193 template <typename Derived>
9194 StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9195 OMPTargetExitDataDirective *D) {
9196 DeclarationNameInfo DirName;
9197 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_exit_data, DirName,
9198 nullptr, D->getBeginLoc());
9199 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9200 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9201 return Res;
9204 template <typename Derived>
9205 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
9206 OMPTargetParallelDirective *D) {
9207 DeclarationNameInfo DirName;
9208 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel, DirName,
9209 nullptr, D->getBeginLoc());
9210 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9211 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9212 return Res;
9215 template <typename Derived>
9216 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
9217 OMPTargetParallelForDirective *D) {
9218 DeclarationNameInfo DirName;
9219 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_for, DirName,
9220 nullptr, D->getBeginLoc());
9221 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9222 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9223 return Res;
9226 template <typename Derived>
9227 StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
9228 OMPTargetUpdateDirective *D) {
9229 DeclarationNameInfo DirName;
9230 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_update, DirName,
9231 nullptr, D->getBeginLoc());
9232 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9233 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9234 return Res;
9237 template <typename Derived>
9238 StmtResult
9239 TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
9240 DeclarationNameInfo DirName;
9241 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams, DirName, nullptr,
9242 D->getBeginLoc());
9243 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9244 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9245 return Res;
9248 template <typename Derived>
9249 StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
9250 OMPCancellationPointDirective *D) {
9251 DeclarationNameInfo DirName;
9252 getDerived().getSema().StartOpenMPDSABlock(OMPD_cancellation_point, DirName,
9253 nullptr, D->getBeginLoc());
9254 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9255 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9256 return Res;
9259 template <typename Derived>
9260 StmtResult
9261 TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
9262 DeclarationNameInfo DirName;
9263 getDerived().getSema().StartOpenMPDSABlock(OMPD_cancel, DirName, nullptr,
9264 D->getBeginLoc());
9265 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9266 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9267 return Res;
9270 template <typename Derived>
9271 StmtResult
9272 TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
9273 DeclarationNameInfo DirName;
9274 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop, DirName, nullptr,
9275 D->getBeginLoc());
9276 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9277 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9278 return Res;
9281 template <typename Derived>
9282 StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
9283 OMPTaskLoopSimdDirective *D) {
9284 DeclarationNameInfo DirName;
9285 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop_simd, DirName,
9286 nullptr, D->getBeginLoc());
9287 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9288 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9289 return Res;
9292 template <typename Derived>
9293 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
9294 OMPMasterTaskLoopDirective *D) {
9295 DeclarationNameInfo DirName;
9296 getDerived().getSema().StartOpenMPDSABlock(OMPD_master_taskloop, DirName,
9297 nullptr, D->getBeginLoc());
9298 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9299 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9300 return Res;
9303 template <typename Derived>
9304 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
9305 OMPMaskedTaskLoopDirective *D) {
9306 DeclarationNameInfo DirName;
9307 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked_taskloop, DirName,
9308 nullptr, D->getBeginLoc());
9309 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9310 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9311 return Res;
9314 template <typename Derived>
9315 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
9316 OMPMasterTaskLoopSimdDirective *D) {
9317 DeclarationNameInfo DirName;
9318 getDerived().getSema().StartOpenMPDSABlock(OMPD_master_taskloop_simd, DirName,
9319 nullptr, D->getBeginLoc());
9320 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9321 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9322 return Res;
9325 template <typename Derived>
9326 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
9327 OMPMaskedTaskLoopSimdDirective *D) {
9328 DeclarationNameInfo DirName;
9329 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked_taskloop_simd, DirName,
9330 nullptr, D->getBeginLoc());
9331 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9332 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9333 return Res;
9336 template <typename Derived>
9337 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
9338 OMPParallelMasterTaskLoopDirective *D) {
9339 DeclarationNameInfo DirName;
9340 getDerived().getSema().StartOpenMPDSABlock(
9341 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
9342 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9343 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9344 return Res;
9347 template <typename Derived>
9348 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
9349 OMPParallelMaskedTaskLoopDirective *D) {
9350 DeclarationNameInfo DirName;
9351 getDerived().getSema().StartOpenMPDSABlock(
9352 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9353 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9354 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9355 return Res;
9358 template <typename Derived>
9359 StmtResult
9360 TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
9361 OMPParallelMasterTaskLoopSimdDirective *D) {
9362 DeclarationNameInfo DirName;
9363 getDerived().getSema().StartOpenMPDSABlock(
9364 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9365 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9366 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9367 return Res;
9370 template <typename Derived>
9371 StmtResult
9372 TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
9373 OMPParallelMaskedTaskLoopSimdDirective *D) {
9374 DeclarationNameInfo DirName;
9375 getDerived().getSema().StartOpenMPDSABlock(
9376 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9377 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9378 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9379 return Res;
9382 template <typename Derived>
9383 StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
9384 OMPDistributeDirective *D) {
9385 DeclarationNameInfo DirName;
9386 getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute, DirName, nullptr,
9387 D->getBeginLoc());
9388 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9389 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9390 return Res;
9393 template <typename Derived>
9394 StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
9395 OMPDistributeParallelForDirective *D) {
9396 DeclarationNameInfo DirName;
9397 getDerived().getSema().StartOpenMPDSABlock(
9398 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9399 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9400 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9401 return Res;
9404 template <typename Derived>
9405 StmtResult
9406 TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
9407 OMPDistributeParallelForSimdDirective *D) {
9408 DeclarationNameInfo DirName;
9409 getDerived().getSema().StartOpenMPDSABlock(
9410 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9411 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9412 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9413 return Res;
9416 template <typename Derived>
9417 StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
9418 OMPDistributeSimdDirective *D) {
9419 DeclarationNameInfo DirName;
9420 getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute_simd, DirName,
9421 nullptr, D->getBeginLoc());
9422 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9423 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9424 return Res;
9427 template <typename Derived>
9428 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
9429 OMPTargetParallelForSimdDirective *D) {
9430 DeclarationNameInfo DirName;
9431 getDerived().getSema().StartOpenMPDSABlock(
9432 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9433 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9434 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9435 return Res;
9438 template <typename Derived>
9439 StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
9440 OMPTargetSimdDirective *D) {
9441 DeclarationNameInfo DirName;
9442 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_simd, DirName, nullptr,
9443 D->getBeginLoc());
9444 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9445 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9446 return Res;
9449 template <typename Derived>
9450 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
9451 OMPTeamsDistributeDirective *D) {
9452 DeclarationNameInfo DirName;
9453 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams_distribute, DirName,
9454 nullptr, D->getBeginLoc());
9455 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9456 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9457 return Res;
9460 template <typename Derived>
9461 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
9462 OMPTeamsDistributeSimdDirective *D) {
9463 DeclarationNameInfo DirName;
9464 getDerived().getSema().StartOpenMPDSABlock(
9465 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9466 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9467 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9468 return Res;
9471 template <typename Derived>
9472 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
9473 OMPTeamsDistributeParallelForSimdDirective *D) {
9474 DeclarationNameInfo DirName;
9475 getDerived().getSema().StartOpenMPDSABlock(
9476 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
9477 D->getBeginLoc());
9478 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9479 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9480 return Res;
9483 template <typename Derived>
9484 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
9485 OMPTeamsDistributeParallelForDirective *D) {
9486 DeclarationNameInfo DirName;
9487 getDerived().getSema().StartOpenMPDSABlock(
9488 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9489 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9490 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9491 return Res;
9494 template <typename Derived>
9495 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
9496 OMPTargetTeamsDirective *D) {
9497 DeclarationNameInfo DirName;
9498 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams, DirName,
9499 nullptr, D->getBeginLoc());
9500 auto Res = getDerived().TransformOMPExecutableDirective(D);
9501 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9502 return Res;
9505 template <typename Derived>
9506 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
9507 OMPTargetTeamsDistributeDirective *D) {
9508 DeclarationNameInfo DirName;
9509 getDerived().getSema().StartOpenMPDSABlock(
9510 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
9511 auto Res = getDerived().TransformOMPExecutableDirective(D);
9512 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9513 return Res;
9516 template <typename Derived>
9517 StmtResult
9518 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
9519 OMPTargetTeamsDistributeParallelForDirective *D) {
9520 DeclarationNameInfo DirName;
9521 getDerived().getSema().StartOpenMPDSABlock(
9522 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
9523 D->getBeginLoc());
9524 auto Res = getDerived().TransformOMPExecutableDirective(D);
9525 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9526 return Res;
9529 template <typename Derived>
9530 StmtResult TreeTransform<Derived>::
9531 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
9532 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
9533 DeclarationNameInfo DirName;
9534 getDerived().getSema().StartOpenMPDSABlock(
9535 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
9536 D->getBeginLoc());
9537 auto Res = getDerived().TransformOMPExecutableDirective(D);
9538 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9539 return Res;
9542 template <typename Derived>
9543 StmtResult
9544 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
9545 OMPTargetTeamsDistributeSimdDirective *D) {
9546 DeclarationNameInfo DirName;
9547 getDerived().getSema().StartOpenMPDSABlock(
9548 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9549 auto Res = getDerived().TransformOMPExecutableDirective(D);
9550 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9551 return Res;
9554 template <typename Derived>
9555 StmtResult
9556 TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
9557 DeclarationNameInfo DirName;
9558 getDerived().getSema().StartOpenMPDSABlock(OMPD_interop, DirName, nullptr,
9559 D->getBeginLoc());
9560 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9561 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9562 return Res;
9565 template <typename Derived>
9566 StmtResult
9567 TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
9568 DeclarationNameInfo DirName;
9569 getDerived().getSema().StartOpenMPDSABlock(OMPD_dispatch, DirName, nullptr,
9570 D->getBeginLoc());
9571 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9572 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9573 return Res;
9576 template <typename Derived>
9577 StmtResult
9578 TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
9579 DeclarationNameInfo DirName;
9580 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked, DirName, nullptr,
9581 D->getBeginLoc());
9582 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9583 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9584 return Res;
9587 template <typename Derived>
9588 StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
9589 OMPGenericLoopDirective *D) {
9590 DeclarationNameInfo DirName;
9591 getDerived().getSema().StartOpenMPDSABlock(OMPD_loop, DirName, nullptr,
9592 D->getBeginLoc());
9593 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9594 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9595 return Res;
9598 template <typename Derived>
9599 StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
9600 OMPTeamsGenericLoopDirective *D) {
9601 DeclarationNameInfo DirName;
9602 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams_loop, DirName, nullptr,
9603 D->getBeginLoc());
9604 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9605 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9606 return Res;
9609 template <typename Derived>
9610 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
9611 OMPTargetTeamsGenericLoopDirective *D) {
9612 DeclarationNameInfo DirName;
9613 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams_loop, DirName,
9614 nullptr, D->getBeginLoc());
9615 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9616 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9617 return Res;
9620 template <typename Derived>
9621 StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
9622 OMPParallelGenericLoopDirective *D) {
9623 DeclarationNameInfo DirName;
9624 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_loop, DirName,
9625 nullptr, D->getBeginLoc());
9626 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9627 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9628 return Res;
9631 template <typename Derived>
9632 StmtResult
9633 TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
9634 OMPTargetParallelGenericLoopDirective *D) {
9635 DeclarationNameInfo DirName;
9636 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_loop, DirName,
9637 nullptr, D->getBeginLoc());
9638 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9639 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9640 return Res;
9643 //===----------------------------------------------------------------------===//
9644 // OpenMP clause transformation
9645 //===----------------------------------------------------------------------===//
9646 template <typename Derived>
9647 OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
9648 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9649 if (Cond.isInvalid())
9650 return nullptr;
9651 return getDerived().RebuildOMPIfClause(
9652 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
9653 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
9656 template <typename Derived>
9657 OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
9658 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9659 if (Cond.isInvalid())
9660 return nullptr;
9661 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
9662 C->getLParenLoc(), C->getEndLoc());
9665 template <typename Derived>
9666 OMPClause *
9667 TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
9668 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
9669 if (NumThreads.isInvalid())
9670 return nullptr;
9671 return getDerived().RebuildOMPNumThreadsClause(
9672 NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9675 template <typename Derived>
9676 OMPClause *
9677 TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
9678 ExprResult E = getDerived().TransformExpr(C->getSafelen());
9679 if (E.isInvalid())
9680 return nullptr;
9681 return getDerived().RebuildOMPSafelenClause(
9682 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9685 template <typename Derived>
9686 OMPClause *
9687 TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
9688 ExprResult E = getDerived().TransformExpr(C->getAllocator());
9689 if (E.isInvalid())
9690 return nullptr;
9691 return getDerived().RebuildOMPAllocatorClause(
9692 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9695 template <typename Derived>
9696 OMPClause *
9697 TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
9698 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
9699 if (E.isInvalid())
9700 return nullptr;
9701 return getDerived().RebuildOMPSimdlenClause(
9702 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9705 template <typename Derived>
9706 OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
9707 SmallVector<Expr *, 4> TransformedSizes;
9708 TransformedSizes.reserve(C->getNumSizes());
9709 bool Changed = false;
9710 for (Expr *E : C->getSizesRefs()) {
9711 if (!E) {
9712 TransformedSizes.push_back(nullptr);
9713 continue;
9716 ExprResult T = getDerived().TransformExpr(E);
9717 if (T.isInvalid())
9718 return nullptr;
9719 if (E != T.get())
9720 Changed = true;
9721 TransformedSizes.push_back(T.get());
9724 if (!Changed && !getDerived().AlwaysRebuild())
9725 return C;
9726 return RebuildOMPSizesClause(TransformedSizes, C->getBeginLoc(),
9727 C->getLParenLoc(), C->getEndLoc());
9730 template <typename Derived>
9731 OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
9732 if (!getDerived().AlwaysRebuild())
9733 return C;
9734 return RebuildOMPFullClause(C->getBeginLoc(), C->getEndLoc());
9737 template <typename Derived>
9738 OMPClause *
9739 TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
9740 ExprResult T = getDerived().TransformExpr(C->getFactor());
9741 if (T.isInvalid())
9742 return nullptr;
9743 Expr *Factor = T.get();
9744 bool Changed = Factor != C->getFactor();
9746 if (!Changed && !getDerived().AlwaysRebuild())
9747 return C;
9748 return RebuildOMPPartialClause(Factor, C->getBeginLoc(), C->getLParenLoc(),
9749 C->getEndLoc());
9752 template <typename Derived>
9753 OMPClause *
9754 TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
9755 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
9756 if (E.isInvalid())
9757 return nullptr;
9758 return getDerived().RebuildOMPCollapseClause(
9759 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9762 template <typename Derived>
9763 OMPClause *
9764 TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
9765 return getDerived().RebuildOMPDefaultClause(
9766 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
9767 C->getLParenLoc(), C->getEndLoc());
9770 template <typename Derived>
9771 OMPClause *
9772 TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
9773 return getDerived().RebuildOMPProcBindClause(
9774 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
9775 C->getLParenLoc(), C->getEndLoc());
9778 template <typename Derived>
9779 OMPClause *
9780 TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
9781 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
9782 if (E.isInvalid())
9783 return nullptr;
9784 return getDerived().RebuildOMPScheduleClause(
9785 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
9786 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
9787 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
9788 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
9791 template <typename Derived>
9792 OMPClause *
9793 TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
9794 ExprResult E;
9795 if (auto *Num = C->getNumForLoops()) {
9796 E = getDerived().TransformExpr(Num);
9797 if (E.isInvalid())
9798 return nullptr;
9800 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
9801 C->getLParenLoc(), E.get());
9804 template <typename Derived>
9805 OMPClause *
9806 TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
9807 ExprResult E;
9808 if (Expr *Evt = C->getEventHandler()) {
9809 E = getDerived().TransformExpr(Evt);
9810 if (E.isInvalid())
9811 return nullptr;
9813 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
9814 C->getLParenLoc(), C->getEndLoc());
9817 template <typename Derived>
9818 OMPClause *
9819 TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
9820 // No need to rebuild this clause, no template-dependent parameters.
9821 return C;
9824 template <typename Derived>
9825 OMPClause *
9826 TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
9827 // No need to rebuild this clause, no template-dependent parameters.
9828 return C;
9831 template <typename Derived>
9832 OMPClause *
9833 TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
9834 // No need to rebuild this clause, no template-dependent parameters.
9835 return C;
9838 template <typename Derived>
9839 OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
9840 // No need to rebuild this clause, no template-dependent parameters.
9841 return C;
9844 template <typename Derived>
9845 OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
9846 // No need to rebuild this clause, no template-dependent parameters.
9847 return C;
9850 template <typename Derived>
9851 OMPClause *
9852 TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
9853 // No need to rebuild this clause, no template-dependent parameters.
9854 return C;
9857 template <typename Derived>
9858 OMPClause *
9859 TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
9860 // No need to rebuild this clause, no template-dependent parameters.
9861 return C;
9864 template <typename Derived>
9865 OMPClause *
9866 TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
9867 // No need to rebuild this clause, no template-dependent parameters.
9868 return C;
9871 template <typename Derived>
9872 OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
9873 // No need to rebuild this clause, no template-dependent parameters.
9874 return C;
9877 template <typename Derived>
9878 OMPClause *
9879 TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
9880 // No need to rebuild this clause, no template-dependent parameters.
9881 return C;
9884 template <typename Derived>
9885 OMPClause *
9886 TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
9887 // No need to rebuild this clause, no template-dependent parameters.
9888 return C;
9891 template <typename Derived>
9892 OMPClause *
9893 TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
9894 // No need to rebuild this clause, no template-dependent parameters.
9895 return C;
9898 template <typename Derived>
9899 OMPClause *
9900 TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
9901 // No need to rebuild this clause, no template-dependent parameters.
9902 return C;
9905 template <typename Derived>
9906 OMPClause *
9907 TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
9908 // No need to rebuild this clause, no template-dependent parameters.
9909 return C;
9912 template <typename Derived>
9913 OMPClause *
9914 TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
9915 // No need to rebuild this clause, no template-dependent parameters.
9916 return C;
9919 template <typename Derived>
9920 OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
9921 // No need to rebuild this clause, no template-dependent parameters.
9922 return C;
9925 template <typename Derived>
9926 OMPClause *
9927 TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
9928 // No need to rebuild this clause, no template-dependent parameters.
9929 return C;
9932 template <typename Derived>
9933 OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
9934 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
9935 if (IVR.isInvalid())
9936 return nullptr;
9938 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
9939 InteropInfo.PreferTypes.reserve(C->varlist_size() - 1);
9940 for (Expr *E : llvm::drop_begin(C->varlists())) {
9941 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
9942 if (ER.isInvalid())
9943 return nullptr;
9944 InteropInfo.PreferTypes.push_back(ER.get());
9946 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
9947 C->getBeginLoc(), C->getLParenLoc(),
9948 C->getVarLoc(), C->getEndLoc());
9951 template <typename Derived>
9952 OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
9953 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
9954 if (ER.isInvalid())
9955 return nullptr;
9956 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
9957 C->getLParenLoc(), C->getVarLoc(),
9958 C->getEndLoc());
9961 template <typename Derived>
9962 OMPClause *
9963 TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
9964 ExprResult ER;
9965 if (Expr *IV = C->getInteropVar()) {
9966 ER = getDerived().TransformExpr(IV);
9967 if (ER.isInvalid())
9968 return nullptr;
9970 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
9971 C->getLParenLoc(), C->getVarLoc(),
9972 C->getEndLoc());
9975 template <typename Derived>
9976 OMPClause *
9977 TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
9978 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9979 if (Cond.isInvalid())
9980 return nullptr;
9981 return getDerived().RebuildOMPNovariantsClause(
9982 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9985 template <typename Derived>
9986 OMPClause *
9987 TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
9988 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9989 if (Cond.isInvalid())
9990 return nullptr;
9991 return getDerived().RebuildOMPNocontextClause(
9992 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9995 template <typename Derived>
9996 OMPClause *
9997 TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
9998 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
9999 if (ThreadID.isInvalid())
10000 return nullptr;
10001 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10002 C->getLParenLoc(), C->getEndLoc());
10005 template <typename Derived>
10006 OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10007 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10008 if (E.isInvalid())
10009 return nullptr;
10010 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10011 C->getLParenLoc(), C->getEndLoc());
10014 template <typename Derived>
10015 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10016 OMPUnifiedAddressClause *C) {
10017 llvm_unreachable("unified_address clause cannot appear in dependent context");
10020 template <typename Derived>
10021 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10022 OMPUnifiedSharedMemoryClause *C) {
10023 llvm_unreachable(
10024 "unified_shared_memory clause cannot appear in dependent context");
10027 template <typename Derived>
10028 OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10029 OMPReverseOffloadClause *C) {
10030 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10033 template <typename Derived>
10034 OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10035 OMPDynamicAllocatorsClause *C) {
10036 llvm_unreachable(
10037 "dynamic_allocators clause cannot appear in dependent context");
10040 template <typename Derived>
10041 OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10042 OMPAtomicDefaultMemOrderClause *C) {
10043 llvm_unreachable(
10044 "atomic_default_mem_order clause cannot appear in dependent context");
10047 template <typename Derived>
10048 OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10049 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10050 C->getBeginLoc(), C->getLParenLoc(),
10051 C->getEndLoc());
10054 template <typename Derived>
10055 OMPClause *
10056 TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10057 return getDerived().RebuildOMPSeverityClause(
10058 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10059 C->getLParenLoc(), C->getEndLoc());
10062 template <typename Derived>
10063 OMPClause *
10064 TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10065 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10066 if (E.isInvalid())
10067 return nullptr;
10068 return getDerived().RebuildOMPMessageClause(
10069 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10070 C->getEndLoc());
10073 template <typename Derived>
10074 OMPClause *
10075 TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10076 llvm::SmallVector<Expr *, 16> Vars;
10077 Vars.reserve(C->varlist_size());
10078 for (auto *VE : C->varlists()) {
10079 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10080 if (EVar.isInvalid())
10081 return nullptr;
10082 Vars.push_back(EVar.get());
10084 return getDerived().RebuildOMPPrivateClause(
10085 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10088 template <typename Derived>
10089 OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10090 OMPFirstprivateClause *C) {
10091 llvm::SmallVector<Expr *, 16> Vars;
10092 Vars.reserve(C->varlist_size());
10093 for (auto *VE : C->varlists()) {
10094 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10095 if (EVar.isInvalid())
10096 return nullptr;
10097 Vars.push_back(EVar.get());
10099 return getDerived().RebuildOMPFirstprivateClause(
10100 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10103 template <typename Derived>
10104 OMPClause *
10105 TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10106 llvm::SmallVector<Expr *, 16> Vars;
10107 Vars.reserve(C->varlist_size());
10108 for (auto *VE : C->varlists()) {
10109 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10110 if (EVar.isInvalid())
10111 return nullptr;
10112 Vars.push_back(EVar.get());
10114 return getDerived().RebuildOMPLastprivateClause(
10115 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10116 C->getLParenLoc(), C->getEndLoc());
10119 template <typename Derived>
10120 OMPClause *
10121 TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
10122 llvm::SmallVector<Expr *, 16> Vars;
10123 Vars.reserve(C->varlist_size());
10124 for (auto *VE : C->varlists()) {
10125 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10126 if (EVar.isInvalid())
10127 return nullptr;
10128 Vars.push_back(EVar.get());
10130 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
10131 C->getLParenLoc(), C->getEndLoc());
10134 template <typename Derived>
10135 OMPClause *
10136 TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
10137 llvm::SmallVector<Expr *, 16> Vars;
10138 Vars.reserve(C->varlist_size());
10139 for (auto *VE : C->varlists()) {
10140 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10141 if (EVar.isInvalid())
10142 return nullptr;
10143 Vars.push_back(EVar.get());
10145 CXXScopeSpec ReductionIdScopeSpec;
10146 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10148 DeclarationNameInfo NameInfo = C->getNameInfo();
10149 if (NameInfo.getName()) {
10150 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10151 if (!NameInfo.getName())
10152 return nullptr;
10154 // Build a list of all UDR decls with the same names ranged by the Scopes.
10155 // The Scope boundary is a duplication of the previous decl.
10156 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10157 for (auto *E : C->reduction_ops()) {
10158 // Transform all the decls.
10159 if (E) {
10160 auto *ULE = cast<UnresolvedLookupExpr>(E);
10161 UnresolvedSet<8> Decls;
10162 for (auto *D : ULE->decls()) {
10163 NamedDecl *InstD =
10164 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10165 Decls.addDecl(InstD, InstD->getAccess());
10167 UnresolvedReductions.push_back(
10168 UnresolvedLookupExpr::Create(
10169 SemaRef.Context, /*NamingClass=*/nullptr,
10170 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context),
10171 NameInfo, /*ADL=*/true, ULE->isOverloaded(),
10172 Decls.begin(), Decls.end()));
10173 } else
10174 UnresolvedReductions.push_back(nullptr);
10176 return getDerived().RebuildOMPReductionClause(
10177 Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(),
10178 C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
10179 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10182 template <typename Derived>
10183 OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
10184 OMPTaskReductionClause *C) {
10185 llvm::SmallVector<Expr *, 16> Vars;
10186 Vars.reserve(C->varlist_size());
10187 for (auto *VE : C->varlists()) {
10188 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10189 if (EVar.isInvalid())
10190 return nullptr;
10191 Vars.push_back(EVar.get());
10193 CXXScopeSpec ReductionIdScopeSpec;
10194 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10196 DeclarationNameInfo NameInfo = C->getNameInfo();
10197 if (NameInfo.getName()) {
10198 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10199 if (!NameInfo.getName())
10200 return nullptr;
10202 // Build a list of all UDR decls with the same names ranged by the Scopes.
10203 // The Scope boundary is a duplication of the previous decl.
10204 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10205 for (auto *E : C->reduction_ops()) {
10206 // Transform all the decls.
10207 if (E) {
10208 auto *ULE = cast<UnresolvedLookupExpr>(E);
10209 UnresolvedSet<8> Decls;
10210 for (auto *D : ULE->decls()) {
10211 NamedDecl *InstD =
10212 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10213 Decls.addDecl(InstD, InstD->getAccess());
10215 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10216 SemaRef.Context, /*NamingClass=*/nullptr,
10217 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10218 /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end()));
10219 } else
10220 UnresolvedReductions.push_back(nullptr);
10222 return getDerived().RebuildOMPTaskReductionClause(
10223 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10224 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10227 template <typename Derived>
10228 OMPClause *
10229 TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
10230 llvm::SmallVector<Expr *, 16> Vars;
10231 Vars.reserve(C->varlist_size());
10232 for (auto *VE : C->varlists()) {
10233 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10234 if (EVar.isInvalid())
10235 return nullptr;
10236 Vars.push_back(EVar.get());
10238 CXXScopeSpec ReductionIdScopeSpec;
10239 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10241 DeclarationNameInfo NameInfo = C->getNameInfo();
10242 if (NameInfo.getName()) {
10243 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10244 if (!NameInfo.getName())
10245 return nullptr;
10247 // Build a list of all UDR decls with the same names ranged by the Scopes.
10248 // The Scope boundary is a duplication of the previous decl.
10249 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10250 for (auto *E : C->reduction_ops()) {
10251 // Transform all the decls.
10252 if (E) {
10253 auto *ULE = cast<UnresolvedLookupExpr>(E);
10254 UnresolvedSet<8> Decls;
10255 for (auto *D : ULE->decls()) {
10256 NamedDecl *InstD =
10257 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10258 Decls.addDecl(InstD, InstD->getAccess());
10260 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10261 SemaRef.Context, /*NamingClass=*/nullptr,
10262 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10263 /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end()));
10264 } else
10265 UnresolvedReductions.push_back(nullptr);
10267 return getDerived().RebuildOMPInReductionClause(
10268 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10269 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10272 template <typename Derived>
10273 OMPClause *
10274 TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
10275 llvm::SmallVector<Expr *, 16> Vars;
10276 Vars.reserve(C->varlist_size());
10277 for (auto *VE : C->varlists()) {
10278 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10279 if (EVar.isInvalid())
10280 return nullptr;
10281 Vars.push_back(EVar.get());
10283 ExprResult Step = getDerived().TransformExpr(C->getStep());
10284 if (Step.isInvalid())
10285 return nullptr;
10286 return getDerived().RebuildOMPLinearClause(
10287 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
10288 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
10289 C->getEndLoc());
10292 template <typename Derived>
10293 OMPClause *
10294 TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
10295 llvm::SmallVector<Expr *, 16> Vars;
10296 Vars.reserve(C->varlist_size());
10297 for (auto *VE : C->varlists()) {
10298 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10299 if (EVar.isInvalid())
10300 return nullptr;
10301 Vars.push_back(EVar.get());
10303 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
10304 if (Alignment.isInvalid())
10305 return nullptr;
10306 return getDerived().RebuildOMPAlignedClause(
10307 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
10308 C->getColonLoc(), C->getEndLoc());
10311 template <typename Derived>
10312 OMPClause *
10313 TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
10314 llvm::SmallVector<Expr *, 16> Vars;
10315 Vars.reserve(C->varlist_size());
10316 for (auto *VE : C->varlists()) {
10317 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10318 if (EVar.isInvalid())
10319 return nullptr;
10320 Vars.push_back(EVar.get());
10322 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
10323 C->getLParenLoc(), C->getEndLoc());
10326 template <typename Derived>
10327 OMPClause *
10328 TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
10329 llvm::SmallVector<Expr *, 16> Vars;
10330 Vars.reserve(C->varlist_size());
10331 for (auto *VE : C->varlists()) {
10332 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10333 if (EVar.isInvalid())
10334 return nullptr;
10335 Vars.push_back(EVar.get());
10337 return getDerived().RebuildOMPCopyprivateClause(
10338 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10341 template <typename Derived>
10342 OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
10343 llvm::SmallVector<Expr *, 16> Vars;
10344 Vars.reserve(C->varlist_size());
10345 for (auto *VE : C->varlists()) {
10346 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10347 if (EVar.isInvalid())
10348 return nullptr;
10349 Vars.push_back(EVar.get());
10351 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
10352 C->getLParenLoc(), C->getEndLoc());
10355 template <typename Derived>
10356 OMPClause *
10357 TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
10358 ExprResult E = getDerived().TransformExpr(C->getDepobj());
10359 if (E.isInvalid())
10360 return nullptr;
10361 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
10362 C->getLParenLoc(), C->getEndLoc());
10365 template <typename Derived>
10366 OMPClause *
10367 TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
10368 llvm::SmallVector<Expr *, 16> Vars;
10369 Expr *DepModifier = C->getModifier();
10370 if (DepModifier) {
10371 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
10372 if (DepModRes.isInvalid())
10373 return nullptr;
10374 DepModifier = DepModRes.get();
10376 Vars.reserve(C->varlist_size());
10377 for (auto *VE : C->varlists()) {
10378 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10379 if (EVar.isInvalid())
10380 return nullptr;
10381 Vars.push_back(EVar.get());
10383 return getDerived().RebuildOMPDependClause(
10384 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
10385 C->getOmpAllMemoryLoc()},
10386 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10389 template <typename Derived>
10390 OMPClause *
10391 TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
10392 ExprResult E = getDerived().TransformExpr(C->getDevice());
10393 if (E.isInvalid())
10394 return nullptr;
10395 return getDerived().RebuildOMPDeviceClause(
10396 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10397 C->getModifierLoc(), C->getEndLoc());
10400 template <typename Derived, class T>
10401 bool transformOMPMappableExprListClause(
10402 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
10403 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
10404 DeclarationNameInfo &MapperIdInfo,
10405 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
10406 // Transform expressions in the list.
10407 Vars.reserve(C->varlist_size());
10408 for (auto *VE : C->varlists()) {
10409 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
10410 if (EVar.isInvalid())
10411 return true;
10412 Vars.push_back(EVar.get());
10414 // Transform mapper scope specifier and identifier.
10415 NestedNameSpecifierLoc QualifierLoc;
10416 if (C->getMapperQualifierLoc()) {
10417 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
10418 C->getMapperQualifierLoc());
10419 if (!QualifierLoc)
10420 return true;
10422 MapperIdScopeSpec.Adopt(QualifierLoc);
10423 MapperIdInfo = C->getMapperIdInfo();
10424 if (MapperIdInfo.getName()) {
10425 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
10426 if (!MapperIdInfo.getName())
10427 return true;
10429 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
10430 // the previous user-defined mapper lookup in dependent environment.
10431 for (auto *E : C->mapperlists()) {
10432 // Transform all the decls.
10433 if (E) {
10434 auto *ULE = cast<UnresolvedLookupExpr>(E);
10435 UnresolvedSet<8> Decls;
10436 for (auto *D : ULE->decls()) {
10437 NamedDecl *InstD =
10438 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
10439 Decls.addDecl(InstD, InstD->getAccess());
10441 UnresolvedMappers.push_back(UnresolvedLookupExpr::Create(
10442 TT.getSema().Context, /*NamingClass=*/nullptr,
10443 MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
10444 MapperIdInfo, /*ADL=*/true, ULE->isOverloaded(), Decls.begin(),
10445 Decls.end()));
10446 } else {
10447 UnresolvedMappers.push_back(nullptr);
10450 return false;
10453 template <typename Derived>
10454 OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
10455 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10456 llvm::SmallVector<Expr *, 16> Vars;
10457 Expr *IteratorModifier = C->getIteratorModifier();
10458 if (IteratorModifier) {
10459 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
10460 if (MapModRes.isInvalid())
10461 return nullptr;
10462 IteratorModifier = MapModRes.get();
10464 CXXScopeSpec MapperIdScopeSpec;
10465 DeclarationNameInfo MapperIdInfo;
10466 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10467 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
10468 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10469 return nullptr;
10470 return getDerived().RebuildOMPMapClause(
10471 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
10472 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
10473 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10476 template <typename Derived>
10477 OMPClause *
10478 TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
10479 Expr *Allocator = C->getAllocator();
10480 if (Allocator) {
10481 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
10482 if (AllocatorRes.isInvalid())
10483 return nullptr;
10484 Allocator = AllocatorRes.get();
10486 llvm::SmallVector<Expr *, 16> Vars;
10487 Vars.reserve(C->varlist_size());
10488 for (auto *VE : C->varlists()) {
10489 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10490 if (EVar.isInvalid())
10491 return nullptr;
10492 Vars.push_back(EVar.get());
10494 return getDerived().RebuildOMPAllocateClause(
10495 Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10496 C->getEndLoc());
10499 template <typename Derived>
10500 OMPClause *
10501 TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
10502 ExprResult E = getDerived().TransformExpr(C->getNumTeams());
10503 if (E.isInvalid())
10504 return nullptr;
10505 return getDerived().RebuildOMPNumTeamsClause(
10506 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10509 template <typename Derived>
10510 OMPClause *
10511 TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
10512 ExprResult E = getDerived().TransformExpr(C->getThreadLimit());
10513 if (E.isInvalid())
10514 return nullptr;
10515 return getDerived().RebuildOMPThreadLimitClause(
10516 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10519 template <typename Derived>
10520 OMPClause *
10521 TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
10522 ExprResult E = getDerived().TransformExpr(C->getPriority());
10523 if (E.isInvalid())
10524 return nullptr;
10525 return getDerived().RebuildOMPPriorityClause(
10526 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10529 template <typename Derived>
10530 OMPClause *
10531 TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
10532 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
10533 if (E.isInvalid())
10534 return nullptr;
10535 return getDerived().RebuildOMPGrainsizeClause(
10536 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10537 C->getModifierLoc(), C->getEndLoc());
10540 template <typename Derived>
10541 OMPClause *
10542 TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
10543 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
10544 if (E.isInvalid())
10545 return nullptr;
10546 return getDerived().RebuildOMPNumTasksClause(
10547 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10548 C->getModifierLoc(), C->getEndLoc());
10551 template <typename Derived>
10552 OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
10553 ExprResult E = getDerived().TransformExpr(C->getHint());
10554 if (E.isInvalid())
10555 return nullptr;
10556 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
10557 C->getLParenLoc(), C->getEndLoc());
10560 template <typename Derived>
10561 OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
10562 OMPDistScheduleClause *C) {
10563 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10564 if (E.isInvalid())
10565 return nullptr;
10566 return getDerived().RebuildOMPDistScheduleClause(
10567 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10568 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10571 template <typename Derived>
10572 OMPClause *
10573 TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
10574 // Rebuild Defaultmap Clause since we need to invoke the checking of
10575 // defaultmap(none:variable-category) after template initialization.
10576 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
10577 C->getDefaultmapKind(),
10578 C->getBeginLoc(),
10579 C->getLParenLoc(),
10580 C->getDefaultmapModifierLoc(),
10581 C->getDefaultmapKindLoc(),
10582 C->getEndLoc());
10585 template <typename Derived>
10586 OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
10587 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10588 llvm::SmallVector<Expr *, 16> Vars;
10589 CXXScopeSpec MapperIdScopeSpec;
10590 DeclarationNameInfo MapperIdInfo;
10591 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10592 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
10593 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10594 return nullptr;
10595 return getDerived().RebuildOMPToClause(
10596 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10597 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10600 template <typename Derived>
10601 OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
10602 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10603 llvm::SmallVector<Expr *, 16> Vars;
10604 CXXScopeSpec MapperIdScopeSpec;
10605 DeclarationNameInfo MapperIdInfo;
10606 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10607 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
10608 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10609 return nullptr;
10610 return getDerived().RebuildOMPFromClause(
10611 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10612 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10615 template <typename Derived>
10616 OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
10617 OMPUseDevicePtrClause *C) {
10618 llvm::SmallVector<Expr *, 16> Vars;
10619 Vars.reserve(C->varlist_size());
10620 for (auto *VE : C->varlists()) {
10621 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10622 if (EVar.isInvalid())
10623 return nullptr;
10624 Vars.push_back(EVar.get());
10626 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10627 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
10630 template <typename Derived>
10631 OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
10632 OMPUseDeviceAddrClause *C) {
10633 llvm::SmallVector<Expr *, 16> Vars;
10634 Vars.reserve(C->varlist_size());
10635 for (auto *VE : C->varlists()) {
10636 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10637 if (EVar.isInvalid())
10638 return nullptr;
10639 Vars.push_back(EVar.get());
10641 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10642 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
10645 template <typename Derived>
10646 OMPClause *
10647 TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
10648 llvm::SmallVector<Expr *, 16> Vars;
10649 Vars.reserve(C->varlist_size());
10650 for (auto *VE : C->varlists()) {
10651 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10652 if (EVar.isInvalid())
10653 return nullptr;
10654 Vars.push_back(EVar.get());
10656 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10657 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
10660 template <typename Derived>
10661 OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
10662 OMPHasDeviceAddrClause *C) {
10663 llvm::SmallVector<Expr *, 16> Vars;
10664 Vars.reserve(C->varlist_size());
10665 for (auto *VE : C->varlists()) {
10666 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10667 if (EVar.isInvalid())
10668 return nullptr;
10669 Vars.push_back(EVar.get());
10671 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10672 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
10675 template <typename Derived>
10676 OMPClause *
10677 TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
10678 llvm::SmallVector<Expr *, 16> Vars;
10679 Vars.reserve(C->varlist_size());
10680 for (auto *VE : C->varlists()) {
10681 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10682 if (EVar.isInvalid())
10683 return nullptr;
10684 Vars.push_back(EVar.get());
10686 return getDerived().RebuildOMPNontemporalClause(
10687 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10690 template <typename Derived>
10691 OMPClause *
10692 TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
10693 llvm::SmallVector<Expr *, 16> Vars;
10694 Vars.reserve(C->varlist_size());
10695 for (auto *VE : C->varlists()) {
10696 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10697 if (EVar.isInvalid())
10698 return nullptr;
10699 Vars.push_back(EVar.get());
10701 return getDerived().RebuildOMPInclusiveClause(
10702 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10705 template <typename Derived>
10706 OMPClause *
10707 TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
10708 llvm::SmallVector<Expr *, 16> Vars;
10709 Vars.reserve(C->varlist_size());
10710 for (auto *VE : C->varlists()) {
10711 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10712 if (EVar.isInvalid())
10713 return nullptr;
10714 Vars.push_back(EVar.get());
10716 return getDerived().RebuildOMPExclusiveClause(
10717 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10720 template <typename Derived>
10721 OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
10722 OMPUsesAllocatorsClause *C) {
10723 SmallVector<Sema::UsesAllocatorsData, 16> Data;
10724 Data.reserve(C->getNumberOfAllocators());
10725 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
10726 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
10727 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
10728 if (Allocator.isInvalid())
10729 continue;
10730 ExprResult AllocatorTraits;
10731 if (Expr *AT = D.AllocatorTraits) {
10732 AllocatorTraits = getDerived().TransformExpr(AT);
10733 if (AllocatorTraits.isInvalid())
10734 continue;
10736 Sema::UsesAllocatorsData &NewD = Data.emplace_back();
10737 NewD.Allocator = Allocator.get();
10738 NewD.AllocatorTraits = AllocatorTraits.get();
10739 NewD.LParenLoc = D.LParenLoc;
10740 NewD.RParenLoc = D.RParenLoc;
10742 return getDerived().RebuildOMPUsesAllocatorsClause(
10743 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10746 template <typename Derived>
10747 OMPClause *
10748 TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
10749 SmallVector<Expr *, 4> Locators;
10750 Locators.reserve(C->varlist_size());
10751 ExprResult ModifierRes;
10752 if (Expr *Modifier = C->getModifier()) {
10753 ModifierRes = getDerived().TransformExpr(Modifier);
10754 if (ModifierRes.isInvalid())
10755 return nullptr;
10757 for (Expr *E : C->varlists()) {
10758 ExprResult Locator = getDerived().TransformExpr(E);
10759 if (Locator.isInvalid())
10760 continue;
10761 Locators.push_back(Locator.get());
10763 return getDerived().RebuildOMPAffinityClause(
10764 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
10765 ModifierRes.get(), Locators);
10768 template <typename Derived>
10769 OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
10770 return getDerived().RebuildOMPOrderClause(
10771 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
10772 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
10775 template <typename Derived>
10776 OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
10777 return getDerived().RebuildOMPBindClause(
10778 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
10779 C->getLParenLoc(), C->getEndLoc());
10782 template <typename Derived>
10783 OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
10784 OMPXDynCGroupMemClause *C) {
10785 ExprResult Size = getDerived().TransformExpr(C->getSize());
10786 if (Size.isInvalid())
10787 return nullptr;
10788 return getDerived().RebuildOMPXDynCGroupMemClause(
10789 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10792 template <typename Derived>
10793 OMPClause *
10794 TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
10795 llvm::SmallVector<Expr *, 16> Vars;
10796 Vars.reserve(C->varlist_size());
10797 for (auto *VE : C->varlists()) {
10798 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10799 if (EVar.isInvalid())
10800 return nullptr;
10801 Vars.push_back(EVar.get());
10803 return getDerived().RebuildOMPDoacrossClause(
10804 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
10805 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10808 template <typename Derived>
10809 OMPClause *
10810 TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
10811 SmallVector<const Attr *> NewAttrs;
10812 for (auto *A : C->getAttrs())
10813 NewAttrs.push_back(getDerived().TransformAttr(A));
10814 return getDerived().RebuildOMPXAttributeClause(
10815 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10818 template <typename Derived>
10819 OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
10820 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
10823 //===----------------------------------------------------------------------===//
10824 // Expression transformation
10825 //===----------------------------------------------------------------------===//
10826 template<typename Derived>
10827 ExprResult
10828 TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
10829 return TransformExpr(E->getSubExpr());
10832 template <typename Derived>
10833 ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
10834 SYCLUniqueStableNameExpr *E) {
10835 if (!E->isTypeDependent())
10836 return E;
10838 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
10840 if (!NewT)
10841 return ExprError();
10843 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
10844 return E;
10846 return getDerived().RebuildSYCLUniqueStableNameExpr(
10847 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
10850 template<typename Derived>
10851 ExprResult
10852 TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
10853 if (!E->isTypeDependent())
10854 return E;
10856 return getDerived().RebuildPredefinedExpr(E->getLocation(),
10857 E->getIdentKind());
10860 template<typename Derived>
10861 ExprResult
10862 TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
10863 NestedNameSpecifierLoc QualifierLoc;
10864 if (E->getQualifierLoc()) {
10865 QualifierLoc
10866 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
10867 if (!QualifierLoc)
10868 return ExprError();
10871 ValueDecl *ND
10872 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
10873 E->getDecl()));
10874 if (!ND)
10875 return ExprError();
10877 NamedDecl *Found = ND;
10878 if (E->getFoundDecl() != E->getDecl()) {
10879 Found = cast_or_null<NamedDecl>(
10880 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
10881 if (!Found)
10882 return ExprError();
10885 DeclarationNameInfo NameInfo = E->getNameInfo();
10886 if (NameInfo.getName()) {
10887 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10888 if (!NameInfo.getName())
10889 return ExprError();
10892 if (!getDerived().AlwaysRebuild() &&
10893 QualifierLoc == E->getQualifierLoc() &&
10894 ND == E->getDecl() &&
10895 Found == E->getFoundDecl() &&
10896 NameInfo.getName() == E->getDecl()->getDeclName() &&
10897 !E->hasExplicitTemplateArgs()) {
10899 // Mark it referenced in the new context regardless.
10900 // FIXME: this is a bit instantiation-specific.
10901 SemaRef.MarkDeclRefReferenced(E);
10903 return E;
10906 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
10907 if (E->hasExplicitTemplateArgs()) {
10908 TemplateArgs = &TransArgs;
10909 TransArgs.setLAngleLoc(E->getLAngleLoc());
10910 TransArgs.setRAngleLoc(E->getRAngleLoc());
10911 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
10912 E->getNumTemplateArgs(),
10913 TransArgs))
10914 return ExprError();
10917 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
10918 Found, TemplateArgs);
10921 template<typename Derived>
10922 ExprResult
10923 TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
10924 return E;
10927 template <typename Derived>
10928 ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
10929 FixedPointLiteral *E) {
10930 return E;
10933 template<typename Derived>
10934 ExprResult
10935 TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
10936 return E;
10939 template<typename Derived>
10940 ExprResult
10941 TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
10942 return E;
10945 template<typename Derived>
10946 ExprResult
10947 TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
10948 return E;
10951 template<typename Derived>
10952 ExprResult
10953 TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
10954 return E;
10957 template<typename Derived>
10958 ExprResult
10959 TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
10960 return getDerived().TransformCallExpr(E);
10963 template<typename Derived>
10964 ExprResult
10965 TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
10966 ExprResult ControllingExpr;
10967 TypeSourceInfo *ControllingType = nullptr;
10968 if (E->isExprPredicate())
10969 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
10970 else
10971 ControllingType = getDerived().TransformType(E->getControllingType());
10973 if (ControllingExpr.isInvalid() && !ControllingType)
10974 return ExprError();
10976 SmallVector<Expr *, 4> AssocExprs;
10977 SmallVector<TypeSourceInfo *, 4> AssocTypes;
10978 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
10979 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
10980 if (TSI) {
10981 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
10982 if (!AssocType)
10983 return ExprError();
10984 AssocTypes.push_back(AssocType);
10985 } else {
10986 AssocTypes.push_back(nullptr);
10989 ExprResult AssocExpr =
10990 getDerived().TransformExpr(Assoc.getAssociationExpr());
10991 if (AssocExpr.isInvalid())
10992 return ExprError();
10993 AssocExprs.push_back(AssocExpr.get());
10996 if (!ControllingType)
10997 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
10998 E->getDefaultLoc(),
10999 E->getRParenLoc(),
11000 ControllingExpr.get(),
11001 AssocTypes,
11002 AssocExprs);
11003 return getDerived().RebuildGenericSelectionExpr(
11004 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
11005 ControllingType, AssocTypes, AssocExprs);
11008 template<typename Derived>
11009 ExprResult
11010 TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
11011 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
11012 if (SubExpr.isInvalid())
11013 return ExprError();
11015 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11016 return E;
11018 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
11019 E->getRParen());
11022 /// The operand of a unary address-of operator has special rules: it's
11023 /// allowed to refer to a non-static member of a class even if there's no 'this'
11024 /// object available.
11025 template<typename Derived>
11026 ExprResult
11027 TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
11028 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
11029 return getDerived().TransformDependentScopeDeclRefExpr(DRE, true, nullptr);
11030 else
11031 return getDerived().TransformExpr(E);
11034 template<typename Derived>
11035 ExprResult
11036 TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
11037 ExprResult SubExpr;
11038 if (E->getOpcode() == UO_AddrOf)
11039 SubExpr = TransformAddressOfOperand(E->getSubExpr());
11040 else
11041 SubExpr = TransformExpr(E->getSubExpr());
11042 if (SubExpr.isInvalid())
11043 return ExprError();
11045 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11046 return E;
11048 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
11049 E->getOpcode(),
11050 SubExpr.get());
11053 template<typename Derived>
11054 ExprResult
11055 TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
11056 // Transform the type.
11057 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
11058 if (!Type)
11059 return ExprError();
11061 // Transform all of the components into components similar to what the
11062 // parser uses.
11063 // FIXME: It would be slightly more efficient in the non-dependent case to
11064 // just map FieldDecls, rather than requiring the rebuilder to look for
11065 // the fields again. However, __builtin_offsetof is rare enough in
11066 // template code that we don't care.
11067 bool ExprChanged = false;
11068 typedef Sema::OffsetOfComponent Component;
11069 SmallVector<Component, 4> Components;
11070 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
11071 const OffsetOfNode &ON = E->getComponent(I);
11072 Component Comp;
11073 Comp.isBrackets = true;
11074 Comp.LocStart = ON.getSourceRange().getBegin();
11075 Comp.LocEnd = ON.getSourceRange().getEnd();
11076 switch (ON.getKind()) {
11077 case OffsetOfNode::Array: {
11078 Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
11079 ExprResult Index = getDerived().TransformExpr(FromIndex);
11080 if (Index.isInvalid())
11081 return ExprError();
11083 ExprChanged = ExprChanged || Index.get() != FromIndex;
11084 Comp.isBrackets = true;
11085 Comp.U.E = Index.get();
11086 break;
11089 case OffsetOfNode::Field:
11090 case OffsetOfNode::Identifier:
11091 Comp.isBrackets = false;
11092 Comp.U.IdentInfo = ON.getFieldName();
11093 if (!Comp.U.IdentInfo)
11094 continue;
11096 break;
11098 case OffsetOfNode::Base:
11099 // Will be recomputed during the rebuild.
11100 continue;
11103 Components.push_back(Comp);
11106 // If nothing changed, retain the existing expression.
11107 if (!getDerived().AlwaysRebuild() &&
11108 Type == E->getTypeSourceInfo() &&
11109 !ExprChanged)
11110 return E;
11112 // Build a new offsetof expression.
11113 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
11114 Components, E->getRParenLoc());
11117 template<typename Derived>
11118 ExprResult
11119 TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
11120 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
11121 "opaque value expression requires transformation");
11122 return E;
11125 template<typename Derived>
11126 ExprResult
11127 TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
11128 return E;
11131 template <typename Derived>
11132 ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
11133 llvm::SmallVector<Expr *, 8> Children;
11134 bool Changed = false;
11135 for (Expr *C : E->subExpressions()) {
11136 ExprResult NewC = getDerived().TransformExpr(C);
11137 if (NewC.isInvalid())
11138 return ExprError();
11139 Children.push_back(NewC.get());
11141 Changed |= NewC.get() != C;
11143 if (!getDerived().AlwaysRebuild() && !Changed)
11144 return E;
11145 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
11146 Children, E->getType());
11149 template<typename Derived>
11150 ExprResult
11151 TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
11152 // Rebuild the syntactic form. The original syntactic form has
11153 // opaque-value expressions in it, so strip those away and rebuild
11154 // the result. This is a really awful way of doing this, but the
11155 // better solution (rebuilding the semantic expressions and
11156 // rebinding OVEs as necessary) doesn't work; we'd need
11157 // TreeTransform to not strip away implicit conversions.
11158 Expr *newSyntacticForm = SemaRef.recreateSyntacticForm(E);
11159 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
11160 if (result.isInvalid()) return ExprError();
11162 // If that gives us a pseudo-object result back, the pseudo-object
11163 // expression must have been an lvalue-to-rvalue conversion which we
11164 // should reapply.
11165 if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
11166 result = SemaRef.checkPseudoObjectRValue(result.get());
11168 return result;
11171 template<typename Derived>
11172 ExprResult
11173 TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
11174 UnaryExprOrTypeTraitExpr *E) {
11175 if (E->isArgumentType()) {
11176 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
11178 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
11179 if (!NewT)
11180 return ExprError();
11182 if (!getDerived().AlwaysRebuild() && OldT == NewT)
11183 return E;
11185 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
11186 E->getKind(),
11187 E->getSourceRange());
11190 // C++0x [expr.sizeof]p1:
11191 // The operand is either an expression, which is an unevaluated operand
11192 // [...]
11193 EnterExpressionEvaluationContext Unevaluated(
11194 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
11195 Sema::ReuseLambdaContextDecl);
11197 // Try to recover if we have something like sizeof(T::X) where X is a type.
11198 // Notably, there must be *exactly* one set of parens if X is a type.
11199 TypeSourceInfo *RecoveryTSI = nullptr;
11200 ExprResult SubExpr;
11201 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
11202 if (auto *DRE =
11203 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
11204 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
11205 PE, DRE, false, &RecoveryTSI);
11206 else
11207 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
11209 if (RecoveryTSI) {
11210 return getDerived().RebuildUnaryExprOrTypeTrait(
11211 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
11212 } else if (SubExpr.isInvalid())
11213 return ExprError();
11215 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
11216 return E;
11218 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
11219 E->getOperatorLoc(),
11220 E->getKind(),
11221 E->getSourceRange());
11224 template<typename Derived>
11225 ExprResult
11226 TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
11227 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11228 if (LHS.isInvalid())
11229 return ExprError();
11231 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11232 if (RHS.isInvalid())
11233 return ExprError();
11236 if (!getDerived().AlwaysRebuild() &&
11237 LHS.get() == E->getLHS() &&
11238 RHS.get() == E->getRHS())
11239 return E;
11241 return getDerived().RebuildArraySubscriptExpr(
11242 LHS.get(),
11243 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
11246 template <typename Derived>
11247 ExprResult
11248 TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
11249 ExprResult Base = getDerived().TransformExpr(E->getBase());
11250 if (Base.isInvalid())
11251 return ExprError();
11253 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
11254 if (RowIdx.isInvalid())
11255 return ExprError();
11257 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
11258 if (ColumnIdx.isInvalid())
11259 return ExprError();
11261 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
11262 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
11263 return E;
11265 return getDerived().RebuildMatrixSubscriptExpr(
11266 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
11269 template <typename Derived>
11270 ExprResult
11271 TreeTransform<Derived>::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) {
11272 ExprResult Base = getDerived().TransformExpr(E->getBase());
11273 if (Base.isInvalid())
11274 return ExprError();
11276 ExprResult LowerBound;
11277 if (E->getLowerBound()) {
11278 LowerBound = getDerived().TransformExpr(E->getLowerBound());
11279 if (LowerBound.isInvalid())
11280 return ExprError();
11283 ExprResult Length;
11284 if (E->getLength()) {
11285 Length = getDerived().TransformExpr(E->getLength());
11286 if (Length.isInvalid())
11287 return ExprError();
11290 ExprResult Stride;
11291 if (Expr *Str = E->getStride()) {
11292 Stride = getDerived().TransformExpr(Str);
11293 if (Stride.isInvalid())
11294 return ExprError();
11297 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
11298 LowerBound.get() == E->getLowerBound() && Length.get() == E->getLength())
11299 return E;
11301 return getDerived().RebuildOMPArraySectionExpr(
11302 Base.get(), E->getBase()->getEndLoc(), LowerBound.get(),
11303 E->getColonLocFirst(), E->getColonLocSecond(), Length.get(), Stride.get(),
11304 E->getRBracketLoc());
11307 template <typename Derived>
11308 ExprResult
11309 TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
11310 ExprResult Base = getDerived().TransformExpr(E->getBase());
11311 if (Base.isInvalid())
11312 return ExprError();
11314 SmallVector<Expr *, 4> Dims;
11315 bool ErrorFound = false;
11316 for (Expr *Dim : E->getDimensions()) {
11317 ExprResult DimRes = getDerived().TransformExpr(Dim);
11318 if (DimRes.isInvalid()) {
11319 ErrorFound = true;
11320 continue;
11322 Dims.push_back(DimRes.get());
11325 if (ErrorFound)
11326 return ExprError();
11327 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
11328 E->getRParenLoc(), Dims,
11329 E->getBracketsRanges());
11332 template <typename Derived>
11333 ExprResult
11334 TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
11335 unsigned NumIterators = E->numOfIterators();
11336 SmallVector<Sema::OMPIteratorData, 4> Data(NumIterators);
11338 bool ErrorFound = false;
11339 bool NeedToRebuild = getDerived().AlwaysRebuild();
11340 for (unsigned I = 0; I < NumIterators; ++I) {
11341 auto *D = cast<VarDecl>(E->getIteratorDecl(I));
11342 Data[I].DeclIdent = D->getIdentifier();
11343 Data[I].DeclIdentLoc = D->getLocation();
11344 if (D->getLocation() == D->getBeginLoc()) {
11345 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
11346 "Implicit type must be int.");
11347 } else {
11348 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
11349 QualType DeclTy = getDerived().TransformType(D->getType());
11350 Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI);
11352 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
11353 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
11354 ExprResult End = getDerived().TransformExpr(Range.End);
11355 ExprResult Step = getDerived().TransformExpr(Range.Step);
11356 ErrorFound = ErrorFound ||
11357 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
11358 !Data[I].Type.get().isNull())) ||
11359 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
11360 if (ErrorFound)
11361 continue;
11362 Data[I].Range.Begin = Begin.get();
11363 Data[I].Range.End = End.get();
11364 Data[I].Range.Step = Step.get();
11365 Data[I].AssignLoc = E->getAssignLoc(I);
11366 Data[I].ColonLoc = E->getColonLoc(I);
11367 Data[I].SecColonLoc = E->getSecondColonLoc(I);
11368 NeedToRebuild =
11369 NeedToRebuild ||
11370 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
11371 D->getType().getTypePtrOrNull()) ||
11372 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
11373 Range.Step != Data[I].Range.Step;
11375 if (ErrorFound)
11376 return ExprError();
11377 if (!NeedToRebuild)
11378 return E;
11380 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
11381 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
11382 if (!Res.isUsable())
11383 return Res;
11384 auto *IE = cast<OMPIteratorExpr>(Res.get());
11385 for (unsigned I = 0; I < NumIterators; ++I)
11386 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
11387 IE->getIteratorDecl(I));
11388 return Res;
11391 template<typename Derived>
11392 ExprResult
11393 TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
11394 // Transform the callee.
11395 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
11396 if (Callee.isInvalid())
11397 return ExprError();
11399 // Transform arguments.
11400 bool ArgChanged = false;
11401 SmallVector<Expr*, 8> Args;
11402 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
11403 &ArgChanged))
11404 return ExprError();
11406 if (!getDerived().AlwaysRebuild() &&
11407 Callee.get() == E->getCallee() &&
11408 !ArgChanged)
11409 return SemaRef.MaybeBindToTemporary(E);
11411 // FIXME: Wrong source location information for the '('.
11412 SourceLocation FakeLParenLoc
11413 = ((Expr *)Callee.get())->getSourceRange().getBegin();
11415 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11416 if (E->hasStoredFPFeatures()) {
11417 FPOptionsOverride NewOverrides = E->getFPFeatures();
11418 getSema().CurFPFeatures =
11419 NewOverrides.applyOverrides(getSema().getLangOpts());
11420 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11423 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
11424 Args,
11425 E->getRParenLoc());
11428 template<typename Derived>
11429 ExprResult
11430 TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
11431 ExprResult Base = getDerived().TransformExpr(E->getBase());
11432 if (Base.isInvalid())
11433 return ExprError();
11435 NestedNameSpecifierLoc QualifierLoc;
11436 if (E->hasQualifier()) {
11437 QualifierLoc
11438 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
11440 if (!QualifierLoc)
11441 return ExprError();
11443 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
11445 ValueDecl *Member
11446 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
11447 E->getMemberDecl()));
11448 if (!Member)
11449 return ExprError();
11451 NamedDecl *FoundDecl = E->getFoundDecl();
11452 if (FoundDecl == E->getMemberDecl()) {
11453 FoundDecl = Member;
11454 } else {
11455 FoundDecl = cast_or_null<NamedDecl>(
11456 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
11457 if (!FoundDecl)
11458 return ExprError();
11461 if (!getDerived().AlwaysRebuild() &&
11462 Base.get() == E->getBase() &&
11463 QualifierLoc == E->getQualifierLoc() &&
11464 Member == E->getMemberDecl() &&
11465 FoundDecl == E->getFoundDecl() &&
11466 !E->hasExplicitTemplateArgs()) {
11468 // Skip for member expression of (this->f), rebuilt thisi->f is needed
11469 // for Openmp where the field need to be privatizized in the case.
11470 if (!(isa<CXXThisExpr>(E->getBase()) &&
11471 getSema().isOpenMPRebuildMemberExpr(cast<ValueDecl>(Member)))) {
11472 // Mark it referenced in the new context regardless.
11473 // FIXME: this is a bit instantiation-specific.
11474 SemaRef.MarkMemberReferenced(E);
11475 return E;
11479 TemplateArgumentListInfo TransArgs;
11480 if (E->hasExplicitTemplateArgs()) {
11481 TransArgs.setLAngleLoc(E->getLAngleLoc());
11482 TransArgs.setRAngleLoc(E->getRAngleLoc());
11483 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
11484 E->getNumTemplateArgs(),
11485 TransArgs))
11486 return ExprError();
11489 // FIXME: Bogus source location for the operator
11490 SourceLocation FakeOperatorLoc =
11491 SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
11493 // FIXME: to do this check properly, we will need to preserve the
11494 // first-qualifier-in-scope here, just in case we had a dependent
11495 // base (and therefore couldn't do the check) and a
11496 // nested-name-qualifier (and therefore could do the lookup).
11497 NamedDecl *FirstQualifierInScope = nullptr;
11498 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
11499 if (MemberNameInfo.getName()) {
11500 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
11501 if (!MemberNameInfo.getName())
11502 return ExprError();
11505 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
11506 E->isArrow(),
11507 QualifierLoc,
11508 TemplateKWLoc,
11509 MemberNameInfo,
11510 Member,
11511 FoundDecl,
11512 (E->hasExplicitTemplateArgs()
11513 ? &TransArgs : nullptr),
11514 FirstQualifierInScope);
11517 template<typename Derived>
11518 ExprResult
11519 TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
11520 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11521 if (LHS.isInvalid())
11522 return ExprError();
11524 ExprResult RHS =
11525 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
11526 if (RHS.isInvalid())
11527 return ExprError();
11529 if (!getDerived().AlwaysRebuild() &&
11530 LHS.get() == E->getLHS() &&
11531 RHS.get() == E->getRHS())
11532 return E;
11534 if (E->isCompoundAssignmentOp())
11535 // FPFeatures has already been established from trailing storage
11536 return getDerived().RebuildBinaryOperator(
11537 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
11538 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11539 FPOptionsOverride NewOverrides(E->getFPFeatures());
11540 getSema().CurFPFeatures =
11541 NewOverrides.applyOverrides(getSema().getLangOpts());
11542 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11543 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
11544 LHS.get(), RHS.get());
11547 template <typename Derived>
11548 ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
11549 CXXRewrittenBinaryOperator *E) {
11550 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
11552 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
11553 if (LHS.isInvalid())
11554 return ExprError();
11556 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
11557 if (RHS.isInvalid())
11558 return ExprError();
11560 // Extract the already-resolved callee declarations so that we can restrict
11561 // ourselves to using them as the unqualified lookup results when rebuilding.
11562 UnresolvedSet<2> UnqualLookups;
11563 bool ChangedAnyLookups = false;
11564 Expr *PossibleBinOps[] = {E->getSemanticForm(),
11565 const_cast<Expr *>(Decomp.InnerBinOp)};
11566 for (Expr *PossibleBinOp : PossibleBinOps) {
11567 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());
11568 if (!Op)
11569 continue;
11570 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());
11571 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))
11572 continue;
11574 // Transform the callee in case we built a call to a local extern
11575 // declaration.
11576 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
11577 E->getOperatorLoc(), Callee->getFoundDecl()));
11578 if (!Found)
11579 return ExprError();
11580 if (Found != Callee->getFoundDecl())
11581 ChangedAnyLookups = true;
11582 UnqualLookups.addDecl(Found);
11585 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
11586 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
11587 // Mark all functions used in the rewrite as referenced. Note that when
11588 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
11589 // function calls, and/or there might be a user-defined conversion sequence
11590 // applied to the operands of the <.
11591 // FIXME: this is a bit instantiation-specific.
11592 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
11593 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);
11594 return E;
11597 return getDerived().RebuildCXXRewrittenBinaryOperator(
11598 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
11601 template<typename Derived>
11602 ExprResult
11603 TreeTransform<Derived>::TransformCompoundAssignOperator(
11604 CompoundAssignOperator *E) {
11605 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11606 FPOptionsOverride NewOverrides(E->getFPFeatures());
11607 getSema().CurFPFeatures =
11608 NewOverrides.applyOverrides(getSema().getLangOpts());
11609 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11610 return getDerived().TransformBinaryOperator(E);
11613 template<typename Derived>
11614 ExprResult TreeTransform<Derived>::
11615 TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
11616 // Just rebuild the common and RHS expressions and see whether we
11617 // get any changes.
11619 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
11620 if (commonExpr.isInvalid())
11621 return ExprError();
11623 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
11624 if (rhs.isInvalid())
11625 return ExprError();
11627 if (!getDerived().AlwaysRebuild() &&
11628 commonExpr.get() == e->getCommon() &&
11629 rhs.get() == e->getFalseExpr())
11630 return e;
11632 return getDerived().RebuildConditionalOperator(commonExpr.get(),
11633 e->getQuestionLoc(),
11634 nullptr,
11635 e->getColonLoc(),
11636 rhs.get());
11639 template<typename Derived>
11640 ExprResult
11641 TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
11642 ExprResult Cond = getDerived().TransformExpr(E->getCond());
11643 if (Cond.isInvalid())
11644 return ExprError();
11646 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11647 if (LHS.isInvalid())
11648 return ExprError();
11650 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11651 if (RHS.isInvalid())
11652 return ExprError();
11654 if (!getDerived().AlwaysRebuild() &&
11655 Cond.get() == E->getCond() &&
11656 LHS.get() == E->getLHS() &&
11657 RHS.get() == E->getRHS())
11658 return E;
11660 return getDerived().RebuildConditionalOperator(Cond.get(),
11661 E->getQuestionLoc(),
11662 LHS.get(),
11663 E->getColonLoc(),
11664 RHS.get());
11667 template<typename Derived>
11668 ExprResult
11669 TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
11670 // Implicit casts are eliminated during transformation, since they
11671 // will be recomputed by semantic analysis after transformation.
11672 return getDerived().TransformExpr(E->getSubExprAsWritten());
11675 template<typename Derived>
11676 ExprResult
11677 TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
11678 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
11679 if (!Type)
11680 return ExprError();
11682 ExprResult SubExpr
11683 = getDerived().TransformExpr(E->getSubExprAsWritten());
11684 if (SubExpr.isInvalid())
11685 return ExprError();
11687 if (!getDerived().AlwaysRebuild() &&
11688 Type == E->getTypeInfoAsWritten() &&
11689 SubExpr.get() == E->getSubExpr())
11690 return E;
11692 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
11693 Type,
11694 E->getRParenLoc(),
11695 SubExpr.get());
11698 template<typename Derived>
11699 ExprResult
11700 TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
11701 TypeSourceInfo *OldT = E->getTypeSourceInfo();
11702 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
11703 if (!NewT)
11704 return ExprError();
11706 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
11707 if (Init.isInvalid())
11708 return ExprError();
11710 if (!getDerived().AlwaysRebuild() &&
11711 OldT == NewT &&
11712 Init.get() == E->getInitializer())
11713 return SemaRef.MaybeBindToTemporary(E);
11715 // Note: the expression type doesn't necessarily match the
11716 // type-as-written, but that's okay, because it should always be
11717 // derivable from the initializer.
11719 return getDerived().RebuildCompoundLiteralExpr(
11720 E->getLParenLoc(), NewT,
11721 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
11724 template<typename Derived>
11725 ExprResult
11726 TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
11727 ExprResult Base = getDerived().TransformExpr(E->getBase());
11728 if (Base.isInvalid())
11729 return ExprError();
11731 if (!getDerived().AlwaysRebuild() &&
11732 Base.get() == E->getBase())
11733 return E;
11735 // FIXME: Bad source location
11736 SourceLocation FakeOperatorLoc =
11737 SemaRef.getLocForEndOfToken(E->getBase()->getEndLoc());
11738 return getDerived().RebuildExtVectorElementExpr(
11739 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
11740 E->getAccessor());
11743 template<typename Derived>
11744 ExprResult
11745 TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
11746 if (InitListExpr *Syntactic = E->getSyntacticForm())
11747 E = Syntactic;
11749 bool InitChanged = false;
11751 EnterExpressionEvaluationContext Context(
11752 getSema(), EnterExpressionEvaluationContext::InitList);
11754 SmallVector<Expr*, 4> Inits;
11755 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
11756 Inits, &InitChanged))
11757 return ExprError();
11759 if (!getDerived().AlwaysRebuild() && !InitChanged) {
11760 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
11761 // in some cases. We can't reuse it in general, because the syntactic and
11762 // semantic forms are linked, and we can't know that semantic form will
11763 // match even if the syntactic form does.
11766 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
11767 E->getRBraceLoc());
11770 template<typename Derived>
11771 ExprResult
11772 TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
11773 Designation Desig;
11775 // transform the initializer value
11776 ExprResult Init = getDerived().TransformExpr(E->getInit());
11777 if (Init.isInvalid())
11778 return ExprError();
11780 // transform the designators.
11781 SmallVector<Expr*, 4> ArrayExprs;
11782 bool ExprChanged = false;
11783 for (const DesignatedInitExpr::Designator &D : E->designators()) {
11784 if (D.isFieldDesignator()) {
11785 if (D.getFieldDecl()) {
11786 FieldDecl *Field = cast_or_null<FieldDecl>(
11787 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
11788 if (Field != D.getFieldDecl())
11789 // Rebuild the expression when the transformed FieldDecl is
11790 // different to the already assigned FieldDecl.
11791 ExprChanged = true;
11792 if (Field->isAnonymousStructOrUnion())
11793 continue;
11794 } else {
11795 // Ensure that the designator expression is rebuilt when there isn't
11796 // a resolved FieldDecl in the designator as we don't want to assign
11797 // a FieldDecl to a pattern designator that will be instantiated again.
11798 ExprChanged = true;
11800 Desig.AddDesignator(Designator::CreateFieldDesignator(
11801 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
11802 continue;
11805 if (D.isArrayDesignator()) {
11806 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
11807 if (Index.isInvalid())
11808 return ExprError();
11810 Desig.AddDesignator(
11811 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
11813 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
11814 ArrayExprs.push_back(Index.get());
11815 continue;
11818 assert(D.isArrayRangeDesignator() && "New kind of designator?");
11819 ExprResult Start
11820 = getDerived().TransformExpr(E->getArrayRangeStart(D));
11821 if (Start.isInvalid())
11822 return ExprError();
11824 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
11825 if (End.isInvalid())
11826 return ExprError();
11828 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
11829 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
11831 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
11832 End.get() != E->getArrayRangeEnd(D);
11834 ArrayExprs.push_back(Start.get());
11835 ArrayExprs.push_back(End.get());
11838 if (!getDerived().AlwaysRebuild() &&
11839 Init.get() == E->getInit() &&
11840 !ExprChanged)
11841 return E;
11843 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
11844 E->getEqualOrColonLoc(),
11845 E->usesGNUSyntax(), Init.get());
11848 // Seems that if TransformInitListExpr() only works on the syntactic form of an
11849 // InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
11850 template<typename Derived>
11851 ExprResult
11852 TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
11853 DesignatedInitUpdateExpr *E) {
11854 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
11855 "initializer");
11856 return ExprError();
11859 template<typename Derived>
11860 ExprResult
11861 TreeTransform<Derived>::TransformNoInitExpr(
11862 NoInitExpr *E) {
11863 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
11864 return ExprError();
11867 template<typename Derived>
11868 ExprResult
11869 TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
11870 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
11871 return ExprError();
11874 template<typename Derived>
11875 ExprResult
11876 TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
11877 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
11878 return ExprError();
11881 template<typename Derived>
11882 ExprResult
11883 TreeTransform<Derived>::TransformImplicitValueInitExpr(
11884 ImplicitValueInitExpr *E) {
11885 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
11887 // FIXME: Will we ever have proper type location here? Will we actually
11888 // need to transform the type?
11889 QualType T = getDerived().TransformType(E->getType());
11890 if (T.isNull())
11891 return ExprError();
11893 if (!getDerived().AlwaysRebuild() &&
11894 T == E->getType())
11895 return E;
11897 return getDerived().RebuildImplicitValueInitExpr(T);
11900 template<typename Derived>
11901 ExprResult
11902 TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
11903 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
11904 if (!TInfo)
11905 return ExprError();
11907 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
11908 if (SubExpr.isInvalid())
11909 return ExprError();
11911 if (!getDerived().AlwaysRebuild() &&
11912 TInfo == E->getWrittenTypeInfo() &&
11913 SubExpr.get() == E->getSubExpr())
11914 return E;
11916 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
11917 TInfo, E->getRParenLoc());
11920 template<typename Derived>
11921 ExprResult
11922 TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
11923 bool ArgumentChanged = false;
11924 SmallVector<Expr*, 4> Inits;
11925 if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits,
11926 &ArgumentChanged))
11927 return ExprError();
11929 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
11930 Inits,
11931 E->getRParenLoc());
11934 /// Transform an address-of-label expression.
11936 /// By default, the transformation of an address-of-label expression always
11937 /// rebuilds the expression, so that the label identifier can be resolved to
11938 /// the corresponding label statement by semantic analysis.
11939 template<typename Derived>
11940 ExprResult
11941 TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
11942 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
11943 E->getLabel());
11944 if (!LD)
11945 return ExprError();
11947 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
11948 cast<LabelDecl>(LD));
11951 template<typename Derived>
11952 ExprResult
11953 TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
11954 SemaRef.ActOnStartStmtExpr();
11955 StmtResult SubStmt
11956 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
11957 if (SubStmt.isInvalid()) {
11958 SemaRef.ActOnStmtExprError();
11959 return ExprError();
11962 unsigned OldDepth = E->getTemplateDepth();
11963 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
11965 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
11966 SubStmt.get() == E->getSubStmt()) {
11967 // Calling this an 'error' is unintuitive, but it does the right thing.
11968 SemaRef.ActOnStmtExprError();
11969 return SemaRef.MaybeBindToTemporary(E);
11972 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
11973 E->getRParenLoc(), NewDepth);
11976 template<typename Derived>
11977 ExprResult
11978 TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
11979 ExprResult Cond = getDerived().TransformExpr(E->getCond());
11980 if (Cond.isInvalid())
11981 return ExprError();
11983 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11984 if (LHS.isInvalid())
11985 return ExprError();
11987 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11988 if (RHS.isInvalid())
11989 return ExprError();
11991 if (!getDerived().AlwaysRebuild() &&
11992 Cond.get() == E->getCond() &&
11993 LHS.get() == E->getLHS() &&
11994 RHS.get() == E->getRHS())
11995 return E;
11997 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
11998 Cond.get(), LHS.get(), RHS.get(),
11999 E->getRParenLoc());
12002 template<typename Derived>
12003 ExprResult
12004 TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
12005 return E;
12008 template<typename Derived>
12009 ExprResult
12010 TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
12011 switch (E->getOperator()) {
12012 case OO_New:
12013 case OO_Delete:
12014 case OO_Array_New:
12015 case OO_Array_Delete:
12016 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
12018 case OO_Subscript:
12019 case OO_Call: {
12020 // This is a call to an object's operator().
12021 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
12023 // Transform the object itself.
12024 ExprResult Object = getDerived().TransformExpr(E->getArg(0));
12025 if (Object.isInvalid())
12026 return ExprError();
12028 // FIXME: Poor location information
12029 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
12030 static_cast<Expr *>(Object.get())->getEndLoc());
12032 // Transform the call arguments.
12033 SmallVector<Expr*, 8> Args;
12034 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
12035 Args))
12036 return ExprError();
12038 if (E->getOperator() == OO_Subscript)
12039 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
12040 Args, E->getEndLoc());
12042 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
12043 E->getEndLoc());
12046 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
12047 case OO_##Name: \
12048 break;
12050 #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
12051 #include "clang/Basic/OperatorKinds.def"
12053 case OO_Conditional:
12054 llvm_unreachable("conditional operator is not actually overloadable");
12056 case OO_None:
12057 case NUM_OVERLOADED_OPERATORS:
12058 llvm_unreachable("not an overloaded operator?");
12061 ExprResult First;
12062 if (E->getOperator() == OO_Amp)
12063 First = getDerived().TransformAddressOfOperand(E->getArg(0));
12064 else
12065 First = getDerived().TransformExpr(E->getArg(0));
12066 if (First.isInvalid())
12067 return ExprError();
12069 ExprResult Second;
12070 if (E->getNumArgs() == 2) {
12071 Second =
12072 getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);
12073 if (Second.isInvalid())
12074 return ExprError();
12077 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12078 FPOptionsOverride NewOverrides(E->getFPFeatures());
12079 getSema().CurFPFeatures =
12080 NewOverrides.applyOverrides(getSema().getLangOpts());
12081 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12083 Expr *Callee = E->getCallee();
12084 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
12085 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
12086 Sema::LookupOrdinaryName);
12087 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
12088 return ExprError();
12090 return getDerived().RebuildCXXOperatorCallExpr(
12091 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
12092 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
12095 UnresolvedSet<1> Functions;
12096 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
12097 Callee = ICE->getSubExprAsWritten();
12098 NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();
12099 ValueDecl *VD = cast_or_null<ValueDecl>(
12100 getDerived().TransformDecl(DR->getLocation(), DR));
12101 if (!VD)
12102 return ExprError();
12104 if (!isa<CXXMethodDecl>(VD))
12105 Functions.addDecl(VD);
12107 return getDerived().RebuildCXXOperatorCallExpr(
12108 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
12109 /*RequiresADL=*/false, Functions, First.get(), Second.get());
12112 template<typename Derived>
12113 ExprResult
12114 TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
12115 return getDerived().TransformCallExpr(E);
12118 template <typename Derived>
12119 ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
12120 bool NeedRebuildFunc = E->getIdentKind() == SourceLocIdentKind::Function &&
12121 getSema().CurContext != E->getParentContext();
12123 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
12124 return E;
12126 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
12127 E->getBeginLoc(), E->getEndLoc(),
12128 getSema().CurContext);
12131 template<typename Derived>
12132 ExprResult
12133 TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
12134 // Transform the callee.
12135 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
12136 if (Callee.isInvalid())
12137 return ExprError();
12139 // Transform exec config.
12140 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
12141 if (EC.isInvalid())
12142 return ExprError();
12144 // Transform arguments.
12145 bool ArgChanged = false;
12146 SmallVector<Expr*, 8> Args;
12147 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
12148 &ArgChanged))
12149 return ExprError();
12151 if (!getDerived().AlwaysRebuild() &&
12152 Callee.get() == E->getCallee() &&
12153 !ArgChanged)
12154 return SemaRef.MaybeBindToTemporary(E);
12156 // FIXME: Wrong source location information for the '('.
12157 SourceLocation FakeLParenLoc
12158 = ((Expr *)Callee.get())->getSourceRange().getBegin();
12159 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
12160 Args,
12161 E->getRParenLoc(), EC.get());
12164 template<typename Derived>
12165 ExprResult
12166 TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
12167 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
12168 if (!Type)
12169 return ExprError();
12171 ExprResult SubExpr
12172 = getDerived().TransformExpr(E->getSubExprAsWritten());
12173 if (SubExpr.isInvalid())
12174 return ExprError();
12176 if (!getDerived().AlwaysRebuild() &&
12177 Type == E->getTypeInfoAsWritten() &&
12178 SubExpr.get() == E->getSubExpr())
12179 return E;
12180 return getDerived().RebuildCXXNamedCastExpr(
12181 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
12182 Type, E->getAngleBrackets().getEnd(),
12183 // FIXME. this should be '(' location
12184 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
12187 template<typename Derived>
12188 ExprResult
12189 TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
12190 TypeSourceInfo *TSI =
12191 getDerived().TransformType(BCE->getTypeInfoAsWritten());
12192 if (!TSI)
12193 return ExprError();
12195 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
12196 if (Sub.isInvalid())
12197 return ExprError();
12199 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
12200 Sub.get(), BCE->getEndLoc());
12203 template<typename Derived>
12204 ExprResult
12205 TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
12206 return getDerived().TransformCXXNamedCastExpr(E);
12209 template<typename Derived>
12210 ExprResult
12211 TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
12212 return getDerived().TransformCXXNamedCastExpr(E);
12215 template<typename Derived>
12216 ExprResult
12217 TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
12218 CXXReinterpretCastExpr *E) {
12219 return getDerived().TransformCXXNamedCastExpr(E);
12222 template<typename Derived>
12223 ExprResult
12224 TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
12225 return getDerived().TransformCXXNamedCastExpr(E);
12228 template<typename Derived>
12229 ExprResult
12230 TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
12231 return getDerived().TransformCXXNamedCastExpr(E);
12234 template<typename Derived>
12235 ExprResult
12236 TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
12237 CXXFunctionalCastExpr *E) {
12238 TypeSourceInfo *Type =
12239 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
12240 if (!Type)
12241 return ExprError();
12243 ExprResult SubExpr
12244 = getDerived().TransformExpr(E->getSubExprAsWritten());
12245 if (SubExpr.isInvalid())
12246 return ExprError();
12248 if (!getDerived().AlwaysRebuild() &&
12249 Type == E->getTypeInfoAsWritten() &&
12250 SubExpr.get() == E->getSubExpr())
12251 return E;
12253 return getDerived().RebuildCXXFunctionalCastExpr(Type,
12254 E->getLParenLoc(),
12255 SubExpr.get(),
12256 E->getRParenLoc(),
12257 E->isListInitialization());
12260 template<typename Derived>
12261 ExprResult
12262 TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
12263 if (E->isTypeOperand()) {
12264 TypeSourceInfo *TInfo
12265 = getDerived().TransformType(E->getTypeOperandSourceInfo());
12266 if (!TInfo)
12267 return ExprError();
12269 if (!getDerived().AlwaysRebuild() &&
12270 TInfo == E->getTypeOperandSourceInfo())
12271 return E;
12273 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
12274 TInfo, E->getEndLoc());
12277 // Typeid's operand is an unevaluated context, unless it's a polymorphic
12278 // type. We must not unilaterally enter unevaluated context here, as then
12279 // semantic processing can re-transform an already transformed operand.
12280 Expr *Op = E->getExprOperand();
12281 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
12282 if (E->isGLValue())
12283 if (auto *RecordT = Op->getType()->getAs<RecordType>())
12284 if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
12285 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
12287 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
12288 Sema::ReuseLambdaContextDecl);
12290 ExprResult SubExpr = getDerived().TransformExpr(Op);
12291 if (SubExpr.isInvalid())
12292 return ExprError();
12294 if (!getDerived().AlwaysRebuild() &&
12295 SubExpr.get() == E->getExprOperand())
12296 return E;
12298 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
12299 SubExpr.get(), E->getEndLoc());
12302 template<typename Derived>
12303 ExprResult
12304 TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
12305 if (E->isTypeOperand()) {
12306 TypeSourceInfo *TInfo
12307 = getDerived().TransformType(E->getTypeOperandSourceInfo());
12308 if (!TInfo)
12309 return ExprError();
12311 if (!getDerived().AlwaysRebuild() &&
12312 TInfo == E->getTypeOperandSourceInfo())
12313 return E;
12315 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
12316 TInfo, E->getEndLoc());
12319 EnterExpressionEvaluationContext Unevaluated(
12320 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
12322 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
12323 if (SubExpr.isInvalid())
12324 return ExprError();
12326 if (!getDerived().AlwaysRebuild() &&
12327 SubExpr.get() == E->getExprOperand())
12328 return E;
12330 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
12331 SubExpr.get(), E->getEndLoc());
12334 template<typename Derived>
12335 ExprResult
12336 TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
12337 return E;
12340 template<typename Derived>
12341 ExprResult
12342 TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
12343 CXXNullPtrLiteralExpr *E) {
12344 return E;
12347 template<typename Derived>
12348 ExprResult
12349 TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
12351 // In lambdas, the qualifiers of the type depends of where in
12352 // the call operator `this` appear, and we do not have a good way to
12353 // rebuild this information, so we transform the type.
12355 // In other contexts, the type of `this` may be overrided
12356 // for type deduction, so we need to recompute it.
12357 QualType T = getSema().getCurLambda() ?
12358 getDerived().TransformType(E->getType())
12359 : getSema().getCurrentThisType();
12361 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
12362 // Mark it referenced in the new context regardless.
12363 // FIXME: this is a bit instantiation-specific.
12364 getSema().MarkThisReferenced(E);
12365 return E;
12368 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
12371 template<typename Derived>
12372 ExprResult
12373 TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
12374 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12375 if (SubExpr.isInvalid())
12376 return ExprError();
12378 if (!getDerived().AlwaysRebuild() &&
12379 SubExpr.get() == E->getSubExpr())
12380 return E;
12382 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
12383 E->isThrownVariableInScope());
12386 template<typename Derived>
12387 ExprResult
12388 TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
12389 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
12390 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
12391 if (!Param)
12392 return ExprError();
12394 ExprResult InitRes;
12395 if (E->hasRewrittenInit()) {
12396 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
12397 if (InitRes.isInvalid())
12398 return ExprError();
12401 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
12402 E->getUsedContext() == SemaRef.CurContext &&
12403 InitRes.get() == E->getRewrittenExpr())
12404 return E;
12406 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
12407 InitRes.get());
12410 template<typename Derived>
12411 ExprResult
12412 TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
12413 FieldDecl *Field = cast_or_null<FieldDecl>(
12414 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
12415 if (!Field)
12416 return ExprError();
12418 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
12419 E->getUsedContext() == SemaRef.CurContext)
12420 return E;
12422 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
12425 template<typename Derived>
12426 ExprResult
12427 TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
12428 CXXScalarValueInitExpr *E) {
12429 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
12430 if (!T)
12431 return ExprError();
12433 if (!getDerived().AlwaysRebuild() &&
12434 T == E->getTypeSourceInfo())
12435 return E;
12437 return getDerived().RebuildCXXScalarValueInitExpr(T,
12438 /*FIXME:*/T->getTypeLoc().getEndLoc(),
12439 E->getRParenLoc());
12442 template<typename Derived>
12443 ExprResult
12444 TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
12445 // Transform the type that we're allocating
12446 TypeSourceInfo *AllocTypeInfo =
12447 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
12448 if (!AllocTypeInfo)
12449 return ExprError();
12451 // Transform the size of the array we're allocating (if any).
12452 std::optional<Expr *> ArraySize;
12453 if (E->isArray()) {
12454 ExprResult NewArraySize;
12455 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
12456 NewArraySize = getDerived().TransformExpr(*OldArraySize);
12457 if (NewArraySize.isInvalid())
12458 return ExprError();
12460 ArraySize = NewArraySize.get();
12463 // Transform the placement arguments (if any).
12464 bool ArgumentChanged = false;
12465 SmallVector<Expr*, 8> PlacementArgs;
12466 if (getDerived().TransformExprs(E->getPlacementArgs(),
12467 E->getNumPlacementArgs(), true,
12468 PlacementArgs, &ArgumentChanged))
12469 return ExprError();
12471 // Transform the initializer (if any).
12472 Expr *OldInit = E->getInitializer();
12473 ExprResult NewInit;
12474 if (OldInit)
12475 NewInit = getDerived().TransformInitializer(OldInit, true);
12476 if (NewInit.isInvalid())
12477 return ExprError();
12479 // Transform new operator and delete operator.
12480 FunctionDecl *OperatorNew = nullptr;
12481 if (E->getOperatorNew()) {
12482 OperatorNew = cast_or_null<FunctionDecl>(
12483 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
12484 if (!OperatorNew)
12485 return ExprError();
12488 FunctionDecl *OperatorDelete = nullptr;
12489 if (E->getOperatorDelete()) {
12490 OperatorDelete = cast_or_null<FunctionDecl>(
12491 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
12492 if (!OperatorDelete)
12493 return ExprError();
12496 if (!getDerived().AlwaysRebuild() &&
12497 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
12498 ArraySize == E->getArraySize() &&
12499 NewInit.get() == OldInit &&
12500 OperatorNew == E->getOperatorNew() &&
12501 OperatorDelete == E->getOperatorDelete() &&
12502 !ArgumentChanged) {
12503 // Mark any declarations we need as referenced.
12504 // FIXME: instantiation-specific.
12505 if (OperatorNew)
12506 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorNew);
12507 if (OperatorDelete)
12508 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
12510 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
12511 QualType ElementType
12512 = SemaRef.Context.getBaseElementType(E->getAllocatedType());
12513 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
12514 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
12515 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
12516 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor);
12521 return E;
12524 QualType AllocType = AllocTypeInfo->getType();
12525 if (!ArraySize) {
12526 // If no array size was specified, but the new expression was
12527 // instantiated with an array type (e.g., "new T" where T is
12528 // instantiated with "int[4]"), extract the outer bound from the
12529 // array type as our array size. We do this with constant and
12530 // dependently-sized array types.
12531 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);
12532 if (!ArrayT) {
12533 // Do nothing
12534 } else if (const ConstantArrayType *ConsArrayT
12535 = dyn_cast<ConstantArrayType>(ArrayT)) {
12536 ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),
12537 SemaRef.Context.getSizeType(),
12538 /*FIXME:*/ E->getBeginLoc());
12539 AllocType = ConsArrayT->getElementType();
12540 } else if (const DependentSizedArrayType *DepArrayT
12541 = dyn_cast<DependentSizedArrayType>(ArrayT)) {
12542 if (DepArrayT->getSizeExpr()) {
12543 ArraySize = DepArrayT->getSizeExpr();
12544 AllocType = DepArrayT->getElementType();
12549 return getDerived().RebuildCXXNewExpr(
12550 E->getBeginLoc(), E->isGlobalNew(),
12551 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
12552 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
12553 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
12556 template<typename Derived>
12557 ExprResult
12558 TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
12559 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
12560 if (Operand.isInvalid())
12561 return ExprError();
12563 // Transform the delete operator, if known.
12564 FunctionDecl *OperatorDelete = nullptr;
12565 if (E->getOperatorDelete()) {
12566 OperatorDelete = cast_or_null<FunctionDecl>(
12567 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
12568 if (!OperatorDelete)
12569 return ExprError();
12572 if (!getDerived().AlwaysRebuild() &&
12573 Operand.get() == E->getArgument() &&
12574 OperatorDelete == E->getOperatorDelete()) {
12575 // Mark any declarations we need as referenced.
12576 // FIXME: instantiation-specific.
12577 if (OperatorDelete)
12578 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
12580 if (!E->getArgument()->isTypeDependent()) {
12581 QualType Destroyed = SemaRef.Context.getBaseElementType(
12582 E->getDestroyedType());
12583 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
12584 CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
12585 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
12586 SemaRef.LookupDestructor(Record));
12590 return E;
12593 return getDerived().RebuildCXXDeleteExpr(
12594 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
12597 template<typename Derived>
12598 ExprResult
12599 TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
12600 CXXPseudoDestructorExpr *E) {
12601 ExprResult Base = getDerived().TransformExpr(E->getBase());
12602 if (Base.isInvalid())
12603 return ExprError();
12605 ParsedType ObjectTypePtr;
12606 bool MayBePseudoDestructor = false;
12607 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
12608 E->getOperatorLoc(),
12609 E->isArrow()? tok::arrow : tok::period,
12610 ObjectTypePtr,
12611 MayBePseudoDestructor);
12612 if (Base.isInvalid())
12613 return ExprError();
12615 QualType ObjectType = ObjectTypePtr.get();
12616 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
12617 if (QualifierLoc) {
12618 QualifierLoc
12619 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
12620 if (!QualifierLoc)
12621 return ExprError();
12623 CXXScopeSpec SS;
12624 SS.Adopt(QualifierLoc);
12626 PseudoDestructorTypeStorage Destroyed;
12627 if (E->getDestroyedTypeInfo()) {
12628 TypeSourceInfo *DestroyedTypeInfo
12629 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
12630 ObjectType, nullptr, SS);
12631 if (!DestroyedTypeInfo)
12632 return ExprError();
12633 Destroyed = DestroyedTypeInfo;
12634 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
12635 // We aren't likely to be able to resolve the identifier down to a type
12636 // now anyway, so just retain the identifier.
12637 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
12638 E->getDestroyedTypeLoc());
12639 } else {
12640 // Look for a destructor known with the given name.
12641 ParsedType T = SemaRef.getDestructorName(
12642 *E->getDestroyedTypeIdentifier(), E->getDestroyedTypeLoc(),
12643 /*Scope=*/nullptr, SS, ObjectTypePtr, false);
12644 if (!T)
12645 return ExprError();
12647 Destroyed
12648 = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),
12649 E->getDestroyedTypeLoc());
12652 TypeSourceInfo *ScopeTypeInfo = nullptr;
12653 if (E->getScopeTypeInfo()) {
12654 CXXScopeSpec EmptySS;
12655 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
12656 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
12657 if (!ScopeTypeInfo)
12658 return ExprError();
12661 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
12662 E->getOperatorLoc(),
12663 E->isArrow(),
12665 ScopeTypeInfo,
12666 E->getColonColonLoc(),
12667 E->getTildeLoc(),
12668 Destroyed);
12671 template <typename Derived>
12672 bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
12673 bool RequiresADL,
12674 LookupResult &R) {
12675 // Transform all the decls.
12676 bool AllEmptyPacks = true;
12677 for (auto *OldD : Old->decls()) {
12678 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
12679 if (!InstD) {
12680 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
12681 // This can happen because of dependent hiding.
12682 if (isa<UsingShadowDecl>(OldD))
12683 continue;
12684 else {
12685 R.clear();
12686 return true;
12690 // Expand using pack declarations.
12691 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
12692 ArrayRef<NamedDecl*> Decls = SingleDecl;
12693 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
12694 Decls = UPD->expansions();
12696 // Expand using declarations.
12697 for (auto *D : Decls) {
12698 if (auto *UD = dyn_cast<UsingDecl>(D)) {
12699 for (auto *SD : UD->shadows())
12700 R.addDecl(SD);
12701 } else {
12702 R.addDecl(D);
12706 AllEmptyPacks &= Decls.empty();
12709 // C++ [temp.res]/8.4.2:
12710 // The program is ill-formed, no diagnostic required, if [...] lookup for
12711 // a name in the template definition found a using-declaration, but the
12712 // lookup in the corresponding scope in the instantiation odoes not find
12713 // any declarations because the using-declaration was a pack expansion and
12714 // the corresponding pack is empty
12715 if (AllEmptyPacks && !RequiresADL) {
12716 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
12717 << isa<UnresolvedMemberExpr>(Old) << Old->getName();
12718 return true;
12721 // Resolve a kind, but don't do any further analysis. If it's
12722 // ambiguous, the callee needs to deal with it.
12723 R.resolveKind();
12724 return false;
12727 template<typename Derived>
12728 ExprResult
12729 TreeTransform<Derived>::TransformUnresolvedLookupExpr(
12730 UnresolvedLookupExpr *Old) {
12731 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
12732 Sema::LookupOrdinaryName);
12734 // Transform the declaration set.
12735 if (TransformOverloadExprDecls(Old, Old->requiresADL(), R))
12736 return ExprError();
12738 // Rebuild the nested-name qualifier, if present.
12739 CXXScopeSpec SS;
12740 if (Old->getQualifierLoc()) {
12741 NestedNameSpecifierLoc QualifierLoc
12742 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
12743 if (!QualifierLoc)
12744 return ExprError();
12746 SS.Adopt(QualifierLoc);
12749 if (Old->getNamingClass()) {
12750 CXXRecordDecl *NamingClass
12751 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
12752 Old->getNameLoc(),
12753 Old->getNamingClass()));
12754 if (!NamingClass) {
12755 R.clear();
12756 return ExprError();
12759 R.setNamingClass(NamingClass);
12762 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
12764 // If we have neither explicit template arguments, nor the template keyword,
12765 // it's a normal declaration name or member reference.
12766 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) {
12767 NamedDecl *D = R.getAsSingle<NamedDecl>();
12768 // In a C++11 unevaluated context, an UnresolvedLookupExpr might refer to an
12769 // instance member. In other contexts, BuildPossibleImplicitMemberExpr will
12770 // give a good diagnostic.
12771 if (D && D->isCXXInstanceMember()) {
12772 return SemaRef.BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, R,
12773 /*TemplateArgs=*/nullptr,
12774 /*Scope=*/nullptr);
12777 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
12780 // If we have template arguments, rebuild them, then rebuild the
12781 // templateid expression.
12782 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
12783 if (Old->hasExplicitTemplateArgs() &&
12784 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
12785 Old->getNumTemplateArgs(),
12786 TransArgs)) {
12787 R.clear();
12788 return ExprError();
12791 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
12792 Old->requiresADL(), &TransArgs);
12795 template<typename Derived>
12796 ExprResult
12797 TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
12798 bool ArgChanged = false;
12799 SmallVector<TypeSourceInfo *, 4> Args;
12800 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
12801 TypeSourceInfo *From = E->getArg(I);
12802 TypeLoc FromTL = From->getTypeLoc();
12803 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
12804 TypeLocBuilder TLB;
12805 TLB.reserve(FromTL.getFullDataSize());
12806 QualType To = getDerived().TransformType(TLB, FromTL);
12807 if (To.isNull())
12808 return ExprError();
12810 if (To == From->getType())
12811 Args.push_back(From);
12812 else {
12813 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12814 ArgChanged = true;
12816 continue;
12819 ArgChanged = true;
12821 // We have a pack expansion. Instantiate it.
12822 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
12823 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
12824 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
12825 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
12827 // Determine whether the set of unexpanded parameter packs can and should
12828 // be expanded.
12829 bool Expand = true;
12830 bool RetainExpansion = false;
12831 std::optional<unsigned> OrigNumExpansions =
12832 ExpansionTL.getTypePtr()->getNumExpansions();
12833 std::optional<unsigned> NumExpansions = OrigNumExpansions;
12834 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
12835 PatternTL.getSourceRange(),
12836 Unexpanded,
12837 Expand, RetainExpansion,
12838 NumExpansions))
12839 return ExprError();
12841 if (!Expand) {
12842 // The transform has determined that we should perform a simple
12843 // transformation on the pack expansion, producing another pack
12844 // expansion.
12845 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
12847 TypeLocBuilder TLB;
12848 TLB.reserve(From->getTypeLoc().getFullDataSize());
12850 QualType To = getDerived().TransformType(TLB, PatternTL);
12851 if (To.isNull())
12852 return ExprError();
12854 To = getDerived().RebuildPackExpansionType(To,
12855 PatternTL.getSourceRange(),
12856 ExpansionTL.getEllipsisLoc(),
12857 NumExpansions);
12858 if (To.isNull())
12859 return ExprError();
12861 PackExpansionTypeLoc ToExpansionTL
12862 = TLB.push<PackExpansionTypeLoc>(To);
12863 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
12864 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12865 continue;
12868 // Expand the pack expansion by substituting for each argument in the
12869 // pack(s).
12870 for (unsigned I = 0; I != *NumExpansions; ++I) {
12871 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
12872 TypeLocBuilder TLB;
12873 TLB.reserve(PatternTL.getFullDataSize());
12874 QualType To = getDerived().TransformType(TLB, PatternTL);
12875 if (To.isNull())
12876 return ExprError();
12878 if (To->containsUnexpandedParameterPack()) {
12879 To = getDerived().RebuildPackExpansionType(To,
12880 PatternTL.getSourceRange(),
12881 ExpansionTL.getEllipsisLoc(),
12882 NumExpansions);
12883 if (To.isNull())
12884 return ExprError();
12886 PackExpansionTypeLoc ToExpansionTL
12887 = TLB.push<PackExpansionTypeLoc>(To);
12888 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
12891 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12894 if (!RetainExpansion)
12895 continue;
12897 // If we're supposed to retain a pack expansion, do so by temporarily
12898 // forgetting the partially-substituted parameter pack.
12899 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
12901 TypeLocBuilder TLB;
12902 TLB.reserve(From->getTypeLoc().getFullDataSize());
12904 QualType To = getDerived().TransformType(TLB, PatternTL);
12905 if (To.isNull())
12906 return ExprError();
12908 To = getDerived().RebuildPackExpansionType(To,
12909 PatternTL.getSourceRange(),
12910 ExpansionTL.getEllipsisLoc(),
12911 NumExpansions);
12912 if (To.isNull())
12913 return ExprError();
12915 PackExpansionTypeLoc ToExpansionTL
12916 = TLB.push<PackExpansionTypeLoc>(To);
12917 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
12918 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12921 if (!getDerived().AlwaysRebuild() && !ArgChanged)
12922 return E;
12924 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
12925 E->getEndLoc());
12928 template<typename Derived>
12929 ExprResult
12930 TreeTransform<Derived>::TransformConceptSpecializationExpr(
12931 ConceptSpecializationExpr *E) {
12932 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
12933 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
12934 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
12935 Old->NumTemplateArgs, TransArgs))
12936 return ExprError();
12938 return getDerived().RebuildConceptSpecializationExpr(
12939 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
12940 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
12941 &TransArgs);
12944 template<typename Derived>
12945 ExprResult
12946 TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
12947 SmallVector<ParmVarDecl*, 4> TransParams;
12948 SmallVector<QualType, 4> TransParamTypes;
12949 Sema::ExtParameterInfoBuilder ExtParamInfos;
12951 // C++2a [expr.prim.req]p2
12952 // Expressions appearing within a requirement-body are unevaluated operands.
12953 EnterExpressionEvaluationContext Ctx(
12954 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
12955 Sema::ReuseLambdaContextDecl);
12957 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
12958 getSema().Context, getSema().CurContext,
12959 E->getBody()->getBeginLoc());
12961 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
12963 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
12964 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
12965 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
12967 for (ParmVarDecl *Param : TransParams)
12968 if (Param)
12969 Param->setDeclContext(Body);
12971 // On failure to transform, TransformRequiresTypeParams returns an expression
12972 // in the event that the transformation of the type params failed in some way.
12973 // It is expected that this will result in a 'not satisfied' Requires clause
12974 // when instantiating.
12975 if (!TypeParamResult.isUnset())
12976 return TypeParamResult;
12978 SmallVector<concepts::Requirement *, 4> TransReqs;
12979 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
12980 TransReqs))
12981 return ExprError();
12983 for (concepts::Requirement *Req : TransReqs) {
12984 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
12985 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
12986 ER->getReturnTypeRequirement()
12987 .getTypeConstraintTemplateParameterList()->getParam(0)
12988 ->setDeclContext(Body);
12993 return getDerived().RebuildRequiresExpr(
12994 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
12995 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
12998 template<typename Derived>
12999 bool TreeTransform<Derived>::TransformRequiresExprRequirements(
13000 ArrayRef<concepts::Requirement *> Reqs,
13001 SmallVectorImpl<concepts::Requirement *> &Transformed) {
13002 for (concepts::Requirement *Req : Reqs) {
13003 concepts::Requirement *TransReq = nullptr;
13004 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
13005 TransReq = getDerived().TransformTypeRequirement(TypeReq);
13006 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
13007 TransReq = getDerived().TransformExprRequirement(ExprReq);
13008 else
13009 TransReq = getDerived().TransformNestedRequirement(
13010 cast<concepts::NestedRequirement>(Req));
13011 if (!TransReq)
13012 return true;
13013 Transformed.push_back(TransReq);
13015 return false;
13018 template<typename Derived>
13019 concepts::TypeRequirement *
13020 TreeTransform<Derived>::TransformTypeRequirement(
13021 concepts::TypeRequirement *Req) {
13022 if (Req->isSubstitutionFailure()) {
13023 if (getDerived().AlwaysRebuild())
13024 return getDerived().RebuildTypeRequirement(
13025 Req->getSubstitutionDiagnostic());
13026 return Req;
13028 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
13029 if (!TransType)
13030 return nullptr;
13031 return getDerived().RebuildTypeRequirement(TransType);
13034 template<typename Derived>
13035 concepts::ExprRequirement *
13036 TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
13037 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
13038 if (Req->isExprSubstitutionFailure())
13039 TransExpr = Req->getExprSubstitutionDiagnostic();
13040 else {
13041 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
13042 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
13043 TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
13044 if (TransExprRes.isInvalid())
13045 return nullptr;
13046 TransExpr = TransExprRes.get();
13049 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
13050 const auto &RetReq = Req->getReturnTypeRequirement();
13051 if (RetReq.isEmpty())
13052 TransRetReq.emplace();
13053 else if (RetReq.isSubstitutionFailure())
13054 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
13055 else if (RetReq.isTypeConstraint()) {
13056 TemplateParameterList *OrigTPL =
13057 RetReq.getTypeConstraintTemplateParameterList();
13058 TemplateParameterList *TPL =
13059 getDerived().TransformTemplateParameterList(OrigTPL);
13060 if (!TPL)
13061 return nullptr;
13062 TransRetReq.emplace(TPL);
13064 assert(TransRetReq && "All code paths leading here must set TransRetReq");
13065 if (Expr *E = TransExpr.dyn_cast<Expr *>())
13066 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
13067 Req->getNoexceptLoc(),
13068 std::move(*TransRetReq));
13069 return getDerived().RebuildExprRequirement(
13070 TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(),
13071 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
13074 template<typename Derived>
13075 concepts::NestedRequirement *
13076 TreeTransform<Derived>::TransformNestedRequirement(
13077 concepts::NestedRequirement *Req) {
13078 if (Req->hasInvalidConstraint()) {
13079 if (getDerived().AlwaysRebuild())
13080 return getDerived().RebuildNestedRequirement(
13081 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
13082 return Req;
13084 ExprResult TransConstraint =
13085 getDerived().TransformExpr(Req->getConstraintExpr());
13086 if (TransConstraint.isInvalid())
13087 return nullptr;
13088 return getDerived().RebuildNestedRequirement(TransConstraint.get());
13091 template<typename Derived>
13092 ExprResult
13093 TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
13094 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
13095 if (!T)
13096 return ExprError();
13098 if (!getDerived().AlwaysRebuild() &&
13099 T == E->getQueriedTypeSourceInfo())
13100 return E;
13102 ExprResult SubExpr;
13104 EnterExpressionEvaluationContext Unevaluated(
13105 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13106 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
13107 if (SubExpr.isInvalid())
13108 return ExprError();
13110 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
13111 return E;
13114 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
13115 SubExpr.get(), E->getEndLoc());
13118 template<typename Derived>
13119 ExprResult
13120 TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
13121 ExprResult SubExpr;
13123 EnterExpressionEvaluationContext Unevaluated(
13124 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13125 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
13126 if (SubExpr.isInvalid())
13127 return ExprError();
13129 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
13130 return E;
13133 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
13134 SubExpr.get(), E->getEndLoc());
13137 template <typename Derived>
13138 ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
13139 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
13140 TypeSourceInfo **RecoveryTSI) {
13141 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
13142 DRE, AddrTaken, RecoveryTSI);
13144 // Propagate both errors and recovered types, which return ExprEmpty.
13145 if (!NewDRE.isUsable())
13146 return NewDRE;
13148 // We got an expr, wrap it up in parens.
13149 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
13150 return PE;
13151 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
13152 PE->getRParen());
13155 template <typename Derived>
13156 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
13157 DependentScopeDeclRefExpr *E) {
13158 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
13159 nullptr);
13162 template <typename Derived>
13163 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
13164 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
13165 TypeSourceInfo **RecoveryTSI) {
13166 assert(E->getQualifierLoc());
13167 NestedNameSpecifierLoc QualifierLoc =
13168 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13169 if (!QualifierLoc)
13170 return ExprError();
13171 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13173 // TODO: If this is a conversion-function-id, verify that the
13174 // destination type name (if present) resolves the same way after
13175 // instantiation as it did in the local scope.
13177 DeclarationNameInfo NameInfo =
13178 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
13179 if (!NameInfo.getName())
13180 return ExprError();
13182 if (!E->hasExplicitTemplateArgs()) {
13183 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
13184 // Note: it is sufficient to compare the Name component of NameInfo:
13185 // if name has not changed, DNLoc has not changed either.
13186 NameInfo.getName() == E->getDeclName())
13187 return E;
13189 return getDerived().RebuildDependentScopeDeclRefExpr(
13190 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
13191 IsAddressOfOperand, RecoveryTSI);
13194 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
13195 if (getDerived().TransformTemplateArguments(
13196 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
13197 return ExprError();
13199 return getDerived().RebuildDependentScopeDeclRefExpr(
13200 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
13201 RecoveryTSI);
13204 template<typename Derived>
13205 ExprResult
13206 TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
13207 // CXXConstructExprs other than for list-initialization and
13208 // CXXTemporaryObjectExpr are always implicit, so when we have
13209 // a 1-argument construction we just transform that argument.
13210 if (getDerived().AllowSkippingCXXConstructExpr() &&
13211 ((E->getNumArgs() == 1 ||
13212 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) &&
13213 (!getDerived().DropCallArgument(E->getArg(0))) &&
13214 !E->isListInitialization()))
13215 return getDerived().TransformInitializer(E->getArg(0),
13216 /*DirectInit*/ false);
13218 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
13220 QualType T = getDerived().TransformType(E->getType());
13221 if (T.isNull())
13222 return ExprError();
13224 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13225 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13226 if (!Constructor)
13227 return ExprError();
13229 bool ArgumentChanged = false;
13230 SmallVector<Expr*, 8> Args;
13232 EnterExpressionEvaluationContext Context(
13233 getSema(), EnterExpressionEvaluationContext::InitList,
13234 E->isListInitialization());
13235 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13236 &ArgumentChanged))
13237 return ExprError();
13240 if (!getDerived().AlwaysRebuild() &&
13241 T == E->getType() &&
13242 Constructor == E->getConstructor() &&
13243 !ArgumentChanged) {
13244 // Mark the constructor as referenced.
13245 // FIXME: Instantiation-specific
13246 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13247 return E;
13250 return getDerived().RebuildCXXConstructExpr(
13251 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
13252 E->hadMultipleCandidates(), E->isListInitialization(),
13253 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
13254 E->getConstructionKind(), E->getParenOrBraceRange());
13257 template<typename Derived>
13258 ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
13259 CXXInheritedCtorInitExpr *E) {
13260 QualType T = getDerived().TransformType(E->getType());
13261 if (T.isNull())
13262 return ExprError();
13264 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13265 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13266 if (!Constructor)
13267 return ExprError();
13269 if (!getDerived().AlwaysRebuild() &&
13270 T == E->getType() &&
13271 Constructor == E->getConstructor()) {
13272 // Mark the constructor as referenced.
13273 // FIXME: Instantiation-specific
13274 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13275 return E;
13278 return getDerived().RebuildCXXInheritedCtorInitExpr(
13279 T, E->getLocation(), Constructor,
13280 E->constructsVBase(), E->inheritedFromVBase());
13283 /// Transform a C++ temporary-binding expression.
13285 /// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
13286 /// transform the subexpression and return that.
13287 template<typename Derived>
13288 ExprResult
13289 TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
13290 if (auto *Dtor = E->getTemporary()->getDestructor())
13291 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
13292 const_cast<CXXDestructorDecl *>(Dtor));
13293 return getDerived().TransformExpr(E->getSubExpr());
13296 /// Transform a C++ expression that contains cleanups that should
13297 /// be run after the expression is evaluated.
13299 /// Since ExprWithCleanups nodes are implicitly generated, we
13300 /// just transform the subexpression and return that.
13301 template<typename Derived>
13302 ExprResult
13303 TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
13304 return getDerived().TransformExpr(E->getSubExpr());
13307 template<typename Derived>
13308 ExprResult
13309 TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
13310 CXXTemporaryObjectExpr *E) {
13311 TypeSourceInfo *T =
13312 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
13313 if (!T)
13314 return ExprError();
13316 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13317 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13318 if (!Constructor)
13319 return ExprError();
13321 bool ArgumentChanged = false;
13322 SmallVector<Expr*, 8> Args;
13323 Args.reserve(E->getNumArgs());
13325 EnterExpressionEvaluationContext Context(
13326 getSema(), EnterExpressionEvaluationContext::InitList,
13327 E->isListInitialization());
13328 if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13329 &ArgumentChanged))
13330 return ExprError();
13333 if (!getDerived().AlwaysRebuild() &&
13334 T == E->getTypeSourceInfo() &&
13335 Constructor == E->getConstructor() &&
13336 !ArgumentChanged) {
13337 // FIXME: Instantiation-specific
13338 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13339 return SemaRef.MaybeBindToTemporary(E);
13342 // FIXME: We should just pass E->isListInitialization(), but we're not
13343 // prepared to handle list-initialization without a child InitListExpr.
13344 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
13345 return getDerived().RebuildCXXTemporaryObjectExpr(
13346 T, LParenLoc, Args, E->getEndLoc(),
13347 /*ListInitialization=*/LParenLoc.isInvalid());
13350 template<typename Derived>
13351 ExprResult
13352 TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
13353 // Transform any init-capture expressions before entering the scope of the
13354 // lambda body, because they are not semantically within that scope.
13355 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
13356 struct TransformedInitCapture {
13357 // The location of the ... if the result is retaining a pack expansion.
13358 SourceLocation EllipsisLoc;
13359 // Zero or more expansions of the init-capture.
13360 SmallVector<InitCaptureInfoTy, 4> Expansions;
13362 SmallVector<TransformedInitCapture, 4> InitCaptures;
13363 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
13364 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13365 CEnd = E->capture_end();
13366 C != CEnd; ++C) {
13367 if (!E->isInitCapture(C))
13368 continue;
13370 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
13371 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
13373 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
13374 std::optional<unsigned> NumExpansions) {
13375 ExprResult NewExprInitResult = getDerived().TransformInitializer(
13376 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
13378 if (NewExprInitResult.isInvalid()) {
13379 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
13380 return;
13382 Expr *NewExprInit = NewExprInitResult.get();
13384 QualType NewInitCaptureType =
13385 getSema().buildLambdaInitCaptureInitialization(
13386 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
13387 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
13388 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=
13389 VarDecl::CInit,
13390 NewExprInit);
13391 Result.Expansions.push_back(
13392 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
13395 // If this is an init-capture pack, consider expanding the pack now.
13396 if (OldVD->isParameterPack()) {
13397 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
13398 ->getTypeLoc()
13399 .castAs<PackExpansionTypeLoc>();
13400 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
13401 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
13403 // Determine whether the set of unexpanded parameter packs can and should
13404 // be expanded.
13405 bool Expand = true;
13406 bool RetainExpansion = false;
13407 std::optional<unsigned> OrigNumExpansions =
13408 ExpansionTL.getTypePtr()->getNumExpansions();
13409 std::optional<unsigned> NumExpansions = OrigNumExpansions;
13410 if (getDerived().TryExpandParameterPacks(
13411 ExpansionTL.getEllipsisLoc(),
13412 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
13413 RetainExpansion, NumExpansions))
13414 return ExprError();
13415 if (Expand) {
13416 for (unsigned I = 0; I != *NumExpansions; ++I) {
13417 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
13418 SubstInitCapture(SourceLocation(), std::nullopt);
13421 if (!Expand || RetainExpansion) {
13422 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
13423 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
13424 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
13426 } else {
13427 SubstInitCapture(SourceLocation(), std::nullopt);
13431 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
13432 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
13434 // Create the local class that will describe the lambda.
13436 // FIXME: DependencyKind below is wrong when substituting inside a templated
13437 // context that isn't a DeclContext (such as a variable template), or when
13438 // substituting an unevaluated lambda inside of a function's parameter's type
13439 // - as parameter types are not instantiated from within a function's DC. We
13440 // use evaluation contexts to distinguish the function parameter case.
13441 CXXRecordDecl::LambdaDependencyKind DependencyKind =
13442 CXXRecordDecl::LDK_Unknown;
13443 if ((getSema().isUnevaluatedContext() ||
13444 getSema().isConstantEvaluatedContext()) &&
13445 (getSema().CurContext->isFileContext() ||
13446 !getSema().CurContext->getParent()->isDependentContext()))
13447 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
13449 CXXRecordDecl *OldClass = E->getLambdaClass();
13450 CXXRecordDecl *Class = getSema().createLambdaClosureType(
13451 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
13452 E->getCaptureDefault());
13453 getDerived().transformedLocalDecl(OldClass, {Class});
13455 CXXMethodDecl *NewCallOperator =
13456 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
13457 NewCallOperator->setLexicalDeclContext(getSema().CurContext);
13459 // Enter the scope of the lambda.
13460 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
13461 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
13462 E->hasExplicitParameters(), E->isMutable());
13464 // Introduce the context of the call operator.
13465 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
13466 /*NewThisContext*/false);
13468 bool Invalid = false;
13470 // Transform captures.
13471 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13472 CEnd = E->capture_end();
13473 C != CEnd; ++C) {
13474 // When we hit the first implicit capture, tell Sema that we've finished
13475 // the list of explicit captures.
13476 if (C->isImplicit())
13477 break;
13479 // Capturing 'this' is trivial.
13480 if (C->capturesThis()) {
13481 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
13482 /*BuildAndDiagnose*/ true, nullptr,
13483 C->getCaptureKind() == LCK_StarThis);
13484 continue;
13486 // Captured expression will be recaptured during captured variables
13487 // rebuilding.
13488 if (C->capturesVLAType())
13489 continue;
13491 // Rebuild init-captures, including the implied field declaration.
13492 if (E->isInitCapture(C)) {
13493 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
13495 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
13496 llvm::SmallVector<Decl*, 4> NewVDs;
13498 for (InitCaptureInfoTy &Info : NewC.Expansions) {
13499 ExprResult Init = Info.first;
13500 QualType InitQualType = Info.second;
13501 if (Init.isInvalid() || InitQualType.isNull()) {
13502 Invalid = true;
13503 break;
13505 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
13506 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
13507 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
13508 getSema().CurContext);
13509 if (!NewVD) {
13510 Invalid = true;
13511 break;
13513 NewVDs.push_back(NewVD);
13514 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
13517 if (Invalid)
13518 break;
13520 getDerived().transformedLocalDecl(OldVD, NewVDs);
13521 continue;
13524 assert(C->capturesVariable() && "unexpected kind of lambda capture");
13526 // Determine the capture kind for Sema.
13527 Sema::TryCaptureKind Kind
13528 = C->isImplicit()? Sema::TryCapture_Implicit
13529 : C->getCaptureKind() == LCK_ByCopy
13530 ? Sema::TryCapture_ExplicitByVal
13531 : Sema::TryCapture_ExplicitByRef;
13532 SourceLocation EllipsisLoc;
13533 if (C->isPackExpansion()) {
13534 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
13535 bool ShouldExpand = false;
13536 bool RetainExpansion = false;
13537 std::optional<unsigned> NumExpansions;
13538 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
13539 C->getLocation(),
13540 Unexpanded,
13541 ShouldExpand, RetainExpansion,
13542 NumExpansions)) {
13543 Invalid = true;
13544 continue;
13547 if (ShouldExpand) {
13548 // The transform has determined that we should perform an expansion;
13549 // transform and capture each of the arguments.
13550 // expansion of the pattern. Do so.
13551 auto *Pack = cast<VarDecl>(C->getCapturedVar());
13552 for (unsigned I = 0; I != *NumExpansions; ++I) {
13553 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
13554 VarDecl *CapturedVar
13555 = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
13556 Pack));
13557 if (!CapturedVar) {
13558 Invalid = true;
13559 continue;
13562 // Capture the transformed variable.
13563 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
13566 // FIXME: Retain a pack expansion if RetainExpansion is true.
13568 continue;
13571 EllipsisLoc = C->getEllipsisLoc();
13574 // Transform the captured variable.
13575 auto *CapturedVar = cast_or_null<ValueDecl>(
13576 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
13577 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
13578 Invalid = true;
13579 continue;
13582 // Capture the transformed variable.
13583 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
13584 EllipsisLoc);
13586 getSema().finishLambdaExplicitCaptures(LSI);
13588 // Transform the template parameters, and add them to the current
13589 // instantiation scope. The null case is handled correctly.
13590 auto TPL = getDerived().TransformTemplateParameterList(
13591 E->getTemplateParameterList());
13592 LSI->GLTemplateParameterList = TPL;
13593 if (TPL)
13594 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
13595 TPL);
13597 // Transform the type of the original lambda's call operator.
13598 // The transformation MUST be done in the CurrentInstantiationScope since
13599 // it introduces a mapping of the original to the newly created
13600 // transformed parameters.
13601 TypeSourceInfo *NewCallOpTSI = nullptr;
13603 TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo();
13604 auto OldCallOpFPTL =
13605 OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
13607 TypeLocBuilder NewCallOpTLBuilder;
13608 SmallVector<QualType, 4> ExceptionStorage;
13609 TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
13610 QualType NewCallOpType = TransformFunctionProtoType(
13611 NewCallOpTLBuilder, OldCallOpFPTL, nullptr, Qualifiers(),
13612 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
13613 return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI,
13614 ExceptionStorage, Changed);
13616 if (NewCallOpType.isNull())
13617 return ExprError();
13618 NewCallOpTSI =
13619 NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
13622 getSema().CompleteLambdaCallOperator(
13623 NewCallOperator, E->getCallOperator()->getLocation(),
13624 E->getCallOperator()->getInnerLocStart(),
13625 E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
13626 E->getCallOperator()->getConstexprKind(),
13627 E->getCallOperator()->getStorageClass(),
13628 NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
13629 E->hasExplicitResultType());
13631 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
13632 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
13635 // Number the lambda for linkage purposes if necessary.
13636 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
13638 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
13639 if (getDerived().ReplacingOriginal()) {
13640 Numbering = OldClass->getLambdaNumbering();
13643 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
13646 // FIXME: Sema's lambda-building mechanism expects us to push an expression
13647 // evaluation context even if we're not transforming the function body.
13648 getSema().PushExpressionEvaluationContext(
13649 Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
13651 // Instantiate the body of the lambda expression.
13652 StmtResult Body =
13653 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
13655 // ActOnLambda* will pop the function scope for us.
13656 FuncScopeCleanup.disable();
13658 if (Body.isInvalid()) {
13659 SavedContext.pop();
13660 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
13661 /*IsInstantiation=*/true);
13662 return ExprError();
13665 // Copy the LSI before ActOnFinishFunctionBody removes it.
13666 // FIXME: This is dumb. Store the lambda information somewhere that outlives
13667 // the call operator.
13668 auto LSICopy = *LSI;
13669 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
13670 /*IsInstantiation*/ true);
13671 SavedContext.pop();
13673 return getSema().BuildLambdaExpr(E->getBeginLoc(), Body.get()->getEndLoc(),
13674 &LSICopy);
13677 template<typename Derived>
13678 StmtResult
13679 TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
13680 return TransformStmt(S);
13683 template<typename Derived>
13684 StmtResult
13685 TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
13686 // Transform captures.
13687 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13688 CEnd = E->capture_end();
13689 C != CEnd; ++C) {
13690 // When we hit the first implicit capture, tell Sema that we've finished
13691 // the list of explicit captures.
13692 if (!C->isImplicit())
13693 continue;
13695 // Capturing 'this' is trivial.
13696 if (C->capturesThis()) {
13697 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
13698 /*BuildAndDiagnose*/ true, nullptr,
13699 C->getCaptureKind() == LCK_StarThis);
13700 continue;
13702 // Captured expression will be recaptured during captured variables
13703 // rebuilding.
13704 if (C->capturesVLAType())
13705 continue;
13707 assert(C->capturesVariable() && "unexpected kind of lambda capture");
13708 assert(!E->isInitCapture(C) && "implicit init-capture?");
13710 // Transform the captured variable.
13711 VarDecl *CapturedVar = cast_or_null<VarDecl>(
13712 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
13713 if (!CapturedVar || CapturedVar->isInvalidDecl())
13714 return StmtError();
13716 // Capture the transformed variable.
13717 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
13720 return S;
13723 template<typename Derived>
13724 ExprResult
13725 TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
13726 CXXUnresolvedConstructExpr *E) {
13727 TypeSourceInfo *T =
13728 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
13729 if (!T)
13730 return ExprError();
13732 bool ArgumentChanged = false;
13733 SmallVector<Expr*, 8> Args;
13734 Args.reserve(E->getNumArgs());
13736 EnterExpressionEvaluationContext Context(
13737 getSema(), EnterExpressionEvaluationContext::InitList,
13738 E->isListInitialization());
13739 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
13740 &ArgumentChanged))
13741 return ExprError();
13744 if (!getDerived().AlwaysRebuild() &&
13745 T == E->getTypeSourceInfo() &&
13746 !ArgumentChanged)
13747 return E;
13749 // FIXME: we're faking the locations of the commas
13750 return getDerived().RebuildCXXUnresolvedConstructExpr(
13751 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
13754 template<typename Derived>
13755 ExprResult
13756 TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
13757 CXXDependentScopeMemberExpr *E) {
13758 // Transform the base of the expression.
13759 ExprResult Base((Expr*) nullptr);
13760 Expr *OldBase;
13761 QualType BaseType;
13762 QualType ObjectType;
13763 if (!E->isImplicitAccess()) {
13764 OldBase = E->getBase();
13765 Base = getDerived().TransformExpr(OldBase);
13766 if (Base.isInvalid())
13767 return ExprError();
13769 // Start the member reference and compute the object's type.
13770 ParsedType ObjectTy;
13771 bool MayBePseudoDestructor = false;
13772 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
13773 E->getOperatorLoc(),
13774 E->isArrow()? tok::arrow : tok::period,
13775 ObjectTy,
13776 MayBePseudoDestructor);
13777 if (Base.isInvalid())
13778 return ExprError();
13780 ObjectType = ObjectTy.get();
13781 BaseType = ((Expr*) Base.get())->getType();
13782 } else {
13783 OldBase = nullptr;
13784 BaseType = getDerived().TransformType(E->getBaseType());
13785 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
13788 // Transform the first part of the nested-name-specifier that qualifies
13789 // the member name.
13790 NamedDecl *FirstQualifierInScope
13791 = getDerived().TransformFirstQualifierInScope(
13792 E->getFirstQualifierFoundInScope(),
13793 E->getQualifierLoc().getBeginLoc());
13795 NestedNameSpecifierLoc QualifierLoc;
13796 if (E->getQualifier()) {
13797 QualifierLoc
13798 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
13799 ObjectType,
13800 FirstQualifierInScope);
13801 if (!QualifierLoc)
13802 return ExprError();
13805 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13807 // TODO: If this is a conversion-function-id, verify that the
13808 // destination type name (if present) resolves the same way after
13809 // instantiation as it did in the local scope.
13811 DeclarationNameInfo NameInfo
13812 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
13813 if (!NameInfo.getName())
13814 return ExprError();
13816 if (!E->hasExplicitTemplateArgs()) {
13817 // This is a reference to a member without an explicitly-specified
13818 // template argument list. Optimize for this common case.
13819 if (!getDerived().AlwaysRebuild() &&
13820 Base.get() == OldBase &&
13821 BaseType == E->getBaseType() &&
13822 QualifierLoc == E->getQualifierLoc() &&
13823 NameInfo.getName() == E->getMember() &&
13824 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
13825 return E;
13827 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
13828 BaseType,
13829 E->isArrow(),
13830 E->getOperatorLoc(),
13831 QualifierLoc,
13832 TemplateKWLoc,
13833 FirstQualifierInScope,
13834 NameInfo,
13835 /*TemplateArgs*/nullptr);
13838 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
13839 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13840 E->getNumTemplateArgs(),
13841 TransArgs))
13842 return ExprError();
13844 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
13845 BaseType,
13846 E->isArrow(),
13847 E->getOperatorLoc(),
13848 QualifierLoc,
13849 TemplateKWLoc,
13850 FirstQualifierInScope,
13851 NameInfo,
13852 &TransArgs);
13855 template <typename Derived>
13856 ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
13857 UnresolvedMemberExpr *Old) {
13858 // Transform the base of the expression.
13859 ExprResult Base((Expr *)nullptr);
13860 QualType BaseType;
13861 if (!Old->isImplicitAccess()) {
13862 Base = getDerived().TransformExpr(Old->getBase());
13863 if (Base.isInvalid())
13864 return ExprError();
13865 Base =
13866 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
13867 if (Base.isInvalid())
13868 return ExprError();
13869 BaseType = Base.get()->getType();
13870 } else {
13871 BaseType = getDerived().TransformType(Old->getBaseType());
13874 NestedNameSpecifierLoc QualifierLoc;
13875 if (Old->getQualifierLoc()) {
13876 QualifierLoc =
13877 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
13878 if (!QualifierLoc)
13879 return ExprError();
13882 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
13884 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
13886 // Transform the declaration set.
13887 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ false, R))
13888 return ExprError();
13890 // Determine the naming class.
13891 if (Old->getNamingClass()) {
13892 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
13893 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
13894 if (!NamingClass)
13895 return ExprError();
13897 R.setNamingClass(NamingClass);
13900 TemplateArgumentListInfo TransArgs;
13901 if (Old->hasExplicitTemplateArgs()) {
13902 TransArgs.setLAngleLoc(Old->getLAngleLoc());
13903 TransArgs.setRAngleLoc(Old->getRAngleLoc());
13904 if (getDerived().TransformTemplateArguments(
13905 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
13906 return ExprError();
13909 // FIXME: to do this check properly, we will need to preserve the
13910 // first-qualifier-in-scope here, just in case we had a dependent
13911 // base (and therefore couldn't do the check) and a
13912 // nested-name-qualifier (and therefore could do the lookup).
13913 NamedDecl *FirstQualifierInScope = nullptr;
13915 return getDerived().RebuildUnresolvedMemberExpr(
13916 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
13917 TemplateKWLoc, FirstQualifierInScope, R,
13918 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
13921 template<typename Derived>
13922 ExprResult
13923 TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
13924 EnterExpressionEvaluationContext Unevaluated(
13925 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13926 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
13927 if (SubExpr.isInvalid())
13928 return ExprError();
13930 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
13931 return E;
13933 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
13936 template<typename Derived>
13937 ExprResult
13938 TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
13939 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
13940 if (Pattern.isInvalid())
13941 return ExprError();
13943 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
13944 return E;
13946 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
13947 E->getNumExpansions());
13950 template<typename Derived>
13951 ExprResult
13952 TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
13953 // If E is not value-dependent, then nothing will change when we transform it.
13954 // Note: This is an instantiation-centric view.
13955 if (!E->isValueDependent())
13956 return E;
13958 EnterExpressionEvaluationContext Unevaluated(
13959 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
13961 ArrayRef<TemplateArgument> PackArgs;
13962 TemplateArgument ArgStorage;
13964 // Find the argument list to transform.
13965 if (E->isPartiallySubstituted()) {
13966 PackArgs = E->getPartialArguments();
13967 } else if (E->isValueDependent()) {
13968 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
13969 bool ShouldExpand = false;
13970 bool RetainExpansion = false;
13971 std::optional<unsigned> NumExpansions;
13972 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
13973 Unexpanded,
13974 ShouldExpand, RetainExpansion,
13975 NumExpansions))
13976 return ExprError();
13978 // If we need to expand the pack, build a template argument from it and
13979 // expand that.
13980 if (ShouldExpand) {
13981 auto *Pack = E->getPack();
13982 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) {
13983 ArgStorage = getSema().Context.getPackExpansionType(
13984 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
13985 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {
13986 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
13987 } else {
13988 auto *VD = cast<ValueDecl>(Pack);
13989 ExprResult DRE = getSema().BuildDeclRefExpr(
13990 VD, VD->getType().getNonLValueExprType(getSema().Context),
13991 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
13992 E->getPackLoc());
13993 if (DRE.isInvalid())
13994 return ExprError();
13995 ArgStorage = new (getSema().Context)
13996 PackExpansionExpr(getSema().Context.DependentTy, DRE.get(),
13997 E->getPackLoc(), std::nullopt);
13999 PackArgs = ArgStorage;
14003 // If we're not expanding the pack, just transform the decl.
14004 if (!PackArgs.size()) {
14005 auto *Pack = cast_or_null<NamedDecl>(
14006 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
14007 if (!Pack)
14008 return ExprError();
14009 return getDerived().RebuildSizeOfPackExpr(
14010 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
14011 std::nullopt, std::nullopt);
14014 // Try to compute the result without performing a partial substitution.
14015 std::optional<unsigned> Result = 0;
14016 for (const TemplateArgument &Arg : PackArgs) {
14017 if (!Arg.isPackExpansion()) {
14018 Result = *Result + 1;
14019 continue;
14022 TemplateArgumentLoc ArgLoc;
14023 InventTemplateArgumentLoc(Arg, ArgLoc);
14025 // Find the pattern of the pack expansion.
14026 SourceLocation Ellipsis;
14027 std::optional<unsigned> OrigNumExpansions;
14028 TemplateArgumentLoc Pattern =
14029 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
14030 OrigNumExpansions);
14032 // Substitute under the pack expansion. Do not expand the pack (yet).
14033 TemplateArgumentLoc OutPattern;
14034 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14035 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
14036 /*Uneval*/ true))
14037 return true;
14039 // See if we can determine the number of arguments from the result.
14040 std::optional<unsigned> NumExpansions =
14041 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
14042 if (!NumExpansions) {
14043 // No: we must be in an alias template expansion, and we're going to need
14044 // to actually expand the packs.
14045 Result = std::nullopt;
14046 break;
14049 Result = *Result + *NumExpansions;
14052 // Common case: we could determine the number of expansions without
14053 // substituting.
14054 if (Result)
14055 return getDerived().RebuildSizeOfPackExpr(
14056 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
14057 *Result, std::nullopt);
14059 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
14060 E->getPackLoc());
14062 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
14063 typedef TemplateArgumentLocInventIterator<
14064 Derived, const TemplateArgument*> PackLocIterator;
14065 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
14066 PackLocIterator(*this, PackArgs.end()),
14067 TransformedPackArgs, /*Uneval*/true))
14068 return ExprError();
14071 // Check whether we managed to fully-expand the pack.
14072 // FIXME: Is it possible for us to do so and not hit the early exit path?
14073 SmallVector<TemplateArgument, 8> Args;
14074 bool PartialSubstitution = false;
14075 for (auto &Loc : TransformedPackArgs.arguments()) {
14076 Args.push_back(Loc.getArgument());
14077 if (Loc.getArgument().isPackExpansion())
14078 PartialSubstitution = true;
14081 if (PartialSubstitution)
14082 return getDerived().RebuildSizeOfPackExpr(
14083 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
14084 std::nullopt, Args);
14086 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
14087 E->getPackLoc(), E->getRParenLoc(),
14088 Args.size(), std::nullopt);
14091 template<typename Derived>
14092 ExprResult
14093 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
14094 SubstNonTypeTemplateParmPackExpr *E) {
14095 // Default behavior is to do nothing with this transformation.
14096 return E;
14099 template<typename Derived>
14100 ExprResult
14101 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
14102 SubstNonTypeTemplateParmExpr *E) {
14103 // Default behavior is to do nothing with this transformation.
14104 return E;
14107 template<typename Derived>
14108 ExprResult
14109 TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
14110 // Default behavior is to do nothing with this transformation.
14111 return E;
14114 template<typename Derived>
14115 ExprResult
14116 TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
14117 MaterializeTemporaryExpr *E) {
14118 return getDerived().TransformExpr(E->getSubExpr());
14121 template<typename Derived>
14122 ExprResult
14123 TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
14124 UnresolvedLookupExpr *Callee = nullptr;
14125 if (Expr *OldCallee = E->getCallee()) {
14126 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
14127 if (CalleeResult.isInvalid())
14128 return ExprError();
14129 Callee = cast<UnresolvedLookupExpr>(CalleeResult.get());
14132 Expr *Pattern = E->getPattern();
14134 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14135 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
14136 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
14138 // Determine whether the set of unexpanded parameter packs can and should
14139 // be expanded.
14140 bool Expand = true;
14141 bool RetainExpansion = false;
14142 std::optional<unsigned> OrigNumExpansions = E->getNumExpansions(),
14143 NumExpansions = OrigNumExpansions;
14144 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
14145 Pattern->getSourceRange(),
14146 Unexpanded,
14147 Expand, RetainExpansion,
14148 NumExpansions))
14149 return true;
14151 if (!Expand) {
14152 // Do not expand any packs here, just transform and rebuild a fold
14153 // expression.
14154 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14156 ExprResult LHS =
14157 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
14158 if (LHS.isInvalid())
14159 return true;
14161 ExprResult RHS =
14162 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
14163 if (RHS.isInvalid())
14164 return true;
14166 if (!getDerived().AlwaysRebuild() &&
14167 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
14168 return E;
14170 return getDerived().RebuildCXXFoldExpr(
14171 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
14172 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
14175 // Formally a fold expression expands to nested parenthesized expressions.
14176 // Enforce this limit to avoid creating trees so deep we can't safely traverse
14177 // them.
14178 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) {
14179 SemaRef.Diag(E->getEllipsisLoc(),
14180 clang::diag::err_fold_expression_limit_exceeded)
14181 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
14182 << E->getSourceRange();
14183 SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);
14184 return ExprError();
14187 // The transform has determined that we should perform an elementwise
14188 // expansion of the pattern. Do so.
14189 ExprResult Result = getDerived().TransformExpr(E->getInit());
14190 if (Result.isInvalid())
14191 return true;
14192 bool LeftFold = E->isLeftFold();
14194 // If we're retaining an expansion for a right fold, it is the innermost
14195 // component and takes the init (if any).
14196 if (!LeftFold && RetainExpansion) {
14197 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14199 ExprResult Out = getDerived().TransformExpr(Pattern);
14200 if (Out.isInvalid())
14201 return true;
14203 Result = getDerived().RebuildCXXFoldExpr(
14204 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
14205 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
14206 if (Result.isInvalid())
14207 return true;
14210 for (unsigned I = 0; I != *NumExpansions; ++I) {
14211 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(
14212 getSema(), LeftFold ? I : *NumExpansions - I - 1);
14213 ExprResult Out = getDerived().TransformExpr(Pattern);
14214 if (Out.isInvalid())
14215 return true;
14217 if (Out.get()->containsUnexpandedParameterPack()) {
14218 // We still have a pack; retain a pack expansion for this slice.
14219 Result = getDerived().RebuildCXXFoldExpr(
14220 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
14221 E->getOperator(), E->getEllipsisLoc(),
14222 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
14223 OrigNumExpansions);
14224 } else if (Result.isUsable()) {
14225 // We've got down to a single element; build a binary operator.
14226 Expr *LHS = LeftFold ? Result.get() : Out.get();
14227 Expr *RHS = LeftFold ? Out.get() : Result.get();
14228 if (Callee) {
14229 UnresolvedSet<16> Functions;
14230 Functions.append(Callee->decls_begin(), Callee->decls_end());
14231 Result = getDerived().RebuildCXXOperatorCallExpr(
14232 BinaryOperator::getOverloadedOperator(E->getOperator()),
14233 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
14234 Functions, LHS, RHS);
14235 } else {
14236 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
14237 E->getOperator(), LHS, RHS);
14239 } else
14240 Result = Out;
14242 if (Result.isInvalid())
14243 return true;
14246 // If we're retaining an expansion for a left fold, it is the outermost
14247 // component and takes the complete expansion so far as its init (if any).
14248 if (LeftFold && RetainExpansion) {
14249 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14251 ExprResult Out = getDerived().TransformExpr(Pattern);
14252 if (Out.isInvalid())
14253 return true;
14255 Result = getDerived().RebuildCXXFoldExpr(
14256 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
14257 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
14258 if (Result.isInvalid())
14259 return true;
14262 // If we had no init and an empty pack, and we're not retaining an expansion,
14263 // then produce a fallback value or error.
14264 if (Result.isUnset())
14265 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
14266 E->getOperator());
14268 return Result;
14271 template <typename Derived>
14272 ExprResult
14273 TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
14274 SmallVector<Expr *, 4> TransformedInits;
14275 ArrayRef<Expr *> InitExprs = E->getInitExprs();
14276 if (TransformExprs(InitExprs.data(), InitExprs.size(), true,
14277 TransformedInits))
14278 return ExprError();
14280 return getDerived().RebuildParenListExpr(E->getBeginLoc(), TransformedInits,
14281 E->getEndLoc());
14284 template<typename Derived>
14285 ExprResult
14286 TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
14287 CXXStdInitializerListExpr *E) {
14288 return getDerived().TransformExpr(E->getSubExpr());
14291 template<typename Derived>
14292 ExprResult
14293 TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
14294 return SemaRef.MaybeBindToTemporary(E);
14297 template<typename Derived>
14298 ExprResult
14299 TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
14300 return E;
14303 template<typename Derived>
14304 ExprResult
14305 TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
14306 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14307 if (SubExpr.isInvalid())
14308 return ExprError();
14310 if (!getDerived().AlwaysRebuild() &&
14311 SubExpr.get() == E->getSubExpr())
14312 return E;
14314 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
14317 template<typename Derived>
14318 ExprResult
14319 TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
14320 // Transform each of the elements.
14321 SmallVector<Expr *, 8> Elements;
14322 bool ArgChanged = false;
14323 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
14324 /*IsCall=*/false, Elements, &ArgChanged))
14325 return ExprError();
14327 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14328 return SemaRef.MaybeBindToTemporary(E);
14330 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
14331 Elements.data(),
14332 Elements.size());
14335 template<typename Derived>
14336 ExprResult
14337 TreeTransform<Derived>::TransformObjCDictionaryLiteral(
14338 ObjCDictionaryLiteral *E) {
14339 // Transform each of the elements.
14340 SmallVector<ObjCDictionaryElement, 8> Elements;
14341 bool ArgChanged = false;
14342 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
14343 ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);
14345 if (OrigElement.isPackExpansion()) {
14346 // This key/value element is a pack expansion.
14347 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14348 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
14349 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
14350 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
14352 // Determine whether the set of unexpanded parameter packs can
14353 // and should be expanded.
14354 bool Expand = true;
14355 bool RetainExpansion = false;
14356 std::optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
14357 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14358 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
14359 OrigElement.Value->getEndLoc());
14360 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
14361 PatternRange, Unexpanded, Expand,
14362 RetainExpansion, NumExpansions))
14363 return ExprError();
14365 if (!Expand) {
14366 // The transform has determined that we should perform a simple
14367 // transformation on the pack expansion, producing another pack
14368 // expansion.
14369 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14370 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14371 if (Key.isInvalid())
14372 return ExprError();
14374 if (Key.get() != OrigElement.Key)
14375 ArgChanged = true;
14377 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
14378 if (Value.isInvalid())
14379 return ExprError();
14381 if (Value.get() != OrigElement.Value)
14382 ArgChanged = true;
14384 ObjCDictionaryElement Expansion = {
14385 Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions
14387 Elements.push_back(Expansion);
14388 continue;
14391 // Record right away that the argument was changed. This needs
14392 // to happen even if the array expands to nothing.
14393 ArgChanged = true;
14395 // The transform has determined that we should perform an elementwise
14396 // expansion of the pattern. Do so.
14397 for (unsigned I = 0; I != *NumExpansions; ++I) {
14398 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14399 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14400 if (Key.isInvalid())
14401 return ExprError();
14403 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
14404 if (Value.isInvalid())
14405 return ExprError();
14407 ObjCDictionaryElement Element = {
14408 Key.get(), Value.get(), SourceLocation(), NumExpansions
14411 // If any unexpanded parameter packs remain, we still have a
14412 // pack expansion.
14413 // FIXME: Can this really happen?
14414 if (Key.get()->containsUnexpandedParameterPack() ||
14415 Value.get()->containsUnexpandedParameterPack())
14416 Element.EllipsisLoc = OrigElement.EllipsisLoc;
14418 Elements.push_back(Element);
14421 // FIXME: Retain a pack expansion if RetainExpansion is true.
14423 // We've finished with this pack expansion.
14424 continue;
14427 // Transform and check key.
14428 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14429 if (Key.isInvalid())
14430 return ExprError();
14432 if (Key.get() != OrigElement.Key)
14433 ArgChanged = true;
14435 // Transform and check value.
14436 ExprResult Value
14437 = getDerived().TransformExpr(OrigElement.Value);
14438 if (Value.isInvalid())
14439 return ExprError();
14441 if (Value.get() != OrigElement.Value)
14442 ArgChanged = true;
14444 ObjCDictionaryElement Element = {Key.get(), Value.get(), SourceLocation(),
14445 std::nullopt};
14446 Elements.push_back(Element);
14449 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14450 return SemaRef.MaybeBindToTemporary(E);
14452 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
14453 Elements);
14456 template<typename Derived>
14457 ExprResult
14458 TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
14459 TypeSourceInfo *EncodedTypeInfo
14460 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
14461 if (!EncodedTypeInfo)
14462 return ExprError();
14464 if (!getDerived().AlwaysRebuild() &&
14465 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
14466 return E;
14468 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
14469 EncodedTypeInfo,
14470 E->getRParenLoc());
14473 template<typename Derived>
14474 ExprResult TreeTransform<Derived>::
14475 TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
14476 // This is a kind of implicit conversion, and it needs to get dropped
14477 // and recomputed for the same general reasons that ImplicitCastExprs
14478 // do, as well a more specific one: this expression is only valid when
14479 // it appears *immediately* as an argument expression.
14480 return getDerived().TransformExpr(E->getSubExpr());
14483 template<typename Derived>
14484 ExprResult TreeTransform<Derived>::
14485 TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
14486 TypeSourceInfo *TSInfo
14487 = getDerived().TransformType(E->getTypeInfoAsWritten());
14488 if (!TSInfo)
14489 return ExprError();
14491 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
14492 if (Result.isInvalid())
14493 return ExprError();
14495 if (!getDerived().AlwaysRebuild() &&
14496 TSInfo == E->getTypeInfoAsWritten() &&
14497 Result.get() == E->getSubExpr())
14498 return E;
14500 return SemaRef.BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(),
14501 E->getBridgeKeywordLoc(), TSInfo,
14502 Result.get());
14505 template <typename Derived>
14506 ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
14507 ObjCAvailabilityCheckExpr *E) {
14508 return E;
14511 template<typename Derived>
14512 ExprResult
14513 TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
14514 // Transform arguments.
14515 bool ArgChanged = false;
14516 SmallVector<Expr*, 8> Args;
14517 Args.reserve(E->getNumArgs());
14518 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
14519 &ArgChanged))
14520 return ExprError();
14522 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
14523 // Class message: transform the receiver type.
14524 TypeSourceInfo *ReceiverTypeInfo
14525 = getDerived().TransformType(E->getClassReceiverTypeInfo());
14526 if (!ReceiverTypeInfo)
14527 return ExprError();
14529 // If nothing changed, just retain the existing message send.
14530 if (!getDerived().AlwaysRebuild() &&
14531 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
14532 return SemaRef.MaybeBindToTemporary(E);
14534 // Build a new class message send.
14535 SmallVector<SourceLocation, 16> SelLocs;
14536 E->getSelectorLocs(SelLocs);
14537 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
14538 E->getSelector(),
14539 SelLocs,
14540 E->getMethodDecl(),
14541 E->getLeftLoc(),
14542 Args,
14543 E->getRightLoc());
14545 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
14546 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
14547 if (!E->getMethodDecl())
14548 return ExprError();
14550 // Build a new class message send to 'super'.
14551 SmallVector<SourceLocation, 16> SelLocs;
14552 E->getSelectorLocs(SelLocs);
14553 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
14554 E->getSelector(),
14555 SelLocs,
14556 E->getReceiverType(),
14557 E->getMethodDecl(),
14558 E->getLeftLoc(),
14559 Args,
14560 E->getRightLoc());
14563 // Instance message: transform the receiver
14564 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
14565 "Only class and instance messages may be instantiated");
14566 ExprResult Receiver
14567 = getDerived().TransformExpr(E->getInstanceReceiver());
14568 if (Receiver.isInvalid())
14569 return ExprError();
14571 // If nothing changed, just retain the existing message send.
14572 if (!getDerived().AlwaysRebuild() &&
14573 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
14574 return SemaRef.MaybeBindToTemporary(E);
14576 // Build a new instance message send.
14577 SmallVector<SourceLocation, 16> SelLocs;
14578 E->getSelectorLocs(SelLocs);
14579 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
14580 E->getSelector(),
14581 SelLocs,
14582 E->getMethodDecl(),
14583 E->getLeftLoc(),
14584 Args,
14585 E->getRightLoc());
14588 template<typename Derived>
14589 ExprResult
14590 TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
14591 return E;
14594 template<typename Derived>
14595 ExprResult
14596 TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
14597 return E;
14600 template<typename Derived>
14601 ExprResult
14602 TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
14603 // Transform the base expression.
14604 ExprResult Base = getDerived().TransformExpr(E->getBase());
14605 if (Base.isInvalid())
14606 return ExprError();
14608 // We don't need to transform the ivar; it will never change.
14610 // If nothing changed, just retain the existing expression.
14611 if (!getDerived().AlwaysRebuild() &&
14612 Base.get() == E->getBase())
14613 return E;
14615 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
14616 E->getLocation(),
14617 E->isArrow(), E->isFreeIvar());
14620 template<typename Derived>
14621 ExprResult
14622 TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
14623 // 'super' and types never change. Property never changes. Just
14624 // retain the existing expression.
14625 if (!E->isObjectReceiver())
14626 return E;
14628 // Transform the base expression.
14629 ExprResult Base = getDerived().TransformExpr(E->getBase());
14630 if (Base.isInvalid())
14631 return ExprError();
14633 // We don't need to transform the property; it will never change.
14635 // If nothing changed, just retain the existing expression.
14636 if (!getDerived().AlwaysRebuild() &&
14637 Base.get() == E->getBase())
14638 return E;
14640 if (E->isExplicitProperty())
14641 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
14642 E->getExplicitProperty(),
14643 E->getLocation());
14645 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
14646 SemaRef.Context.PseudoObjectTy,
14647 E->getImplicitPropertyGetter(),
14648 E->getImplicitPropertySetter(),
14649 E->getLocation());
14652 template<typename Derived>
14653 ExprResult
14654 TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
14655 // Transform the base expression.
14656 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
14657 if (Base.isInvalid())
14658 return ExprError();
14660 // Transform the key expression.
14661 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
14662 if (Key.isInvalid())
14663 return ExprError();
14665 // If nothing changed, just retain the existing expression.
14666 if (!getDerived().AlwaysRebuild() &&
14667 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
14668 return E;
14670 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
14671 Base.get(), Key.get(),
14672 E->getAtIndexMethodDecl(),
14673 E->setAtIndexMethodDecl());
14676 template<typename Derived>
14677 ExprResult
14678 TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
14679 // Transform the base expression.
14680 ExprResult Base = getDerived().TransformExpr(E->getBase());
14681 if (Base.isInvalid())
14682 return ExprError();
14684 // If nothing changed, just retain the existing expression.
14685 if (!getDerived().AlwaysRebuild() &&
14686 Base.get() == E->getBase())
14687 return E;
14689 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
14690 E->getOpLoc(),
14691 E->isArrow());
14694 template<typename Derived>
14695 ExprResult
14696 TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
14697 bool ArgumentChanged = false;
14698 SmallVector<Expr*, 8> SubExprs;
14699 SubExprs.reserve(E->getNumSubExprs());
14700 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
14701 SubExprs, &ArgumentChanged))
14702 return ExprError();
14704 if (!getDerived().AlwaysRebuild() &&
14705 !ArgumentChanged)
14706 return E;
14708 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
14709 SubExprs,
14710 E->getRParenLoc());
14713 template<typename Derived>
14714 ExprResult
14715 TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
14716 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
14717 if (SrcExpr.isInvalid())
14718 return ExprError();
14720 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
14721 if (!Type)
14722 return ExprError();
14724 if (!getDerived().AlwaysRebuild() &&
14725 Type == E->getTypeSourceInfo() &&
14726 SrcExpr.get() == E->getSrcExpr())
14727 return E;
14729 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
14730 SrcExpr.get(), Type,
14731 E->getRParenLoc());
14734 template<typename Derived>
14735 ExprResult
14736 TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
14737 BlockDecl *oldBlock = E->getBlockDecl();
14739 SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr);
14740 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
14742 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
14743 blockScope->TheDecl->setBlockMissingReturnType(
14744 oldBlock->blockMissingReturnType());
14746 SmallVector<ParmVarDecl*, 4> params;
14747 SmallVector<QualType, 4> paramTypes;
14749 const FunctionProtoType *exprFunctionType = E->getFunctionType();
14751 // Parameter substitution.
14752 Sema::ExtParameterInfoBuilder extParamInfos;
14753 if (getDerived().TransformFunctionTypeParams(
14754 E->getCaretLocation(), oldBlock->parameters(), nullptr,
14755 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
14756 extParamInfos)) {
14757 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
14758 return ExprError();
14761 QualType exprResultType =
14762 getDerived().TransformType(exprFunctionType->getReturnType());
14764 auto epi = exprFunctionType->getExtProtoInfo();
14765 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size());
14767 QualType functionType =
14768 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
14769 blockScope->FunctionType = functionType;
14771 // Set the parameters on the block decl.
14772 if (!params.empty())
14773 blockScope->TheDecl->setParams(params);
14775 if (!oldBlock->blockMissingReturnType()) {
14776 blockScope->HasImplicitReturnType = false;
14777 blockScope->ReturnType = exprResultType;
14780 // Transform the body
14781 StmtResult body = getDerived().TransformStmt(E->getBody());
14782 if (body.isInvalid()) {
14783 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
14784 return ExprError();
14787 #ifndef NDEBUG
14788 // In builds with assertions, make sure that we captured everything we
14789 // captured before.
14790 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
14791 for (const auto &I : oldBlock->captures()) {
14792 VarDecl *oldCapture = I.getVariable();
14794 // Ignore parameter packs.
14795 if (oldCapture->isParameterPack())
14796 continue;
14798 VarDecl *newCapture =
14799 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
14800 oldCapture));
14801 assert(blockScope->CaptureMap.count(newCapture));
14804 // The this pointer may not be captured by the instantiated block, even when
14805 // it's captured by the original block, if the expression causing the
14806 // capture is in the discarded branch of a constexpr if statement.
14807 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
14808 "this pointer isn't captured in the old block");
14810 #endif
14812 return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(),
14813 /*Scope=*/nullptr);
14816 template<typename Derived>
14817 ExprResult
14818 TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
14819 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
14820 if (SrcExpr.isInvalid())
14821 return ExprError();
14823 QualType Type = getDerived().TransformType(E->getType());
14825 return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(),
14826 E->getRParenLoc());
14829 template<typename Derived>
14830 ExprResult
14831 TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
14832 bool ArgumentChanged = false;
14833 SmallVector<Expr*, 8> SubExprs;
14834 SubExprs.reserve(E->getNumSubExprs());
14835 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
14836 SubExprs, &ArgumentChanged))
14837 return ExprError();
14839 if (!getDerived().AlwaysRebuild() &&
14840 !ArgumentChanged)
14841 return E;
14843 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
14844 E->getOp(), E->getRParenLoc());
14847 //===----------------------------------------------------------------------===//
14848 // Type reconstruction
14849 //===----------------------------------------------------------------------===//
14851 template<typename Derived>
14852 QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
14853 SourceLocation Star) {
14854 return SemaRef.BuildPointerType(PointeeType, Star,
14855 getDerived().getBaseEntity());
14858 template<typename Derived>
14859 QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
14860 SourceLocation Star) {
14861 return SemaRef.BuildBlockPointerType(PointeeType, Star,
14862 getDerived().getBaseEntity());
14865 template<typename Derived>
14866 QualType
14867 TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
14868 bool WrittenAsLValue,
14869 SourceLocation Sigil) {
14870 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue,
14871 Sigil, getDerived().getBaseEntity());
14874 template<typename Derived>
14875 QualType
14876 TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
14877 QualType ClassType,
14878 SourceLocation Sigil) {
14879 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil,
14880 getDerived().getBaseEntity());
14883 template<typename Derived>
14884 QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
14885 const ObjCTypeParamDecl *Decl,
14886 SourceLocation ProtocolLAngleLoc,
14887 ArrayRef<ObjCProtocolDecl *> Protocols,
14888 ArrayRef<SourceLocation> ProtocolLocs,
14889 SourceLocation ProtocolRAngleLoc) {
14890 return SemaRef.BuildObjCTypeParamType(Decl,
14891 ProtocolLAngleLoc, Protocols,
14892 ProtocolLocs, ProtocolRAngleLoc,
14893 /*FailOnError=*/true);
14896 template<typename Derived>
14897 QualType TreeTransform<Derived>::RebuildObjCObjectType(
14898 QualType BaseType,
14899 SourceLocation Loc,
14900 SourceLocation TypeArgsLAngleLoc,
14901 ArrayRef<TypeSourceInfo *> TypeArgs,
14902 SourceLocation TypeArgsRAngleLoc,
14903 SourceLocation ProtocolLAngleLoc,
14904 ArrayRef<ObjCProtocolDecl *> Protocols,
14905 ArrayRef<SourceLocation> ProtocolLocs,
14906 SourceLocation ProtocolRAngleLoc) {
14907 return SemaRef.BuildObjCObjectType(BaseType, Loc, TypeArgsLAngleLoc, TypeArgs,
14908 TypeArgsRAngleLoc, ProtocolLAngleLoc,
14909 Protocols, ProtocolLocs, ProtocolRAngleLoc,
14910 /*FailOnError=*/true,
14911 /*Rebuilding=*/true);
14914 template<typename Derived>
14915 QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
14916 QualType PointeeType,
14917 SourceLocation Star) {
14918 return SemaRef.Context.getObjCObjectPointerType(PointeeType);
14921 template <typename Derived>
14922 QualType TreeTransform<Derived>::RebuildArrayType(
14923 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
14924 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
14925 if (SizeExpr || !Size)
14926 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
14927 IndexTypeQuals, BracketsRange,
14928 getDerived().getBaseEntity());
14930 QualType Types[] = {
14931 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
14932 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
14933 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
14935 QualType SizeType;
14936 for (const auto &T : Types)
14937 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
14938 SizeType = T;
14939 break;
14942 // Note that we can return a VariableArrayType here in the case where
14943 // the element type was a dependent VariableArrayType.
14944 IntegerLiteral *ArraySize
14945 = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType,
14946 /*FIXME*/BracketsRange.getBegin());
14947 return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize,
14948 IndexTypeQuals, BracketsRange,
14949 getDerived().getBaseEntity());
14952 template <typename Derived>
14953 QualType TreeTransform<Derived>::RebuildConstantArrayType(
14954 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
14955 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
14956 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
14957 IndexTypeQuals, BracketsRange);
14960 template <typename Derived>
14961 QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
14962 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
14963 SourceRange BracketsRange) {
14964 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
14965 IndexTypeQuals, BracketsRange);
14968 template <typename Derived>
14969 QualType TreeTransform<Derived>::RebuildVariableArrayType(
14970 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
14971 unsigned IndexTypeQuals, SourceRange BracketsRange) {
14972 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
14973 SizeExpr,
14974 IndexTypeQuals, BracketsRange);
14977 template <typename Derived>
14978 QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
14979 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
14980 unsigned IndexTypeQuals, SourceRange BracketsRange) {
14981 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
14982 SizeExpr,
14983 IndexTypeQuals, BracketsRange);
14986 template <typename Derived>
14987 QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
14988 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
14989 return SemaRef.BuildAddressSpaceAttr(PointeeType, AddrSpaceExpr,
14990 AttributeLoc);
14993 template <typename Derived>
14994 QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
14995 unsigned NumElements,
14996 VectorKind VecKind) {
14997 // FIXME: semantic checking!
14998 return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);
15001 template <typename Derived>
15002 QualType TreeTransform<Derived>::RebuildDependentVectorType(
15003 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
15004 VectorKind VecKind) {
15005 return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc);
15008 template<typename Derived>
15009 QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
15010 unsigned NumElements,
15011 SourceLocation AttributeLoc) {
15012 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
15013 NumElements, true);
15014 IntegerLiteral *VectorSize
15015 = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
15016 AttributeLoc);
15017 return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
15020 template<typename Derived>
15021 QualType
15022 TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
15023 Expr *SizeExpr,
15024 SourceLocation AttributeLoc) {
15025 return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
15028 template <typename Derived>
15029 QualType TreeTransform<Derived>::RebuildConstantMatrixType(
15030 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
15031 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
15032 NumColumns);
15035 template <typename Derived>
15036 QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
15037 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
15038 SourceLocation AttributeLoc) {
15039 return SemaRef.BuildMatrixType(ElementType, RowExpr, ColumnExpr,
15040 AttributeLoc);
15043 template<typename Derived>
15044 QualType TreeTransform<Derived>::RebuildFunctionProtoType(
15045 QualType T,
15046 MutableArrayRef<QualType> ParamTypes,
15047 const FunctionProtoType::ExtProtoInfo &EPI) {
15048 return SemaRef.BuildFunctionType(T, ParamTypes,
15049 getDerived().getBaseLocation(),
15050 getDerived().getBaseEntity(),
15051 EPI);
15054 template<typename Derived>
15055 QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
15056 return SemaRef.Context.getFunctionNoProtoType(T);
15059 template<typename Derived>
15060 QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
15061 Decl *D) {
15062 assert(D && "no decl found");
15063 if (D->isInvalidDecl()) return QualType();
15065 // FIXME: Doesn't account for ObjCInterfaceDecl!
15066 if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
15067 // A valid resolved using typename pack expansion decl can have multiple
15068 // UsingDecls, but they must each have exactly one type, and it must be
15069 // the same type in every case. But we must have at least one expansion!
15070 if (UPD->expansions().empty()) {
15071 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
15072 << UPD->isCXXClassMember() << UPD;
15073 return QualType();
15076 // We might still have some unresolved types. Try to pick a resolved type
15077 // if we can. The final instantiation will check that the remaining
15078 // unresolved types instantiate to the type we pick.
15079 QualType FallbackT;
15080 QualType T;
15081 for (auto *E : UPD->expansions()) {
15082 QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
15083 if (ThisT.isNull())
15084 continue;
15085 else if (ThisT->getAs<UnresolvedUsingType>())
15086 FallbackT = ThisT;
15087 else if (T.isNull())
15088 T = ThisT;
15089 else
15090 assert(getSema().Context.hasSameType(ThisT, T) &&
15091 "mismatched resolved types in using pack expansion");
15093 return T.isNull() ? FallbackT : T;
15094 } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
15095 assert(Using->hasTypename() &&
15096 "UnresolvedUsingTypenameDecl transformed to non-typename using");
15098 // A valid resolved using typename decl points to exactly one type decl.
15099 assert(++Using->shadow_begin() == Using->shadow_end());
15101 UsingShadowDecl *Shadow = *Using->shadow_begin();
15102 if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), Loc))
15103 return QualType();
15104 return SemaRef.Context.getUsingType(
15105 Shadow, SemaRef.Context.getTypeDeclType(
15106 cast<TypeDecl>(Shadow->getTargetDecl())));
15107 } else {
15108 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
15109 "UnresolvedUsingTypenameDecl transformed to non-using decl");
15110 return SemaRef.Context.getTypeDeclType(
15111 cast<UnresolvedUsingTypenameDecl>(D));
15115 template <typename Derived>
15116 QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
15117 TypeOfKind Kind) {
15118 return SemaRef.BuildTypeofExprType(E, Kind);
15121 template<typename Derived>
15122 QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
15123 TypeOfKind Kind) {
15124 return SemaRef.Context.getTypeOfType(Underlying, Kind);
15127 template <typename Derived>
15128 QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
15129 return SemaRef.BuildDecltypeType(E);
15132 template<typename Derived>
15133 QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
15134 UnaryTransformType::UTTKind UKind,
15135 SourceLocation Loc) {
15136 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
15139 template<typename Derived>
15140 QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
15141 TemplateName Template,
15142 SourceLocation TemplateNameLoc,
15143 TemplateArgumentListInfo &TemplateArgs) {
15144 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
15147 template<typename Derived>
15148 QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
15149 SourceLocation KWLoc) {
15150 return SemaRef.BuildAtomicType(ValueType, KWLoc);
15153 template<typename Derived>
15154 QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
15155 SourceLocation KWLoc,
15156 bool isReadPipe) {
15157 return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc)
15158 : SemaRef.BuildWritePipeType(ValueType, KWLoc);
15161 template <typename Derived>
15162 QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
15163 unsigned NumBits,
15164 SourceLocation Loc) {
15165 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
15166 NumBits, true);
15167 IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,
15168 SemaRef.Context.IntTy, Loc);
15169 return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc);
15172 template <typename Derived>
15173 QualType TreeTransform<Derived>::RebuildDependentBitIntType(
15174 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
15175 return SemaRef.BuildBitIntType(IsUnsigned, NumBitsExpr, Loc);
15178 template<typename Derived>
15179 TemplateName
15180 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15181 bool TemplateKW,
15182 TemplateDecl *Template) {
15183 return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW,
15184 TemplateName(Template));
15187 template<typename Derived>
15188 TemplateName
15189 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15190 SourceLocation TemplateKWLoc,
15191 const IdentifierInfo &Name,
15192 SourceLocation NameLoc,
15193 QualType ObjectType,
15194 NamedDecl *FirstQualifierInScope,
15195 bool AllowInjectedClassName) {
15196 UnqualifiedId TemplateName;
15197 TemplateName.setIdentifier(&Name, NameLoc);
15198 Sema::TemplateTy Template;
15199 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
15200 TemplateName, ParsedType::make(ObjectType),
15201 /*EnteringContext=*/false, Template,
15202 AllowInjectedClassName);
15203 return Template.get();
15206 template<typename Derived>
15207 TemplateName
15208 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15209 SourceLocation TemplateKWLoc,
15210 OverloadedOperatorKind Operator,
15211 SourceLocation NameLoc,
15212 QualType ObjectType,
15213 bool AllowInjectedClassName) {
15214 UnqualifiedId Name;
15215 // FIXME: Bogus location information.
15216 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
15217 Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);
15218 Sema::TemplateTy Template;
15219 getSema().ActOnTemplateName(
15220 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(ObjectType),
15221 /*EnteringContext=*/false, Template, AllowInjectedClassName);
15222 return Template.get();
15225 template <typename Derived>
15226 ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
15227 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
15228 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
15229 Expr *Second) {
15230 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
15232 if (First->getObjectKind() == OK_ObjCProperty) {
15233 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
15234 if (BinaryOperator::isAssignmentOp(Opc))
15235 return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc, Opc,
15236 First, Second);
15237 ExprResult Result = SemaRef.CheckPlaceholderExpr(First);
15238 if (Result.isInvalid())
15239 return ExprError();
15240 First = Result.get();
15243 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
15244 ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
15245 if (Result.isInvalid())
15246 return ExprError();
15247 Second = Result.get();
15250 // Determine whether this should be a builtin operation.
15251 if (Op == OO_Subscript) {
15252 if (!First->getType()->isOverloadableType() &&
15253 !Second->getType()->isOverloadableType())
15254 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
15255 OpLoc);
15256 } else if (Op == OO_Arrow) {
15257 // It is possible that the type refers to a RecoveryExpr created earlier
15258 // in the tree transformation.
15259 if (First->getType()->isDependentType())
15260 return ExprError();
15261 // -> is never a builtin operation.
15262 return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);
15263 } else if (Second == nullptr || isPostIncDec) {
15264 if (!First->getType()->isOverloadableType() ||
15265 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
15266 // The argument is not of overloadable type, or this is an expression
15267 // of the form &Class::member, so try to create a built-in unary
15268 // operation.
15269 UnaryOperatorKind Opc
15270 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
15272 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
15274 } else {
15275 if (!First->getType()->isOverloadableType() &&
15276 !Second->getType()->isOverloadableType()) {
15277 // Neither of the arguments is an overloadable type, so try to
15278 // create a built-in binary operation.
15279 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
15280 ExprResult Result
15281 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
15282 if (Result.isInvalid())
15283 return ExprError();
15285 return Result;
15289 // Add any functions found via argument-dependent lookup.
15290 Expr *Args[2] = { First, Second };
15291 unsigned NumArgs = 1 + (Second != nullptr);
15293 // Create the overloaded operator invocation for unary operators.
15294 if (NumArgs == 1 || isPostIncDec) {
15295 UnaryOperatorKind Opc
15296 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
15297 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First,
15298 RequiresADL);
15301 // Create the overloaded operator invocation for binary operators.
15302 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
15303 ExprResult Result = SemaRef.CreateOverloadedBinOp(
15304 OpLoc, Opc, Functions, Args[0], Args[1], RequiresADL);
15305 if (Result.isInvalid())
15306 return ExprError();
15308 return Result;
15311 template<typename Derived>
15312 ExprResult
15313 TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
15314 SourceLocation OperatorLoc,
15315 bool isArrow,
15316 CXXScopeSpec &SS,
15317 TypeSourceInfo *ScopeType,
15318 SourceLocation CCLoc,
15319 SourceLocation TildeLoc,
15320 PseudoDestructorTypeStorage Destroyed) {
15321 QualType BaseType = Base->getType();
15322 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
15323 (!isArrow && !BaseType->getAs<RecordType>()) ||
15324 (isArrow && BaseType->getAs<PointerType>() &&
15325 !BaseType->castAs<PointerType>()->getPointeeType()
15326 ->template getAs<RecordType>())){
15327 // This pseudo-destructor expression is still a pseudo-destructor.
15328 return SemaRef.BuildPseudoDestructorExpr(
15329 Base, OperatorLoc, isArrow ? tok::arrow : tok::period, SS, ScopeType,
15330 CCLoc, TildeLoc, Destroyed);
15333 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
15334 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
15335 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
15336 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
15337 NameInfo.setNamedTypeInfo(DestroyedType);
15339 // The scope type is now known to be a valid nested name specifier
15340 // component. Tack it on to the end of the nested name specifier.
15341 if (ScopeType) {
15342 if (!ScopeType->getType()->getAs<TagType>()) {
15343 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
15344 diag::err_expected_class_or_namespace)
15345 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
15346 return ExprError();
15348 SS.Extend(SemaRef.Context, SourceLocation(), ScopeType->getTypeLoc(),
15349 CCLoc);
15352 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
15353 return getSema().BuildMemberReferenceExpr(Base, BaseType,
15354 OperatorLoc, isArrow,
15355 SS, TemplateKWLoc,
15356 /*FIXME: FirstQualifier*/ nullptr,
15357 NameInfo,
15358 /*TemplateArgs*/ nullptr,
15359 /*S*/nullptr);
15362 template<typename Derived>
15363 StmtResult
15364 TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
15365 SourceLocation Loc = S->getBeginLoc();
15366 CapturedDecl *CD = S->getCapturedDecl();
15367 unsigned NumParams = CD->getNumParams();
15368 unsigned ContextParamPos = CD->getContextParamPosition();
15369 SmallVector<Sema::CapturedParamNameType, 4> Params;
15370 for (unsigned I = 0; I < NumParams; ++I) {
15371 if (I != ContextParamPos) {
15372 Params.push_back(
15373 std::make_pair(
15374 CD->getParam(I)->getName(),
15375 getDerived().TransformType(CD->getParam(I)->getType())));
15376 } else {
15377 Params.push_back(std::make_pair(StringRef(), QualType()));
15380 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
15381 S->getCapturedRegionKind(), Params);
15382 StmtResult Body;
15384 Sema::CompoundScopeRAII CompoundScope(getSema());
15385 Body = getDerived().TransformStmt(S->getCapturedStmt());
15388 if (Body.isInvalid()) {
15389 getSema().ActOnCapturedRegionError();
15390 return StmtError();
15393 return getSema().ActOnCapturedRegionEnd(Body.get());
15396 } // end namespace clang
15398 #endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H