[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / lib / Sema / TreeTransform.h
blob22357d55d37331bf3e0045a159791e7e55c04986
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) << SomeDecl
1213 << NTK << 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 << Kind << Id << DC << QualifierLoc.getSourceRange();
1220 break;
1222 return QualType();
1225 if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false,
1226 IdLoc, Id)) {
1227 SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
1228 SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
1229 return QualType();
1232 // Build the elaborated-type-specifier type.
1233 QualType T = SemaRef.Context.getTypeDeclType(Tag);
1234 return SemaRef.Context.getElaboratedType(Keyword,
1235 QualifierLoc.getNestedNameSpecifier(),
1239 /// Build a new pack expansion type.
1241 /// By default, builds a new PackExpansionType type from the given pattern.
1242 /// Subclasses may override this routine to provide different behavior.
1243 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1244 SourceLocation EllipsisLoc,
1245 std::optional<unsigned> NumExpansions) {
1246 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1247 NumExpansions);
1250 /// Build a new atomic type given its value type.
1252 /// By default, performs semantic analysis when building the atomic type.
1253 /// Subclasses may override this routine to provide different behavior.
1254 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1256 /// Build a new pipe type given its value type.
1257 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1258 bool isReadPipe);
1260 /// Build a bit-precise int given its value type.
1261 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1262 SourceLocation Loc);
1264 /// Build a dependent bit-precise int given its value type.
1265 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1266 SourceLocation Loc);
1268 /// Build a new template name given a nested name specifier, a flag
1269 /// indicating whether the "template" keyword was provided, and the template
1270 /// that the template name refers to.
1272 /// By default, builds the new template name directly. Subclasses may override
1273 /// this routine to provide different behavior.
1274 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1275 bool TemplateKW,
1276 TemplateDecl *Template);
1278 /// Build a new template name given a nested name specifier and the
1279 /// name that is referred to as a template.
1281 /// By default, performs semantic analysis to determine whether the name can
1282 /// be resolved to a specific template, then builds the appropriate kind of
1283 /// template name. Subclasses may override this routine to provide different
1284 /// behavior.
1285 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1286 SourceLocation TemplateKWLoc,
1287 const IdentifierInfo &Name,
1288 SourceLocation NameLoc, QualType ObjectType,
1289 NamedDecl *FirstQualifierInScope,
1290 bool AllowInjectedClassName);
1292 /// Build a new template name given a nested name specifier and the
1293 /// overloaded operator name that is referred to as a template.
1295 /// By default, performs semantic analysis to determine whether the name can
1296 /// be resolved to a specific template, then builds the appropriate kind of
1297 /// template name. Subclasses may override this routine to provide different
1298 /// behavior.
1299 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1300 SourceLocation TemplateKWLoc,
1301 OverloadedOperatorKind Operator,
1302 SourceLocation NameLoc, QualType ObjectType,
1303 bool AllowInjectedClassName);
1305 /// Build a new template name given a template template parameter pack
1306 /// and the
1308 /// By default, performs semantic analysis to determine whether the name can
1309 /// be resolved to a specific template, then builds the appropriate kind of
1310 /// template name. Subclasses may override this routine to provide different
1311 /// behavior.
1312 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1313 Decl *AssociatedDecl, unsigned Index,
1314 bool Final) {
1315 return getSema().Context.getSubstTemplateTemplateParmPack(
1316 ArgPack, AssociatedDecl, Index, Final);
1319 /// Build a new compound statement.
1321 /// By default, performs semantic analysis to build the new statement.
1322 /// Subclasses may override this routine to provide different behavior.
1323 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1324 MultiStmtArg Statements,
1325 SourceLocation RBraceLoc,
1326 bool IsStmtExpr) {
1327 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1328 IsStmtExpr);
1331 /// Build a new case statement.
1333 /// By default, performs semantic analysis to build the new statement.
1334 /// Subclasses may override this routine to provide different behavior.
1335 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1336 Expr *LHS,
1337 SourceLocation EllipsisLoc,
1338 Expr *RHS,
1339 SourceLocation ColonLoc) {
1340 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1341 ColonLoc);
1344 /// Attach the body to a new case statement.
1346 /// By default, performs semantic analysis to build the new statement.
1347 /// Subclasses may override this routine to provide different behavior.
1348 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1349 getSema().ActOnCaseStmtBody(S, Body);
1350 return S;
1353 /// Build a new default statement.
1355 /// By default, performs semantic analysis to build the new statement.
1356 /// Subclasses may override this routine to provide different behavior.
1357 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1358 SourceLocation ColonLoc,
1359 Stmt *SubStmt) {
1360 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1361 /*CurScope=*/nullptr);
1364 /// Build a new label statement.
1366 /// By default, performs semantic analysis to build the new statement.
1367 /// Subclasses may override this routine to provide different behavior.
1368 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1369 SourceLocation ColonLoc, Stmt *SubStmt) {
1370 return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt);
1373 /// Build a new attributed statement.
1375 /// By default, performs semantic analysis to build the new statement.
1376 /// Subclasses may override this routine to provide different behavior.
1377 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1378 ArrayRef<const Attr *> Attrs,
1379 Stmt *SubStmt) {
1380 return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt);
1383 /// Build a new "if" statement.
1385 /// By default, performs semantic analysis to build the new statement.
1386 /// Subclasses may override this routine to provide different behavior.
1387 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1388 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1389 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1390 SourceLocation ElseLoc, Stmt *Else) {
1391 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1392 Then, ElseLoc, Else);
1395 /// Start building a new switch statement.
1397 /// By default, performs semantic analysis to build the new statement.
1398 /// Subclasses may override this routine to provide different behavior.
1399 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1400 SourceLocation LParenLoc, Stmt *Init,
1401 Sema::ConditionResult Cond,
1402 SourceLocation RParenLoc) {
1403 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1404 RParenLoc);
1407 /// Attach the body to the switch statement.
1409 /// By default, performs semantic analysis to build the new statement.
1410 /// Subclasses may override this routine to provide different behavior.
1411 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1412 Stmt *Switch, Stmt *Body) {
1413 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1416 /// Build a new while statement.
1418 /// By default, performs semantic analysis to build the new statement.
1419 /// Subclasses may override this routine to provide different behavior.
1420 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1421 Sema::ConditionResult Cond,
1422 SourceLocation RParenLoc, Stmt *Body) {
1423 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1426 /// Build a new do-while statement.
1428 /// By default, performs semantic analysis to build the new statement.
1429 /// Subclasses may override this routine to provide different behavior.
1430 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1431 SourceLocation WhileLoc, SourceLocation LParenLoc,
1432 Expr *Cond, SourceLocation RParenLoc) {
1433 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1434 Cond, RParenLoc);
1437 /// Build a new for statement.
1439 /// By default, performs semantic analysis to build the new statement.
1440 /// Subclasses may override this routine to provide different behavior.
1441 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1442 Stmt *Init, Sema::ConditionResult Cond,
1443 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1444 Stmt *Body) {
1445 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1446 Inc, RParenLoc, Body);
1449 /// Build a new goto statement.
1451 /// By default, performs semantic analysis to build the new statement.
1452 /// Subclasses may override this routine to provide different behavior.
1453 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1454 LabelDecl *Label) {
1455 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1458 /// Build a new indirect goto statement.
1460 /// By default, performs semantic analysis to build the new statement.
1461 /// Subclasses may override this routine to provide different behavior.
1462 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1463 SourceLocation StarLoc,
1464 Expr *Target) {
1465 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1468 /// Build a new return statement.
1470 /// By default, performs semantic analysis to build the new statement.
1471 /// Subclasses may override this routine to provide different behavior.
1472 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1473 return getSema().BuildReturnStmt(ReturnLoc, Result);
1476 /// Build a new declaration statement.
1478 /// By default, performs semantic analysis to build the new statement.
1479 /// Subclasses may override this routine to provide different behavior.
1480 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1481 SourceLocation StartLoc, SourceLocation EndLoc) {
1482 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1483 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1486 /// Build a new inline asm statement.
1488 /// By default, performs semantic analysis to build the new statement.
1489 /// Subclasses may override this routine to provide different behavior.
1490 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1491 bool IsVolatile, unsigned NumOutputs,
1492 unsigned NumInputs, IdentifierInfo **Names,
1493 MultiExprArg Constraints, MultiExprArg Exprs,
1494 Expr *AsmString, MultiExprArg Clobbers,
1495 unsigned NumLabels,
1496 SourceLocation RParenLoc) {
1497 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1498 NumInputs, Names, Constraints, Exprs,
1499 AsmString, Clobbers, NumLabels, RParenLoc);
1502 /// Build a new MS style inline asm statement.
1504 /// By default, performs semantic analysis to build the new statement.
1505 /// Subclasses may override this routine to provide different behavior.
1506 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1507 ArrayRef<Token> AsmToks,
1508 StringRef AsmString,
1509 unsigned NumOutputs, unsigned NumInputs,
1510 ArrayRef<StringRef> Constraints,
1511 ArrayRef<StringRef> Clobbers,
1512 ArrayRef<Expr*> Exprs,
1513 SourceLocation EndLoc) {
1514 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1515 NumOutputs, NumInputs,
1516 Constraints, Clobbers, Exprs, EndLoc);
1519 /// Build a new co_return statement.
1521 /// By default, performs semantic analysis to build the new statement.
1522 /// Subclasses may override this routine to provide different behavior.
1523 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1524 bool IsImplicit) {
1525 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1528 /// Build a new co_await expression.
1530 /// By default, performs semantic analysis to build the new expression.
1531 /// Subclasses may override this routine to provide different behavior.
1532 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1533 UnresolvedLookupExpr *OpCoawaitLookup,
1534 bool IsImplicit) {
1535 // This function rebuilds a coawait-expr given its operator.
1536 // For an explicit coawait-expr, the rebuild involves the full set
1537 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1538 // including calling await_transform().
1539 // For an implicit coawait-expr, we need to rebuild the "operator
1540 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1541 // This mirrors how the implicit CoawaitExpr is originally created
1542 // in Sema::ActOnCoroutineBodyStart().
1543 if (IsImplicit) {
1544 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1545 CoawaitLoc, Operand, OpCoawaitLookup);
1546 if (Suspend.isInvalid())
1547 return ExprError();
1548 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1549 Suspend.get(), true);
1552 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1553 OpCoawaitLookup);
1556 /// Build a new co_await expression.
1558 /// By default, performs semantic analysis to build the new expression.
1559 /// Subclasses may override this routine to provide different behavior.
1560 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1561 Expr *Result,
1562 UnresolvedLookupExpr *Lookup) {
1563 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1566 /// Build a new co_yield expression.
1568 /// By default, performs semantic analysis to build the new expression.
1569 /// Subclasses may override this routine to provide different behavior.
1570 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1571 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1574 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1575 return getSema().BuildCoroutineBodyStmt(Args);
1578 /// Build a new Objective-C \@try statement.
1580 /// By default, performs semantic analysis to build the new statement.
1581 /// Subclasses may override this routine to provide different behavior.
1582 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1583 Stmt *TryBody,
1584 MultiStmtArg CatchStmts,
1585 Stmt *Finally) {
1586 return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1587 Finally);
1590 /// Rebuild an Objective-C exception declaration.
1592 /// By default, performs semantic analysis to build the new declaration.
1593 /// Subclasses may override this routine to provide different behavior.
1594 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1595 TypeSourceInfo *TInfo, QualType T) {
1596 return getSema().BuildObjCExceptionDecl(TInfo, T,
1597 ExceptionDecl->getInnerLocStart(),
1598 ExceptionDecl->getLocation(),
1599 ExceptionDecl->getIdentifier());
1602 /// Build a new Objective-C \@catch statement.
1604 /// By default, performs semantic analysis to build the new statement.
1605 /// Subclasses may override this routine to provide different behavior.
1606 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1607 SourceLocation RParenLoc,
1608 VarDecl *Var,
1609 Stmt *Body) {
1610 return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
1611 Var, Body);
1614 /// Build a new Objective-C \@finally statement.
1616 /// By default, performs semantic analysis to build the new statement.
1617 /// Subclasses may override this routine to provide different behavior.
1618 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1619 Stmt *Body) {
1620 return getSema().ActOnObjCAtFinallyStmt(AtLoc, Body);
1623 /// Build a new Objective-C \@throw statement.
1625 /// By default, performs semantic analysis to build the new statement.
1626 /// Subclasses may override this routine to provide different behavior.
1627 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1628 Expr *Operand) {
1629 return getSema().BuildObjCAtThrowStmt(AtLoc, Operand);
1632 /// Build a new OpenMP Canonical loop.
1634 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1635 /// OMPCanonicalLoop.
1636 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1637 return getSema().ActOnOpenMPCanonicalLoop(LoopStmt);
1640 /// Build a new OpenMP executable directive.
1642 /// By default, performs semantic analysis to build the new statement.
1643 /// Subclasses may override this routine to provide different behavior.
1644 StmtResult RebuildOMPExecutableDirective(
1645 OpenMPDirectiveKind Kind, DeclarationNameInfo DirName,
1646 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
1647 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
1648 OpenMPDirectiveKind PrevMappedDirective = OMPD_unknown) {
1650 return getSema().ActOnOpenMPExecutableDirective(
1651 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc,
1652 PrevMappedDirective);
1655 /// Build a new OpenMP 'if' clause.
1657 /// By default, performs semantic analysis to build the new OpenMP clause.
1658 /// Subclasses may override this routine to provide different behavior.
1659 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1660 Expr *Condition, SourceLocation StartLoc,
1661 SourceLocation LParenLoc,
1662 SourceLocation NameModifierLoc,
1663 SourceLocation ColonLoc,
1664 SourceLocation EndLoc) {
1665 return getSema().ActOnOpenMPIfClause(NameModifier, Condition, StartLoc,
1666 LParenLoc, NameModifierLoc, ColonLoc,
1667 EndLoc);
1670 /// Build a new OpenMP 'final' clause.
1672 /// By default, performs semantic analysis to build the new OpenMP clause.
1673 /// Subclasses may override this routine to provide different behavior.
1674 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1675 SourceLocation LParenLoc,
1676 SourceLocation EndLoc) {
1677 return getSema().ActOnOpenMPFinalClause(Condition, StartLoc, LParenLoc,
1678 EndLoc);
1681 /// Build a new OpenMP 'num_threads' clause.
1683 /// By default, performs semantic analysis to build the new OpenMP clause.
1684 /// Subclasses may override this routine to provide different behavior.
1685 OMPClause *RebuildOMPNumThreadsClause(Expr *NumThreads,
1686 SourceLocation StartLoc,
1687 SourceLocation LParenLoc,
1688 SourceLocation EndLoc) {
1689 return getSema().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc,
1690 LParenLoc, EndLoc);
1693 /// Build a new OpenMP 'safelen' clause.
1695 /// By default, performs semantic analysis to build the new OpenMP clause.
1696 /// Subclasses may override this routine to provide different behavior.
1697 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1698 SourceLocation LParenLoc,
1699 SourceLocation EndLoc) {
1700 return getSema().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc, EndLoc);
1703 /// Build a new OpenMP 'simdlen' clause.
1705 /// By default, performs semantic analysis to build the new OpenMP clause.
1706 /// Subclasses may override this routine to provide different behavior.
1707 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1708 SourceLocation LParenLoc,
1709 SourceLocation EndLoc) {
1710 return getSema().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc, EndLoc);
1713 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1714 SourceLocation StartLoc,
1715 SourceLocation LParenLoc,
1716 SourceLocation EndLoc) {
1717 return getSema().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc, EndLoc);
1720 /// Build a new OpenMP 'full' clause.
1721 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1722 SourceLocation EndLoc) {
1723 return getSema().ActOnOpenMPFullClause(StartLoc, EndLoc);
1726 /// Build a new OpenMP 'partial' clause.
1727 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1728 SourceLocation LParenLoc,
1729 SourceLocation EndLoc) {
1730 return getSema().ActOnOpenMPPartialClause(Factor, StartLoc, LParenLoc,
1731 EndLoc);
1734 /// Build a new OpenMP 'allocator' clause.
1736 /// By default, performs semantic analysis to build the new OpenMP clause.
1737 /// Subclasses may override this routine to provide different behavior.
1738 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1739 SourceLocation LParenLoc,
1740 SourceLocation EndLoc) {
1741 return getSema().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc, EndLoc);
1744 /// Build a new OpenMP 'collapse' clause.
1746 /// By default, performs semantic analysis to build the new OpenMP clause.
1747 /// Subclasses may override this routine to provide different behavior.
1748 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1749 SourceLocation LParenLoc,
1750 SourceLocation EndLoc) {
1751 return getSema().ActOnOpenMPCollapseClause(Num, StartLoc, LParenLoc,
1752 EndLoc);
1755 /// Build a new OpenMP 'default' clause.
1757 /// By default, performs semantic analysis to build the new OpenMP clause.
1758 /// Subclasses may override this routine to provide different behavior.
1759 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1760 SourceLocation StartLoc,
1761 SourceLocation LParenLoc,
1762 SourceLocation EndLoc) {
1763 return getSema().ActOnOpenMPDefaultClause(Kind, KindKwLoc,
1764 StartLoc, LParenLoc, EndLoc);
1767 /// Build a new OpenMP 'proc_bind' clause.
1769 /// By default, performs semantic analysis to build the new OpenMP clause.
1770 /// Subclasses may override this routine to provide different behavior.
1771 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1772 SourceLocation KindKwLoc,
1773 SourceLocation StartLoc,
1774 SourceLocation LParenLoc,
1775 SourceLocation EndLoc) {
1776 return getSema().ActOnOpenMPProcBindClause(Kind, KindKwLoc,
1777 StartLoc, LParenLoc, EndLoc);
1780 /// Build a new OpenMP 'schedule' clause.
1782 /// By default, performs semantic analysis to build the new OpenMP clause.
1783 /// Subclasses may override this routine to provide different behavior.
1784 OMPClause *RebuildOMPScheduleClause(
1785 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1786 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1787 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1788 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1789 return getSema().ActOnOpenMPScheduleClause(
1790 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1791 CommaLoc, EndLoc);
1794 /// Build a new OpenMP 'ordered' clause.
1796 /// By default, performs semantic analysis to build the new OpenMP clause.
1797 /// Subclasses may override this routine to provide different behavior.
1798 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1799 SourceLocation EndLoc,
1800 SourceLocation LParenLoc, Expr *Num) {
1801 return getSema().ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Num);
1804 /// Build a new OpenMP 'private' clause.
1806 /// By default, performs semantic analysis to build the new OpenMP clause.
1807 /// Subclasses may override this routine to provide different behavior.
1808 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1809 SourceLocation StartLoc,
1810 SourceLocation LParenLoc,
1811 SourceLocation EndLoc) {
1812 return getSema().ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc,
1813 EndLoc);
1816 /// Build a new OpenMP 'firstprivate' clause.
1818 /// By default, performs semantic analysis to build the new OpenMP clause.
1819 /// Subclasses may override this routine to provide different behavior.
1820 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1821 SourceLocation StartLoc,
1822 SourceLocation LParenLoc,
1823 SourceLocation EndLoc) {
1824 return getSema().ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc,
1825 EndLoc);
1828 /// Build a new OpenMP 'lastprivate' clause.
1830 /// By default, performs semantic analysis to build the new OpenMP clause.
1831 /// Subclasses may override this routine to provide different behavior.
1832 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1833 OpenMPLastprivateModifier LPKind,
1834 SourceLocation LPKindLoc,
1835 SourceLocation ColonLoc,
1836 SourceLocation StartLoc,
1837 SourceLocation LParenLoc,
1838 SourceLocation EndLoc) {
1839 return getSema().ActOnOpenMPLastprivateClause(
1840 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1843 /// Build a new OpenMP 'shared' clause.
1845 /// By default, performs semantic analysis to build the new OpenMP clause.
1846 /// Subclasses may override this routine to provide different behavior.
1847 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1848 SourceLocation StartLoc,
1849 SourceLocation LParenLoc,
1850 SourceLocation EndLoc) {
1851 return getSema().ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc,
1852 EndLoc);
1855 /// Build a new OpenMP 'reduction' clause.
1857 /// By default, performs semantic analysis to build the new statement.
1858 /// Subclasses may override this routine to provide different behavior.
1859 OMPClause *RebuildOMPReductionClause(
1860 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1861 SourceLocation StartLoc, SourceLocation LParenLoc,
1862 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1863 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1864 const DeclarationNameInfo &ReductionId,
1865 ArrayRef<Expr *> UnresolvedReductions) {
1866 return getSema().ActOnOpenMPReductionClause(
1867 VarList, Modifier, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
1868 ReductionIdScopeSpec, ReductionId, UnresolvedReductions);
1871 /// Build a new OpenMP 'task_reduction' clause.
1873 /// By default, performs semantic analysis to build the new statement.
1874 /// Subclasses may override this routine to provide different behavior.
1875 OMPClause *RebuildOMPTaskReductionClause(
1876 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1877 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1878 CXXScopeSpec &ReductionIdScopeSpec,
1879 const DeclarationNameInfo &ReductionId,
1880 ArrayRef<Expr *> UnresolvedReductions) {
1881 return getSema().ActOnOpenMPTaskReductionClause(
1882 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1883 ReductionId, UnresolvedReductions);
1886 /// Build a new OpenMP 'in_reduction' clause.
1888 /// By default, performs semantic analysis to build the new statement.
1889 /// Subclasses may override this routine to provide different behavior.
1890 OMPClause *
1891 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1892 SourceLocation LParenLoc, SourceLocation ColonLoc,
1893 SourceLocation EndLoc,
1894 CXXScopeSpec &ReductionIdScopeSpec,
1895 const DeclarationNameInfo &ReductionId,
1896 ArrayRef<Expr *> UnresolvedReductions) {
1897 return getSema().ActOnOpenMPInReductionClause(
1898 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1899 ReductionId, UnresolvedReductions);
1902 /// Build a new OpenMP 'linear' clause.
1904 /// By default, performs semantic analysis to build the new OpenMP clause.
1905 /// Subclasses may override this routine to provide different behavior.
1906 OMPClause *RebuildOMPLinearClause(
1907 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1908 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1909 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1910 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
1911 return getSema().ActOnOpenMPLinearClause(VarList, Step, StartLoc, LParenLoc,
1912 Modifier, ModifierLoc, ColonLoc,
1913 StepModifierLoc, EndLoc);
1916 /// Build a new OpenMP 'aligned' clause.
1918 /// By default, performs semantic analysis to build the new OpenMP clause.
1919 /// Subclasses may override this routine to provide different behavior.
1920 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
1921 SourceLocation StartLoc,
1922 SourceLocation LParenLoc,
1923 SourceLocation ColonLoc,
1924 SourceLocation EndLoc) {
1925 return getSema().ActOnOpenMPAlignedClause(VarList, Alignment, StartLoc,
1926 LParenLoc, ColonLoc, EndLoc);
1929 /// Build a new OpenMP 'copyin' clause.
1931 /// By default, performs semantic analysis to build the new OpenMP clause.
1932 /// Subclasses may override this routine to provide different behavior.
1933 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
1934 SourceLocation StartLoc,
1935 SourceLocation LParenLoc,
1936 SourceLocation EndLoc) {
1937 return getSema().ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc,
1938 EndLoc);
1941 /// Build a new OpenMP 'copyprivate' clause.
1943 /// By default, performs semantic analysis to build the new OpenMP clause.
1944 /// Subclasses may override this routine to provide different behavior.
1945 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
1946 SourceLocation StartLoc,
1947 SourceLocation LParenLoc,
1948 SourceLocation EndLoc) {
1949 return getSema().ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc,
1950 EndLoc);
1953 /// Build a new OpenMP 'flush' pseudo clause.
1955 /// By default, performs semantic analysis to build the new OpenMP clause.
1956 /// Subclasses may override this routine to provide different behavior.
1957 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
1958 SourceLocation StartLoc,
1959 SourceLocation LParenLoc,
1960 SourceLocation EndLoc) {
1961 return getSema().ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc,
1962 EndLoc);
1965 /// Build a new OpenMP 'depobj' pseudo clause.
1967 /// By default, performs semantic analysis to build the new OpenMP clause.
1968 /// Subclasses may override this routine to provide different behavior.
1969 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
1970 SourceLocation LParenLoc,
1971 SourceLocation EndLoc) {
1972 return getSema().ActOnOpenMPDepobjClause(Depobj, StartLoc, LParenLoc,
1973 EndLoc);
1976 /// Build a new OpenMP 'depend' pseudo clause.
1978 /// By default, performs semantic analysis to build the new OpenMP clause.
1979 /// Subclasses may override this routine to provide different behavior.
1980 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
1981 Expr *DepModifier, ArrayRef<Expr *> VarList,
1982 SourceLocation StartLoc,
1983 SourceLocation LParenLoc,
1984 SourceLocation EndLoc) {
1985 return getSema().ActOnOpenMPDependClause(Data, DepModifier, VarList,
1986 StartLoc, LParenLoc, EndLoc);
1989 /// Build a new OpenMP 'device' clause.
1991 /// By default, performs semantic analysis to build the new statement.
1992 /// Subclasses may override this routine to provide different behavior.
1993 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
1994 Expr *Device, SourceLocation StartLoc,
1995 SourceLocation LParenLoc,
1996 SourceLocation ModifierLoc,
1997 SourceLocation EndLoc) {
1998 return getSema().ActOnOpenMPDeviceClause(Modifier, Device, StartLoc,
1999 LParenLoc, ModifierLoc, EndLoc);
2002 /// Build a new OpenMP 'map' clause.
2004 /// By default, performs semantic analysis to build the new OpenMP clause.
2005 /// Subclasses may override this routine to provide different behavior.
2006 OMPClause *RebuildOMPMapClause(
2007 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2008 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2009 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2010 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2011 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2012 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2013 return getSema().ActOnOpenMPMapClause(
2014 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2015 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2016 ColonLoc, VarList, Locs,
2017 /*NoDiagnose=*/false, UnresolvedMappers);
2020 /// Build a new OpenMP 'allocate' clause.
2022 /// By default, performs semantic analysis to build the new OpenMP clause.
2023 /// Subclasses may override this routine to provide different behavior.
2024 OMPClause *RebuildOMPAllocateClause(Expr *Allocate, ArrayRef<Expr *> VarList,
2025 SourceLocation StartLoc,
2026 SourceLocation LParenLoc,
2027 SourceLocation ColonLoc,
2028 SourceLocation EndLoc) {
2029 return getSema().ActOnOpenMPAllocateClause(Allocate, VarList, StartLoc,
2030 LParenLoc, ColonLoc, EndLoc);
2033 /// Build a new OpenMP 'num_teams' clause.
2035 /// By default, performs semantic analysis to build the new statement.
2036 /// Subclasses may override this routine to provide different behavior.
2037 OMPClause *RebuildOMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc,
2038 SourceLocation LParenLoc,
2039 SourceLocation EndLoc) {
2040 return getSema().ActOnOpenMPNumTeamsClause(NumTeams, StartLoc, LParenLoc,
2041 EndLoc);
2044 /// Build a new OpenMP 'thread_limit' clause.
2046 /// By default, performs semantic analysis to build the new statement.
2047 /// Subclasses may override this routine to provide different behavior.
2048 OMPClause *RebuildOMPThreadLimitClause(Expr *ThreadLimit,
2049 SourceLocation StartLoc,
2050 SourceLocation LParenLoc,
2051 SourceLocation EndLoc) {
2052 return getSema().ActOnOpenMPThreadLimitClause(ThreadLimit, StartLoc,
2053 LParenLoc, EndLoc);
2056 /// Build a new OpenMP 'priority' clause.
2058 /// By default, performs semantic analysis to build the new statement.
2059 /// Subclasses may override this routine to provide different behavior.
2060 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2061 SourceLocation LParenLoc,
2062 SourceLocation EndLoc) {
2063 return getSema().ActOnOpenMPPriorityClause(Priority, StartLoc, LParenLoc,
2064 EndLoc);
2067 /// Build a new OpenMP 'grainsize' clause.
2069 /// By default, performs semantic analysis to build the new statement.
2070 /// Subclasses may override this routine to provide different behavior.
2071 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2072 Expr *Device, SourceLocation StartLoc,
2073 SourceLocation LParenLoc,
2074 SourceLocation ModifierLoc,
2075 SourceLocation EndLoc) {
2076 return getSema().ActOnOpenMPGrainsizeClause(Modifier, Device, StartLoc,
2077 LParenLoc, ModifierLoc, EndLoc);
2080 /// Build a new OpenMP 'num_tasks' clause.
2082 /// By default, performs semantic analysis to build the new statement.
2083 /// Subclasses may override this routine to provide different behavior.
2084 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2085 Expr *NumTasks, SourceLocation StartLoc,
2086 SourceLocation LParenLoc,
2087 SourceLocation ModifierLoc,
2088 SourceLocation EndLoc) {
2089 return getSema().ActOnOpenMPNumTasksClause(Modifier, NumTasks, StartLoc,
2090 LParenLoc, ModifierLoc, EndLoc);
2093 /// Build a new OpenMP 'hint' clause.
2095 /// By default, performs semantic analysis to build the new statement.
2096 /// Subclasses may override this routine to provide different behavior.
2097 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2098 SourceLocation LParenLoc,
2099 SourceLocation EndLoc) {
2100 return getSema().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc, EndLoc);
2103 /// Build a new OpenMP 'detach' clause.
2105 /// By default, performs semantic analysis to build the new statement.
2106 /// Subclasses may override this routine to provide different behavior.
2107 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2108 SourceLocation LParenLoc,
2109 SourceLocation EndLoc) {
2110 return getSema().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
2113 /// Build a new OpenMP 'dist_schedule' clause.
2115 /// By default, performs semantic analysis to build the new OpenMP clause.
2116 /// Subclasses may override this routine to provide different behavior.
2117 OMPClause *
2118 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2119 Expr *ChunkSize, SourceLocation StartLoc,
2120 SourceLocation LParenLoc, SourceLocation KindLoc,
2121 SourceLocation CommaLoc, SourceLocation EndLoc) {
2122 return getSema().ActOnOpenMPDistScheduleClause(
2123 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2126 /// Build a new OpenMP 'to' clause.
2128 /// By default, performs semantic analysis to build the new statement.
2129 /// Subclasses may override this routine to provide different behavior.
2130 OMPClause *
2131 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2132 ArrayRef<SourceLocation> MotionModifiersLoc,
2133 CXXScopeSpec &MapperIdScopeSpec,
2134 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2135 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2136 ArrayRef<Expr *> UnresolvedMappers) {
2137 return getSema().ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
2138 MapperIdScopeSpec, MapperId, ColonLoc,
2139 VarList, Locs, UnresolvedMappers);
2142 /// Build a new OpenMP 'from' clause.
2144 /// By default, performs semantic analysis to build the new statement.
2145 /// Subclasses may override this routine to provide different behavior.
2146 OMPClause *
2147 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2148 ArrayRef<SourceLocation> MotionModifiersLoc,
2149 CXXScopeSpec &MapperIdScopeSpec,
2150 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2151 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2152 ArrayRef<Expr *> UnresolvedMappers) {
2153 return getSema().ActOnOpenMPFromClause(
2154 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2155 ColonLoc, VarList, Locs, UnresolvedMappers);
2158 /// Build a new OpenMP 'use_device_ptr' clause.
2160 /// By default, performs semantic analysis to build the new OpenMP clause.
2161 /// Subclasses may override this routine to provide different behavior.
2162 OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
2163 const OMPVarListLocTy &Locs) {
2164 return getSema().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2167 /// Build a new OpenMP 'use_device_addr' clause.
2169 /// By default, performs semantic analysis to build the new OpenMP clause.
2170 /// Subclasses may override this routine to provide different behavior.
2171 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2172 const OMPVarListLocTy &Locs) {
2173 return getSema().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2176 /// Build a new OpenMP 'is_device_ptr' clause.
2178 /// By default, performs semantic analysis to build the new OpenMP clause.
2179 /// Subclasses may override this routine to provide different behavior.
2180 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2181 const OMPVarListLocTy &Locs) {
2182 return getSema().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2185 /// Build a new OpenMP 'has_device_addr' clause.
2187 /// By default, performs semantic analysis to build the new OpenMP clause.
2188 /// Subclasses may override this routine to provide different behavior.
2189 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2190 const OMPVarListLocTy &Locs) {
2191 return getSema().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2194 /// Build a new OpenMP 'defaultmap' clause.
2196 /// By default, performs semantic analysis to build the new OpenMP clause.
2197 /// Subclasses may override this routine to provide different behavior.
2198 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2199 OpenMPDefaultmapClauseKind Kind,
2200 SourceLocation StartLoc,
2201 SourceLocation LParenLoc,
2202 SourceLocation MLoc,
2203 SourceLocation KindLoc,
2204 SourceLocation EndLoc) {
2205 return getSema().ActOnOpenMPDefaultmapClause(M, Kind, StartLoc, LParenLoc,
2206 MLoc, KindLoc, EndLoc);
2209 /// Build a new OpenMP 'nontemporal' clause.
2211 /// By default, performs semantic analysis to build the new OpenMP clause.
2212 /// Subclasses may override this routine to provide different behavior.
2213 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2214 SourceLocation StartLoc,
2215 SourceLocation LParenLoc,
2216 SourceLocation EndLoc) {
2217 return getSema().ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc,
2218 EndLoc);
2221 /// Build a new OpenMP 'inclusive' clause.
2223 /// By default, performs semantic analysis to build the new OpenMP clause.
2224 /// Subclasses may override this routine to provide different behavior.
2225 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2226 SourceLocation StartLoc,
2227 SourceLocation LParenLoc,
2228 SourceLocation EndLoc) {
2229 return getSema().ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc,
2230 EndLoc);
2233 /// Build a new OpenMP 'exclusive' clause.
2235 /// By default, performs semantic analysis to build the new OpenMP clause.
2236 /// Subclasses may override this routine to provide different behavior.
2237 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2238 SourceLocation StartLoc,
2239 SourceLocation LParenLoc,
2240 SourceLocation EndLoc) {
2241 return getSema().ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc,
2242 EndLoc);
2245 /// Build a new OpenMP 'uses_allocators' clause.
2247 /// By default, performs semantic analysis to build the new OpenMP clause.
2248 /// Subclasses may override this routine to provide different behavior.
2249 OMPClause *RebuildOMPUsesAllocatorsClause(
2250 ArrayRef<Sema::UsesAllocatorsData> Data, SourceLocation StartLoc,
2251 SourceLocation LParenLoc, SourceLocation EndLoc) {
2252 return getSema().ActOnOpenMPUsesAllocatorClause(StartLoc, LParenLoc, EndLoc,
2253 Data);
2256 /// Build a new OpenMP 'affinity' clause.
2258 /// By default, performs semantic analysis to build the new OpenMP clause.
2259 /// Subclasses may override this routine to provide different behavior.
2260 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2261 SourceLocation LParenLoc,
2262 SourceLocation ColonLoc,
2263 SourceLocation EndLoc, Expr *Modifier,
2264 ArrayRef<Expr *> Locators) {
2265 return getSema().ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc,
2266 EndLoc, Modifier, Locators);
2269 /// Build a new OpenMP 'order' clause.
2271 /// By default, performs semantic analysis to build the new OpenMP clause.
2272 /// Subclasses may override this routine to provide different behavior.
2273 OMPClause *RebuildOMPOrderClause(
2274 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2275 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2276 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2277 return getSema().ActOnOpenMPOrderClause(Modifier, Kind, StartLoc, LParenLoc,
2278 ModifierKwLoc, KindKwLoc, EndLoc);
2281 /// Build a new OpenMP 'init' clause.
2283 /// By default, performs semantic analysis to build the new OpenMP clause.
2284 /// Subclasses may override this routine to provide different behavior.
2285 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2286 SourceLocation StartLoc,
2287 SourceLocation LParenLoc,
2288 SourceLocation VarLoc,
2289 SourceLocation EndLoc) {
2290 return getSema().ActOnOpenMPInitClause(InteropVar, InteropInfo, StartLoc,
2291 LParenLoc, VarLoc, EndLoc);
2294 /// Build a new OpenMP 'use' clause.
2296 /// By default, performs semantic analysis to build the new OpenMP clause.
2297 /// Subclasses may override this routine to provide different behavior.
2298 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2299 SourceLocation LParenLoc,
2300 SourceLocation VarLoc, SourceLocation EndLoc) {
2301 return getSema().ActOnOpenMPUseClause(InteropVar, StartLoc, LParenLoc,
2302 VarLoc, EndLoc);
2305 /// Build a new OpenMP 'destroy' clause.
2307 /// By default, performs semantic analysis to build the new OpenMP clause.
2308 /// Subclasses may override this routine to provide different behavior.
2309 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2310 SourceLocation LParenLoc,
2311 SourceLocation VarLoc,
2312 SourceLocation EndLoc) {
2313 return getSema().ActOnOpenMPDestroyClause(InteropVar, StartLoc, LParenLoc,
2314 VarLoc, EndLoc);
2317 /// Build a new OpenMP 'novariants' clause.
2319 /// By default, performs semantic analysis to build the new OpenMP clause.
2320 /// Subclasses may override this routine to provide different behavior.
2321 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2322 SourceLocation StartLoc,
2323 SourceLocation LParenLoc,
2324 SourceLocation EndLoc) {
2325 return getSema().ActOnOpenMPNovariantsClause(Condition, StartLoc, LParenLoc,
2326 EndLoc);
2329 /// Build a new OpenMP 'nocontext' clause.
2331 /// By default, performs semantic analysis to build the new OpenMP clause.
2332 /// Subclasses may override this routine to provide different behavior.
2333 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2334 SourceLocation LParenLoc,
2335 SourceLocation EndLoc) {
2336 return getSema().ActOnOpenMPNocontextClause(Condition, StartLoc, LParenLoc,
2337 EndLoc);
2340 /// Build a new OpenMP 'filter' clause.
2342 /// By default, performs semantic analysis to build the new OpenMP clause.
2343 /// Subclasses may override this routine to provide different behavior.
2344 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2345 SourceLocation LParenLoc,
2346 SourceLocation EndLoc) {
2347 return getSema().ActOnOpenMPFilterClause(ThreadID, StartLoc, LParenLoc,
2348 EndLoc);
2351 /// Build a new OpenMP 'bind' clause.
2353 /// By default, performs semantic analysis to build the new OpenMP clause.
2354 /// Subclasses may override this routine to provide different behavior.
2355 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2356 SourceLocation KindLoc,
2357 SourceLocation StartLoc,
2358 SourceLocation LParenLoc,
2359 SourceLocation EndLoc) {
2360 return getSema().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc, LParenLoc,
2361 EndLoc);
2364 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2366 /// By default, performs semantic analysis to build the new OpenMP clause.
2367 /// Subclasses may override this routine to provide different behavior.
2368 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2369 SourceLocation LParenLoc,
2370 SourceLocation EndLoc) {
2371 return getSema().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc, LParenLoc,
2372 EndLoc);
2375 /// Build a new OpenMP 'ompx_attribute' clause.
2377 /// By default, performs semantic analysis to build the new OpenMP clause.
2378 /// Subclasses may override this routine to provide different behavior.
2379 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2380 SourceLocation StartLoc,
2381 SourceLocation LParenLoc,
2382 SourceLocation EndLoc) {
2383 return getSema().ActOnOpenMPXAttributeClause(Attrs, StartLoc, LParenLoc,
2384 EndLoc);
2387 /// Build a new OpenMP 'ompx_bare' clause.
2389 /// By default, performs semantic analysis to build the new OpenMP clause.
2390 /// Subclasses may override this routine to provide different behavior.
2391 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2392 SourceLocation EndLoc) {
2393 return getSema().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2396 /// Build a new OpenMP 'align' clause.
2398 /// By default, performs semantic analysis to build the new OpenMP clause.
2399 /// Subclasses may override this routine to provide different behavior.
2400 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2401 SourceLocation LParenLoc,
2402 SourceLocation EndLoc) {
2403 return getSema().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc, EndLoc);
2406 /// Build a new OpenMP 'at' clause.
2408 /// By default, performs semantic analysis to build the new OpenMP clause.
2409 /// Subclasses may override this routine to provide different behavior.
2410 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2411 SourceLocation StartLoc,
2412 SourceLocation LParenLoc,
2413 SourceLocation EndLoc) {
2414 return getSema().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc, LParenLoc,
2415 EndLoc);
2418 /// Build a new OpenMP 'severity' clause.
2420 /// By default, performs semantic analysis to build the new OpenMP clause.
2421 /// Subclasses may override this routine to provide different behavior.
2422 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2423 SourceLocation KwLoc,
2424 SourceLocation StartLoc,
2425 SourceLocation LParenLoc,
2426 SourceLocation EndLoc) {
2427 return getSema().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc, LParenLoc,
2428 EndLoc);
2431 /// Build a new OpenMP 'message' clause.
2433 /// By default, performs semantic analysis to build the new OpenMP clause.
2434 /// Subclasses may override this routine to provide different behavior.
2435 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2436 SourceLocation LParenLoc,
2437 SourceLocation EndLoc) {
2438 return getSema().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc, EndLoc);
2441 /// Build a new OpenMP 'doacross' clause.
2443 /// By default, performs semantic analysis to build the new OpenMP clause.
2444 /// Subclasses may override this routine to provide different behavior.
2445 OMPClause *
2446 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2447 SourceLocation DepLoc, SourceLocation ColonLoc,
2448 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2449 SourceLocation LParenLoc, SourceLocation EndLoc) {
2450 return getSema().ActOnOpenMPDoacrossClause(
2451 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2454 /// Rebuild the operand to an Objective-C \@synchronized statement.
2456 /// By default, performs semantic analysis to build the new statement.
2457 /// Subclasses may override this routine to provide different behavior.
2458 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2459 Expr *object) {
2460 return getSema().ActOnObjCAtSynchronizedOperand(atLoc, object);
2463 /// Build a new Objective-C \@synchronized statement.
2465 /// By default, performs semantic analysis to build the new statement.
2466 /// Subclasses may override this routine to provide different behavior.
2467 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2468 Expr *Object, Stmt *Body) {
2469 return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2472 /// Build a new Objective-C \@autoreleasepool statement.
2474 /// By default, performs semantic analysis to build the new statement.
2475 /// Subclasses may override this routine to provide different behavior.
2476 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2477 Stmt *Body) {
2478 return getSema().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2481 /// Build a new Objective-C fast enumeration statement.
2483 /// By default, performs semantic analysis to build the new statement.
2484 /// Subclasses may override this routine to provide different behavior.
2485 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2486 Stmt *Element,
2487 Expr *Collection,
2488 SourceLocation RParenLoc,
2489 Stmt *Body) {
2490 StmtResult ForEachStmt = getSema().ActOnObjCForCollectionStmt(ForLoc,
2491 Element,
2492 Collection,
2493 RParenLoc);
2494 if (ForEachStmt.isInvalid())
2495 return StmtError();
2497 return getSema().FinishObjCForCollectionStmt(ForEachStmt.get(), Body);
2500 /// Build a new C++ exception declaration.
2502 /// By default, performs semantic analysis to build the new decaration.
2503 /// Subclasses may override this routine to provide different behavior.
2504 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2505 TypeSourceInfo *Declarator,
2506 SourceLocation StartLoc,
2507 SourceLocation IdLoc,
2508 IdentifierInfo *Id) {
2509 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2510 StartLoc, IdLoc, Id);
2511 if (Var)
2512 getSema().CurContext->addDecl(Var);
2513 return Var;
2516 /// Build a new C++ catch statement.
2518 /// By default, performs semantic analysis to build the new statement.
2519 /// Subclasses may override this routine to provide different behavior.
2520 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2521 VarDecl *ExceptionDecl,
2522 Stmt *Handler) {
2523 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2524 Handler));
2527 /// Build a new C++ try statement.
2529 /// By default, performs semantic analysis to build the new statement.
2530 /// Subclasses may override this routine to provide different behavior.
2531 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2532 ArrayRef<Stmt *> Handlers) {
2533 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2536 /// Build a new C++0x range-based for statement.
2538 /// By default, performs semantic analysis to build the new statement.
2539 /// Subclasses may override this routine to provide different behavior.
2540 StmtResult RebuildCXXForRangeStmt(SourceLocation ForLoc,
2541 SourceLocation CoawaitLoc, Stmt *Init,
2542 SourceLocation ColonLoc, Stmt *Range,
2543 Stmt *Begin, Stmt *End, Expr *Cond,
2544 Expr *Inc, Stmt *LoopVar,
2545 SourceLocation RParenLoc) {
2546 // If we've just learned that the range is actually an Objective-C
2547 // collection, treat this as an Objective-C fast enumeration loop.
2548 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
2549 if (RangeStmt->isSingleDecl()) {
2550 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
2551 if (RangeVar->isInvalidDecl())
2552 return StmtError();
2554 Expr *RangeExpr = RangeVar->getInit();
2555 if (!RangeExpr->isTypeDependent() &&
2556 RangeExpr->getType()->isObjCObjectPointerType()) {
2557 // FIXME: Support init-statements in Objective-C++20 ranged for
2558 // statement.
2559 if (Init) {
2560 return SemaRef.Diag(Init->getBeginLoc(),
2561 diag::err_objc_for_range_init_stmt)
2562 << Init->getSourceRange();
2564 return getSema().ActOnObjCForCollectionStmt(ForLoc, LoopVar,
2565 RangeExpr, RParenLoc);
2571 return getSema().BuildCXXForRangeStmt(ForLoc, CoawaitLoc, Init, ColonLoc,
2572 Range, Begin, End, Cond, Inc, LoopVar,
2573 RParenLoc, Sema::BFRK_Rebuild);
2576 /// Build a new C++0x range-based for statement.
2578 /// By default, performs semantic analysis to build the new statement.
2579 /// Subclasses may override this routine to provide different behavior.
2580 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2581 bool IsIfExists,
2582 NestedNameSpecifierLoc QualifierLoc,
2583 DeclarationNameInfo NameInfo,
2584 Stmt *Nested) {
2585 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2586 QualifierLoc, NameInfo, Nested);
2589 /// Attach body to a C++0x range-based for statement.
2591 /// By default, performs semantic analysis to finish the new statement.
2592 /// Subclasses may override this routine to provide different behavior.
2593 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2594 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2597 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2598 Stmt *TryBlock, Stmt *Handler) {
2599 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2602 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2603 Stmt *Block) {
2604 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2607 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2608 return SEHFinallyStmt::Create(getSema().getASTContext(), Loc, Block);
2611 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2612 SourceLocation LParen,
2613 SourceLocation RParen,
2614 TypeSourceInfo *TSI) {
2615 return getSema().BuildSYCLUniqueStableNameExpr(OpLoc, LParen, RParen, TSI);
2618 /// Build a new predefined expression.
2620 /// By default, performs semantic analysis to build the new expression.
2621 /// Subclasses may override this routine to provide different behavior.
2622 ExprResult RebuildPredefinedExpr(SourceLocation Loc,
2623 PredefinedExpr::IdentKind IK) {
2624 return getSema().BuildPredefinedExpr(Loc, IK);
2627 /// Build a new expression that references a declaration.
2629 /// By default, performs semantic analysis to build the new expression.
2630 /// Subclasses may override this routine to provide different behavior.
2631 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2632 LookupResult &R,
2633 bool RequiresADL) {
2634 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2638 /// Build a new expression that references a declaration.
2640 /// By default, performs semantic analysis to build the new expression.
2641 /// Subclasses may override this routine to provide different behavior.
2642 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2643 ValueDecl *VD,
2644 const DeclarationNameInfo &NameInfo,
2645 NamedDecl *Found,
2646 TemplateArgumentListInfo *TemplateArgs) {
2647 CXXScopeSpec SS;
2648 SS.Adopt(QualifierLoc);
2649 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2650 TemplateArgs);
2653 /// Build a new expression in parentheses.
2655 /// By default, performs semantic analysis to build the new expression.
2656 /// Subclasses may override this routine to provide different behavior.
2657 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2658 SourceLocation RParen) {
2659 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2662 /// Build a new pseudo-destructor expression.
2664 /// By default, performs semantic analysis to build the new expression.
2665 /// Subclasses may override this routine to provide different behavior.
2666 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2667 SourceLocation OperatorLoc,
2668 bool isArrow,
2669 CXXScopeSpec &SS,
2670 TypeSourceInfo *ScopeType,
2671 SourceLocation CCLoc,
2672 SourceLocation TildeLoc,
2673 PseudoDestructorTypeStorage Destroyed);
2675 /// Build a new unary operator expression.
2677 /// By default, performs semantic analysis to build the new expression.
2678 /// Subclasses may override this routine to provide different behavior.
2679 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2680 UnaryOperatorKind Opc,
2681 Expr *SubExpr) {
2682 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2685 /// Build a new builtin offsetof expression.
2687 /// By default, performs semantic analysis to build the new expression.
2688 /// Subclasses may override this routine to provide different behavior.
2689 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2690 TypeSourceInfo *Type,
2691 ArrayRef<Sema::OffsetOfComponent> Components,
2692 SourceLocation RParenLoc) {
2693 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2694 RParenLoc);
2697 /// Build a new sizeof, alignof or vec_step expression with a
2698 /// type argument.
2700 /// By default, performs semantic analysis to build the new expression.
2701 /// Subclasses may override this routine to provide different behavior.
2702 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2703 SourceLocation OpLoc,
2704 UnaryExprOrTypeTrait ExprKind,
2705 SourceRange R) {
2706 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2709 /// Build a new sizeof, alignof or vec step expression with an
2710 /// expression argument.
2712 /// By default, performs semantic analysis to build the new expression.
2713 /// Subclasses may override this routine to provide different behavior.
2714 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2715 UnaryExprOrTypeTrait ExprKind,
2716 SourceRange R) {
2717 ExprResult Result
2718 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2719 if (Result.isInvalid())
2720 return ExprError();
2722 return Result;
2725 /// Build a new array subscript expression.
2727 /// By default, performs semantic analysis to build the new expression.
2728 /// Subclasses may override this routine to provide different behavior.
2729 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2730 SourceLocation LBracketLoc,
2731 Expr *RHS,
2732 SourceLocation RBracketLoc) {
2733 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2734 LBracketLoc, RHS,
2735 RBracketLoc);
2738 /// Build a new matrix subscript expression.
2740 /// By default, performs semantic analysis to build the new expression.
2741 /// Subclasses may override this routine to provide different behavior.
2742 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2743 Expr *ColumnIdx,
2744 SourceLocation RBracketLoc) {
2745 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2746 RBracketLoc);
2749 /// Build a new array section expression.
2751 /// By default, performs semantic analysis to build the new expression.
2752 /// Subclasses may override this routine to provide different behavior.
2753 ExprResult RebuildOMPArraySectionExpr(Expr *Base, SourceLocation LBracketLoc,
2754 Expr *LowerBound,
2755 SourceLocation ColonLocFirst,
2756 SourceLocation ColonLocSecond,
2757 Expr *Length, Expr *Stride,
2758 SourceLocation RBracketLoc) {
2759 return getSema().ActOnOMPArraySectionExpr(Base, LBracketLoc, LowerBound,
2760 ColonLocFirst, ColonLocSecond,
2761 Length, Stride, RBracketLoc);
2764 /// Build a new array shaping expression.
2766 /// By default, performs semantic analysis to build the new expression.
2767 /// Subclasses may override this routine to provide different behavior.
2768 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2769 SourceLocation RParenLoc,
2770 ArrayRef<Expr *> Dims,
2771 ArrayRef<SourceRange> BracketsRanges) {
2772 return getSema().ActOnOMPArrayShapingExpr(Base, LParenLoc, RParenLoc, Dims,
2773 BracketsRanges);
2776 /// Build a new iterator expression.
2778 /// By default, performs semantic analysis to build the new expression.
2779 /// Subclasses may override this routine to provide different behavior.
2780 ExprResult RebuildOMPIteratorExpr(
2781 SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc,
2782 ArrayRef<Sema::OMPIteratorData> Data) {
2783 return getSema().ActOnOMPIteratorExpr(/*Scope=*/nullptr, IteratorKwLoc,
2784 LLoc, RLoc, Data);
2787 /// Build a new call expression.
2789 /// By default, performs semantic analysis to build the new expression.
2790 /// Subclasses may override this routine to provide different behavior.
2791 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2792 MultiExprArg Args,
2793 SourceLocation RParenLoc,
2794 Expr *ExecConfig = nullptr) {
2795 return getSema().ActOnCallExpr(
2796 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2799 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2800 MultiExprArg Args,
2801 SourceLocation RParenLoc) {
2802 return getSema().ActOnArraySubscriptExpr(
2803 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2806 /// Build a new member access expression.
2808 /// By default, performs semantic analysis to build the new expression.
2809 /// Subclasses may override this routine to provide different behavior.
2810 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2811 bool isArrow,
2812 NestedNameSpecifierLoc QualifierLoc,
2813 SourceLocation TemplateKWLoc,
2814 const DeclarationNameInfo &MemberNameInfo,
2815 ValueDecl *Member,
2816 NamedDecl *FoundDecl,
2817 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2818 NamedDecl *FirstQualifierInScope) {
2819 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2820 isArrow);
2821 if (!Member->getDeclName()) {
2822 // We have a reference to an unnamed field. This is always the
2823 // base of an anonymous struct/union member access, i.e. the
2824 // field is always of record type.
2825 assert(Member->getType()->isRecordType() &&
2826 "unnamed member not of record type?");
2828 BaseResult =
2829 getSema().PerformObjectMemberConversion(BaseResult.get(),
2830 QualifierLoc.getNestedNameSpecifier(),
2831 FoundDecl, Member);
2832 if (BaseResult.isInvalid())
2833 return ExprError();
2834 Base = BaseResult.get();
2836 CXXScopeSpec EmptySS;
2837 return getSema().BuildFieldReferenceExpr(
2838 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
2839 DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()), MemberNameInfo);
2842 CXXScopeSpec SS;
2843 SS.Adopt(QualifierLoc);
2845 Base = BaseResult.get();
2846 QualType BaseType = Base->getType();
2848 if (isArrow && !BaseType->isPointerType())
2849 return ExprError();
2851 // FIXME: this involves duplicating earlier analysis in a lot of
2852 // cases; we should avoid this when possible.
2853 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2854 R.addDecl(FoundDecl);
2855 R.resolveKind();
2857 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2858 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {
2859 if (auto *ThisClass = cast<CXXThisExpr>(Base)
2860 ->getType()
2861 ->getPointeeType()
2862 ->getAsCXXRecordDecl()) {
2863 auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());
2864 // In unevaluated contexts, an expression supposed to be a member access
2865 // might reference a member in an unrelated class.
2866 if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))
2867 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2868 VK_LValue, Member->getLocation());
2872 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2873 SS, TemplateKWLoc,
2874 FirstQualifierInScope,
2875 R, ExplicitTemplateArgs,
2876 /*S*/nullptr);
2879 /// Build a new binary operator expression.
2881 /// By default, performs semantic analysis to build the new expression.
2882 /// Subclasses may override this routine to provide different behavior.
2883 ExprResult RebuildBinaryOperator(SourceLocation OpLoc,
2884 BinaryOperatorKind Opc,
2885 Expr *LHS, Expr *RHS) {
2886 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS);
2889 /// Build a new rewritten operator expression.
2891 /// By default, performs semantic analysis to build the new expression.
2892 /// Subclasses may override this routine to provide different behavior.
2893 ExprResult RebuildCXXRewrittenBinaryOperator(
2894 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2895 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2896 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2897 RHS, /*RequiresADL*/false);
2900 /// Build a new conditional operator expression.
2902 /// By default, performs semantic analysis to build the new expression.
2903 /// Subclasses may override this routine to provide different behavior.
2904 ExprResult RebuildConditionalOperator(Expr *Cond,
2905 SourceLocation QuestionLoc,
2906 Expr *LHS,
2907 SourceLocation ColonLoc,
2908 Expr *RHS) {
2909 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
2910 LHS, RHS);
2913 /// Build a new C-style cast expression.
2915 /// By default, performs semantic analysis to build the new expression.
2916 /// Subclasses may override this routine to provide different behavior.
2917 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
2918 TypeSourceInfo *TInfo,
2919 SourceLocation RParenLoc,
2920 Expr *SubExpr) {
2921 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
2922 SubExpr);
2925 /// Build a new compound literal expression.
2927 /// By default, performs semantic analysis to build the new expression.
2928 /// Subclasses may override this routine to provide different behavior.
2929 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
2930 TypeSourceInfo *TInfo,
2931 SourceLocation RParenLoc,
2932 Expr *Init) {
2933 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
2934 Init);
2937 /// Build a new extended vector element access expression.
2939 /// By default, performs semantic analysis to build the new expression.
2940 /// Subclasses may override this routine to provide different behavior.
2941 ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,
2942 bool IsArrow,
2943 SourceLocation AccessorLoc,
2944 IdentifierInfo &Accessor) {
2946 CXXScopeSpec SS;
2947 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
2948 return getSema().BuildMemberReferenceExpr(
2949 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
2950 /*FirstQualifierInScope*/ nullptr, NameInfo,
2951 /* TemplateArgs */ nullptr,
2952 /*S*/ nullptr);
2955 /// Build a new initializer list expression.
2957 /// By default, performs semantic analysis to build the new expression.
2958 /// Subclasses may override this routine to provide different behavior.
2959 ExprResult RebuildInitList(SourceLocation LBraceLoc,
2960 MultiExprArg Inits,
2961 SourceLocation RBraceLoc) {
2962 return SemaRef.BuildInitList(LBraceLoc, Inits, RBraceLoc);
2965 /// Build a new designated initializer expression.
2967 /// By default, performs semantic analysis to build the new expression.
2968 /// Subclasses may override this routine to provide different behavior.
2969 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
2970 MultiExprArg ArrayExprs,
2971 SourceLocation EqualOrColonLoc,
2972 bool GNUSyntax,
2973 Expr *Init) {
2974 ExprResult Result
2975 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
2976 Init);
2977 if (Result.isInvalid())
2978 return ExprError();
2980 return Result;
2983 /// Build a new value-initialized expression.
2985 /// By default, builds the implicit value initialization without performing
2986 /// any semantic analysis. Subclasses may override this routine to provide
2987 /// different behavior.
2988 ExprResult RebuildImplicitValueInitExpr(QualType T) {
2989 return new (SemaRef.Context) ImplicitValueInitExpr(T);
2992 /// Build a new \c va_arg expression.
2994 /// By default, performs semantic analysis to build the new expression.
2995 /// Subclasses may override this routine to provide different behavior.
2996 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
2997 Expr *SubExpr, TypeSourceInfo *TInfo,
2998 SourceLocation RParenLoc) {
2999 return getSema().BuildVAArgExpr(BuiltinLoc,
3000 SubExpr, TInfo,
3001 RParenLoc);
3004 /// Build a new expression list in parentheses.
3006 /// By default, performs semantic analysis to build the new expression.
3007 /// Subclasses may override this routine to provide different behavior.
3008 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3009 MultiExprArg SubExprs,
3010 SourceLocation RParenLoc) {
3011 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3014 /// Build a new address-of-label expression.
3016 /// By default, performs semantic analysis, using the name of the label
3017 /// rather than attempting to map the label statement itself.
3018 /// Subclasses may override this routine to provide different behavior.
3019 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3020 SourceLocation LabelLoc, LabelDecl *Label) {
3021 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3024 /// Build a new GNU statement expression.
3026 /// By default, performs semantic analysis to build the new expression.
3027 /// Subclasses may override this routine to provide different behavior.
3028 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3029 SourceLocation RParenLoc, unsigned TemplateDepth) {
3030 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3031 TemplateDepth);
3034 /// Build a new __builtin_choose_expr expression.
3036 /// By default, performs semantic analysis to build the new expression.
3037 /// Subclasses may override this routine to provide different behavior.
3038 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3039 Expr *Cond, Expr *LHS, Expr *RHS,
3040 SourceLocation RParenLoc) {
3041 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3042 Cond, LHS, RHS,
3043 RParenLoc);
3046 /// Build a new generic selection expression with an expression predicate.
3048 /// By default, performs semantic analysis to build the new expression.
3049 /// Subclasses may override this routine to provide different behavior.
3050 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3051 SourceLocation DefaultLoc,
3052 SourceLocation RParenLoc,
3053 Expr *ControllingExpr,
3054 ArrayRef<TypeSourceInfo *> Types,
3055 ArrayRef<Expr *> Exprs) {
3056 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3057 /*PredicateIsExpr=*/true,
3058 ControllingExpr, Types, Exprs);
3061 /// Build a new generic selection expression with a type predicate.
3063 /// By default, performs semantic analysis to build the new expression.
3064 /// Subclasses may override this routine to provide different behavior.
3065 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3066 SourceLocation DefaultLoc,
3067 SourceLocation RParenLoc,
3068 TypeSourceInfo *ControllingType,
3069 ArrayRef<TypeSourceInfo *> Types,
3070 ArrayRef<Expr *> Exprs) {
3071 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3072 /*PredicateIsExpr=*/false,
3073 ControllingType, Types, Exprs);
3076 /// Build a new overloaded operator call expression.
3078 /// By default, performs semantic analysis to build the new expression.
3079 /// The semantic analysis provides the behavior of template instantiation,
3080 /// copying with transformations that turn what looks like an overloaded
3081 /// operator call into a use of a builtin operator, performing
3082 /// argument-dependent lookup, etc. Subclasses may override this routine to
3083 /// provide different behavior.
3084 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3085 SourceLocation OpLoc,
3086 SourceLocation CalleeLoc,
3087 bool RequiresADL,
3088 const UnresolvedSetImpl &Functions,
3089 Expr *First, Expr *Second);
3091 /// Build a new C++ "named" cast expression, such as static_cast or
3092 /// reinterpret_cast.
3094 /// By default, this routine dispatches to one of the more-specific routines
3095 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3096 /// Subclasses may override this routine to provide different behavior.
3097 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3098 Stmt::StmtClass Class,
3099 SourceLocation LAngleLoc,
3100 TypeSourceInfo *TInfo,
3101 SourceLocation RAngleLoc,
3102 SourceLocation LParenLoc,
3103 Expr *SubExpr,
3104 SourceLocation RParenLoc) {
3105 switch (Class) {
3106 case Stmt::CXXStaticCastExprClass:
3107 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3108 RAngleLoc, LParenLoc,
3109 SubExpr, RParenLoc);
3111 case Stmt::CXXDynamicCastExprClass:
3112 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3113 RAngleLoc, LParenLoc,
3114 SubExpr, RParenLoc);
3116 case Stmt::CXXReinterpretCastExprClass:
3117 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3118 RAngleLoc, LParenLoc,
3119 SubExpr,
3120 RParenLoc);
3122 case Stmt::CXXConstCastExprClass:
3123 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3124 RAngleLoc, LParenLoc,
3125 SubExpr, RParenLoc);
3127 case Stmt::CXXAddrspaceCastExprClass:
3128 return getDerived().RebuildCXXAddrspaceCastExpr(
3129 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3131 default:
3132 llvm_unreachable("Invalid C++ named cast");
3136 /// Build a new C++ static_cast expression.
3138 /// By default, performs semantic analysis to build the new expression.
3139 /// Subclasses may override this routine to provide different behavior.
3140 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3141 SourceLocation LAngleLoc,
3142 TypeSourceInfo *TInfo,
3143 SourceLocation RAngleLoc,
3144 SourceLocation LParenLoc,
3145 Expr *SubExpr,
3146 SourceLocation RParenLoc) {
3147 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3148 TInfo, SubExpr,
3149 SourceRange(LAngleLoc, RAngleLoc),
3150 SourceRange(LParenLoc, RParenLoc));
3153 /// Build a new C++ dynamic_cast expression.
3155 /// By default, performs semantic analysis to build the new expression.
3156 /// Subclasses may override this routine to provide different behavior.
3157 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3158 SourceLocation LAngleLoc,
3159 TypeSourceInfo *TInfo,
3160 SourceLocation RAngleLoc,
3161 SourceLocation LParenLoc,
3162 Expr *SubExpr,
3163 SourceLocation RParenLoc) {
3164 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3165 TInfo, SubExpr,
3166 SourceRange(LAngleLoc, RAngleLoc),
3167 SourceRange(LParenLoc, RParenLoc));
3170 /// Build a new C++ reinterpret_cast expression.
3172 /// By default, performs semantic analysis to build the new expression.
3173 /// Subclasses may override this routine to provide different behavior.
3174 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3175 SourceLocation LAngleLoc,
3176 TypeSourceInfo *TInfo,
3177 SourceLocation RAngleLoc,
3178 SourceLocation LParenLoc,
3179 Expr *SubExpr,
3180 SourceLocation RParenLoc) {
3181 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3182 TInfo, SubExpr,
3183 SourceRange(LAngleLoc, RAngleLoc),
3184 SourceRange(LParenLoc, RParenLoc));
3187 /// Build a new C++ const_cast expression.
3189 /// By default, performs semantic analysis to build the new expression.
3190 /// Subclasses may override this routine to provide different behavior.
3191 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3192 SourceLocation LAngleLoc,
3193 TypeSourceInfo *TInfo,
3194 SourceLocation RAngleLoc,
3195 SourceLocation LParenLoc,
3196 Expr *SubExpr,
3197 SourceLocation RParenLoc) {
3198 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3199 TInfo, SubExpr,
3200 SourceRange(LAngleLoc, RAngleLoc),
3201 SourceRange(LParenLoc, RParenLoc));
3204 ExprResult
3205 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3206 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3207 SourceLocation LParenLoc, Expr *SubExpr,
3208 SourceLocation RParenLoc) {
3209 return getSema().BuildCXXNamedCast(
3210 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3211 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3214 /// Build a new C++ functional-style cast expression.
3216 /// By default, performs semantic analysis to build the new expression.
3217 /// Subclasses may override this routine to provide different behavior.
3218 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3219 SourceLocation LParenLoc,
3220 Expr *Sub,
3221 SourceLocation RParenLoc,
3222 bool ListInitialization) {
3223 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3224 // CXXParenListInitExpr. Pass its expanded arguments so that the
3225 // CXXParenListInitExpr can be rebuilt.
3226 if (auto *PLE = dyn_cast<ParenListExpr>(Sub))
3227 return getSema().BuildCXXTypeConstructExpr(
3228 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3229 RParenLoc, ListInitialization);
3230 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3231 MultiExprArg(&Sub, 1), RParenLoc,
3232 ListInitialization);
3235 /// Build a new C++ __builtin_bit_cast expression.
3237 /// By default, performs semantic analysis to build the new expression.
3238 /// Subclasses may override this routine to provide different behavior.
3239 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3240 TypeSourceInfo *TSI, Expr *Sub,
3241 SourceLocation RParenLoc) {
3242 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3245 /// Build a new C++ typeid(type) expression.
3247 /// By default, performs semantic analysis to build the new expression.
3248 /// Subclasses may override this routine to provide different behavior.
3249 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3250 SourceLocation TypeidLoc,
3251 TypeSourceInfo *Operand,
3252 SourceLocation RParenLoc) {
3253 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3254 RParenLoc);
3258 /// Build a new C++ typeid(expr) expression.
3260 /// By default, performs semantic analysis to build the new expression.
3261 /// Subclasses may override this routine to provide different behavior.
3262 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3263 SourceLocation TypeidLoc,
3264 Expr *Operand,
3265 SourceLocation RParenLoc) {
3266 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3267 RParenLoc);
3270 /// Build a new C++ __uuidof(type) expression.
3272 /// By default, performs semantic analysis to build the new expression.
3273 /// Subclasses may override this routine to provide different behavior.
3274 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3275 TypeSourceInfo *Operand,
3276 SourceLocation RParenLoc) {
3277 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3280 /// Build a new C++ __uuidof(expr) expression.
3282 /// By default, performs semantic analysis to build the new expression.
3283 /// Subclasses may override this routine to provide different behavior.
3284 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3285 Expr *Operand, SourceLocation RParenLoc) {
3286 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3289 /// Build a new C++ "this" expression.
3291 /// By default, builds a new "this" expression without performing any
3292 /// semantic analysis. Subclasses may override this routine to provide
3293 /// different behavior.
3294 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3295 QualType ThisType,
3296 bool isImplicit) {
3297 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3300 /// Build a new C++ throw expression.
3302 /// By default, performs semantic analysis to build the new expression.
3303 /// Subclasses may override this routine to provide different behavior.
3304 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3305 bool IsThrownVariableInScope) {
3306 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3309 /// Build a new C++ default-argument expression.
3311 /// By default, builds a new default-argument expression, which does not
3312 /// require any semantic analysis. Subclasses may override this routine to
3313 /// provide different behavior.
3314 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3315 Expr *RewrittenExpr) {
3316 return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param,
3317 RewrittenExpr, getSema().CurContext);
3320 /// Build a new C++11 default-initialization expression.
3322 /// By default, builds a new default field initialization expression, which
3323 /// does not require any semantic analysis. Subclasses may override this
3324 /// routine to provide different behavior.
3325 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3326 FieldDecl *Field) {
3327 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3330 /// Build a new C++ zero-initialization expression.
3332 /// By default, performs semantic analysis to build the new expression.
3333 /// Subclasses may override this routine to provide different behavior.
3334 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3335 SourceLocation LParenLoc,
3336 SourceLocation RParenLoc) {
3337 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, std::nullopt,
3338 RParenLoc,
3339 /*ListInitialization=*/false);
3342 /// Build a new C++ "new" expression.
3344 /// By default, performs semantic analysis to build the new expression.
3345 /// Subclasses may override this routine to provide different behavior.
3346 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3347 SourceLocation PlacementLParen,
3348 MultiExprArg PlacementArgs,
3349 SourceLocation PlacementRParen,
3350 SourceRange TypeIdParens, QualType AllocatedType,
3351 TypeSourceInfo *AllocatedTypeInfo,
3352 std::optional<Expr *> ArraySize,
3353 SourceRange DirectInitRange, Expr *Initializer) {
3354 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3355 PlacementLParen,
3356 PlacementArgs,
3357 PlacementRParen,
3358 TypeIdParens,
3359 AllocatedType,
3360 AllocatedTypeInfo,
3361 ArraySize,
3362 DirectInitRange,
3363 Initializer);
3366 /// Build a new C++ "delete" expression.
3368 /// By default, performs semantic analysis to build the new expression.
3369 /// Subclasses may override this routine to provide different behavior.
3370 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3371 bool IsGlobalDelete,
3372 bool IsArrayForm,
3373 Expr *Operand) {
3374 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3375 Operand);
3378 /// Build a new type trait expression.
3380 /// By default, performs semantic analysis to build the new expression.
3381 /// Subclasses may override this routine to provide different behavior.
3382 ExprResult RebuildTypeTrait(TypeTrait Trait,
3383 SourceLocation StartLoc,
3384 ArrayRef<TypeSourceInfo *> Args,
3385 SourceLocation RParenLoc) {
3386 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3389 /// Build a new array type trait expression.
3391 /// By default, performs semantic analysis to build the new expression.
3392 /// Subclasses may override this routine to provide different behavior.
3393 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3394 SourceLocation StartLoc,
3395 TypeSourceInfo *TSInfo,
3396 Expr *DimExpr,
3397 SourceLocation RParenLoc) {
3398 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3401 /// Build a new expression trait expression.
3403 /// By default, performs semantic analysis to build the new expression.
3404 /// Subclasses may override this routine to provide different behavior.
3405 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3406 SourceLocation StartLoc,
3407 Expr *Queried,
3408 SourceLocation RParenLoc) {
3409 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3412 /// Build a new (previously unresolved) declaration reference
3413 /// expression.
3415 /// By default, performs semantic analysis to build the new expression.
3416 /// Subclasses may override this routine to provide different behavior.
3417 ExprResult RebuildDependentScopeDeclRefExpr(
3418 NestedNameSpecifierLoc QualifierLoc,
3419 SourceLocation TemplateKWLoc,
3420 const DeclarationNameInfo &NameInfo,
3421 const TemplateArgumentListInfo *TemplateArgs,
3422 bool IsAddressOfOperand,
3423 TypeSourceInfo **RecoveryTSI) {
3424 CXXScopeSpec SS;
3425 SS.Adopt(QualifierLoc);
3427 if (TemplateArgs || TemplateKWLoc.isValid())
3428 return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, NameInfo,
3429 TemplateArgs);
3431 return getSema().BuildQualifiedDeclarationNameExpr(
3432 SS, NameInfo, IsAddressOfOperand, /*S*/nullptr, RecoveryTSI);
3435 /// Build a new template-id expression.
3437 /// By default, performs semantic analysis to build the new expression.
3438 /// Subclasses may override this routine to provide different behavior.
3439 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3440 SourceLocation TemplateKWLoc,
3441 LookupResult &R,
3442 bool RequiresADL,
3443 const TemplateArgumentListInfo *TemplateArgs) {
3444 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3445 TemplateArgs);
3448 /// Build a new object-construction expression.
3450 /// By default, performs semantic analysis to build the new expression.
3451 /// Subclasses may override this routine to provide different behavior.
3452 ExprResult RebuildCXXConstructExpr(QualType T,
3453 SourceLocation Loc,
3454 CXXConstructorDecl *Constructor,
3455 bool IsElidable,
3456 MultiExprArg Args,
3457 bool HadMultipleCandidates,
3458 bool ListInitialization,
3459 bool StdInitListInitialization,
3460 bool RequiresZeroInit,
3461 CXXConstructExpr::ConstructionKind ConstructKind,
3462 SourceRange ParenRange) {
3463 // Reconstruct the constructor we originally found, which might be
3464 // different if this is a call to an inherited constructor.
3465 CXXConstructorDecl *FoundCtor = Constructor;
3466 if (Constructor->isInheritingConstructor())
3467 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3469 SmallVector<Expr *, 8> ConvertedArgs;
3470 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3471 ConvertedArgs))
3472 return ExprError();
3474 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3475 IsElidable,
3476 ConvertedArgs,
3477 HadMultipleCandidates,
3478 ListInitialization,
3479 StdInitListInitialization,
3480 RequiresZeroInit, ConstructKind,
3481 ParenRange);
3484 /// Build a new implicit construction via inherited constructor
3485 /// expression.
3486 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3487 CXXConstructorDecl *Constructor,
3488 bool ConstructsVBase,
3489 bool InheritedFromVBase) {
3490 return new (getSema().Context) CXXInheritedCtorInitExpr(
3491 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3494 /// Build a new object-construction expression.
3496 /// By default, performs semantic analysis to build the new expression.
3497 /// Subclasses may override this routine to provide different behavior.
3498 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3499 SourceLocation LParenOrBraceLoc,
3500 MultiExprArg Args,
3501 SourceLocation RParenOrBraceLoc,
3502 bool ListInitialization) {
3503 return getSema().BuildCXXTypeConstructExpr(
3504 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3507 /// Build a new object-construction expression.
3509 /// By default, performs semantic analysis to build the new expression.
3510 /// Subclasses may override this routine to provide different behavior.
3511 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3512 SourceLocation LParenLoc,
3513 MultiExprArg Args,
3514 SourceLocation RParenLoc,
3515 bool ListInitialization) {
3516 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3517 RParenLoc, ListInitialization);
3520 /// Build a new member reference expression.
3522 /// By default, performs semantic analysis to build the new expression.
3523 /// Subclasses may override this routine to provide different behavior.
3524 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3525 QualType BaseType,
3526 bool IsArrow,
3527 SourceLocation OperatorLoc,
3528 NestedNameSpecifierLoc QualifierLoc,
3529 SourceLocation TemplateKWLoc,
3530 NamedDecl *FirstQualifierInScope,
3531 const DeclarationNameInfo &MemberNameInfo,
3532 const TemplateArgumentListInfo *TemplateArgs) {
3533 CXXScopeSpec SS;
3534 SS.Adopt(QualifierLoc);
3536 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3537 OperatorLoc, IsArrow,
3538 SS, TemplateKWLoc,
3539 FirstQualifierInScope,
3540 MemberNameInfo,
3541 TemplateArgs, /*S*/nullptr);
3544 /// Build a new member reference expression.
3546 /// By default, performs semantic analysis to build the new expression.
3547 /// Subclasses may override this routine to provide different behavior.
3548 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3549 SourceLocation OperatorLoc,
3550 bool IsArrow,
3551 NestedNameSpecifierLoc QualifierLoc,
3552 SourceLocation TemplateKWLoc,
3553 NamedDecl *FirstQualifierInScope,
3554 LookupResult &R,
3555 const TemplateArgumentListInfo *TemplateArgs) {
3556 CXXScopeSpec SS;
3557 SS.Adopt(QualifierLoc);
3559 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3560 OperatorLoc, IsArrow,
3561 SS, TemplateKWLoc,
3562 FirstQualifierInScope,
3563 R, TemplateArgs, /*S*/nullptr);
3566 /// Build a new noexcept expression.
3568 /// By default, performs semantic analysis to build the new expression.
3569 /// Subclasses may override this routine to provide different behavior.
3570 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3571 return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd());
3574 /// Build a new expression to compute the length of a parameter pack.
3575 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3576 SourceLocation PackLoc,
3577 SourceLocation RParenLoc,
3578 std::optional<unsigned> Length,
3579 ArrayRef<TemplateArgument> PartialArgs) {
3580 return SizeOfPackExpr::Create(SemaRef.Context, OperatorLoc, Pack, PackLoc,
3581 RParenLoc, Length, PartialArgs);
3584 /// Build a new expression representing a call to a source location
3585 /// builtin.
3587 /// By default, performs semantic analysis to build the new expression.
3588 /// Subclasses may override this routine to provide different behavior.
3589 ExprResult RebuildSourceLocExpr(SourceLocExpr::IdentKind Kind,
3590 QualType ResultTy, SourceLocation BuiltinLoc,
3591 SourceLocation RPLoc,
3592 DeclContext *ParentContext) {
3593 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3594 ParentContext);
3597 /// Build a new Objective-C boxed expression.
3599 /// By default, performs semantic analysis to build the new expression.
3600 /// Subclasses may override this routine to provide different behavior.
3601 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3602 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3603 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3604 TemplateArgumentListInfo *TALI) {
3605 CXXScopeSpec SS;
3606 SS.Adopt(NNS);
3607 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3608 ConceptNameInfo,
3609 FoundDecl,
3610 NamedConcept, TALI);
3611 if (Result.isInvalid())
3612 return ExprError();
3613 return Result;
3616 /// \brief Build a new requires expression.
3618 /// By default, performs semantic analysis to build the new expression.
3619 /// Subclasses may override this routine to provide different behavior.
3620 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3621 RequiresExprBodyDecl *Body,
3622 SourceLocation LParenLoc,
3623 ArrayRef<ParmVarDecl *> LocalParameters,
3624 SourceLocation RParenLoc,
3625 ArrayRef<concepts::Requirement *> Requirements,
3626 SourceLocation ClosingBraceLoc) {
3627 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3628 LocalParameters, RParenLoc, Requirements,
3629 ClosingBraceLoc);
3632 concepts::TypeRequirement *
3633 RebuildTypeRequirement(
3634 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3635 return SemaRef.BuildTypeRequirement(SubstDiag);
3638 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3639 return SemaRef.BuildTypeRequirement(T);
3642 concepts::ExprRequirement *
3643 RebuildExprRequirement(
3644 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3645 SourceLocation NoexceptLoc,
3646 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3647 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
3648 std::move(Ret));
3651 concepts::ExprRequirement *
3652 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3653 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3654 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
3655 std::move(Ret));
3658 concepts::NestedRequirement *
3659 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3660 const ASTConstraintSatisfaction &Satisfaction) {
3661 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3662 Satisfaction);
3665 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3666 return SemaRef.BuildNestedRequirement(Constraint);
3669 /// \brief Build a new Objective-C boxed expression.
3671 /// By default, performs semantic analysis to build the new expression.
3672 /// Subclasses may override this routine to provide different behavior.
3673 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3674 return getSema().BuildObjCBoxedExpr(SR, ValueExpr);
3677 /// Build a new Objective-C array literal.
3679 /// By default, performs semantic analysis to build the new expression.
3680 /// Subclasses may override this routine to provide different behavior.
3681 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3682 Expr **Elements, unsigned NumElements) {
3683 return getSema().BuildObjCArrayLiteral(Range,
3684 MultiExprArg(Elements, NumElements));
3687 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3688 Expr *Base, Expr *Key,
3689 ObjCMethodDecl *getterMethod,
3690 ObjCMethodDecl *setterMethod) {
3691 return getSema().BuildObjCSubscriptExpression(RB, Base, Key,
3692 getterMethod, setterMethod);
3695 /// Build a new Objective-C dictionary literal.
3697 /// By default, performs semantic analysis to build the new expression.
3698 /// Subclasses may override this routine to provide different behavior.
3699 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3700 MutableArrayRef<ObjCDictionaryElement> Elements) {
3701 return getSema().BuildObjCDictionaryLiteral(Range, Elements);
3704 /// Build a new Objective-C \@encode expression.
3706 /// By default, performs semantic analysis to build the new expression.
3707 /// Subclasses may override this routine to provide different behavior.
3708 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3709 TypeSourceInfo *EncodeTypeInfo,
3710 SourceLocation RParenLoc) {
3711 return SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, RParenLoc);
3714 /// Build a new Objective-C class message.
3715 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3716 Selector Sel,
3717 ArrayRef<SourceLocation> SelectorLocs,
3718 ObjCMethodDecl *Method,
3719 SourceLocation LBracLoc,
3720 MultiExprArg Args,
3721 SourceLocation RBracLoc) {
3722 return SemaRef.BuildClassMessage(ReceiverTypeInfo,
3723 ReceiverTypeInfo->getType(),
3724 /*SuperLoc=*/SourceLocation(),
3725 Sel, Method, LBracLoc, SelectorLocs,
3726 RBracLoc, Args);
3729 /// Build a new Objective-C instance message.
3730 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3731 Selector Sel,
3732 ArrayRef<SourceLocation> SelectorLocs,
3733 ObjCMethodDecl *Method,
3734 SourceLocation LBracLoc,
3735 MultiExprArg Args,
3736 SourceLocation RBracLoc) {
3737 return SemaRef.BuildInstanceMessage(Receiver,
3738 Receiver->getType(),
3739 /*SuperLoc=*/SourceLocation(),
3740 Sel, Method, LBracLoc, SelectorLocs,
3741 RBracLoc, Args);
3744 /// Build a new Objective-C instance/class message to 'super'.
3745 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3746 Selector Sel,
3747 ArrayRef<SourceLocation> SelectorLocs,
3748 QualType SuperType,
3749 ObjCMethodDecl *Method,
3750 SourceLocation LBracLoc,
3751 MultiExprArg Args,
3752 SourceLocation RBracLoc) {
3753 return Method->isInstanceMethod() ? SemaRef.BuildInstanceMessage(nullptr,
3754 SuperType,
3755 SuperLoc,
3756 Sel, Method, LBracLoc, SelectorLocs,
3757 RBracLoc, Args)
3758 : SemaRef.BuildClassMessage(nullptr,
3759 SuperType,
3760 SuperLoc,
3761 Sel, Method, LBracLoc, SelectorLocs,
3762 RBracLoc, Args);
3767 /// Build a new Objective-C ivar reference expression.
3769 /// By default, performs semantic analysis to build the new expression.
3770 /// Subclasses may override this routine to provide different behavior.
3771 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3772 SourceLocation IvarLoc,
3773 bool IsArrow, bool IsFreeIvar) {
3774 CXXScopeSpec SS;
3775 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3776 ExprResult Result = getSema().BuildMemberReferenceExpr(
3777 BaseArg, BaseArg->getType(),
3778 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3779 /*FirstQualifierInScope=*/nullptr, NameInfo,
3780 /*TemplateArgs=*/nullptr,
3781 /*S=*/nullptr);
3782 if (IsFreeIvar && Result.isUsable())
3783 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
3784 return Result;
3787 /// Build a new Objective-C property reference expression.
3789 /// By default, performs semantic analysis to build the new expression.
3790 /// Subclasses may override this routine to provide different behavior.
3791 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3792 ObjCPropertyDecl *Property,
3793 SourceLocation PropertyLoc) {
3794 CXXScopeSpec SS;
3795 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3796 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3797 /*FIXME:*/PropertyLoc,
3798 /*IsArrow=*/false,
3799 SS, SourceLocation(),
3800 /*FirstQualifierInScope=*/nullptr,
3801 NameInfo,
3802 /*TemplateArgs=*/nullptr,
3803 /*S=*/nullptr);
3806 /// Build a new Objective-C property reference expression.
3808 /// By default, performs semantic analysis to build the new expression.
3809 /// Subclasses may override this routine to provide different behavior.
3810 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3811 ObjCMethodDecl *Getter,
3812 ObjCMethodDecl *Setter,
3813 SourceLocation PropertyLoc) {
3814 // Since these expressions can only be value-dependent, we do not
3815 // need to perform semantic analysis again.
3816 return Owned(
3817 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3818 VK_LValue, OK_ObjCProperty,
3819 PropertyLoc, Base));
3822 /// Build a new Objective-C "isa" expression.
3824 /// By default, performs semantic analysis to build the new expression.
3825 /// Subclasses may override this routine to provide different behavior.
3826 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
3827 SourceLocation OpLoc, bool IsArrow) {
3828 CXXScopeSpec SS;
3829 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3830 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3831 OpLoc, IsArrow,
3832 SS, SourceLocation(),
3833 /*FirstQualifierInScope=*/nullptr,
3834 NameInfo,
3835 /*TemplateArgs=*/nullptr,
3836 /*S=*/nullptr);
3839 /// Build a new shuffle vector expression.
3841 /// By default, performs semantic analysis to build the new expression.
3842 /// Subclasses may override this routine to provide different behavior.
3843 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
3844 MultiExprArg SubExprs,
3845 SourceLocation RParenLoc) {
3846 // Find the declaration for __builtin_shufflevector
3847 const IdentifierInfo &Name
3848 = SemaRef.Context.Idents.get("__builtin_shufflevector");
3849 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
3850 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
3851 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3853 // Build a reference to the __builtin_shufflevector builtin
3854 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
3855 Expr *Callee = new (SemaRef.Context)
3856 DeclRefExpr(SemaRef.Context, Builtin, false,
3857 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3858 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
3859 Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
3860 CK_BuiltinFnToFnPtr).get();
3862 // Build the CallExpr
3863 ExprResult TheCall = CallExpr::Create(
3864 SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
3865 Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc,
3866 FPOptionsOverride());
3868 // Type-check the __builtin_shufflevector expression.
3869 return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
3872 /// Build a new convert vector expression.
3873 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
3874 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3875 SourceLocation RParenLoc) {
3876 return SemaRef.SemaConvertVectorExpr(SrcExpr, DstTInfo,
3877 BuiltinLoc, RParenLoc);
3880 /// Build a new template argument pack expansion.
3882 /// By default, performs semantic analysis to build a new pack expansion
3883 /// for a template argument. Subclasses may override this routine to provide
3884 /// different behavior.
3885 TemplateArgumentLoc
3886 RebuildPackExpansion(TemplateArgumentLoc Pattern, SourceLocation EllipsisLoc,
3887 std::optional<unsigned> NumExpansions) {
3888 switch (Pattern.getArgument().getKind()) {
3889 case TemplateArgument::Expression: {
3890 ExprResult Result
3891 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
3892 EllipsisLoc, NumExpansions);
3893 if (Result.isInvalid())
3894 return TemplateArgumentLoc();
3896 return TemplateArgumentLoc(Result.get(), Result.get());
3899 case TemplateArgument::Template:
3900 return TemplateArgumentLoc(
3901 SemaRef.Context,
3902 TemplateArgument(Pattern.getArgument().getAsTemplate(),
3903 NumExpansions),
3904 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
3905 EllipsisLoc);
3907 case TemplateArgument::Null:
3908 case TemplateArgument::Integral:
3909 case TemplateArgument::Declaration:
3910 case TemplateArgument::Pack:
3911 case TemplateArgument::TemplateExpansion:
3912 case TemplateArgument::NullPtr:
3913 llvm_unreachable("Pack expansion pattern has no parameter packs");
3915 case TemplateArgument::Type:
3916 if (TypeSourceInfo *Expansion
3917 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
3918 EllipsisLoc,
3919 NumExpansions))
3920 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
3921 Expansion);
3922 break;
3925 return TemplateArgumentLoc();
3928 /// Build a new expression pack expansion.
3930 /// By default, performs semantic analysis to build a new pack expansion
3931 /// for an expression. Subclasses may override this routine to provide
3932 /// different behavior.
3933 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
3934 std::optional<unsigned> NumExpansions) {
3935 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
3938 /// Build a new C++1z fold-expression.
3940 /// By default, performs semantic analysis in order to build a new fold
3941 /// expression.
3942 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
3943 SourceLocation LParenLoc, Expr *LHS,
3944 BinaryOperatorKind Operator,
3945 SourceLocation EllipsisLoc, Expr *RHS,
3946 SourceLocation RParenLoc,
3947 std::optional<unsigned> NumExpansions) {
3948 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
3949 EllipsisLoc, RHS, RParenLoc,
3950 NumExpansions);
3953 /// Build an empty C++1z fold-expression with the given operator.
3955 /// By default, produces the fallback value for the fold-expression, or
3956 /// produce an error if there is no fallback value.
3957 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
3958 BinaryOperatorKind Operator) {
3959 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
3962 /// Build a new atomic operation expression.
3964 /// By default, performs semantic analysis to build the new expression.
3965 /// Subclasses may override this routine to provide different behavior.
3966 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
3967 AtomicExpr::AtomicOp Op,
3968 SourceLocation RParenLoc) {
3969 // Use this for all of the locations, since we don't know the difference
3970 // between the call and the expr at this point.
3971 SourceRange Range{BuiltinLoc, RParenLoc};
3972 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
3973 Sema::AtomicArgumentOrder::AST);
3976 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
3977 ArrayRef<Expr *> SubExprs, QualType Type) {
3978 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
3981 private:
3982 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
3983 QualType ObjectType,
3984 NamedDecl *FirstQualifierInScope,
3985 CXXScopeSpec &SS);
3987 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
3988 QualType ObjectType,
3989 NamedDecl *FirstQualifierInScope,
3990 CXXScopeSpec &SS);
3992 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
3993 NamedDecl *FirstQualifierInScope,
3994 CXXScopeSpec &SS);
3996 QualType TransformDependentNameType(TypeLocBuilder &TLB,
3997 DependentNameTypeLoc TL,
3998 bool DeducibleTSTContext);
4001 template <typename Derived>
4002 StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4003 if (!S)
4004 return S;
4006 switch (S->getStmtClass()) {
4007 case Stmt::NoStmtClass: break;
4009 // Transform individual statement nodes
4010 // Pass SDK into statements that can produce a value
4011 #define STMT(Node, Parent) \
4012 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4013 #define VALUESTMT(Node, Parent) \
4014 case Stmt::Node##Class: \
4015 return getDerived().Transform##Node(cast<Node>(S), SDK);
4016 #define ABSTRACT_STMT(Node)
4017 #define EXPR(Node, Parent)
4018 #include "clang/AST/StmtNodes.inc"
4020 // Transform expressions by calling TransformExpr.
4021 #define STMT(Node, Parent)
4022 #define ABSTRACT_STMT(Stmt)
4023 #define EXPR(Node, Parent) case Stmt::Node##Class:
4024 #include "clang/AST/StmtNodes.inc"
4026 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
4028 if (SDK == SDK_StmtExprResult)
4029 E = getSema().ActOnStmtExprResult(E);
4030 return getSema().ActOnExprStmt(E, SDK == SDK_Discarded);
4034 return S;
4037 template<typename Derived>
4038 OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4039 if (!S)
4040 return S;
4042 switch (S->getClauseKind()) {
4043 default: break;
4044 // Transform individual clause nodes
4045 #define GEN_CLANG_CLAUSE_CLASS
4046 #define CLAUSE_CLASS(Enum, Str, Class) \
4047 case Enum: \
4048 return getDerived().Transform##Class(cast<Class>(S));
4049 #include "llvm/Frontend/OpenMP/OMP.inc"
4052 return S;
4056 template<typename Derived>
4057 ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4058 if (!E)
4059 return E;
4061 switch (E->getStmtClass()) {
4062 case Stmt::NoStmtClass: break;
4063 #define STMT(Node, Parent) case Stmt::Node##Class: break;
4064 #define ABSTRACT_STMT(Stmt)
4065 #define EXPR(Node, Parent) \
4066 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4067 #include "clang/AST/StmtNodes.inc"
4070 return E;
4073 template<typename Derived>
4074 ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4075 bool NotCopyInit) {
4076 // Initializers are instantiated like expressions, except that various outer
4077 // layers are stripped.
4078 if (!Init)
4079 return Init;
4081 if (auto *FE = dyn_cast<FullExpr>(Init))
4082 Init = FE->getSubExpr();
4084 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {
4085 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4086 Init = OVE->getSourceExpr();
4089 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
4090 Init = MTE->getSubExpr();
4092 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
4093 Init = Binder->getSubExpr();
4095 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
4096 Init = ICE->getSubExprAsWritten();
4098 if (CXXStdInitializerListExpr *ILE =
4099 dyn_cast<CXXStdInitializerListExpr>(Init))
4100 return TransformInitializer(ILE->getSubExpr(), NotCopyInit);
4102 // If this is copy-initialization, we only need to reconstruct
4103 // InitListExprs. Other forms of copy-initialization will be a no-op if
4104 // the initializer is already the right type.
4105 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
4106 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4107 return getDerived().TransformExpr(Init);
4109 // Revert value-initialization back to empty parens.
4110 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
4111 SourceRange Parens = VIE->getSourceRange();
4112 return getDerived().RebuildParenListExpr(Parens.getBegin(), std::nullopt,
4113 Parens.getEnd());
4116 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4117 if (isa<ImplicitValueInitExpr>(Init))
4118 return getDerived().RebuildParenListExpr(SourceLocation(), std::nullopt,
4119 SourceLocation());
4121 // Revert initialization by constructor back to a parenthesized or braced list
4122 // of expressions. Any other form of initializer can just be reused directly.
4123 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
4124 return getDerived().TransformExpr(Init);
4126 // If the initialization implicitly converted an initializer list to a
4127 // std::initializer_list object, unwrap the std::initializer_list too.
4128 if (Construct && Construct->isStdInitListInitialization())
4129 return TransformInitializer(Construct->getArg(0), NotCopyInit);
4131 // Enter a list-init context if this was list initialization.
4132 EnterExpressionEvaluationContext Context(
4133 getSema(), EnterExpressionEvaluationContext::InitList,
4134 Construct->isListInitialization());
4136 SmallVector<Expr*, 8> NewArgs;
4137 bool ArgChanged = false;
4138 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4139 /*IsCall*/true, NewArgs, &ArgChanged))
4140 return ExprError();
4142 // If this was list initialization, revert to syntactic list form.
4143 if (Construct->isListInitialization())
4144 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4145 Construct->getEndLoc());
4147 // Build a ParenListExpr to represent anything else.
4148 SourceRange Parens = Construct->getParenOrBraceRange();
4149 if (Parens.isInvalid()) {
4150 // This was a variable declaration's initialization for which no initializer
4151 // was specified.
4152 assert(NewArgs.empty() &&
4153 "no parens or braces but have direct init with arguments?");
4154 return ExprEmpty();
4156 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4157 Parens.getEnd());
4160 template<typename Derived>
4161 bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4162 unsigned NumInputs,
4163 bool IsCall,
4164 SmallVectorImpl<Expr *> &Outputs,
4165 bool *ArgChanged) {
4166 for (unsigned I = 0; I != NumInputs; ++I) {
4167 // If requested, drop call arguments that need to be dropped.
4168 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4169 if (ArgChanged)
4170 *ArgChanged = true;
4172 break;
4175 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
4176 Expr *Pattern = Expansion->getPattern();
4178 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4179 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4180 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4182 // Determine whether the set of unexpanded parameter packs can and should
4183 // be expanded.
4184 bool Expand = true;
4185 bool RetainExpansion = false;
4186 std::optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions();
4187 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4188 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4189 Pattern->getSourceRange(),
4190 Unexpanded,
4191 Expand, RetainExpansion,
4192 NumExpansions))
4193 return true;
4195 if (!Expand) {
4196 // The transform has determined that we should perform a simple
4197 // transformation on the pack expansion, producing another pack
4198 // expansion.
4199 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4200 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4201 if (OutPattern.isInvalid())
4202 return true;
4204 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4205 Expansion->getEllipsisLoc(),
4206 NumExpansions);
4207 if (Out.isInvalid())
4208 return true;
4210 if (ArgChanged)
4211 *ArgChanged = true;
4212 Outputs.push_back(Out.get());
4213 continue;
4216 // Record right away that the argument was changed. This needs
4217 // to happen even if the array expands to nothing.
4218 if (ArgChanged) *ArgChanged = true;
4220 // The transform has determined that we should perform an elementwise
4221 // expansion of the pattern. Do so.
4222 for (unsigned I = 0; I != *NumExpansions; ++I) {
4223 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4224 ExprResult Out = getDerived().TransformExpr(Pattern);
4225 if (Out.isInvalid())
4226 return true;
4228 if (Out.get()->containsUnexpandedParameterPack()) {
4229 Out = getDerived().RebuildPackExpansion(
4230 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4231 if (Out.isInvalid())
4232 return true;
4235 Outputs.push_back(Out.get());
4238 // If we're supposed to retain a pack expansion, do so by temporarily
4239 // forgetting the partially-substituted parameter pack.
4240 if (RetainExpansion) {
4241 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4243 ExprResult Out = getDerived().TransformExpr(Pattern);
4244 if (Out.isInvalid())
4245 return true;
4247 Out = getDerived().RebuildPackExpansion(
4248 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4249 if (Out.isInvalid())
4250 return true;
4252 Outputs.push_back(Out.get());
4255 continue;
4258 ExprResult Result =
4259 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4260 : getDerived().TransformExpr(Inputs[I]);
4261 if (Result.isInvalid())
4262 return true;
4264 if (Result.get() != Inputs[I] && ArgChanged)
4265 *ArgChanged = true;
4267 Outputs.push_back(Result.get());
4270 return false;
4273 template <typename Derived>
4274 Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4275 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4276 if (Var) {
4277 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4278 getDerived().TransformDefinition(Var->getLocation(), Var));
4280 if (!ConditionVar)
4281 return Sema::ConditionError();
4283 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4286 if (Expr) {
4287 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4289 if (CondExpr.isInvalid())
4290 return Sema::ConditionError();
4292 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4293 /*MissingOK=*/true);
4296 return Sema::ConditionResult();
4299 template <typename Derived>
4300 NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4301 NestedNameSpecifierLoc NNS, QualType ObjectType,
4302 NamedDecl *FirstQualifierInScope) {
4303 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4305 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4306 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4307 Qualifier = Qualifier.getPrefix())
4308 Qualifiers.push_back(Qualifier);
4310 insertNNS(NNS);
4312 CXXScopeSpec SS;
4313 while (!Qualifiers.empty()) {
4314 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4315 NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
4317 switch (QNNS->getKind()) {
4318 case NestedNameSpecifier::Identifier: {
4319 Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
4320 Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
4321 ObjectType);
4322 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false,
4323 SS, FirstQualifierInScope, false))
4324 return NestedNameSpecifierLoc();
4325 break;
4328 case NestedNameSpecifier::Namespace: {
4329 NamespaceDecl *NS =
4330 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4331 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4332 SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
4333 break;
4336 case NestedNameSpecifier::NamespaceAlias: {
4337 NamespaceAliasDecl *Alias =
4338 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4339 Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
4340 SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
4341 Q.getLocalEndLoc());
4342 break;
4345 case NestedNameSpecifier::Global:
4346 // There is no meaningful transformation that one could perform on the
4347 // global scope.
4348 SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
4349 break;
4351 case NestedNameSpecifier::Super: {
4352 CXXRecordDecl *RD =
4353 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4354 SourceLocation(), QNNS->getAsRecordDecl()));
4355 SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc());
4356 break;
4359 case NestedNameSpecifier::TypeSpecWithTemplate:
4360 case NestedNameSpecifier::TypeSpec: {
4361 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4362 FirstQualifierInScope, SS);
4364 if (!TL)
4365 return NestedNameSpecifierLoc();
4367 QualType T = TL.getType();
4368 if (T->isDependentType() || T->isRecordType() ||
4369 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4370 if (T->isEnumeralType())
4371 SemaRef.Diag(TL.getBeginLoc(),
4372 diag::warn_cxx98_compat_enum_nested_name_spec);
4374 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4375 SS.Adopt(ETL.getQualifierLoc());
4376 TL = ETL.getNamedTypeLoc();
4378 SS.Extend(SemaRef.Context, /*FIXME:*/ SourceLocation(), TL,
4379 Q.getLocalEndLoc());
4380 break;
4382 // If the nested-name-specifier is an invalid type def, don't emit an
4383 // error because a previous error should have already been emitted.
4384 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4385 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4386 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
4387 << T << SS.getRange();
4389 return NestedNameSpecifierLoc();
4393 // The qualifier-in-scope and object type only apply to the leftmost entity.
4394 FirstQualifierInScope = nullptr;
4395 ObjectType = QualType();
4398 // Don't rebuild the nested-name-specifier if we don't have to.
4399 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4400 !getDerived().AlwaysRebuild())
4401 return NNS;
4403 // If we can re-use the source-location data from the original
4404 // nested-name-specifier, do so.
4405 if (SS.location_size() == NNS.getDataLength() &&
4406 memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)
4407 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4409 // Allocate new nested-name-specifier location information.
4410 return SS.getWithLocInContext(SemaRef.Context);
4413 template<typename Derived>
4414 DeclarationNameInfo
4415 TreeTransform<Derived>
4416 ::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4417 DeclarationName Name = NameInfo.getName();
4418 if (!Name)
4419 return DeclarationNameInfo();
4421 switch (Name.getNameKind()) {
4422 case DeclarationName::Identifier:
4423 case DeclarationName::ObjCZeroArgSelector:
4424 case DeclarationName::ObjCOneArgSelector:
4425 case DeclarationName::ObjCMultiArgSelector:
4426 case DeclarationName::CXXOperatorName:
4427 case DeclarationName::CXXLiteralOperatorName:
4428 case DeclarationName::CXXUsingDirective:
4429 return NameInfo;
4431 case DeclarationName::CXXDeductionGuideName: {
4432 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4433 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4434 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4435 if (!NewTemplate)
4436 return DeclarationNameInfo();
4438 DeclarationNameInfo NewNameInfo(NameInfo);
4439 NewNameInfo.setName(
4440 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(NewTemplate));
4441 return NewNameInfo;
4444 case DeclarationName::CXXConstructorName:
4445 case DeclarationName::CXXDestructorName:
4446 case DeclarationName::CXXConversionFunctionName: {
4447 TypeSourceInfo *NewTInfo;
4448 CanQualType NewCanTy;
4449 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4450 NewTInfo = getDerived().TransformType(OldTInfo);
4451 if (!NewTInfo)
4452 return DeclarationNameInfo();
4453 NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
4455 else {
4456 NewTInfo = nullptr;
4457 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4458 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4459 if (NewT.isNull())
4460 return DeclarationNameInfo();
4461 NewCanTy = SemaRef.Context.getCanonicalType(NewT);
4464 DeclarationName NewName
4465 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
4466 NewCanTy);
4467 DeclarationNameInfo NewNameInfo(NameInfo);
4468 NewNameInfo.setName(NewName);
4469 NewNameInfo.setNamedTypeInfo(NewTInfo);
4470 return NewNameInfo;
4474 llvm_unreachable("Unknown name kind.");
4477 template<typename Derived>
4478 TemplateName
4479 TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
4480 TemplateName Name,
4481 SourceLocation NameLoc,
4482 QualType ObjectType,
4483 NamedDecl *FirstQualifierInScope,
4484 bool AllowInjectedClassName) {
4485 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4486 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4487 assert(Template && "qualified template name must refer to a template");
4489 TemplateDecl *TransTemplate
4490 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4491 Template));
4492 if (!TransTemplate)
4493 return TemplateName();
4495 if (!getDerived().AlwaysRebuild() &&
4496 SS.getScopeRep() == QTN->getQualifier() &&
4497 TransTemplate == Template)
4498 return Name;
4500 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4501 TransTemplate);
4504 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4505 if (SS.getScopeRep()) {
4506 // These apply to the scope specifier, not the template.
4507 ObjectType = QualType();
4508 FirstQualifierInScope = nullptr;
4511 if (!getDerived().AlwaysRebuild() &&
4512 SS.getScopeRep() == DTN->getQualifier() &&
4513 ObjectType.isNull())
4514 return Name;
4516 // FIXME: Preserve the location of the "template" keyword.
4517 SourceLocation TemplateKWLoc = NameLoc;
4519 if (DTN->isIdentifier()) {
4520 return getDerived().RebuildTemplateName(SS,
4521 TemplateKWLoc,
4522 *DTN->getIdentifier(),
4523 NameLoc,
4524 ObjectType,
4525 FirstQualifierInScope,
4526 AllowInjectedClassName);
4529 return getDerived().RebuildTemplateName(SS, TemplateKWLoc,
4530 DTN->getOperator(), NameLoc,
4531 ObjectType, AllowInjectedClassName);
4534 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4535 TemplateDecl *TransTemplate
4536 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4537 Template));
4538 if (!TransTemplate)
4539 return TemplateName();
4541 if (!getDerived().AlwaysRebuild() &&
4542 TransTemplate == Template)
4543 return Name;
4545 return TemplateName(TransTemplate);
4548 if (SubstTemplateTemplateParmPackStorage *SubstPack
4549 = Name.getAsSubstTemplateTemplateParmPack()) {
4550 return getDerived().RebuildTemplateName(
4551 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4552 SubstPack->getIndex(), SubstPack->getFinal());
4555 // These should be getting filtered out before they reach the AST.
4556 llvm_unreachable("overloaded function decl survived to here");
4559 template<typename Derived>
4560 void TreeTransform<Derived>::InventTemplateArgumentLoc(
4561 const TemplateArgument &Arg,
4562 TemplateArgumentLoc &Output) {
4563 Output = getSema().getTrivialTemplateArgumentLoc(
4564 Arg, QualType(), getDerived().getBaseLocation());
4567 template <typename Derived>
4568 bool TreeTransform<Derived>::TransformTemplateArgument(
4569 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4570 bool Uneval) {
4571 const TemplateArgument &Arg = Input.getArgument();
4572 switch (Arg.getKind()) {
4573 case TemplateArgument::Null:
4574 case TemplateArgument::Pack:
4575 llvm_unreachable("Unexpected TemplateArgument");
4577 case TemplateArgument::Integral:
4578 case TemplateArgument::NullPtr:
4579 case TemplateArgument::Declaration: {
4580 // Transform a resolved template argument straight to a resolved template
4581 // argument. We get here when substituting into an already-substituted
4582 // template type argument during concept satisfaction checking.
4583 QualType T = Arg.getNonTypeTemplateArgumentType();
4584 QualType NewT = getDerived().TransformType(T);
4585 if (NewT.isNull())
4586 return true;
4588 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
4589 ? Arg.getAsDecl()
4590 : nullptr;
4591 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4592 getDerived().getBaseLocation(), D))
4593 : nullptr;
4594 if (D && !NewD)
4595 return true;
4597 if (NewT == T && D == NewD)
4598 Output = Input;
4599 else if (Arg.getKind() == TemplateArgument::Integral)
4600 Output = TemplateArgumentLoc(
4601 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4602 TemplateArgumentLocInfo());
4603 else if (Arg.getKind() == TemplateArgument::NullPtr)
4604 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4605 TemplateArgumentLocInfo());
4606 else
4607 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4608 TemplateArgumentLocInfo());
4610 return false;
4613 case TemplateArgument::Type: {
4614 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4615 if (!DI)
4616 DI = InventTypeSourceInfo(Input.getArgument().getAsType());
4618 DI = getDerived().TransformType(DI);
4619 if (!DI)
4620 return true;
4622 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4623 return false;
4626 case TemplateArgument::Template: {
4627 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4628 if (QualifierLoc) {
4629 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4630 if (!QualifierLoc)
4631 return true;
4634 CXXScopeSpec SS;
4635 SS.Adopt(QualifierLoc);
4636 TemplateName Template = getDerived().TransformTemplateName(
4637 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4638 if (Template.isNull())
4639 return true;
4641 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4642 QualifierLoc, Input.getTemplateNameLoc());
4643 return false;
4646 case TemplateArgument::TemplateExpansion:
4647 llvm_unreachable("Caller should expand pack expansions");
4649 case TemplateArgument::Expression: {
4650 // Template argument expressions are constant expressions.
4651 EnterExpressionEvaluationContext Unevaluated(
4652 getSema(),
4653 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
4654 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
4655 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4656 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
4658 Expr *InputExpr = Input.getSourceExpression();
4659 if (!InputExpr)
4660 InputExpr = Input.getArgument().getAsExpr();
4662 ExprResult E = getDerived().TransformExpr(InputExpr);
4663 E = SemaRef.ActOnConstantExpression(E);
4664 if (E.isInvalid())
4665 return true;
4666 Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
4667 return false;
4671 // Work around bogus GCC warning
4672 return true;
4675 /// Iterator adaptor that invents template argument location information
4676 /// for each of the template arguments in its underlying iterator.
4677 template<typename Derived, typename InputIterator>
4678 class TemplateArgumentLocInventIterator {
4679 TreeTransform<Derived> &Self;
4680 InputIterator Iter;
4682 public:
4683 typedef TemplateArgumentLoc value_type;
4684 typedef TemplateArgumentLoc reference;
4685 typedef typename std::iterator_traits<InputIterator>::difference_type
4686 difference_type;
4687 typedef std::input_iterator_tag iterator_category;
4689 class pointer {
4690 TemplateArgumentLoc Arg;
4692 public:
4693 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4695 const TemplateArgumentLoc *operator->() const { return &Arg; }
4698 TemplateArgumentLocInventIterator() { }
4700 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
4701 InputIterator Iter)
4702 : Self(Self), Iter(Iter) { }
4704 TemplateArgumentLocInventIterator &operator++() {
4705 ++Iter;
4706 return *this;
4709 TemplateArgumentLocInventIterator operator++(int) {
4710 TemplateArgumentLocInventIterator Old(*this);
4711 ++(*this);
4712 return Old;
4715 reference operator*() const {
4716 TemplateArgumentLoc Result;
4717 Self.InventTemplateArgumentLoc(*Iter, Result);
4718 return Result;
4721 pointer operator->() const { return pointer(**this); }
4723 friend bool operator==(const TemplateArgumentLocInventIterator &X,
4724 const TemplateArgumentLocInventIterator &Y) {
4725 return X.Iter == Y.Iter;
4728 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
4729 const TemplateArgumentLocInventIterator &Y) {
4730 return X.Iter != Y.Iter;
4734 template<typename Derived>
4735 template<typename InputIterator>
4736 bool TreeTransform<Derived>::TransformTemplateArguments(
4737 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
4738 bool Uneval) {
4739 for (; First != Last; ++First) {
4740 TemplateArgumentLoc Out;
4741 TemplateArgumentLoc In = *First;
4743 if (In.getArgument().getKind() == TemplateArgument::Pack) {
4744 // Unpack argument packs, which we translate them into separate
4745 // arguments.
4746 // FIXME: We could do much better if we could guarantee that the
4747 // TemplateArgumentLocInfo for the pack expansion would be usable for
4748 // all of the template arguments in the argument pack.
4749 typedef TemplateArgumentLocInventIterator<Derived,
4750 TemplateArgument::pack_iterator>
4751 PackLocIterator;
4752 if (TransformTemplateArguments(PackLocIterator(*this,
4753 In.getArgument().pack_begin()),
4754 PackLocIterator(*this,
4755 In.getArgument().pack_end()),
4756 Outputs, Uneval))
4757 return true;
4759 continue;
4762 if (In.getArgument().isPackExpansion()) {
4763 // We have a pack expansion, for which we will be substituting into
4764 // the pattern.
4765 SourceLocation Ellipsis;
4766 std::optional<unsigned> OrigNumExpansions;
4767 TemplateArgumentLoc Pattern
4768 = getSema().getTemplateArgumentPackExpansionPattern(
4769 In, Ellipsis, OrigNumExpansions);
4771 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4772 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4773 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4775 // Determine whether the set of unexpanded parameter packs can and should
4776 // be expanded.
4777 bool Expand = true;
4778 bool RetainExpansion = false;
4779 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4780 if (getDerived().TryExpandParameterPacks(Ellipsis,
4781 Pattern.getSourceRange(),
4782 Unexpanded,
4783 Expand,
4784 RetainExpansion,
4785 NumExpansions))
4786 return true;
4788 if (!Expand) {
4789 // The transform has determined that we should perform a simple
4790 // transformation on the pack expansion, producing another pack
4791 // expansion.
4792 TemplateArgumentLoc OutPattern;
4793 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4794 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
4795 return true;
4797 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
4798 NumExpansions);
4799 if (Out.getArgument().isNull())
4800 return true;
4802 Outputs.addArgument(Out);
4803 continue;
4806 // The transform has determined that we should perform an elementwise
4807 // expansion of the pattern. Do so.
4808 for (unsigned I = 0; I != *NumExpansions; ++I) {
4809 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4811 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4812 return true;
4814 if (Out.getArgument().containsUnexpandedParameterPack()) {
4815 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4816 OrigNumExpansions);
4817 if (Out.getArgument().isNull())
4818 return true;
4821 Outputs.addArgument(Out);
4824 // If we're supposed to retain a pack expansion, do so by temporarily
4825 // forgetting the partially-substituted parameter pack.
4826 if (RetainExpansion) {
4827 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4829 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4830 return true;
4832 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4833 OrigNumExpansions);
4834 if (Out.getArgument().isNull())
4835 return true;
4837 Outputs.addArgument(Out);
4840 continue;
4843 // The simple case:
4844 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
4845 return true;
4847 Outputs.addArgument(Out);
4850 return false;
4854 //===----------------------------------------------------------------------===//
4855 // Type transformation
4856 //===----------------------------------------------------------------------===//
4858 template<typename Derived>
4859 QualType TreeTransform<Derived>::TransformType(QualType T) {
4860 if (getDerived().AlreadyTransformed(T))
4861 return T;
4863 // Temporary workaround. All of these transformations should
4864 // eventually turn into transformations on TypeLocs.
4865 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4866 getDerived().getBaseLocation());
4868 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
4870 if (!NewDI)
4871 return QualType();
4873 return NewDI->getType();
4876 template<typename Derived>
4877 TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
4878 // Refine the base location to the type's location.
4879 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
4880 getDerived().getBaseEntity());
4881 if (getDerived().AlreadyTransformed(DI->getType()))
4882 return DI;
4884 TypeLocBuilder TLB;
4886 TypeLoc TL = DI->getTypeLoc();
4887 TLB.reserve(TL.getFullDataSize());
4889 QualType Result = getDerived().TransformType(TLB, TL);
4890 if (Result.isNull())
4891 return nullptr;
4893 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
4896 template<typename Derived>
4897 QualType
4898 TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
4899 switch (T.getTypeLocClass()) {
4900 #define ABSTRACT_TYPELOC(CLASS, PARENT)
4901 #define TYPELOC(CLASS, PARENT) \
4902 case TypeLoc::CLASS: \
4903 return getDerived().Transform##CLASS##Type(TLB, \
4904 T.castAs<CLASS##TypeLoc>());
4905 #include "clang/AST/TypeLocNodes.def"
4908 llvm_unreachable("unhandled type loc!");
4911 template<typename Derived>
4912 QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
4913 if (!isa<DependentNameType>(T))
4914 return TransformType(T);
4916 if (getDerived().AlreadyTransformed(T))
4917 return T;
4918 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4919 getDerived().getBaseLocation());
4920 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
4921 return NewDI ? NewDI->getType() : QualType();
4924 template<typename Derived>
4925 TypeSourceInfo *
4926 TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
4927 if (!isa<DependentNameType>(DI->getType()))
4928 return TransformType(DI);
4930 // Refine the base location to the type's location.
4931 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
4932 getDerived().getBaseEntity());
4933 if (getDerived().AlreadyTransformed(DI->getType()))
4934 return DI;
4936 TypeLocBuilder TLB;
4938 TypeLoc TL = DI->getTypeLoc();
4939 TLB.reserve(TL.getFullDataSize());
4941 auto QTL = TL.getAs<QualifiedTypeLoc>();
4942 if (QTL)
4943 TL = QTL.getUnqualifiedLoc();
4945 auto DNTL = TL.castAs<DependentNameTypeLoc>();
4947 QualType Result = getDerived().TransformDependentNameType(
4948 TLB, DNTL, /*DeducedTSTContext*/true);
4949 if (Result.isNull())
4950 return nullptr;
4952 if (QTL) {
4953 Result = getDerived().RebuildQualifiedType(Result, QTL);
4954 if (Result.isNull())
4955 return nullptr;
4956 TLB.TypeWasModifiedSafely(Result);
4959 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
4962 template<typename Derived>
4963 QualType
4964 TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
4965 QualifiedTypeLoc T) {
4966 QualType Result;
4967 TypeLoc UnqualTL = T.getUnqualifiedLoc();
4968 auto SuppressObjCLifetime =
4969 T.getType().getLocalQualifiers().hasObjCLifetime();
4970 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
4971 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
4972 SuppressObjCLifetime);
4973 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
4974 Result = getDerived().TransformSubstTemplateTypeParmPackType(
4975 TLB, STTP, SuppressObjCLifetime);
4976 } else {
4977 Result = getDerived().TransformType(TLB, UnqualTL);
4980 if (Result.isNull())
4981 return QualType();
4983 Result = getDerived().RebuildQualifiedType(Result, T);
4985 if (Result.isNull())
4986 return QualType();
4988 // RebuildQualifiedType might have updated the type, but not in a way
4989 // that invalidates the TypeLoc. (There's no location information for
4990 // qualifiers.)
4991 TLB.TypeWasModifiedSafely(Result);
4993 return Result;
4996 template <typename Derived>
4997 QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
4998 QualifiedTypeLoc TL) {
5000 SourceLocation Loc = TL.getBeginLoc();
5001 Qualifiers Quals = TL.getType().getLocalQualifiers();
5003 if ((T.getAddressSpace() != LangAS::Default &&
5004 Quals.getAddressSpace() != LangAS::Default) &&
5005 T.getAddressSpace() != Quals.getAddressSpace()) {
5006 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)
5007 << TL.getType() << T;
5008 return QualType();
5011 // C++ [dcl.fct]p7:
5012 // [When] adding cv-qualifications on top of the function type [...] the
5013 // cv-qualifiers are ignored.
5014 if (T->isFunctionType()) {
5015 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5016 Quals.getAddressSpace());
5017 return T;
5020 // C++ [dcl.ref]p1:
5021 // when the cv-qualifiers are introduced through the use of a typedef-name
5022 // or decltype-specifier [...] the cv-qualifiers are ignored.
5023 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5024 // applied to a reference type.
5025 if (T->isReferenceType()) {
5026 // The only qualifier that applies to a reference type is restrict.
5027 if (!Quals.hasRestrict())
5028 return T;
5029 Quals = Qualifiers::fromCVRMask(Qualifiers::Restrict);
5032 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5033 // resulting type.
5034 if (Quals.hasObjCLifetime()) {
5035 if (!T->isObjCLifetimeType() && !T->isDependentType())
5036 Quals.removeObjCLifetime();
5037 else if (T.getObjCLifetime()) {
5038 // Objective-C ARC:
5039 // A lifetime qualifier applied to a substituted template parameter
5040 // overrides the lifetime qualifier from the template argument.
5041 const AutoType *AutoTy;
5042 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
5043 // 'auto' types behave the same way as template parameters.
5044 QualType Deduced = AutoTy->getDeducedType();
5045 Qualifiers Qs = Deduced.getQualifiers();
5046 Qs.removeObjCLifetime();
5047 Deduced =
5048 SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);
5049 T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),
5050 AutoTy->isDependentType(),
5051 /*isPack=*/false,
5052 AutoTy->getTypeConstraintConcept(),
5053 AutoTy->getTypeConstraintArguments());
5054 } else {
5055 // Otherwise, complain about the addition of a qualifier to an
5056 // already-qualified type.
5057 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5058 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
5059 Quals.removeObjCLifetime();
5064 return SemaRef.BuildQualifiedType(T, Loc, Quals);
5067 template<typename Derived>
5068 TypeLoc
5069 TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
5070 QualType ObjectType,
5071 NamedDecl *UnqualLookup,
5072 CXXScopeSpec &SS) {
5073 if (getDerived().AlreadyTransformed(TL.getType()))
5074 return TL;
5076 TypeSourceInfo *TSI =
5077 TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS);
5078 if (TSI)
5079 return TSI->getTypeLoc();
5080 return TypeLoc();
5083 template<typename Derived>
5084 TypeSourceInfo *
5085 TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5086 QualType ObjectType,
5087 NamedDecl *UnqualLookup,
5088 CXXScopeSpec &SS) {
5089 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5090 return TSInfo;
5092 return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType,
5093 UnqualLookup, SS);
5096 template <typename Derived>
5097 TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5098 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5099 CXXScopeSpec &SS) {
5100 QualType T = TL.getType();
5101 assert(!getDerived().AlreadyTransformed(T));
5103 TypeLocBuilder TLB;
5104 QualType Result;
5106 if (isa<TemplateSpecializationType>(T)) {
5107 TemplateSpecializationTypeLoc SpecTL =
5108 TL.castAs<TemplateSpecializationTypeLoc>();
5110 TemplateName Template = getDerived().TransformTemplateName(
5111 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5112 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5113 if (Template.isNull())
5114 return nullptr;
5116 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5117 Template);
5118 } else if (isa<DependentTemplateSpecializationType>(T)) {
5119 DependentTemplateSpecializationTypeLoc SpecTL =
5120 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5122 TemplateName Template
5123 = getDerived().RebuildTemplateName(SS,
5124 SpecTL.getTemplateKeywordLoc(),
5125 *SpecTL.getTypePtr()->getIdentifier(),
5126 SpecTL.getTemplateNameLoc(),
5127 ObjectType, UnqualLookup,
5128 /*AllowInjectedClassName*/true);
5129 if (Template.isNull())
5130 return nullptr;
5132 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5133 SpecTL,
5134 Template,
5135 SS);
5136 } else {
5137 // Nothing special needs to be done for these.
5138 Result = getDerived().TransformType(TLB, TL);
5141 if (Result.isNull())
5142 return nullptr;
5144 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5147 template <class TyLoc> static inline
5148 QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5149 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5150 NewT.setNameLoc(T.getNameLoc());
5151 return T.getType();
5154 template<typename Derived>
5155 QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5156 BuiltinTypeLoc T) {
5157 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
5158 NewT.setBuiltinLoc(T.getBuiltinLoc());
5159 if (T.needsExtraLocalData())
5160 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5161 return T.getType();
5164 template<typename Derived>
5165 QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5166 ComplexTypeLoc T) {
5167 // FIXME: recurse?
5168 return TransformTypeSpecType(TLB, T);
5171 template <typename Derived>
5172 QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5173 AdjustedTypeLoc TL) {
5174 // Adjustments applied during transformation are handled elsewhere.
5175 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5178 template<typename Derived>
5179 QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5180 DecayedTypeLoc TL) {
5181 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5182 if (OriginalType.isNull())
5183 return QualType();
5185 QualType Result = TL.getType();
5186 if (getDerived().AlwaysRebuild() ||
5187 OriginalType != TL.getOriginalLoc().getType())
5188 Result = SemaRef.Context.getDecayedType(OriginalType);
5189 TLB.push<DecayedTypeLoc>(Result);
5190 // Nothing to set for DecayedTypeLoc.
5191 return Result;
5194 template<typename Derived>
5195 QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5196 PointerTypeLoc TL) {
5197 QualType PointeeType
5198 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5199 if (PointeeType.isNull())
5200 return QualType();
5202 QualType Result = TL.getType();
5203 if (PointeeType->getAs<ObjCObjectType>()) {
5204 // A dependent pointer type 'T *' has is being transformed such
5205 // that an Objective-C class type is being replaced for 'T'. The
5206 // resulting pointer type is an ObjCObjectPointerType, not a
5207 // PointerType.
5208 Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
5210 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
5211 NewT.setStarLoc(TL.getStarLoc());
5212 return Result;
5215 if (getDerived().AlwaysRebuild() ||
5216 PointeeType != TL.getPointeeLoc().getType()) {
5217 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5218 if (Result.isNull())
5219 return QualType();
5222 // Objective-C ARC can add lifetime qualifiers to the type that we're
5223 // pointing to.
5224 TLB.TypeWasModifiedSafely(Result->getPointeeType());
5226 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
5227 NewT.setSigilLoc(TL.getSigilLoc());
5228 return Result;
5231 template<typename Derived>
5232 QualType
5233 TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5234 BlockPointerTypeLoc TL) {
5235 QualType PointeeType
5236 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5237 if (PointeeType.isNull())
5238 return QualType();
5240 QualType Result = TL.getType();
5241 if (getDerived().AlwaysRebuild() ||
5242 PointeeType != TL.getPointeeLoc().getType()) {
5243 Result = getDerived().RebuildBlockPointerType(PointeeType,
5244 TL.getSigilLoc());
5245 if (Result.isNull())
5246 return QualType();
5249 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
5250 NewT.setSigilLoc(TL.getSigilLoc());
5251 return Result;
5254 /// Transforms a reference type. Note that somewhat paradoxically we
5255 /// don't care whether the type itself is an l-value type or an r-value
5256 /// type; we only care if the type was *written* as an l-value type
5257 /// or an r-value type.
5258 template<typename Derived>
5259 QualType
5260 TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5261 ReferenceTypeLoc TL) {
5262 const ReferenceType *T = TL.getTypePtr();
5264 // Note that this works with the pointee-as-written.
5265 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5266 if (PointeeType.isNull())
5267 return QualType();
5269 QualType Result = TL.getType();
5270 if (getDerived().AlwaysRebuild() ||
5271 PointeeType != T->getPointeeTypeAsWritten()) {
5272 Result = getDerived().RebuildReferenceType(PointeeType,
5273 T->isSpelledAsLValue(),
5274 TL.getSigilLoc());
5275 if (Result.isNull())
5276 return QualType();
5279 // Objective-C ARC can add lifetime qualifiers to the type that we're
5280 // referring to.
5281 TLB.TypeWasModifiedSafely(
5282 Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5284 // r-value references can be rebuilt as l-value references.
5285 ReferenceTypeLoc NewTL;
5286 if (isa<LValueReferenceType>(Result))
5287 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
5288 else
5289 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
5290 NewTL.setSigilLoc(TL.getSigilLoc());
5292 return Result;
5295 template<typename Derived>
5296 QualType
5297 TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5298 LValueReferenceTypeLoc TL) {
5299 return TransformReferenceType(TLB, TL);
5302 template<typename Derived>
5303 QualType
5304 TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5305 RValueReferenceTypeLoc TL) {
5306 return TransformReferenceType(TLB, TL);
5309 template<typename Derived>
5310 QualType
5311 TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5312 MemberPointerTypeLoc TL) {
5313 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5314 if (PointeeType.isNull())
5315 return QualType();
5317 TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
5318 TypeSourceInfo *NewClsTInfo = nullptr;
5319 if (OldClsTInfo) {
5320 NewClsTInfo = getDerived().TransformType(OldClsTInfo);
5321 if (!NewClsTInfo)
5322 return QualType();
5325 const MemberPointerType *T = TL.getTypePtr();
5326 QualType OldClsType = QualType(T->getClass(), 0);
5327 QualType NewClsType;
5328 if (NewClsTInfo)
5329 NewClsType = NewClsTInfo->getType();
5330 else {
5331 NewClsType = getDerived().TransformType(OldClsType);
5332 if (NewClsType.isNull())
5333 return QualType();
5336 QualType Result = TL.getType();
5337 if (getDerived().AlwaysRebuild() ||
5338 PointeeType != T->getPointeeType() ||
5339 NewClsType != OldClsType) {
5340 Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
5341 TL.getStarLoc());
5342 if (Result.isNull())
5343 return QualType();
5346 // If we had to adjust the pointee type when building a member pointer, make
5347 // sure to push TypeLoc info for it.
5348 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5349 if (MPT && PointeeType != MPT->getPointeeType()) {
5350 assert(isa<AdjustedType>(MPT->getPointeeType()));
5351 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
5354 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
5355 NewTL.setSigilLoc(TL.getSigilLoc());
5356 NewTL.setClassTInfo(NewClsTInfo);
5358 return Result;
5361 template<typename Derived>
5362 QualType
5363 TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5364 ConstantArrayTypeLoc TL) {
5365 const ConstantArrayType *T = TL.getTypePtr();
5366 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5367 if (ElementType.isNull())
5368 return QualType();
5370 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5371 Expr *OldSize = TL.getSizeExpr();
5372 if (!OldSize)
5373 OldSize = const_cast<Expr*>(T->getSizeExpr());
5374 Expr *NewSize = nullptr;
5375 if (OldSize) {
5376 EnterExpressionEvaluationContext Unevaluated(
5377 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5378 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5379 NewSize = SemaRef.ActOnConstantExpression(NewSize).get();
5382 QualType Result = TL.getType();
5383 if (getDerived().AlwaysRebuild() ||
5384 ElementType != T->getElementType() ||
5385 (T->getSizeExpr() && NewSize != OldSize)) {
5386 Result = getDerived().RebuildConstantArrayType(ElementType,
5387 T->getSizeModifier(),
5388 T->getSize(), NewSize,
5389 T->getIndexTypeCVRQualifiers(),
5390 TL.getBracketsRange());
5391 if (Result.isNull())
5392 return QualType();
5395 // We might have either a ConstantArrayType or a VariableArrayType now:
5396 // a ConstantArrayType is allowed to have an element type which is a
5397 // VariableArrayType if the type is dependent. Fortunately, all array
5398 // types have the same location layout.
5399 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5400 NewTL.setLBracketLoc(TL.getLBracketLoc());
5401 NewTL.setRBracketLoc(TL.getRBracketLoc());
5402 NewTL.setSizeExpr(NewSize);
5404 return Result;
5407 template<typename Derived>
5408 QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5409 TypeLocBuilder &TLB,
5410 IncompleteArrayTypeLoc TL) {
5411 const IncompleteArrayType *T = TL.getTypePtr();
5412 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5413 if (ElementType.isNull())
5414 return QualType();
5416 QualType Result = TL.getType();
5417 if (getDerived().AlwaysRebuild() ||
5418 ElementType != T->getElementType()) {
5419 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5420 T->getSizeModifier(),
5421 T->getIndexTypeCVRQualifiers(),
5422 TL.getBracketsRange());
5423 if (Result.isNull())
5424 return QualType();
5427 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
5428 NewTL.setLBracketLoc(TL.getLBracketLoc());
5429 NewTL.setRBracketLoc(TL.getRBracketLoc());
5430 NewTL.setSizeExpr(nullptr);
5432 return Result;
5435 template<typename Derived>
5436 QualType
5437 TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5438 VariableArrayTypeLoc TL) {
5439 const VariableArrayType *T = TL.getTypePtr();
5440 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5441 if (ElementType.isNull())
5442 return QualType();
5444 ExprResult SizeResult;
5446 EnterExpressionEvaluationContext Context(
5447 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5448 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5450 if (SizeResult.isInvalid())
5451 return QualType();
5452 SizeResult =
5453 SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);
5454 if (SizeResult.isInvalid())
5455 return QualType();
5457 Expr *Size = SizeResult.get();
5459 QualType Result = TL.getType();
5460 if (getDerived().AlwaysRebuild() ||
5461 ElementType != T->getElementType() ||
5462 Size != T->getSizeExpr()) {
5463 Result = getDerived().RebuildVariableArrayType(ElementType,
5464 T->getSizeModifier(),
5465 Size,
5466 T->getIndexTypeCVRQualifiers(),
5467 TL.getBracketsRange());
5468 if (Result.isNull())
5469 return QualType();
5472 // We might have constant size array now, but fortunately it has the same
5473 // location layout.
5474 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5475 NewTL.setLBracketLoc(TL.getLBracketLoc());
5476 NewTL.setRBracketLoc(TL.getRBracketLoc());
5477 NewTL.setSizeExpr(Size);
5479 return Result;
5482 template<typename Derived>
5483 QualType
5484 TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5485 DependentSizedArrayTypeLoc TL) {
5486 const DependentSizedArrayType *T = TL.getTypePtr();
5487 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5488 if (ElementType.isNull())
5489 return QualType();
5491 // Array bounds are constant expressions.
5492 EnterExpressionEvaluationContext Unevaluated(
5493 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5495 // If we have a VLA then it won't be a constant.
5496 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5498 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5499 Expr *origSize = TL.getSizeExpr();
5500 if (!origSize) origSize = T->getSizeExpr();
5502 ExprResult sizeResult
5503 = getDerived().TransformExpr(origSize);
5504 sizeResult = SemaRef.ActOnConstantExpression(sizeResult);
5505 if (sizeResult.isInvalid())
5506 return QualType();
5508 Expr *size = sizeResult.get();
5510 QualType Result = TL.getType();
5511 if (getDerived().AlwaysRebuild() ||
5512 ElementType != T->getElementType() ||
5513 size != origSize) {
5514 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5515 T->getSizeModifier(),
5516 size,
5517 T->getIndexTypeCVRQualifiers(),
5518 TL.getBracketsRange());
5519 if (Result.isNull())
5520 return QualType();
5523 // We might have any sort of array type now, but fortunately they
5524 // all have the same location layout.
5525 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5526 NewTL.setLBracketLoc(TL.getLBracketLoc());
5527 NewTL.setRBracketLoc(TL.getRBracketLoc());
5528 NewTL.setSizeExpr(size);
5530 return Result;
5533 template <typename Derived>
5534 QualType TreeTransform<Derived>::TransformDependentVectorType(
5535 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5536 const DependentVectorType *T = TL.getTypePtr();
5537 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5538 if (ElementType.isNull())
5539 return QualType();
5541 EnterExpressionEvaluationContext Unevaluated(
5542 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5544 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5545 Size = SemaRef.ActOnConstantExpression(Size);
5546 if (Size.isInvalid())
5547 return QualType();
5549 QualType Result = TL.getType();
5550 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5551 Size.get() != T->getSizeExpr()) {
5552 Result = getDerived().RebuildDependentVectorType(
5553 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5554 if (Result.isNull())
5555 return QualType();
5558 // Result might be dependent or not.
5559 if (isa<DependentVectorType>(Result)) {
5560 DependentVectorTypeLoc NewTL =
5561 TLB.push<DependentVectorTypeLoc>(Result);
5562 NewTL.setNameLoc(TL.getNameLoc());
5563 } else {
5564 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5565 NewTL.setNameLoc(TL.getNameLoc());
5568 return Result;
5571 template<typename Derived>
5572 QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5573 TypeLocBuilder &TLB,
5574 DependentSizedExtVectorTypeLoc TL) {
5575 const DependentSizedExtVectorType *T = TL.getTypePtr();
5577 // FIXME: ext vector locs should be nested
5578 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5579 if (ElementType.isNull())
5580 return QualType();
5582 // Vector sizes are constant expressions.
5583 EnterExpressionEvaluationContext Unevaluated(
5584 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5586 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5587 Size = SemaRef.ActOnConstantExpression(Size);
5588 if (Size.isInvalid())
5589 return QualType();
5591 QualType Result = TL.getType();
5592 if (getDerived().AlwaysRebuild() ||
5593 ElementType != T->getElementType() ||
5594 Size.get() != T->getSizeExpr()) {
5595 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5596 Size.get(),
5597 T->getAttributeLoc());
5598 if (Result.isNull())
5599 return QualType();
5602 // Result might be dependent or not.
5603 if (isa<DependentSizedExtVectorType>(Result)) {
5604 DependentSizedExtVectorTypeLoc NewTL
5605 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
5606 NewTL.setNameLoc(TL.getNameLoc());
5607 } else {
5608 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5609 NewTL.setNameLoc(TL.getNameLoc());
5612 return Result;
5615 template <typename Derived>
5616 QualType
5617 TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5618 ConstantMatrixTypeLoc TL) {
5619 const ConstantMatrixType *T = TL.getTypePtr();
5620 QualType ElementType = getDerived().TransformType(T->getElementType());
5621 if (ElementType.isNull())
5622 return QualType();
5624 QualType Result = TL.getType();
5625 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5626 Result = getDerived().RebuildConstantMatrixType(
5627 ElementType, T->getNumRows(), T->getNumColumns());
5628 if (Result.isNull())
5629 return QualType();
5632 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);
5633 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5634 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5635 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5636 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5638 return Result;
5641 template <typename Derived>
5642 QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5643 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5644 const DependentSizedMatrixType *T = TL.getTypePtr();
5646 QualType ElementType = getDerived().TransformType(T->getElementType());
5647 if (ElementType.isNull()) {
5648 return QualType();
5651 // Matrix dimensions are constant expressions.
5652 EnterExpressionEvaluationContext Unevaluated(
5653 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5655 Expr *origRows = TL.getAttrRowOperand();
5656 if (!origRows)
5657 origRows = T->getRowExpr();
5658 Expr *origColumns = TL.getAttrColumnOperand();
5659 if (!origColumns)
5660 origColumns = T->getColumnExpr();
5662 ExprResult rowResult = getDerived().TransformExpr(origRows);
5663 rowResult = SemaRef.ActOnConstantExpression(rowResult);
5664 if (rowResult.isInvalid())
5665 return QualType();
5667 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5668 columnResult = SemaRef.ActOnConstantExpression(columnResult);
5669 if (columnResult.isInvalid())
5670 return QualType();
5672 Expr *rows = rowResult.get();
5673 Expr *columns = columnResult.get();
5675 QualType Result = TL.getType();
5676 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5677 rows != origRows || columns != origColumns) {
5678 Result = getDerived().RebuildDependentSizedMatrixType(
5679 ElementType, rows, columns, T->getAttributeLoc());
5681 if (Result.isNull())
5682 return QualType();
5685 // We might have any sort of matrix type now, but fortunately they
5686 // all have the same location layout.
5687 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);
5688 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5689 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5690 NewTL.setAttrRowOperand(rows);
5691 NewTL.setAttrColumnOperand(columns);
5692 return Result;
5695 template <typename Derived>
5696 QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
5697 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
5698 const DependentAddressSpaceType *T = TL.getTypePtr();
5700 QualType pointeeType = getDerived().TransformType(T->getPointeeType());
5702 if (pointeeType.isNull())
5703 return QualType();
5705 // Address spaces are constant expressions.
5706 EnterExpressionEvaluationContext Unevaluated(
5707 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5709 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
5710 AddrSpace = SemaRef.ActOnConstantExpression(AddrSpace);
5711 if (AddrSpace.isInvalid())
5712 return QualType();
5714 QualType Result = TL.getType();
5715 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
5716 AddrSpace.get() != T->getAddrSpaceExpr()) {
5717 Result = getDerived().RebuildDependentAddressSpaceType(
5718 pointeeType, AddrSpace.get(), T->getAttributeLoc());
5719 if (Result.isNull())
5720 return QualType();
5723 // Result might be dependent or not.
5724 if (isa<DependentAddressSpaceType>(Result)) {
5725 DependentAddressSpaceTypeLoc NewTL =
5726 TLB.push<DependentAddressSpaceTypeLoc>(Result);
5728 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5729 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
5730 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5732 } else {
5733 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(
5734 Result, getDerived().getBaseLocation());
5735 TransformType(TLB, DI->getTypeLoc());
5738 return Result;
5741 template <typename Derived>
5742 QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
5743 VectorTypeLoc TL) {
5744 const VectorType *T = TL.getTypePtr();
5745 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5746 if (ElementType.isNull())
5747 return QualType();
5749 QualType Result = TL.getType();
5750 if (getDerived().AlwaysRebuild() ||
5751 ElementType != T->getElementType()) {
5752 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
5753 T->getVectorKind());
5754 if (Result.isNull())
5755 return QualType();
5758 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5759 NewTL.setNameLoc(TL.getNameLoc());
5761 return Result;
5764 template<typename Derived>
5765 QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
5766 ExtVectorTypeLoc TL) {
5767 const VectorType *T = TL.getTypePtr();
5768 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5769 if (ElementType.isNull())
5770 return QualType();
5772 QualType Result = TL.getType();
5773 if (getDerived().AlwaysRebuild() ||
5774 ElementType != T->getElementType()) {
5775 Result = getDerived().RebuildExtVectorType(ElementType,
5776 T->getNumElements(),
5777 /*FIXME*/ SourceLocation());
5778 if (Result.isNull())
5779 return QualType();
5782 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5783 NewTL.setNameLoc(TL.getNameLoc());
5785 return Result;
5788 template <typename Derived>
5789 ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
5790 ParmVarDecl *OldParm, int indexAdjustment,
5791 std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
5792 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
5793 TypeSourceInfo *NewDI = nullptr;
5795 if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
5796 // If we're substituting into a pack expansion type and we know the
5797 // length we want to expand to, just substitute for the pattern.
5798 TypeLoc OldTL = OldDI->getTypeLoc();
5799 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
5801 TypeLocBuilder TLB;
5802 TypeLoc NewTL = OldDI->getTypeLoc();
5803 TLB.reserve(NewTL.getFullDataSize());
5805 QualType Result = getDerived().TransformType(TLB,
5806 OldExpansionTL.getPatternLoc());
5807 if (Result.isNull())
5808 return nullptr;
5810 Result = RebuildPackExpansionType(Result,
5811 OldExpansionTL.getPatternLoc().getSourceRange(),
5812 OldExpansionTL.getEllipsisLoc(),
5813 NumExpansions);
5814 if (Result.isNull())
5815 return nullptr;
5817 PackExpansionTypeLoc NewExpansionTL
5818 = TLB.push<PackExpansionTypeLoc>(Result);
5819 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
5820 NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result);
5821 } else
5822 NewDI = getDerived().TransformType(OldDI);
5823 if (!NewDI)
5824 return nullptr;
5826 if (NewDI == OldDI && indexAdjustment == 0)
5827 return OldParm;
5829 ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context,
5830 OldParm->getDeclContext(),
5831 OldParm->getInnerLocStart(),
5832 OldParm->getLocation(),
5833 OldParm->getIdentifier(),
5834 NewDI->getType(),
5835 NewDI,
5836 OldParm->getStorageClass(),
5837 /* DefArg */ nullptr);
5838 newParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
5839 OldParm->getFunctionScopeIndex() + indexAdjustment);
5840 transformedLocalDecl(OldParm, {newParm});
5841 return newParm;
5844 template <typename Derived>
5845 bool TreeTransform<Derived>::TransformFunctionTypeParams(
5846 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
5847 const QualType *ParamTypes,
5848 const FunctionProtoType::ExtParameterInfo *ParamInfos,
5849 SmallVectorImpl<QualType> &OutParamTypes,
5850 SmallVectorImpl<ParmVarDecl *> *PVars,
5851 Sema::ExtParameterInfoBuilder &PInfos,
5852 unsigned *LastParamTransformed) {
5853 int indexAdjustment = 0;
5855 unsigned NumParams = Params.size();
5856 for (unsigned i = 0; i != NumParams; ++i) {
5857 if (LastParamTransformed)
5858 *LastParamTransformed = i;
5859 if (ParmVarDecl *OldParm = Params[i]) {
5860 assert(OldParm->getFunctionScopeIndex() == i);
5862 std::optional<unsigned> NumExpansions;
5863 ParmVarDecl *NewParm = nullptr;
5864 if (OldParm->isParameterPack()) {
5865 // We have a function parameter pack that may need to be expanded.
5866 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5868 // Find the parameter packs that could be expanded.
5869 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
5870 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
5871 TypeLoc Pattern = ExpansionTL.getPatternLoc();
5872 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
5874 // Determine whether we should expand the parameter packs.
5875 bool ShouldExpand = false;
5876 bool RetainExpansion = false;
5877 std::optional<unsigned> OrigNumExpansions;
5878 if (Unexpanded.size() > 0) {
5879 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
5880 NumExpansions = OrigNumExpansions;
5881 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
5882 Pattern.getSourceRange(),
5883 Unexpanded,
5884 ShouldExpand,
5885 RetainExpansion,
5886 NumExpansions)) {
5887 return true;
5889 } else {
5890 #ifndef NDEBUG
5891 const AutoType *AT =
5892 Pattern.getType().getTypePtr()->getContainedAutoType();
5893 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
5894 "Could not find parameter packs or undeduced auto type!");
5895 #endif
5898 if (ShouldExpand) {
5899 // Expand the function parameter pack into multiple, separate
5900 // parameters.
5901 getDerived().ExpandingFunctionParameterPack(OldParm);
5902 for (unsigned I = 0; I != *NumExpansions; ++I) {
5903 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
5904 ParmVarDecl *NewParm
5905 = getDerived().TransformFunctionTypeParam(OldParm,
5906 indexAdjustment++,
5907 OrigNumExpansions,
5908 /*ExpectParameterPack=*/false);
5909 if (!NewParm)
5910 return true;
5912 if (ParamInfos)
5913 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5914 OutParamTypes.push_back(NewParm->getType());
5915 if (PVars)
5916 PVars->push_back(NewParm);
5919 // If we're supposed to retain a pack expansion, do so by temporarily
5920 // forgetting the partially-substituted parameter pack.
5921 if (RetainExpansion) {
5922 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5923 ParmVarDecl *NewParm
5924 = getDerived().TransformFunctionTypeParam(OldParm,
5925 indexAdjustment++,
5926 OrigNumExpansions,
5927 /*ExpectParameterPack=*/false);
5928 if (!NewParm)
5929 return true;
5931 if (ParamInfos)
5932 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5933 OutParamTypes.push_back(NewParm->getType());
5934 if (PVars)
5935 PVars->push_back(NewParm);
5938 // The next parameter should have the same adjustment as the
5939 // last thing we pushed, but we post-incremented indexAdjustment
5940 // on every push. Also, if we push nothing, the adjustment should
5941 // go down by one.
5942 indexAdjustment--;
5944 // We're done with the pack expansion.
5945 continue;
5948 // We'll substitute the parameter now without expanding the pack
5949 // expansion.
5950 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
5951 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
5952 indexAdjustment,
5953 NumExpansions,
5954 /*ExpectParameterPack=*/true);
5955 assert(NewParm->isParameterPack() &&
5956 "Parameter pack no longer a parameter pack after "
5957 "transformation.");
5958 } else {
5959 NewParm = getDerived().TransformFunctionTypeParam(
5960 OldParm, indexAdjustment, std::nullopt,
5961 /*ExpectParameterPack=*/false);
5964 if (!NewParm)
5965 return true;
5967 if (ParamInfos)
5968 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5969 OutParamTypes.push_back(NewParm->getType());
5970 if (PVars)
5971 PVars->push_back(NewParm);
5972 continue;
5975 // Deal with the possibility that we don't have a parameter
5976 // declaration for this parameter.
5977 assert(ParamTypes);
5978 QualType OldType = ParamTypes[i];
5979 bool IsPackExpansion = false;
5980 std::optional<unsigned> NumExpansions;
5981 QualType NewType;
5982 if (const PackExpansionType *Expansion
5983 = dyn_cast<PackExpansionType>(OldType)) {
5984 // We have a function parameter pack that may need to be expanded.
5985 QualType Pattern = Expansion->getPattern();
5986 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5987 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5989 // Determine whether we should expand the parameter packs.
5990 bool ShouldExpand = false;
5991 bool RetainExpansion = false;
5992 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
5993 Unexpanded,
5994 ShouldExpand,
5995 RetainExpansion,
5996 NumExpansions)) {
5997 return true;
6000 if (ShouldExpand) {
6001 // Expand the function parameter pack into multiple, separate
6002 // parameters.
6003 for (unsigned I = 0; I != *NumExpansions; ++I) {
6004 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6005 QualType NewType = getDerived().TransformType(Pattern);
6006 if (NewType.isNull())
6007 return true;
6009 if (NewType->containsUnexpandedParameterPack()) {
6010 NewType = getSema().getASTContext().getPackExpansionType(
6011 NewType, std::nullopt);
6013 if (NewType.isNull())
6014 return true;
6017 if (ParamInfos)
6018 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6019 OutParamTypes.push_back(NewType);
6020 if (PVars)
6021 PVars->push_back(nullptr);
6024 // We're done with the pack expansion.
6025 continue;
6028 // If we're supposed to retain a pack expansion, do so by temporarily
6029 // forgetting the partially-substituted parameter pack.
6030 if (RetainExpansion) {
6031 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6032 QualType NewType = getDerived().TransformType(Pattern);
6033 if (NewType.isNull())
6034 return true;
6036 if (ParamInfos)
6037 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6038 OutParamTypes.push_back(NewType);
6039 if (PVars)
6040 PVars->push_back(nullptr);
6043 // We'll substitute the parameter now without expanding the pack
6044 // expansion.
6045 OldType = Expansion->getPattern();
6046 IsPackExpansion = true;
6047 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6048 NewType = getDerived().TransformType(OldType);
6049 } else {
6050 NewType = getDerived().TransformType(OldType);
6053 if (NewType.isNull())
6054 return true;
6056 if (IsPackExpansion)
6057 NewType = getSema().Context.getPackExpansionType(NewType,
6058 NumExpansions);
6060 if (ParamInfos)
6061 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6062 OutParamTypes.push_back(NewType);
6063 if (PVars)
6064 PVars->push_back(nullptr);
6067 #ifndef NDEBUG
6068 if (PVars) {
6069 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6070 if (ParmVarDecl *parm = (*PVars)[i])
6071 assert(parm->getFunctionScopeIndex() == i);
6073 #endif
6075 return false;
6078 template<typename Derived>
6079 QualType
6080 TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6081 FunctionProtoTypeLoc TL) {
6082 SmallVector<QualType, 4> ExceptionStorage;
6083 TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
6084 return getDerived().TransformFunctionProtoType(
6085 TLB, TL, nullptr, Qualifiers(),
6086 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6087 return This->getDerived().TransformExceptionSpec(
6088 TL.getBeginLoc(), ESI, ExceptionStorage, Changed);
6092 template<typename Derived> template<typename Fn>
6093 QualType TreeTransform<Derived>::TransformFunctionProtoType(
6094 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6095 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6097 // Transform the parameters and return type.
6099 // We are required to instantiate the params and return type in source order.
6100 // When the function has a trailing return type, we instantiate the
6101 // parameters before the return type, since the return type can then refer
6102 // to the parameters themselves (via decltype, sizeof, etc.).
6104 SmallVector<QualType, 4> ParamTypes;
6105 SmallVector<ParmVarDecl*, 4> ParamDecls;
6106 Sema::ExtParameterInfoBuilder ExtParamInfos;
6107 const FunctionProtoType *T = TL.getTypePtr();
6109 QualType ResultType;
6111 if (T->hasTrailingReturn()) {
6112 if (getDerived().TransformFunctionTypeParams(
6113 TL.getBeginLoc(), TL.getParams(),
6114 TL.getTypePtr()->param_type_begin(),
6115 T->getExtParameterInfosOrNull(),
6116 ParamTypes, &ParamDecls, ExtParamInfos))
6117 return QualType();
6120 // C++11 [expr.prim.general]p3:
6121 // If a declaration declares a member function or member function
6122 // template of a class X, the expression this is a prvalue of type
6123 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6124 // and the end of the function-definition, member-declarator, or
6125 // declarator.
6126 Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals);
6128 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6129 if (ResultType.isNull())
6130 return QualType();
6133 else {
6134 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6135 if (ResultType.isNull())
6136 return QualType();
6138 if (getDerived().TransformFunctionTypeParams(
6139 TL.getBeginLoc(), TL.getParams(),
6140 TL.getTypePtr()->param_type_begin(),
6141 T->getExtParameterInfosOrNull(),
6142 ParamTypes, &ParamDecls, ExtParamInfos))
6143 return QualType();
6146 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6148 bool EPIChanged = false;
6149 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6150 return QualType();
6152 // Handle extended parameter information.
6153 if (auto NewExtParamInfos =
6154 ExtParamInfos.getPointerOrNull(ParamTypes.size())) {
6155 if (!EPI.ExtParameterInfos ||
6156 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6157 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6158 EPIChanged = true;
6160 EPI.ExtParameterInfos = NewExtParamInfos;
6161 } else if (EPI.ExtParameterInfos) {
6162 EPIChanged = true;
6163 EPI.ExtParameterInfos = nullptr;
6166 QualType Result = TL.getType();
6167 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6168 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6169 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6170 if (Result.isNull())
6171 return QualType();
6174 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
6175 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6176 NewTL.setLParenLoc(TL.getLParenLoc());
6177 NewTL.setRParenLoc(TL.getRParenLoc());
6178 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6179 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6180 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6181 NewTL.setParam(i, ParamDecls[i]);
6183 return Result;
6186 template<typename Derived>
6187 bool TreeTransform<Derived>::TransformExceptionSpec(
6188 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6189 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6190 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6192 // Instantiate a dynamic noexcept expression, if any.
6193 if (isComputedNoexcept(ESI.Type)) {
6194 EnterExpressionEvaluationContext Unevaluated(
6195 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6196 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6197 if (NoexceptExpr.isInvalid())
6198 return true;
6200 ExceptionSpecificationType EST = ESI.Type;
6201 NoexceptExpr =
6202 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6203 if (NoexceptExpr.isInvalid())
6204 return true;
6206 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6207 Changed = true;
6208 ESI.NoexceptExpr = NoexceptExpr.get();
6209 ESI.Type = EST;
6212 if (ESI.Type != EST_Dynamic)
6213 return false;
6215 // Instantiate a dynamic exception specification's type.
6216 for (QualType T : ESI.Exceptions) {
6217 if (const PackExpansionType *PackExpansion =
6218 T->getAs<PackExpansionType>()) {
6219 Changed = true;
6221 // We have a pack expansion. Instantiate it.
6222 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6223 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
6224 Unexpanded);
6225 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6227 // Determine whether the set of unexpanded parameter packs can and
6228 // should
6229 // be expanded.
6230 bool Expand = false;
6231 bool RetainExpansion = false;
6232 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
6233 // FIXME: Track the location of the ellipsis (and track source location
6234 // information for the types in the exception specification in general).
6235 if (getDerived().TryExpandParameterPacks(
6236 Loc, SourceRange(), Unexpanded, Expand,
6237 RetainExpansion, NumExpansions))
6238 return true;
6240 if (!Expand) {
6241 // We can't expand this pack expansion into separate arguments yet;
6242 // just substitute into the pattern and create a new pack expansion
6243 // type.
6244 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6245 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6246 if (U.isNull())
6247 return true;
6249 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
6250 Exceptions.push_back(U);
6251 continue;
6254 // Substitute into the pack expansion pattern for each slice of the
6255 // pack.
6256 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6257 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
6259 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6260 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6261 return true;
6263 Exceptions.push_back(U);
6265 } else {
6266 QualType U = getDerived().TransformType(T);
6267 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6268 return true;
6269 if (T != U)
6270 Changed = true;
6272 Exceptions.push_back(U);
6276 ESI.Exceptions = Exceptions;
6277 if (ESI.Exceptions.empty())
6278 ESI.Type = EST_DynamicNone;
6279 return false;
6282 template<typename Derived>
6283 QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6284 TypeLocBuilder &TLB,
6285 FunctionNoProtoTypeLoc TL) {
6286 const FunctionNoProtoType *T = TL.getTypePtr();
6287 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6288 if (ResultType.isNull())
6289 return QualType();
6291 QualType Result = TL.getType();
6292 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6293 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6295 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
6296 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6297 NewTL.setLParenLoc(TL.getLParenLoc());
6298 NewTL.setRParenLoc(TL.getRParenLoc());
6299 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6301 return Result;
6304 template <typename Derived>
6305 QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6306 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6307 const UnresolvedUsingType *T = TL.getTypePtr();
6308 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6309 if (!D)
6310 return QualType();
6312 QualType Result = TL.getType();
6313 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6314 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6315 if (Result.isNull())
6316 return QualType();
6319 // We might get an arbitrary type spec type back. We should at
6320 // least always get a type spec type, though.
6321 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result);
6322 NewTL.setNameLoc(TL.getNameLoc());
6324 return Result;
6327 template <typename Derived>
6328 QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6329 UsingTypeLoc TL) {
6330 const UsingType *T = TL.getTypePtr();
6332 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6333 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6334 if (!Found)
6335 return QualType();
6337 QualType Underlying = getDerived().TransformType(T->desugar());
6338 if (Underlying.isNull())
6339 return QualType();
6341 QualType Result = TL.getType();
6342 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6343 Underlying != T->getUnderlyingType()) {
6344 Result = getDerived().RebuildUsingType(Found, Underlying);
6345 if (Result.isNull())
6346 return QualType();
6349 TLB.pushTypeSpec(Result).setNameLoc(TL.getNameLoc());
6350 return Result;
6353 template<typename Derived>
6354 QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6355 TypedefTypeLoc TL) {
6356 const TypedefType *T = TL.getTypePtr();
6357 TypedefNameDecl *Typedef
6358 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6359 T->getDecl()));
6360 if (!Typedef)
6361 return QualType();
6363 QualType Result = TL.getType();
6364 if (getDerived().AlwaysRebuild() ||
6365 Typedef != T->getDecl()) {
6366 Result = getDerived().RebuildTypedefType(Typedef);
6367 if (Result.isNull())
6368 return QualType();
6371 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
6372 NewTL.setNameLoc(TL.getNameLoc());
6374 return Result;
6377 template<typename Derived>
6378 QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6379 TypeOfExprTypeLoc TL) {
6380 // typeof expressions are not potentially evaluated contexts
6381 EnterExpressionEvaluationContext Unevaluated(
6382 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6383 Sema::ReuseLambdaContextDecl);
6385 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6386 if (E.isInvalid())
6387 return QualType();
6389 E = SemaRef.HandleExprEvaluationContextForTypeof(E.get());
6390 if (E.isInvalid())
6391 return QualType();
6393 QualType Result = TL.getType();
6394 TypeOfKind Kind = Result->getAs<TypeOfExprType>()->getKind();
6395 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6396 Result =
6397 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6398 if (Result.isNull())
6399 return QualType();
6402 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
6403 NewTL.setTypeofLoc(TL.getTypeofLoc());
6404 NewTL.setLParenLoc(TL.getLParenLoc());
6405 NewTL.setRParenLoc(TL.getRParenLoc());
6407 return Result;
6410 template<typename Derived>
6411 QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6412 TypeOfTypeLoc TL) {
6413 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6414 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6415 if (!New_Under_TI)
6416 return QualType();
6418 QualType Result = TL.getType();
6419 TypeOfKind Kind = Result->getAs<TypeOfType>()->getKind();
6420 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6421 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6422 if (Result.isNull())
6423 return QualType();
6426 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
6427 NewTL.setTypeofLoc(TL.getTypeofLoc());
6428 NewTL.setLParenLoc(TL.getLParenLoc());
6429 NewTL.setRParenLoc(TL.getRParenLoc());
6430 NewTL.setUnmodifiedTInfo(New_Under_TI);
6432 return Result;
6435 template<typename Derived>
6436 QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6437 DecltypeTypeLoc TL) {
6438 const DecltypeType *T = TL.getTypePtr();
6440 // decltype expressions are not potentially evaluated contexts
6441 EnterExpressionEvaluationContext Unevaluated(
6442 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
6443 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
6445 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6446 if (E.isInvalid())
6447 return QualType();
6449 E = getSema().ActOnDecltypeExpression(E.get());
6450 if (E.isInvalid())
6451 return QualType();
6453 QualType Result = TL.getType();
6454 if (getDerived().AlwaysRebuild() ||
6455 E.get() != T->getUnderlyingExpr()) {
6456 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6457 if (Result.isNull())
6458 return QualType();
6460 else E.get();
6462 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
6463 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6464 NewTL.setRParenLoc(TL.getRParenLoc());
6465 return Result;
6468 template<typename Derived>
6469 QualType TreeTransform<Derived>::TransformUnaryTransformType(
6470 TypeLocBuilder &TLB,
6471 UnaryTransformTypeLoc TL) {
6472 QualType Result = TL.getType();
6473 if (Result->isDependentType()) {
6474 const UnaryTransformType *T = TL.getTypePtr();
6475 QualType NewBase =
6476 getDerived().TransformType(TL.getUnderlyingTInfo())->getType();
6477 Result = getDerived().RebuildUnaryTransformType(NewBase,
6478 T->getUTTKind(),
6479 TL.getKWLoc());
6480 if (Result.isNull())
6481 return QualType();
6484 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
6485 NewTL.setKWLoc(TL.getKWLoc());
6486 NewTL.setParensRange(TL.getParensRange());
6487 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6488 return Result;
6491 template<typename Derived>
6492 QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6493 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6494 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6496 CXXScopeSpec SS;
6497 TemplateName TemplateName = getDerived().TransformTemplateName(
6498 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6499 if (TemplateName.isNull())
6500 return QualType();
6502 QualType OldDeduced = T->getDeducedType();
6503 QualType NewDeduced;
6504 if (!OldDeduced.isNull()) {
6505 NewDeduced = getDerived().TransformType(OldDeduced);
6506 if (NewDeduced.isNull())
6507 return QualType();
6510 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
6511 TemplateName, NewDeduced);
6512 if (Result.isNull())
6513 return QualType();
6515 DeducedTemplateSpecializationTypeLoc NewTL =
6516 TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
6517 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6519 return Result;
6522 template<typename Derived>
6523 QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
6524 RecordTypeLoc TL) {
6525 const RecordType *T = TL.getTypePtr();
6526 RecordDecl *Record
6527 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6528 T->getDecl()));
6529 if (!Record)
6530 return QualType();
6532 QualType Result = TL.getType();
6533 if (getDerived().AlwaysRebuild() ||
6534 Record != T->getDecl()) {
6535 Result = getDerived().RebuildRecordType(Record);
6536 if (Result.isNull())
6537 return QualType();
6540 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
6541 NewTL.setNameLoc(TL.getNameLoc());
6543 return Result;
6546 template<typename Derived>
6547 QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
6548 EnumTypeLoc TL) {
6549 const EnumType *T = TL.getTypePtr();
6550 EnumDecl *Enum
6551 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6552 T->getDecl()));
6553 if (!Enum)
6554 return QualType();
6556 QualType Result = TL.getType();
6557 if (getDerived().AlwaysRebuild() ||
6558 Enum != T->getDecl()) {
6559 Result = getDerived().RebuildEnumType(Enum);
6560 if (Result.isNull())
6561 return QualType();
6564 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
6565 NewTL.setNameLoc(TL.getNameLoc());
6567 return Result;
6570 template<typename Derived>
6571 QualType TreeTransform<Derived>::TransformInjectedClassNameType(
6572 TypeLocBuilder &TLB,
6573 InjectedClassNameTypeLoc TL) {
6574 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
6575 TL.getTypePtr()->getDecl());
6576 if (!D) return QualType();
6578 QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
6579 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
6580 return T;
6583 template<typename Derived>
6584 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6585 TypeLocBuilder &TLB,
6586 TemplateTypeParmTypeLoc TL) {
6587 return getDerived().TransformTemplateTypeParmType(
6588 TLB, TL,
6589 /*SuppressObjCLifetime=*/false);
6592 template <typename Derived>
6593 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6594 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
6595 return TransformTypeSpecType(TLB, TL);
6598 template<typename Derived>
6599 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
6600 TypeLocBuilder &TLB,
6601 SubstTemplateTypeParmTypeLoc TL) {
6602 const SubstTemplateTypeParmType *T = TL.getTypePtr();
6604 Decl *NewReplaced =
6605 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
6607 // Substitute into the replacement type, which itself might involve something
6608 // that needs to be transformed. This only tends to occur with default
6609 // template arguments of template template parameters.
6610 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
6611 QualType Replacement = getDerived().TransformType(T->getReplacementType());
6612 if (Replacement.isNull())
6613 return QualType();
6615 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
6616 Replacement, NewReplaced, T->getIndex(), T->getPackIndex());
6618 // Propagate type-source information.
6619 SubstTemplateTypeParmTypeLoc NewTL
6620 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
6621 NewTL.setNameLoc(TL.getNameLoc());
6622 return Result;
6626 template<typename Derived>
6627 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6628 TypeLocBuilder &TLB,
6629 SubstTemplateTypeParmPackTypeLoc TL) {
6630 return getDerived().TransformSubstTemplateTypeParmPackType(
6631 TLB, TL, /*SuppressObjCLifetime=*/false);
6634 template <typename Derived>
6635 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6636 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
6637 return TransformTypeSpecType(TLB, TL);
6640 template<typename Derived>
6641 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
6642 TypeLocBuilder &TLB,
6643 TemplateSpecializationTypeLoc TL) {
6644 const TemplateSpecializationType *T = TL.getTypePtr();
6646 // The nested-name-specifier never matters in a TemplateSpecializationType,
6647 // because we can't have a dependent nested-name-specifier anyway.
6648 CXXScopeSpec SS;
6649 TemplateName Template
6650 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
6651 TL.getTemplateNameLoc());
6652 if (Template.isNull())
6653 return QualType();
6655 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
6658 template<typename Derived>
6659 QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
6660 AtomicTypeLoc TL) {
6661 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6662 if (ValueType.isNull())
6663 return QualType();
6665 QualType Result = TL.getType();
6666 if (getDerived().AlwaysRebuild() ||
6667 ValueType != TL.getValueLoc().getType()) {
6668 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
6669 if (Result.isNull())
6670 return QualType();
6673 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
6674 NewTL.setKWLoc(TL.getKWLoc());
6675 NewTL.setLParenLoc(TL.getLParenLoc());
6676 NewTL.setRParenLoc(TL.getRParenLoc());
6678 return Result;
6681 template <typename Derived>
6682 QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
6683 PipeTypeLoc TL) {
6684 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6685 if (ValueType.isNull())
6686 return QualType();
6688 QualType Result = TL.getType();
6689 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
6690 const PipeType *PT = Result->castAs<PipeType>();
6691 bool isReadPipe = PT->isReadOnly();
6692 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
6693 if (Result.isNull())
6694 return QualType();
6697 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);
6698 NewTL.setKWLoc(TL.getKWLoc());
6700 return Result;
6703 template <typename Derived>
6704 QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
6705 BitIntTypeLoc TL) {
6706 const BitIntType *EIT = TL.getTypePtr();
6707 QualType Result = TL.getType();
6709 if (getDerived().AlwaysRebuild()) {
6710 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
6711 EIT->getNumBits(), TL.getNameLoc());
6712 if (Result.isNull())
6713 return QualType();
6716 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6717 NewTL.setNameLoc(TL.getNameLoc());
6718 return Result;
6721 template <typename Derived>
6722 QualType TreeTransform<Derived>::TransformDependentBitIntType(
6723 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
6724 const DependentBitIntType *EIT = TL.getTypePtr();
6726 EnterExpressionEvaluationContext Unevaluated(
6727 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6728 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
6729 BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr);
6731 if (BitsExpr.isInvalid())
6732 return QualType();
6734 QualType Result = TL.getType();
6736 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
6737 Result = getDerived().RebuildDependentBitIntType(
6738 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
6740 if (Result.isNull())
6741 return QualType();
6744 if (isa<DependentBitIntType>(Result)) {
6745 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);
6746 NewTL.setNameLoc(TL.getNameLoc());
6747 } else {
6748 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6749 NewTL.setNameLoc(TL.getNameLoc());
6751 return Result;
6754 /// Simple iterator that traverses the template arguments in a
6755 /// container that provides a \c getArgLoc() member function.
6757 /// This iterator is intended to be used with the iterator form of
6758 /// \c TreeTransform<Derived>::TransformTemplateArguments().
6759 template<typename ArgLocContainer>
6760 class TemplateArgumentLocContainerIterator {
6761 ArgLocContainer *Container;
6762 unsigned Index;
6764 public:
6765 typedef TemplateArgumentLoc value_type;
6766 typedef TemplateArgumentLoc reference;
6767 typedef int difference_type;
6768 typedef std::input_iterator_tag iterator_category;
6770 class pointer {
6771 TemplateArgumentLoc Arg;
6773 public:
6774 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
6776 const TemplateArgumentLoc *operator->() const {
6777 return &Arg;
6782 TemplateArgumentLocContainerIterator() {}
6784 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
6785 unsigned Index)
6786 : Container(&Container), Index(Index) { }
6788 TemplateArgumentLocContainerIterator &operator++() {
6789 ++Index;
6790 return *this;
6793 TemplateArgumentLocContainerIterator operator++(int) {
6794 TemplateArgumentLocContainerIterator Old(*this);
6795 ++(*this);
6796 return Old;
6799 TemplateArgumentLoc operator*() const {
6800 return Container->getArgLoc(Index);
6803 pointer operator->() const {
6804 return pointer(Container->getArgLoc(Index));
6807 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
6808 const TemplateArgumentLocContainerIterator &Y) {
6809 return X.Container == Y.Container && X.Index == Y.Index;
6812 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
6813 const TemplateArgumentLocContainerIterator &Y) {
6814 return !(X == Y);
6818 template<typename Derived>
6819 QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
6820 AutoTypeLoc TL) {
6821 const AutoType *T = TL.getTypePtr();
6822 QualType OldDeduced = T->getDeducedType();
6823 QualType NewDeduced;
6824 if (!OldDeduced.isNull()) {
6825 NewDeduced = getDerived().TransformType(OldDeduced);
6826 if (NewDeduced.isNull())
6827 return QualType();
6830 ConceptDecl *NewCD = nullptr;
6831 TemplateArgumentListInfo NewTemplateArgs;
6832 NestedNameSpecifierLoc NewNestedNameSpec;
6833 if (T->isConstrained()) {
6834 assert(TL.getConceptReference());
6835 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
6836 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
6838 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
6839 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
6840 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
6841 if (getDerived().TransformTemplateArguments(
6842 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
6843 NewTemplateArgs))
6844 return QualType();
6846 if (TL.getNestedNameSpecifierLoc()) {
6847 NewNestedNameSpec
6848 = getDerived().TransformNestedNameSpecifierLoc(
6849 TL.getNestedNameSpecifierLoc());
6850 if (!NewNestedNameSpec)
6851 return QualType();
6855 QualType Result = TL.getType();
6856 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
6857 T->isDependentType() || T->isConstrained()) {
6858 // FIXME: Maybe don't rebuild if all template arguments are the same.
6859 llvm::SmallVector<TemplateArgument, 4> NewArgList;
6860 NewArgList.reserve(NewTemplateArgs.size());
6861 for (const auto &ArgLoc : NewTemplateArgs.arguments())
6862 NewArgList.push_back(ArgLoc.getArgument());
6863 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
6864 NewArgList);
6865 if (Result.isNull())
6866 return QualType();
6869 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
6870 NewTL.setNameLoc(TL.getNameLoc());
6871 NewTL.setRParenLoc(TL.getRParenLoc());
6872 NewTL.setConceptReference(nullptr);
6874 if (T->isConstrained()) {
6875 DeclarationNameInfo DNI = DeclarationNameInfo(
6876 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
6877 TL.getConceptNameLoc(),
6878 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
6879 auto *CR = ConceptReference::Create(
6880 SemaRef.Context, NewNestedNameSpec, TL.getTemplateKWLoc(), DNI,
6881 TL.getFoundDecl(), TL.getTypePtr()->getTypeConstraintConcept(),
6882 ASTTemplateArgumentListInfo::Create(SemaRef.Context, NewTemplateArgs));
6883 NewTL.setConceptReference(CR);
6886 return Result;
6889 template <typename Derived>
6890 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
6891 TypeLocBuilder &TLB,
6892 TemplateSpecializationTypeLoc TL,
6893 TemplateName Template) {
6894 TemplateArgumentListInfo NewTemplateArgs;
6895 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
6896 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
6897 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
6898 ArgIterator;
6899 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
6900 ArgIterator(TL, TL.getNumArgs()),
6901 NewTemplateArgs))
6902 return QualType();
6904 // FIXME: maybe don't rebuild if all the template arguments are the same.
6906 QualType Result =
6907 getDerived().RebuildTemplateSpecializationType(Template,
6908 TL.getTemplateNameLoc(),
6909 NewTemplateArgs);
6911 if (!Result.isNull()) {
6912 // Specializations of template template parameters are represented as
6913 // TemplateSpecializationTypes, and substitution of type alias templates
6914 // within a dependent context can transform them into
6915 // DependentTemplateSpecializationTypes.
6916 if (isa<DependentTemplateSpecializationType>(Result)) {
6917 DependentTemplateSpecializationTypeLoc NewTL
6918 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
6919 NewTL.setElaboratedKeywordLoc(SourceLocation());
6920 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
6921 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6922 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6923 NewTL.setLAngleLoc(TL.getLAngleLoc());
6924 NewTL.setRAngleLoc(TL.getRAngleLoc());
6925 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6926 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6927 return Result;
6930 TemplateSpecializationTypeLoc NewTL
6931 = TLB.push<TemplateSpecializationTypeLoc>(Result);
6932 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6933 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6934 NewTL.setLAngleLoc(TL.getLAngleLoc());
6935 NewTL.setRAngleLoc(TL.getRAngleLoc());
6936 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6937 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6940 return Result;
6943 template <typename Derived>
6944 QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
6945 TypeLocBuilder &TLB,
6946 DependentTemplateSpecializationTypeLoc TL,
6947 TemplateName Template,
6948 CXXScopeSpec &SS) {
6949 TemplateArgumentListInfo NewTemplateArgs;
6950 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
6951 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
6952 typedef TemplateArgumentLocContainerIterator<
6953 DependentTemplateSpecializationTypeLoc> ArgIterator;
6954 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
6955 ArgIterator(TL, TL.getNumArgs()),
6956 NewTemplateArgs))
6957 return QualType();
6959 // FIXME: maybe don't rebuild if all the template arguments are the same.
6961 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
6962 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
6963 TL.getTypePtr()->getKeyword(), DTN->getQualifier(),
6964 DTN->getIdentifier(), NewTemplateArgs.arguments());
6966 DependentTemplateSpecializationTypeLoc NewTL
6967 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
6968 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
6969 NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
6970 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6971 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6972 NewTL.setLAngleLoc(TL.getLAngleLoc());
6973 NewTL.setRAngleLoc(TL.getRAngleLoc());
6974 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6975 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6976 return Result;
6979 QualType Result
6980 = getDerived().RebuildTemplateSpecializationType(Template,
6981 TL.getTemplateNameLoc(),
6982 NewTemplateArgs);
6984 if (!Result.isNull()) {
6985 /// FIXME: Wrap this in an elaborated-type-specifier?
6986 TemplateSpecializationTypeLoc NewTL
6987 = TLB.push<TemplateSpecializationTypeLoc>(Result);
6988 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6989 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6990 NewTL.setLAngleLoc(TL.getLAngleLoc());
6991 NewTL.setRAngleLoc(TL.getRAngleLoc());
6992 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6993 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6996 return Result;
6999 template<typename Derived>
7000 QualType
7001 TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
7002 ElaboratedTypeLoc TL) {
7003 const ElaboratedType *T = TL.getTypePtr();
7005 NestedNameSpecifierLoc QualifierLoc;
7006 // NOTE: the qualifier in an ElaboratedType is optional.
7007 if (TL.getQualifierLoc()) {
7008 QualifierLoc
7009 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7010 if (!QualifierLoc)
7011 return QualType();
7014 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7015 if (NamedT.isNull())
7016 return QualType();
7018 // C++0x [dcl.type.elab]p2:
7019 // If the identifier resolves to a typedef-name or the simple-template-id
7020 // resolves to an alias template specialization, the
7021 // elaborated-type-specifier is ill-formed.
7022 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7023 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7024 if (const TemplateSpecializationType *TST =
7025 NamedT->getAs<TemplateSpecializationType>()) {
7026 TemplateName Template = TST->getTemplateName();
7027 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7028 Template.getAsTemplateDecl())) {
7029 SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
7030 diag::err_tag_reference_non_tag)
7031 << TAT << Sema::NTK_TypeAliasTemplate
7032 << ElaboratedType::getTagTypeKindForKeyword(T->getKeyword());
7033 SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
7038 QualType Result = TL.getType();
7039 if (getDerived().AlwaysRebuild() ||
7040 QualifierLoc != TL.getQualifierLoc() ||
7041 NamedT != T->getNamedType()) {
7042 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7043 T->getKeyword(),
7044 QualifierLoc, NamedT);
7045 if (Result.isNull())
7046 return QualType();
7049 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7050 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7051 NewTL.setQualifierLoc(QualifierLoc);
7052 return Result;
7055 template<typename Derived>
7056 QualType TreeTransform<Derived>::TransformAttributedType(
7057 TypeLocBuilder &TLB,
7058 AttributedTypeLoc TL) {
7059 const AttributedType *oldType = TL.getTypePtr();
7060 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7061 if (modifiedType.isNull())
7062 return QualType();
7064 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7065 const Attr *oldAttr = TL.getAttr();
7066 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7067 if (oldAttr && !newAttr)
7068 return QualType();
7070 QualType result = TL.getType();
7072 // FIXME: dependent operand expressions?
7073 if (getDerived().AlwaysRebuild() ||
7074 modifiedType != oldType->getModifiedType()) {
7075 // TODO: this is really lame; we should really be rebuilding the
7076 // equivalent type from first principles.
7077 QualType equivalentType
7078 = getDerived().TransformType(oldType->getEquivalentType());
7079 if (equivalentType.isNull())
7080 return QualType();
7082 // Check whether we can add nullability; it is only represented as
7083 // type sugar, and therefore cannot be diagnosed in any other way.
7084 if (auto nullability = oldType->getImmediateNullability()) {
7085 if (!modifiedType->canHaveNullability()) {
7086 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
7087 : TL.getModifiedLoc().getBeginLoc()),
7088 diag::err_nullability_nonpointer)
7089 << DiagNullabilityKind(*nullability, false) << modifiedType;
7090 return QualType();
7094 result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
7095 modifiedType,
7096 equivalentType);
7099 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
7100 newTL.setAttr(newAttr);
7101 return result;
7104 template <typename Derived>
7105 QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7106 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7107 // The BTFTagAttributedType is available for C only.
7108 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7111 template<typename Derived>
7112 QualType
7113 TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7114 ParenTypeLoc TL) {
7115 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7116 if (Inner.isNull())
7117 return QualType();
7119 QualType Result = TL.getType();
7120 if (getDerived().AlwaysRebuild() ||
7121 Inner != TL.getInnerLoc().getType()) {
7122 Result = getDerived().RebuildParenType(Inner);
7123 if (Result.isNull())
7124 return QualType();
7127 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
7128 NewTL.setLParenLoc(TL.getLParenLoc());
7129 NewTL.setRParenLoc(TL.getRParenLoc());
7130 return Result;
7133 template <typename Derived>
7134 QualType
7135 TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7136 MacroQualifiedTypeLoc TL) {
7137 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7138 if (Inner.isNull())
7139 return QualType();
7141 QualType Result = TL.getType();
7142 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7143 Result =
7144 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7145 if (Result.isNull())
7146 return QualType();
7149 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
7150 NewTL.setExpansionLoc(TL.getExpansionLoc());
7151 return Result;
7154 template<typename Derived>
7155 QualType TreeTransform<Derived>::TransformDependentNameType(
7156 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7157 return TransformDependentNameType(TLB, TL, false);
7160 template<typename Derived>
7161 QualType TreeTransform<Derived>::TransformDependentNameType(
7162 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7163 const DependentNameType *T = TL.getTypePtr();
7165 NestedNameSpecifierLoc QualifierLoc
7166 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7167 if (!QualifierLoc)
7168 return QualType();
7170 QualType Result
7171 = getDerived().RebuildDependentNameType(T->getKeyword(),
7172 TL.getElaboratedKeywordLoc(),
7173 QualifierLoc,
7174 T->getIdentifier(),
7175 TL.getNameLoc(),
7176 DeducedTSTContext);
7177 if (Result.isNull())
7178 return QualType();
7180 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7181 QualType NamedT = ElabT->getNamedType();
7182 TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
7184 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7185 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7186 NewTL.setQualifierLoc(QualifierLoc);
7187 } else {
7188 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
7189 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7190 NewTL.setQualifierLoc(QualifierLoc);
7191 NewTL.setNameLoc(TL.getNameLoc());
7193 return Result;
7196 template<typename Derived>
7197 QualType TreeTransform<Derived>::
7198 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7199 DependentTemplateSpecializationTypeLoc TL) {
7200 NestedNameSpecifierLoc QualifierLoc;
7201 if (TL.getQualifierLoc()) {
7202 QualifierLoc
7203 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7204 if (!QualifierLoc)
7205 return QualType();
7208 return getDerived()
7209 .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
7212 template<typename Derived>
7213 QualType TreeTransform<Derived>::
7214 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7215 DependentTemplateSpecializationTypeLoc TL,
7216 NestedNameSpecifierLoc QualifierLoc) {
7217 const DependentTemplateSpecializationType *T = TL.getTypePtr();
7219 TemplateArgumentListInfo NewTemplateArgs;
7220 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7221 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7223 typedef TemplateArgumentLocContainerIterator<
7224 DependentTemplateSpecializationTypeLoc> ArgIterator;
7225 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7226 ArgIterator(TL, TL.getNumArgs()),
7227 NewTemplateArgs))
7228 return QualType();
7230 QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
7231 T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(),
7232 T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs,
7233 /*AllowInjectedClassName*/ false);
7234 if (Result.isNull())
7235 return QualType();
7237 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
7238 QualType NamedT = ElabT->getNamedType();
7240 // Copy information relevant to the template specialization.
7241 TemplateSpecializationTypeLoc NamedTL
7242 = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
7243 NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7244 NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7245 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7246 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7247 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7248 NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7250 // Copy information relevant to the elaborated type.
7251 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7252 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7253 NewTL.setQualifierLoc(QualifierLoc);
7254 } else if (isa<DependentTemplateSpecializationType>(Result)) {
7255 DependentTemplateSpecializationTypeLoc SpecTL
7256 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7257 SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7258 SpecTL.setQualifierLoc(QualifierLoc);
7259 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7260 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7261 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7262 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7263 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7264 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7265 } else {
7266 TemplateSpecializationTypeLoc SpecTL
7267 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7268 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7269 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7270 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7271 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7272 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7273 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7275 return Result;
7278 template<typename Derived>
7279 QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7280 PackExpansionTypeLoc TL) {
7281 QualType Pattern
7282 = getDerived().TransformType(TLB, TL.getPatternLoc());
7283 if (Pattern.isNull())
7284 return QualType();
7286 QualType Result = TL.getType();
7287 if (getDerived().AlwaysRebuild() ||
7288 Pattern != TL.getPatternLoc().getType()) {
7289 Result = getDerived().RebuildPackExpansionType(Pattern,
7290 TL.getPatternLoc().getSourceRange(),
7291 TL.getEllipsisLoc(),
7292 TL.getTypePtr()->getNumExpansions());
7293 if (Result.isNull())
7294 return QualType();
7297 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
7298 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7299 return Result;
7302 template<typename Derived>
7303 QualType
7304 TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7305 ObjCInterfaceTypeLoc TL) {
7306 // ObjCInterfaceType is never dependent.
7307 TLB.pushFullCopy(TL);
7308 return TL.getType();
7311 template<typename Derived>
7312 QualType
7313 TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7314 ObjCTypeParamTypeLoc TL) {
7315 const ObjCTypeParamType *T = TL.getTypePtr();
7316 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7317 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7318 if (!OTP)
7319 return QualType();
7321 QualType Result = TL.getType();
7322 if (getDerived().AlwaysRebuild() ||
7323 OTP != T->getDecl()) {
7324 Result = getDerived().RebuildObjCTypeParamType(
7325 OTP, TL.getProtocolLAngleLoc(),
7326 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7327 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7328 if (Result.isNull())
7329 return QualType();
7332 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
7333 if (TL.getNumProtocols()) {
7334 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7335 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7336 NewTL.setProtocolLoc(i, TL.getProtocolLoc(i));
7337 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7339 return Result;
7342 template<typename Derived>
7343 QualType
7344 TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7345 ObjCObjectTypeLoc TL) {
7346 // Transform base type.
7347 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7348 if (BaseType.isNull())
7349 return QualType();
7351 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7353 // Transform type arguments.
7354 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7355 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7356 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7357 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7358 QualType TypeArg = TypeArgInfo->getType();
7359 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7360 AnyChanged = true;
7362 // We have a pack expansion. Instantiate it.
7363 const auto *PackExpansion = PackExpansionLoc.getType()
7364 ->castAs<PackExpansionType>();
7365 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7366 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
7367 Unexpanded);
7368 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7370 // Determine whether the set of unexpanded parameter packs can
7371 // and should be expanded.
7372 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7373 bool Expand = false;
7374 bool RetainExpansion = false;
7375 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
7376 if (getDerived().TryExpandParameterPacks(
7377 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7378 Unexpanded, Expand, RetainExpansion, NumExpansions))
7379 return QualType();
7381 if (!Expand) {
7382 // We can't expand this pack expansion into separate arguments yet;
7383 // just substitute into the pattern and create a new pack expansion
7384 // type.
7385 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
7387 TypeLocBuilder TypeArgBuilder;
7388 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7389 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7390 PatternLoc);
7391 if (NewPatternType.isNull())
7392 return QualType();
7394 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7395 NewPatternType, NumExpansions);
7396 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);
7397 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7398 NewTypeArgInfos.push_back(
7399 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewExpansionType));
7400 continue;
7403 // Substitute into the pack expansion pattern for each slice of the
7404 // pack.
7405 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
7406 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
7408 TypeLocBuilder TypeArgBuilder;
7409 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7411 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
7412 PatternLoc);
7413 if (NewTypeArg.isNull())
7414 return QualType();
7416 NewTypeArgInfos.push_back(
7417 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7420 continue;
7423 TypeLocBuilder TypeArgBuilder;
7424 TypeArgBuilder.reserve(TypeArgLoc.getFullDataSize());
7425 QualType NewTypeArg =
7426 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
7427 if (NewTypeArg.isNull())
7428 return QualType();
7430 // If nothing changed, just keep the old TypeSourceInfo.
7431 if (NewTypeArg == TypeArg) {
7432 NewTypeArgInfos.push_back(TypeArgInfo);
7433 continue;
7436 NewTypeArgInfos.push_back(
7437 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7438 AnyChanged = true;
7441 QualType Result = TL.getType();
7442 if (getDerived().AlwaysRebuild() || AnyChanged) {
7443 // Rebuild the type.
7444 Result = getDerived().RebuildObjCObjectType(
7445 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
7446 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
7447 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7448 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7450 if (Result.isNull())
7451 return QualType();
7454 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);
7455 NewT.setHasBaseTypeAsWritten(true);
7456 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
7457 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
7458 NewT.setTypeArgTInfo(i, NewTypeArgInfos[i]);
7459 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
7460 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7461 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7462 NewT.setProtocolLoc(i, TL.getProtocolLoc(i));
7463 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7464 return Result;
7467 template<typename Derived>
7468 QualType
7469 TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
7470 ObjCObjectPointerTypeLoc TL) {
7471 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
7472 if (PointeeType.isNull())
7473 return QualType();
7475 QualType Result = TL.getType();
7476 if (getDerived().AlwaysRebuild() ||
7477 PointeeType != TL.getPointeeLoc().getType()) {
7478 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
7479 TL.getStarLoc());
7480 if (Result.isNull())
7481 return QualType();
7484 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
7485 NewT.setStarLoc(TL.getStarLoc());
7486 return Result;
7489 //===----------------------------------------------------------------------===//
7490 // Statement transformation
7491 //===----------------------------------------------------------------------===//
7492 template<typename Derived>
7493 StmtResult
7494 TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
7495 return S;
7498 template<typename Derived>
7499 StmtResult
7500 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
7501 return getDerived().TransformCompoundStmt(S, false);
7504 template<typename Derived>
7505 StmtResult
7506 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
7507 bool IsStmtExpr) {
7508 Sema::CompoundScopeRAII CompoundScope(getSema());
7509 Sema::FPFeaturesStateRAII FPSave(getSema());
7510 if (S->hasStoredFPFeatures())
7511 getSema().resetFPOptions(
7512 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
7514 const Stmt *ExprResult = S->getStmtExprResult();
7515 bool SubStmtInvalid = false;
7516 bool SubStmtChanged = false;
7517 SmallVector<Stmt*, 8> Statements;
7518 for (auto *B : S->body()) {
7519 StmtResult Result = getDerived().TransformStmt(
7520 B, IsStmtExpr && B == ExprResult ? SDK_StmtExprResult : SDK_Discarded);
7522 if (Result.isInvalid()) {
7523 // Immediately fail if this was a DeclStmt, since it's very
7524 // likely that this will cause problems for future statements.
7525 if (isa<DeclStmt>(B))
7526 return StmtError();
7528 // Otherwise, just keep processing substatements and fail later.
7529 SubStmtInvalid = true;
7530 continue;
7533 SubStmtChanged = SubStmtChanged || Result.get() != B;
7534 Statements.push_back(Result.getAs<Stmt>());
7537 if (SubStmtInvalid)
7538 return StmtError();
7540 if (!getDerived().AlwaysRebuild() &&
7541 !SubStmtChanged)
7542 return S;
7544 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
7545 Statements,
7546 S->getRBracLoc(),
7547 IsStmtExpr);
7550 template<typename Derived>
7551 StmtResult
7552 TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
7553 ExprResult LHS, RHS;
7555 EnterExpressionEvaluationContext Unevaluated(
7556 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7558 // Transform the left-hand case value.
7559 LHS = getDerived().TransformExpr(S->getLHS());
7560 LHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), LHS);
7561 if (LHS.isInvalid())
7562 return StmtError();
7564 // Transform the right-hand case value (for the GNU case-range extension).
7565 RHS = getDerived().TransformExpr(S->getRHS());
7566 RHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), RHS);
7567 if (RHS.isInvalid())
7568 return StmtError();
7571 // Build the case statement.
7572 // Case statements are always rebuilt so that they will attached to their
7573 // transformed switch statement.
7574 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
7575 LHS.get(),
7576 S->getEllipsisLoc(),
7577 RHS.get(),
7578 S->getColonLoc());
7579 if (Case.isInvalid())
7580 return StmtError();
7582 // Transform the statement following the case
7583 StmtResult SubStmt =
7584 getDerived().TransformStmt(S->getSubStmt());
7585 if (SubStmt.isInvalid())
7586 return StmtError();
7588 // Attach the body to the case statement
7589 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
7592 template <typename Derived>
7593 StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
7594 // Transform the statement following the default case
7595 StmtResult SubStmt =
7596 getDerived().TransformStmt(S->getSubStmt());
7597 if (SubStmt.isInvalid())
7598 return StmtError();
7600 // Default statements are always rebuilt
7601 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
7602 SubStmt.get());
7605 template<typename Derived>
7606 StmtResult
7607 TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
7608 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7609 if (SubStmt.isInvalid())
7610 return StmtError();
7612 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
7613 S->getDecl());
7614 if (!LD)
7615 return StmtError();
7617 // If we're transforming "in-place" (we're not creating new local
7618 // declarations), assume we're replacing the old label statement
7619 // and clear out the reference to it.
7620 if (LD == S->getDecl())
7621 S->getDecl()->setStmt(nullptr);
7623 // FIXME: Pass the real colon location in.
7624 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
7625 cast<LabelDecl>(LD), SourceLocation(),
7626 SubStmt.get());
7629 template <typename Derived>
7630 const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
7631 if (!R)
7632 return R;
7634 switch (R->getKind()) {
7635 // Transform attributes by calling TransformXXXAttr.
7636 #define ATTR(X) \
7637 case attr::X: \
7638 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
7639 #include "clang/Basic/AttrList.inc"
7641 return R;
7644 template <typename Derived>
7645 const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
7646 const Stmt *InstS,
7647 const Attr *R) {
7648 if (!R)
7649 return R;
7651 switch (R->getKind()) {
7652 // Transform attributes by calling TransformStmtXXXAttr.
7653 #define ATTR(X) \
7654 case attr::X: \
7655 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
7656 #include "clang/Basic/AttrList.inc"
7658 return TransformAttr(R);
7661 template <typename Derived>
7662 StmtResult
7663 TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
7664 StmtDiscardKind SDK) {
7665 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7666 if (SubStmt.isInvalid())
7667 return StmtError();
7669 bool AttrsChanged = false;
7670 SmallVector<const Attr *, 1> Attrs;
7672 // Visit attributes and keep track if any are transformed.
7673 for (const auto *I : S->getAttrs()) {
7674 const Attr *R =
7675 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
7676 AttrsChanged |= (I != R);
7677 if (R)
7678 Attrs.push_back(R);
7681 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
7682 return S;
7684 // If transforming the attributes failed for all of the attributes in the
7685 // statement, don't make an AttributedStmt without attributes.
7686 if (Attrs.empty())
7687 return SubStmt;
7689 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
7690 SubStmt.get());
7693 template<typename Derived>
7694 StmtResult
7695 TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
7696 // Transform the initialization statement
7697 StmtResult Init = getDerived().TransformStmt(S->getInit());
7698 if (Init.isInvalid())
7699 return StmtError();
7701 Sema::ConditionResult Cond;
7702 if (!S->isConsteval()) {
7703 // Transform the condition
7704 Cond = getDerived().TransformCondition(
7705 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
7706 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
7707 : Sema::ConditionKind::Boolean);
7708 if (Cond.isInvalid())
7709 return StmtError();
7712 // If this is a constexpr if, determine which arm we should instantiate.
7713 std::optional<bool> ConstexprConditionValue;
7714 if (S->isConstexpr())
7715 ConstexprConditionValue = Cond.getKnownValue();
7717 // Transform the "then" branch.
7718 StmtResult Then;
7719 if (!ConstexprConditionValue || *ConstexprConditionValue) {
7720 Then = getDerived().TransformStmt(S->getThen());
7721 if (Then.isInvalid())
7722 return StmtError();
7723 } else {
7724 Then = new (getSema().Context) NullStmt(S->getThen()->getBeginLoc());
7727 // Transform the "else" branch.
7728 StmtResult Else;
7729 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
7730 Else = getDerived().TransformStmt(S->getElse());
7731 if (Else.isInvalid())
7732 return StmtError();
7735 if (!getDerived().AlwaysRebuild() &&
7736 Init.get() == S->getInit() &&
7737 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7738 Then.get() == S->getThen() &&
7739 Else.get() == S->getElse())
7740 return S;
7742 return getDerived().RebuildIfStmt(
7743 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
7744 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
7747 template<typename Derived>
7748 StmtResult
7749 TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
7750 // Transform the initialization statement
7751 StmtResult Init = getDerived().TransformStmt(S->getInit());
7752 if (Init.isInvalid())
7753 return StmtError();
7755 // Transform the condition.
7756 Sema::ConditionResult Cond = getDerived().TransformCondition(
7757 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
7758 Sema::ConditionKind::Switch);
7759 if (Cond.isInvalid())
7760 return StmtError();
7762 // Rebuild the switch statement.
7763 StmtResult Switch =
7764 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
7765 Init.get(), Cond, S->getRParenLoc());
7766 if (Switch.isInvalid())
7767 return StmtError();
7769 // Transform the body of the switch statement.
7770 StmtResult Body = getDerived().TransformStmt(S->getBody());
7771 if (Body.isInvalid())
7772 return StmtError();
7774 // Complete the switch statement.
7775 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
7776 Body.get());
7779 template<typename Derived>
7780 StmtResult
7781 TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
7782 // Transform the condition
7783 Sema::ConditionResult Cond = getDerived().TransformCondition(
7784 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
7785 Sema::ConditionKind::Boolean);
7786 if (Cond.isInvalid())
7787 return StmtError();
7789 // Transform the body
7790 StmtResult Body = getDerived().TransformStmt(S->getBody());
7791 if (Body.isInvalid())
7792 return StmtError();
7794 if (!getDerived().AlwaysRebuild() &&
7795 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7796 Body.get() == S->getBody())
7797 return Owned(S);
7799 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
7800 Cond, S->getRParenLoc(), Body.get());
7803 template<typename Derived>
7804 StmtResult
7805 TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
7806 // Transform the body
7807 StmtResult Body = getDerived().TransformStmt(S->getBody());
7808 if (Body.isInvalid())
7809 return StmtError();
7811 // Transform the condition
7812 ExprResult Cond = getDerived().TransformExpr(S->getCond());
7813 if (Cond.isInvalid())
7814 return StmtError();
7816 if (!getDerived().AlwaysRebuild() &&
7817 Cond.get() == S->getCond() &&
7818 Body.get() == S->getBody())
7819 return S;
7821 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
7822 /*FIXME:*/S->getWhileLoc(), Cond.get(),
7823 S->getRParenLoc());
7826 template<typename Derived>
7827 StmtResult
7828 TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
7829 if (getSema().getLangOpts().OpenMP)
7830 getSema().startOpenMPLoop();
7832 // Transform the initialization statement
7833 StmtResult Init = getDerived().TransformStmt(S->getInit());
7834 if (Init.isInvalid())
7835 return StmtError();
7837 // In OpenMP loop region loop control variable must be captured and be
7838 // private. Perform analysis of first part (if any).
7839 if (getSema().getLangOpts().OpenMP && Init.isUsable())
7840 getSema().ActOnOpenMPLoopInitialization(S->getForLoc(), Init.get());
7842 // Transform the condition
7843 Sema::ConditionResult Cond = getDerived().TransformCondition(
7844 S->getForLoc(), S->getConditionVariable(), S->getCond(),
7845 Sema::ConditionKind::Boolean);
7846 if (Cond.isInvalid())
7847 return StmtError();
7849 // Transform the increment
7850 ExprResult Inc = getDerived().TransformExpr(S->getInc());
7851 if (Inc.isInvalid())
7852 return StmtError();
7854 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
7855 if (S->getInc() && !FullInc.get())
7856 return StmtError();
7858 // Transform the body
7859 StmtResult Body = getDerived().TransformStmt(S->getBody());
7860 if (Body.isInvalid())
7861 return StmtError();
7863 if (!getDerived().AlwaysRebuild() &&
7864 Init.get() == S->getInit() &&
7865 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7866 Inc.get() == S->getInc() &&
7867 Body.get() == S->getBody())
7868 return S;
7870 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
7871 Init.get(), Cond, FullInc,
7872 S->getRParenLoc(), Body.get());
7875 template<typename Derived>
7876 StmtResult
7877 TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
7878 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
7879 S->getLabel());
7880 if (!LD)
7881 return StmtError();
7883 // Goto statements must always be rebuilt, to resolve the label.
7884 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
7885 cast<LabelDecl>(LD));
7888 template<typename Derived>
7889 StmtResult
7890 TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
7891 ExprResult Target = getDerived().TransformExpr(S->getTarget());
7892 if (Target.isInvalid())
7893 return StmtError();
7894 Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());
7896 if (!getDerived().AlwaysRebuild() &&
7897 Target.get() == S->getTarget())
7898 return S;
7900 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
7901 Target.get());
7904 template<typename Derived>
7905 StmtResult
7906 TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
7907 return S;
7910 template<typename Derived>
7911 StmtResult
7912 TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
7913 return S;
7916 template<typename Derived>
7917 StmtResult
7918 TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
7919 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
7920 /*NotCopyInit*/false);
7921 if (Result.isInvalid())
7922 return StmtError();
7924 // FIXME: We always rebuild the return statement because there is no way
7925 // to tell whether the return type of the function has changed.
7926 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
7929 template<typename Derived>
7930 StmtResult
7931 TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
7932 bool DeclChanged = false;
7933 SmallVector<Decl *, 4> Decls;
7934 for (auto *D : S->decls()) {
7935 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
7936 if (!Transformed)
7937 return StmtError();
7939 if (Transformed != D)
7940 DeclChanged = true;
7942 Decls.push_back(Transformed);
7945 if (!getDerived().AlwaysRebuild() && !DeclChanged)
7946 return S;
7948 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
7951 template<typename Derived>
7952 StmtResult
7953 TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
7955 SmallVector<Expr*, 8> Constraints;
7956 SmallVector<Expr*, 8> Exprs;
7957 SmallVector<IdentifierInfo *, 4> Names;
7959 ExprResult AsmString;
7960 SmallVector<Expr*, 8> Clobbers;
7962 bool ExprsChanged = false;
7964 // Go through the outputs.
7965 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
7966 Names.push_back(S->getOutputIdentifier(I));
7968 // No need to transform the constraint literal.
7969 Constraints.push_back(S->getOutputConstraintLiteral(I));
7971 // Transform the output expr.
7972 Expr *OutputExpr = S->getOutputExpr(I);
7973 ExprResult Result = getDerived().TransformExpr(OutputExpr);
7974 if (Result.isInvalid())
7975 return StmtError();
7977 ExprsChanged |= Result.get() != OutputExpr;
7979 Exprs.push_back(Result.get());
7982 // Go through the inputs.
7983 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
7984 Names.push_back(S->getInputIdentifier(I));
7986 // No need to transform the constraint literal.
7987 Constraints.push_back(S->getInputConstraintLiteral(I));
7989 // Transform the input expr.
7990 Expr *InputExpr = S->getInputExpr(I);
7991 ExprResult Result = getDerived().TransformExpr(InputExpr);
7992 if (Result.isInvalid())
7993 return StmtError();
7995 ExprsChanged |= Result.get() != InputExpr;
7997 Exprs.push_back(Result.get());
8000 // Go through the Labels.
8001 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8002 Names.push_back(S->getLabelIdentifier(I));
8004 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(I));
8005 if (Result.isInvalid())
8006 return StmtError();
8007 ExprsChanged |= Result.get() != S->getLabelExpr(I);
8008 Exprs.push_back(Result.get());
8010 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8011 return S;
8013 // Go through the clobbers.
8014 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
8015 Clobbers.push_back(S->getClobberStringLiteral(I));
8017 // No need to transform the asm string literal.
8018 AsmString = S->getAsmString();
8019 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8020 S->isVolatile(), S->getNumOutputs(),
8021 S->getNumInputs(), Names.data(),
8022 Constraints, Exprs, AsmString.get(),
8023 Clobbers, S->getNumLabels(),
8024 S->getRParenLoc());
8027 template<typename Derived>
8028 StmtResult
8029 TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8030 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8032 bool HadError = false, HadChange = false;
8034 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8035 SmallVector<Expr*, 8> TransformedExprs;
8036 TransformedExprs.reserve(SrcExprs.size());
8037 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8038 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8039 if (!Result.isUsable()) {
8040 HadError = true;
8041 } else {
8042 HadChange |= (Result.get() != SrcExprs[i]);
8043 TransformedExprs.push_back(Result.get());
8047 if (HadError) return StmtError();
8048 if (!HadChange && !getDerived().AlwaysRebuild())
8049 return Owned(S);
8051 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8052 AsmToks, S->getAsmString(),
8053 S->getNumOutputs(), S->getNumInputs(),
8054 S->getAllConstraints(), S->getClobbers(),
8055 TransformedExprs, S->getEndLoc());
8058 // C++ Coroutines
8059 template<typename Derived>
8060 StmtResult
8061 TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8062 auto *ScopeInfo = SemaRef.getCurFunction();
8063 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
8064 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8065 ScopeInfo->NeedsCoroutineSuspends &&
8066 ScopeInfo->CoroutineSuspends.first == nullptr &&
8067 ScopeInfo->CoroutineSuspends.second == nullptr &&
8068 "expected clean scope info");
8070 // Set that we have (possibly-invalid) suspend points before we do anything
8071 // that may fail.
8072 ScopeInfo->setNeedsCoroutineSuspends(false);
8074 // We re-build the coroutine promise object (and the coroutine parameters its
8075 // type and constructor depend on) based on the types used in our current
8076 // function. We must do so, and set it on the current FunctionScopeInfo,
8077 // before attempting to transform the other parts of the coroutine body
8078 // statement, such as the implicit suspend statements (because those
8079 // statements reference the FunctionScopeInfo::CoroutinePromise).
8080 if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation()))
8081 return StmtError();
8082 auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());
8083 if (!Promise)
8084 return StmtError();
8085 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8086 ScopeInfo->CoroutinePromise = Promise;
8088 // Transform the implicit coroutine statements constructed using dependent
8089 // types during the previous parse: initial and final suspensions, the return
8090 // object, and others. We also transform the coroutine function's body.
8091 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8092 if (InitSuspend.isInvalid())
8093 return StmtError();
8094 StmtResult FinalSuspend =
8095 getDerived().TransformStmt(S->getFinalSuspendStmt());
8096 if (FinalSuspend.isInvalid() ||
8097 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get()))
8098 return StmtError();
8099 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
8100 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8102 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8103 if (BodyRes.isInvalid())
8104 return StmtError();
8106 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8107 if (Builder.isInvalid())
8108 return StmtError();
8110 Expr *ReturnObject = S->getReturnValueInit();
8111 assert(ReturnObject && "the return object is expected to be valid");
8112 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8113 /*NoCopyInit*/ false);
8114 if (Res.isInvalid())
8115 return StmtError();
8116 Builder.ReturnValue = Res.get();
8118 // If during the previous parse the coroutine still had a dependent promise
8119 // statement, we may need to build some implicit coroutine statements
8120 // (such as exception and fallthrough handlers) for the first time.
8121 if (S->hasDependentPromiseType()) {
8122 // We can only build these statements, however, if the current promise type
8123 // is not dependent.
8124 if (!Promise->getType()->isDependentType()) {
8125 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8126 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8127 "these nodes should not have been built yet");
8128 if (!Builder.buildDependentStatements())
8129 return StmtError();
8131 } else {
8132 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8133 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8134 if (Res.isInvalid())
8135 return StmtError();
8136 Builder.OnFallthrough = Res.get();
8139 if (auto *OnException = S->getExceptionHandler()) {
8140 StmtResult Res = getDerived().TransformStmt(OnException);
8141 if (Res.isInvalid())
8142 return StmtError();
8143 Builder.OnException = Res.get();
8146 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8147 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8148 if (Res.isInvalid())
8149 return StmtError();
8150 Builder.ReturnStmtOnAllocFailure = Res.get();
8153 // Transform any additional statements we may have already built
8154 assert(S->getAllocate() && S->getDeallocate() &&
8155 "allocation and deallocation calls must already be built");
8156 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8157 if (AllocRes.isInvalid())
8158 return StmtError();
8159 Builder.Allocate = AllocRes.get();
8161 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8162 if (DeallocRes.isInvalid())
8163 return StmtError();
8164 Builder.Deallocate = DeallocRes.get();
8166 if (auto *ResultDecl = S->getResultDecl()) {
8167 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8168 if (Res.isInvalid())
8169 return StmtError();
8170 Builder.ResultDecl = Res.get();
8173 if (auto *ReturnStmt = S->getReturnStmt()) {
8174 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8175 if (Res.isInvalid())
8176 return StmtError();
8177 Builder.ReturnStmt = Res.get();
8181 return getDerived().RebuildCoroutineBodyStmt(Builder);
8184 template<typename Derived>
8185 StmtResult
8186 TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8187 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8188 /*NotCopyInit*/false);
8189 if (Result.isInvalid())
8190 return StmtError();
8192 // Always rebuild; we don't know if this needs to be injected into a new
8193 // context or if the promise type has changed.
8194 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8195 S->isImplicit());
8198 template <typename Derived>
8199 ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8200 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8201 /*NotCopyInit*/ false);
8202 if (Operand.isInvalid())
8203 return ExprError();
8205 // Rebuild the common-expr from the operand rather than transforming it
8206 // separately.
8208 // FIXME: getCurScope() should not be used during template instantiation.
8209 // We should pick up the set of unqualified lookup results for operator
8210 // co_await during the initial parse.
8211 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8212 getSema().getCurScope(), E->getKeywordLoc());
8214 // Always rebuild; we don't know if this needs to be injected into a new
8215 // context or if the promise type has changed.
8216 return getDerived().RebuildCoawaitExpr(
8217 E->getKeywordLoc(), Operand.get(),
8218 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());
8221 template <typename Derived>
8222 ExprResult
8223 TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8224 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8225 /*NotCopyInit*/ false);
8226 if (OperandResult.isInvalid())
8227 return ExprError();
8229 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8230 E->getOperatorCoawaitLookup());
8232 if (LookupResult.isInvalid())
8233 return ExprError();
8235 // Always rebuild; we don't know if this needs to be injected into a new
8236 // context or if the promise type has changed.
8237 return getDerived().RebuildDependentCoawaitExpr(
8238 E->getKeywordLoc(), OperandResult.get(),
8239 cast<UnresolvedLookupExpr>(LookupResult.get()));
8242 template<typename Derived>
8243 ExprResult
8244 TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8245 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8246 /*NotCopyInit*/false);
8247 if (Result.isInvalid())
8248 return ExprError();
8250 // Always rebuild; we don't know if this needs to be injected into a new
8251 // context or if the promise type has changed.
8252 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8255 // Objective-C Statements.
8257 template<typename Derived>
8258 StmtResult
8259 TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8260 // Transform the body of the @try.
8261 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8262 if (TryBody.isInvalid())
8263 return StmtError();
8265 // Transform the @catch statements (if present).
8266 bool AnyCatchChanged = false;
8267 SmallVector<Stmt*, 8> CatchStmts;
8268 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8269 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8270 if (Catch.isInvalid())
8271 return StmtError();
8272 if (Catch.get() != S->getCatchStmt(I))
8273 AnyCatchChanged = true;
8274 CatchStmts.push_back(Catch.get());
8277 // Transform the @finally statement (if present).
8278 StmtResult Finally;
8279 if (S->getFinallyStmt()) {
8280 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8281 if (Finally.isInvalid())
8282 return StmtError();
8285 // If nothing changed, just retain this statement.
8286 if (!getDerived().AlwaysRebuild() &&
8287 TryBody.get() == S->getTryBody() &&
8288 !AnyCatchChanged &&
8289 Finally.get() == S->getFinallyStmt())
8290 return S;
8292 // Build a new statement.
8293 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8294 CatchStmts, Finally.get());
8297 template<typename Derived>
8298 StmtResult
8299 TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8300 // Transform the @catch parameter, if there is one.
8301 VarDecl *Var = nullptr;
8302 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8303 TypeSourceInfo *TSInfo = nullptr;
8304 if (FromVar->getTypeSourceInfo()) {
8305 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8306 if (!TSInfo)
8307 return StmtError();
8310 QualType T;
8311 if (TSInfo)
8312 T = TSInfo->getType();
8313 else {
8314 T = getDerived().TransformType(FromVar->getType());
8315 if (T.isNull())
8316 return StmtError();
8319 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8320 if (!Var)
8321 return StmtError();
8324 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8325 if (Body.isInvalid())
8326 return StmtError();
8328 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
8329 S->getRParenLoc(),
8330 Var, Body.get());
8333 template<typename Derived>
8334 StmtResult
8335 TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
8336 // Transform the body.
8337 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
8338 if (Body.isInvalid())
8339 return StmtError();
8341 // If nothing changed, just retain this statement.
8342 if (!getDerived().AlwaysRebuild() &&
8343 Body.get() == S->getFinallyBody())
8344 return S;
8346 // Build a new statement.
8347 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
8348 Body.get());
8351 template<typename Derived>
8352 StmtResult
8353 TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
8354 ExprResult Operand;
8355 if (S->getThrowExpr()) {
8356 Operand = getDerived().TransformExpr(S->getThrowExpr());
8357 if (Operand.isInvalid())
8358 return StmtError();
8361 if (!getDerived().AlwaysRebuild() &&
8362 Operand.get() == S->getThrowExpr())
8363 return S;
8365 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
8368 template<typename Derived>
8369 StmtResult
8370 TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
8371 ObjCAtSynchronizedStmt *S) {
8372 // Transform the object we are locking.
8373 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
8374 if (Object.isInvalid())
8375 return StmtError();
8376 Object =
8377 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
8378 Object.get());
8379 if (Object.isInvalid())
8380 return StmtError();
8382 // Transform the body.
8383 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
8384 if (Body.isInvalid())
8385 return StmtError();
8387 // If nothing change, just retain the current statement.
8388 if (!getDerived().AlwaysRebuild() &&
8389 Object.get() == S->getSynchExpr() &&
8390 Body.get() == S->getSynchBody())
8391 return S;
8393 // Build a new statement.
8394 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
8395 Object.get(), Body.get());
8398 template<typename Derived>
8399 StmtResult
8400 TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
8401 ObjCAutoreleasePoolStmt *S) {
8402 // Transform the body.
8403 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
8404 if (Body.isInvalid())
8405 return StmtError();
8407 // If nothing changed, just retain this statement.
8408 if (!getDerived().AlwaysRebuild() &&
8409 Body.get() == S->getSubStmt())
8410 return S;
8412 // Build a new statement.
8413 return getDerived().RebuildObjCAutoreleasePoolStmt(
8414 S->getAtLoc(), Body.get());
8417 template<typename Derived>
8418 StmtResult
8419 TreeTransform<Derived>::TransformObjCForCollectionStmt(
8420 ObjCForCollectionStmt *S) {
8421 // Transform the element statement.
8422 StmtResult Element =
8423 getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded);
8424 if (Element.isInvalid())
8425 return StmtError();
8427 // Transform the collection expression.
8428 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
8429 if (Collection.isInvalid())
8430 return StmtError();
8432 // Transform the body.
8433 StmtResult Body = getDerived().TransformStmt(S->getBody());
8434 if (Body.isInvalid())
8435 return StmtError();
8437 // If nothing changed, just retain this statement.
8438 if (!getDerived().AlwaysRebuild() &&
8439 Element.get() == S->getElement() &&
8440 Collection.get() == S->getCollection() &&
8441 Body.get() == S->getBody())
8442 return S;
8444 // Build a new statement.
8445 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
8446 Element.get(),
8447 Collection.get(),
8448 S->getRParenLoc(),
8449 Body.get());
8452 template <typename Derived>
8453 StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
8454 // Transform the exception declaration, if any.
8455 VarDecl *Var = nullptr;
8456 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
8457 TypeSourceInfo *T =
8458 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
8459 if (!T)
8460 return StmtError();
8462 Var = getDerived().RebuildExceptionDecl(
8463 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
8464 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
8465 if (!Var || Var->isInvalidDecl())
8466 return StmtError();
8469 // Transform the actual exception handler.
8470 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
8471 if (Handler.isInvalid())
8472 return StmtError();
8474 if (!getDerived().AlwaysRebuild() && !Var &&
8475 Handler.get() == S->getHandlerBlock())
8476 return S;
8478 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
8481 template <typename Derived>
8482 StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
8483 // Transform the try block itself.
8484 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8485 if (TryBlock.isInvalid())
8486 return StmtError();
8488 // Transform the handlers.
8489 bool HandlerChanged = false;
8490 SmallVector<Stmt *, 8> Handlers;
8491 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
8492 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I));
8493 if (Handler.isInvalid())
8494 return StmtError();
8496 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
8497 Handlers.push_back(Handler.getAs<Stmt>());
8500 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8501 !HandlerChanged)
8502 return S;
8504 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
8505 Handlers);
8508 template<typename Derived>
8509 StmtResult
8510 TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
8511 StmtResult Init =
8512 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
8513 if (Init.isInvalid())
8514 return StmtError();
8516 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
8517 if (Range.isInvalid())
8518 return StmtError();
8520 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
8521 if (Begin.isInvalid())
8522 return StmtError();
8523 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
8524 if (End.isInvalid())
8525 return StmtError();
8527 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8528 if (Cond.isInvalid())
8529 return StmtError();
8530 if (Cond.get())
8531 Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());
8532 if (Cond.isInvalid())
8533 return StmtError();
8534 if (Cond.get())
8535 Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());
8537 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8538 if (Inc.isInvalid())
8539 return StmtError();
8540 if (Inc.get())
8541 Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());
8543 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
8544 if (LoopVar.isInvalid())
8545 return StmtError();
8547 StmtResult NewStmt = S;
8548 if (getDerived().AlwaysRebuild() ||
8549 Init.get() != S->getInit() ||
8550 Range.get() != S->getRangeStmt() ||
8551 Begin.get() != S->getBeginStmt() ||
8552 End.get() != S->getEndStmt() ||
8553 Cond.get() != S->getCond() ||
8554 Inc.get() != S->getInc() ||
8555 LoopVar.get() != S->getLoopVarStmt()) {
8556 NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
8557 S->getCoawaitLoc(), Init.get(),
8558 S->getColonLoc(), Range.get(),
8559 Begin.get(), End.get(),
8560 Cond.get(),
8561 Inc.get(), LoopVar.get(),
8562 S->getRParenLoc());
8563 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
8564 // Might not have attached any initializer to the loop variable.
8565 getSema().ActOnInitializerError(
8566 cast<DeclStmt>(LoopVar.get())->getSingleDecl());
8567 return StmtError();
8571 StmtResult Body = getDerived().TransformStmt(S->getBody());
8572 if (Body.isInvalid())
8573 return StmtError();
8575 // Body has changed but we didn't rebuild the for-range statement. Rebuild
8576 // it now so we have a new statement to attach the body to.
8577 if (Body.get() != S->getBody() && NewStmt.get() == S) {
8578 NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
8579 S->getCoawaitLoc(), Init.get(),
8580 S->getColonLoc(), Range.get(),
8581 Begin.get(), End.get(),
8582 Cond.get(),
8583 Inc.get(), LoopVar.get(),
8584 S->getRParenLoc());
8585 if (NewStmt.isInvalid())
8586 return StmtError();
8589 if (NewStmt.get() == S)
8590 return S;
8592 return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
8595 template<typename Derived>
8596 StmtResult
8597 TreeTransform<Derived>::TransformMSDependentExistsStmt(
8598 MSDependentExistsStmt *S) {
8599 // Transform the nested-name-specifier, if any.
8600 NestedNameSpecifierLoc QualifierLoc;
8601 if (S->getQualifierLoc()) {
8602 QualifierLoc
8603 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
8604 if (!QualifierLoc)
8605 return StmtError();
8608 // Transform the declaration name.
8609 DeclarationNameInfo NameInfo = S->getNameInfo();
8610 if (NameInfo.getName()) {
8611 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
8612 if (!NameInfo.getName())
8613 return StmtError();
8616 // Check whether anything changed.
8617 if (!getDerived().AlwaysRebuild() &&
8618 QualifierLoc == S->getQualifierLoc() &&
8619 NameInfo.getName() == S->getNameInfo().getName())
8620 return S;
8622 // Determine whether this name exists, if we can.
8623 CXXScopeSpec SS;
8624 SS.Adopt(QualifierLoc);
8625 bool Dependent = false;
8626 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
8627 case Sema::IER_Exists:
8628 if (S->isIfExists())
8629 break;
8631 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8633 case Sema::IER_DoesNotExist:
8634 if (S->isIfNotExists())
8635 break;
8637 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8639 case Sema::IER_Dependent:
8640 Dependent = true;
8641 break;
8643 case Sema::IER_Error:
8644 return StmtError();
8647 // We need to continue with the instantiation, so do so now.
8648 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
8649 if (SubStmt.isInvalid())
8650 return StmtError();
8652 // If we have resolved the name, just transform to the substatement.
8653 if (!Dependent)
8654 return SubStmt;
8656 // The name is still dependent, so build a dependent expression again.
8657 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
8658 S->isIfExists(),
8659 QualifierLoc,
8660 NameInfo,
8661 SubStmt.get());
8664 template<typename Derived>
8665 ExprResult
8666 TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
8667 NestedNameSpecifierLoc QualifierLoc;
8668 if (E->getQualifierLoc()) {
8669 QualifierLoc
8670 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
8671 if (!QualifierLoc)
8672 return ExprError();
8675 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
8676 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
8677 if (!PD)
8678 return ExprError();
8680 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
8681 if (Base.isInvalid())
8682 return ExprError();
8684 return new (SemaRef.getASTContext())
8685 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
8686 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
8687 QualifierLoc, E->getMemberLoc());
8690 template <typename Derived>
8691 ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
8692 MSPropertySubscriptExpr *E) {
8693 auto BaseRes = getDerived().TransformExpr(E->getBase());
8694 if (BaseRes.isInvalid())
8695 return ExprError();
8696 auto IdxRes = getDerived().TransformExpr(E->getIdx());
8697 if (IdxRes.isInvalid())
8698 return ExprError();
8700 if (!getDerived().AlwaysRebuild() &&
8701 BaseRes.get() == E->getBase() &&
8702 IdxRes.get() == E->getIdx())
8703 return E;
8705 return getDerived().RebuildArraySubscriptExpr(
8706 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
8709 template <typename Derived>
8710 StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
8711 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8712 if (TryBlock.isInvalid())
8713 return StmtError();
8715 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
8716 if (Handler.isInvalid())
8717 return StmtError();
8719 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8720 Handler.get() == S->getHandler())
8721 return S;
8723 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
8724 TryBlock.get(), Handler.get());
8727 template <typename Derived>
8728 StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
8729 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
8730 if (Block.isInvalid())
8731 return StmtError();
8733 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
8736 template <typename Derived>
8737 StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
8738 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
8739 if (FilterExpr.isInvalid())
8740 return StmtError();
8742 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
8743 if (Block.isInvalid())
8744 return StmtError();
8746 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
8747 Block.get());
8750 template <typename Derived>
8751 StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
8752 if (isa<SEHFinallyStmt>(Handler))
8753 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
8754 else
8755 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
8758 template<typename Derived>
8759 StmtResult
8760 TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
8761 return S;
8764 //===----------------------------------------------------------------------===//
8765 // OpenMP directive transformation
8766 //===----------------------------------------------------------------------===//
8768 template <typename Derived>
8769 StmtResult
8770 TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
8771 // OMPCanonicalLoops are eliminated during transformation, since they will be
8772 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
8773 // after transformation.
8774 return getDerived().TransformStmt(L->getLoopStmt());
8777 template <typename Derived>
8778 StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
8779 OMPExecutableDirective *D) {
8781 // Transform the clauses
8782 llvm::SmallVector<OMPClause *, 16> TClauses;
8783 ArrayRef<OMPClause *> Clauses = D->clauses();
8784 TClauses.reserve(Clauses.size());
8785 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
8786 I != E; ++I) {
8787 if (*I) {
8788 getDerived().getSema().StartOpenMPClause((*I)->getClauseKind());
8789 OMPClause *Clause = getDerived().TransformOMPClause(*I);
8790 getDerived().getSema().EndOpenMPClause();
8791 if (Clause)
8792 TClauses.push_back(Clause);
8793 } else {
8794 TClauses.push_back(nullptr);
8797 StmtResult AssociatedStmt;
8798 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
8799 getDerived().getSema().ActOnOpenMPRegionStart(D->getDirectiveKind(),
8800 /*CurScope=*/nullptr);
8801 StmtResult Body;
8803 Sema::CompoundScopeRAII CompoundScope(getSema());
8804 Stmt *CS;
8805 if (D->getDirectiveKind() == OMPD_atomic ||
8806 D->getDirectiveKind() == OMPD_critical ||
8807 D->getDirectiveKind() == OMPD_section ||
8808 D->getDirectiveKind() == OMPD_master)
8809 CS = D->getAssociatedStmt();
8810 else
8811 CS = D->getRawStmt();
8812 Body = getDerived().TransformStmt(CS);
8813 if (Body.isUsable() && isOpenMPLoopDirective(D->getDirectiveKind()) &&
8814 getSema().getLangOpts().OpenMPIRBuilder)
8815 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
8817 AssociatedStmt =
8818 getDerived().getSema().ActOnOpenMPRegionEnd(Body, TClauses);
8819 if (AssociatedStmt.isInvalid()) {
8820 return StmtError();
8823 if (TClauses.size() != Clauses.size()) {
8824 return StmtError();
8827 // Transform directive name for 'omp critical' directive.
8828 DeclarationNameInfo DirName;
8829 if (D->getDirectiveKind() == OMPD_critical) {
8830 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
8831 DirName = getDerived().TransformDeclarationNameInfo(DirName);
8833 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
8834 if (D->getDirectiveKind() == OMPD_cancellation_point) {
8835 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();
8836 } else if (D->getDirectiveKind() == OMPD_cancel) {
8837 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();
8840 return getDerived().RebuildOMPExecutableDirective(
8841 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
8842 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc(),
8843 D->getMappedDirective());
8846 template <typename Derived>
8847 StmtResult
8848 TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
8849 // TODO: Fix This
8850 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)
8851 << getOpenMPDirectiveName(D->getDirectiveKind());
8852 return StmtError();
8855 template <typename Derived>
8856 StmtResult
8857 TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
8858 DeclarationNameInfo DirName;
8859 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr,
8860 D->getBeginLoc());
8861 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8862 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8863 return Res;
8866 template <typename Derived>
8867 StmtResult
8868 TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
8869 DeclarationNameInfo DirName;
8870 getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr,
8871 D->getBeginLoc());
8872 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8873 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8874 return Res;
8877 template <typename Derived>
8878 StmtResult
8879 TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
8880 DeclarationNameInfo DirName;
8881 getDerived().getSema().StartOpenMPDSABlock(D->getDirectiveKind(), DirName,
8882 nullptr, D->getBeginLoc());
8883 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8884 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8885 return Res;
8888 template <typename Derived>
8889 StmtResult
8890 TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
8891 DeclarationNameInfo DirName;
8892 getDerived().getSema().StartOpenMPDSABlock(D->getDirectiveKind(), DirName,
8893 nullptr, D->getBeginLoc());
8894 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8895 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8896 return Res;
8899 template <typename Derived>
8900 StmtResult
8901 TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
8902 DeclarationNameInfo DirName;
8903 getDerived().getSema().StartOpenMPDSABlock(OMPD_for, DirName, nullptr,
8904 D->getBeginLoc());
8905 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8906 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8907 return Res;
8910 template <typename Derived>
8911 StmtResult
8912 TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
8913 DeclarationNameInfo DirName;
8914 getDerived().getSema().StartOpenMPDSABlock(OMPD_for_simd, DirName, nullptr,
8915 D->getBeginLoc());
8916 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8917 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8918 return Res;
8921 template <typename Derived>
8922 StmtResult
8923 TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
8924 DeclarationNameInfo DirName;
8925 getDerived().getSema().StartOpenMPDSABlock(OMPD_sections, DirName, nullptr,
8926 D->getBeginLoc());
8927 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8928 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8929 return Res;
8932 template <typename Derived>
8933 StmtResult
8934 TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
8935 DeclarationNameInfo DirName;
8936 getDerived().getSema().StartOpenMPDSABlock(OMPD_section, DirName, nullptr,
8937 D->getBeginLoc());
8938 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8939 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8940 return Res;
8943 template <typename Derived>
8944 StmtResult
8945 TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
8946 DeclarationNameInfo DirName;
8947 getDerived().getSema().StartOpenMPDSABlock(OMPD_scope, DirName, nullptr,
8948 D->getBeginLoc());
8949 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8950 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8951 return Res;
8954 template <typename Derived>
8955 StmtResult
8956 TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
8957 DeclarationNameInfo DirName;
8958 getDerived().getSema().StartOpenMPDSABlock(OMPD_single, DirName, nullptr,
8959 D->getBeginLoc());
8960 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8961 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8962 return Res;
8965 template <typename Derived>
8966 StmtResult
8967 TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
8968 DeclarationNameInfo DirName;
8969 getDerived().getSema().StartOpenMPDSABlock(OMPD_master, DirName, nullptr,
8970 D->getBeginLoc());
8971 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8972 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8973 return Res;
8976 template <typename Derived>
8977 StmtResult
8978 TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
8979 getDerived().getSema().StartOpenMPDSABlock(
8980 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
8981 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8982 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8983 return Res;
8986 template <typename Derived>
8987 StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
8988 OMPParallelForDirective *D) {
8989 DeclarationNameInfo DirName;
8990 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for, DirName,
8991 nullptr, D->getBeginLoc());
8992 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8993 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8994 return Res;
8997 template <typename Derived>
8998 StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
8999 OMPParallelForSimdDirective *D) {
9000 DeclarationNameInfo DirName;
9001 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for_simd, DirName,
9002 nullptr, D->getBeginLoc());
9003 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9004 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9005 return Res;
9008 template <typename Derived>
9009 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9010 OMPParallelMasterDirective *D) {
9011 DeclarationNameInfo DirName;
9012 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_master, DirName,
9013 nullptr, D->getBeginLoc());
9014 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9015 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9016 return Res;
9019 template <typename Derived>
9020 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9021 OMPParallelMaskedDirective *D) {
9022 DeclarationNameInfo DirName;
9023 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_masked, DirName,
9024 nullptr, D->getBeginLoc());
9025 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9026 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9027 return Res;
9030 template <typename Derived>
9031 StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9032 OMPParallelSectionsDirective *D) {
9033 DeclarationNameInfo DirName;
9034 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_sections, DirName,
9035 nullptr, D->getBeginLoc());
9036 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9037 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9038 return Res;
9041 template <typename Derived>
9042 StmtResult
9043 TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9044 DeclarationNameInfo DirName;
9045 getDerived().getSema().StartOpenMPDSABlock(OMPD_task, DirName, nullptr,
9046 D->getBeginLoc());
9047 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9048 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9049 return Res;
9052 template <typename Derived>
9053 StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9054 OMPTaskyieldDirective *D) {
9055 DeclarationNameInfo DirName;
9056 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskyield, DirName, nullptr,
9057 D->getBeginLoc());
9058 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9059 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9060 return Res;
9063 template <typename Derived>
9064 StmtResult
9065 TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9066 DeclarationNameInfo DirName;
9067 getDerived().getSema().StartOpenMPDSABlock(OMPD_barrier, DirName, nullptr,
9068 D->getBeginLoc());
9069 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9070 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9071 return Res;
9074 template <typename Derived>
9075 StmtResult
9076 TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9077 DeclarationNameInfo DirName;
9078 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskwait, DirName, nullptr,
9079 D->getBeginLoc());
9080 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9081 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9082 return Res;
9085 template <typename Derived>
9086 StmtResult
9087 TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9088 DeclarationNameInfo DirName;
9089 getDerived().getSema().StartOpenMPDSABlock(OMPD_error, DirName, nullptr,
9090 D->getBeginLoc());
9091 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9092 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9093 return Res;
9096 template <typename Derived>
9097 StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9098 OMPTaskgroupDirective *D) {
9099 DeclarationNameInfo DirName;
9100 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskgroup, DirName, nullptr,
9101 D->getBeginLoc());
9102 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9103 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9104 return Res;
9107 template <typename Derived>
9108 StmtResult
9109 TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9110 DeclarationNameInfo DirName;
9111 getDerived().getSema().StartOpenMPDSABlock(OMPD_flush, DirName, nullptr,
9112 D->getBeginLoc());
9113 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9114 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9115 return Res;
9118 template <typename Derived>
9119 StmtResult
9120 TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9121 DeclarationNameInfo DirName;
9122 getDerived().getSema().StartOpenMPDSABlock(OMPD_depobj, DirName, nullptr,
9123 D->getBeginLoc());
9124 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9125 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9126 return Res;
9129 template <typename Derived>
9130 StmtResult
9131 TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9132 DeclarationNameInfo DirName;
9133 getDerived().getSema().StartOpenMPDSABlock(OMPD_scan, DirName, nullptr,
9134 D->getBeginLoc());
9135 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9136 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9137 return Res;
9140 template <typename Derived>
9141 StmtResult
9142 TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9143 DeclarationNameInfo DirName;
9144 getDerived().getSema().StartOpenMPDSABlock(OMPD_ordered, DirName, nullptr,
9145 D->getBeginLoc());
9146 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9147 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9148 return Res;
9151 template <typename Derived>
9152 StmtResult
9153 TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9154 DeclarationNameInfo DirName;
9155 getDerived().getSema().StartOpenMPDSABlock(OMPD_atomic, DirName, nullptr,
9156 D->getBeginLoc());
9157 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9158 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9159 return Res;
9162 template <typename Derived>
9163 StmtResult
9164 TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9165 DeclarationNameInfo DirName;
9166 getDerived().getSema().StartOpenMPDSABlock(OMPD_target, DirName, nullptr,
9167 D->getBeginLoc());
9168 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9169 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9170 return Res;
9173 template <typename Derived>
9174 StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9175 OMPTargetDataDirective *D) {
9176 DeclarationNameInfo DirName;
9177 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_data, DirName, nullptr,
9178 D->getBeginLoc());
9179 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9180 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9181 return Res;
9184 template <typename Derived>
9185 StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9186 OMPTargetEnterDataDirective *D) {
9187 DeclarationNameInfo DirName;
9188 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_enter_data, DirName,
9189 nullptr, D->getBeginLoc());
9190 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9191 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9192 return Res;
9195 template <typename Derived>
9196 StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9197 OMPTargetExitDataDirective *D) {
9198 DeclarationNameInfo DirName;
9199 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_exit_data, DirName,
9200 nullptr, D->getBeginLoc());
9201 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9202 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9203 return Res;
9206 template <typename Derived>
9207 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
9208 OMPTargetParallelDirective *D) {
9209 DeclarationNameInfo DirName;
9210 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel, DirName,
9211 nullptr, D->getBeginLoc());
9212 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9213 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9214 return Res;
9217 template <typename Derived>
9218 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
9219 OMPTargetParallelForDirective *D) {
9220 DeclarationNameInfo DirName;
9221 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_for, DirName,
9222 nullptr, D->getBeginLoc());
9223 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9224 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9225 return Res;
9228 template <typename Derived>
9229 StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
9230 OMPTargetUpdateDirective *D) {
9231 DeclarationNameInfo DirName;
9232 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_update, DirName,
9233 nullptr, D->getBeginLoc());
9234 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9235 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9236 return Res;
9239 template <typename Derived>
9240 StmtResult
9241 TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
9242 DeclarationNameInfo DirName;
9243 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams, DirName, nullptr,
9244 D->getBeginLoc());
9245 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9246 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9247 return Res;
9250 template <typename Derived>
9251 StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
9252 OMPCancellationPointDirective *D) {
9253 DeclarationNameInfo DirName;
9254 getDerived().getSema().StartOpenMPDSABlock(OMPD_cancellation_point, DirName,
9255 nullptr, D->getBeginLoc());
9256 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9257 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9258 return Res;
9261 template <typename Derived>
9262 StmtResult
9263 TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
9264 DeclarationNameInfo DirName;
9265 getDerived().getSema().StartOpenMPDSABlock(OMPD_cancel, DirName, nullptr,
9266 D->getBeginLoc());
9267 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9268 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9269 return Res;
9272 template <typename Derived>
9273 StmtResult
9274 TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
9275 DeclarationNameInfo DirName;
9276 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop, DirName, nullptr,
9277 D->getBeginLoc());
9278 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9279 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9280 return Res;
9283 template <typename Derived>
9284 StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
9285 OMPTaskLoopSimdDirective *D) {
9286 DeclarationNameInfo DirName;
9287 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop_simd, DirName,
9288 nullptr, D->getBeginLoc());
9289 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9290 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9291 return Res;
9294 template <typename Derived>
9295 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
9296 OMPMasterTaskLoopDirective *D) {
9297 DeclarationNameInfo DirName;
9298 getDerived().getSema().StartOpenMPDSABlock(OMPD_master_taskloop, DirName,
9299 nullptr, D->getBeginLoc());
9300 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9301 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9302 return Res;
9305 template <typename Derived>
9306 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
9307 OMPMaskedTaskLoopDirective *D) {
9308 DeclarationNameInfo DirName;
9309 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked_taskloop, DirName,
9310 nullptr, D->getBeginLoc());
9311 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9312 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9313 return Res;
9316 template <typename Derived>
9317 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
9318 OMPMasterTaskLoopSimdDirective *D) {
9319 DeclarationNameInfo DirName;
9320 getDerived().getSema().StartOpenMPDSABlock(OMPD_master_taskloop_simd, DirName,
9321 nullptr, D->getBeginLoc());
9322 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9323 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9324 return Res;
9327 template <typename Derived>
9328 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
9329 OMPMaskedTaskLoopSimdDirective *D) {
9330 DeclarationNameInfo DirName;
9331 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked_taskloop_simd, DirName,
9332 nullptr, D->getBeginLoc());
9333 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9334 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9335 return Res;
9338 template <typename Derived>
9339 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
9340 OMPParallelMasterTaskLoopDirective *D) {
9341 DeclarationNameInfo DirName;
9342 getDerived().getSema().StartOpenMPDSABlock(
9343 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
9344 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9345 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9346 return Res;
9349 template <typename Derived>
9350 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
9351 OMPParallelMaskedTaskLoopDirective *D) {
9352 DeclarationNameInfo DirName;
9353 getDerived().getSema().StartOpenMPDSABlock(
9354 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9355 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9356 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9357 return Res;
9360 template <typename Derived>
9361 StmtResult
9362 TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
9363 OMPParallelMasterTaskLoopSimdDirective *D) {
9364 DeclarationNameInfo DirName;
9365 getDerived().getSema().StartOpenMPDSABlock(
9366 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9367 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9368 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9369 return Res;
9372 template <typename Derived>
9373 StmtResult
9374 TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
9375 OMPParallelMaskedTaskLoopSimdDirective *D) {
9376 DeclarationNameInfo DirName;
9377 getDerived().getSema().StartOpenMPDSABlock(
9378 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9379 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9380 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9381 return Res;
9384 template <typename Derived>
9385 StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
9386 OMPDistributeDirective *D) {
9387 DeclarationNameInfo DirName;
9388 getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute, DirName, nullptr,
9389 D->getBeginLoc());
9390 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9391 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9392 return Res;
9395 template <typename Derived>
9396 StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
9397 OMPDistributeParallelForDirective *D) {
9398 DeclarationNameInfo DirName;
9399 getDerived().getSema().StartOpenMPDSABlock(
9400 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9401 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9402 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9403 return Res;
9406 template <typename Derived>
9407 StmtResult
9408 TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
9409 OMPDistributeParallelForSimdDirective *D) {
9410 DeclarationNameInfo DirName;
9411 getDerived().getSema().StartOpenMPDSABlock(
9412 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9413 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9414 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9415 return Res;
9418 template <typename Derived>
9419 StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
9420 OMPDistributeSimdDirective *D) {
9421 DeclarationNameInfo DirName;
9422 getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute_simd, DirName,
9423 nullptr, D->getBeginLoc());
9424 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9425 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9426 return Res;
9429 template <typename Derived>
9430 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
9431 OMPTargetParallelForSimdDirective *D) {
9432 DeclarationNameInfo DirName;
9433 getDerived().getSema().StartOpenMPDSABlock(
9434 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9435 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9436 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9437 return Res;
9440 template <typename Derived>
9441 StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
9442 OMPTargetSimdDirective *D) {
9443 DeclarationNameInfo DirName;
9444 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_simd, DirName, nullptr,
9445 D->getBeginLoc());
9446 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9447 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9448 return Res;
9451 template <typename Derived>
9452 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
9453 OMPTeamsDistributeDirective *D) {
9454 DeclarationNameInfo DirName;
9455 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams_distribute, DirName,
9456 nullptr, D->getBeginLoc());
9457 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9458 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9459 return Res;
9462 template <typename Derived>
9463 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
9464 OMPTeamsDistributeSimdDirective *D) {
9465 DeclarationNameInfo DirName;
9466 getDerived().getSema().StartOpenMPDSABlock(
9467 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9468 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9469 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9470 return Res;
9473 template <typename Derived>
9474 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
9475 OMPTeamsDistributeParallelForSimdDirective *D) {
9476 DeclarationNameInfo DirName;
9477 getDerived().getSema().StartOpenMPDSABlock(
9478 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
9479 D->getBeginLoc());
9480 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9481 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9482 return Res;
9485 template <typename Derived>
9486 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
9487 OMPTeamsDistributeParallelForDirective *D) {
9488 DeclarationNameInfo DirName;
9489 getDerived().getSema().StartOpenMPDSABlock(
9490 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9491 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9492 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9493 return Res;
9496 template <typename Derived>
9497 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
9498 OMPTargetTeamsDirective *D) {
9499 DeclarationNameInfo DirName;
9500 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams, DirName,
9501 nullptr, D->getBeginLoc());
9502 auto Res = getDerived().TransformOMPExecutableDirective(D);
9503 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9504 return Res;
9507 template <typename Derived>
9508 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
9509 OMPTargetTeamsDistributeDirective *D) {
9510 DeclarationNameInfo DirName;
9511 getDerived().getSema().StartOpenMPDSABlock(
9512 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
9513 auto Res = getDerived().TransformOMPExecutableDirective(D);
9514 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9515 return Res;
9518 template <typename Derived>
9519 StmtResult
9520 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
9521 OMPTargetTeamsDistributeParallelForDirective *D) {
9522 DeclarationNameInfo DirName;
9523 getDerived().getSema().StartOpenMPDSABlock(
9524 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
9525 D->getBeginLoc());
9526 auto Res = getDerived().TransformOMPExecutableDirective(D);
9527 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9528 return Res;
9531 template <typename Derived>
9532 StmtResult TreeTransform<Derived>::
9533 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
9534 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
9535 DeclarationNameInfo DirName;
9536 getDerived().getSema().StartOpenMPDSABlock(
9537 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
9538 D->getBeginLoc());
9539 auto Res = getDerived().TransformOMPExecutableDirective(D);
9540 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9541 return Res;
9544 template <typename Derived>
9545 StmtResult
9546 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
9547 OMPTargetTeamsDistributeSimdDirective *D) {
9548 DeclarationNameInfo DirName;
9549 getDerived().getSema().StartOpenMPDSABlock(
9550 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9551 auto Res = getDerived().TransformOMPExecutableDirective(D);
9552 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9553 return Res;
9556 template <typename Derived>
9557 StmtResult
9558 TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
9559 DeclarationNameInfo DirName;
9560 getDerived().getSema().StartOpenMPDSABlock(OMPD_interop, DirName, nullptr,
9561 D->getBeginLoc());
9562 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9563 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9564 return Res;
9567 template <typename Derived>
9568 StmtResult
9569 TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
9570 DeclarationNameInfo DirName;
9571 getDerived().getSema().StartOpenMPDSABlock(OMPD_dispatch, DirName, nullptr,
9572 D->getBeginLoc());
9573 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9574 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9575 return Res;
9578 template <typename Derived>
9579 StmtResult
9580 TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
9581 DeclarationNameInfo DirName;
9582 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked, DirName, nullptr,
9583 D->getBeginLoc());
9584 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9585 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9586 return Res;
9589 template <typename Derived>
9590 StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
9591 OMPGenericLoopDirective *D) {
9592 DeclarationNameInfo DirName;
9593 getDerived().getSema().StartOpenMPDSABlock(OMPD_loop, DirName, nullptr,
9594 D->getBeginLoc());
9595 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9596 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9597 return Res;
9600 template <typename Derived>
9601 StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
9602 OMPTeamsGenericLoopDirective *D) {
9603 DeclarationNameInfo DirName;
9604 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams_loop, DirName, nullptr,
9605 D->getBeginLoc());
9606 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9607 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9608 return Res;
9611 template <typename Derived>
9612 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
9613 OMPTargetTeamsGenericLoopDirective *D) {
9614 DeclarationNameInfo DirName;
9615 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams_loop, DirName,
9616 nullptr, D->getBeginLoc());
9617 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9618 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9619 return Res;
9622 template <typename Derived>
9623 StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
9624 OMPParallelGenericLoopDirective *D) {
9625 DeclarationNameInfo DirName;
9626 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_loop, DirName,
9627 nullptr, D->getBeginLoc());
9628 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9629 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9630 return Res;
9633 template <typename Derived>
9634 StmtResult
9635 TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
9636 OMPTargetParallelGenericLoopDirective *D) {
9637 DeclarationNameInfo DirName;
9638 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_loop, DirName,
9639 nullptr, D->getBeginLoc());
9640 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9641 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9642 return Res;
9645 //===----------------------------------------------------------------------===//
9646 // OpenMP clause transformation
9647 //===----------------------------------------------------------------------===//
9648 template <typename Derived>
9649 OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
9650 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9651 if (Cond.isInvalid())
9652 return nullptr;
9653 return getDerived().RebuildOMPIfClause(
9654 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
9655 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
9658 template <typename Derived>
9659 OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
9660 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9661 if (Cond.isInvalid())
9662 return nullptr;
9663 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
9664 C->getLParenLoc(), C->getEndLoc());
9667 template <typename Derived>
9668 OMPClause *
9669 TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
9670 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
9671 if (NumThreads.isInvalid())
9672 return nullptr;
9673 return getDerived().RebuildOMPNumThreadsClause(
9674 NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9677 template <typename Derived>
9678 OMPClause *
9679 TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
9680 ExprResult E = getDerived().TransformExpr(C->getSafelen());
9681 if (E.isInvalid())
9682 return nullptr;
9683 return getDerived().RebuildOMPSafelenClause(
9684 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9687 template <typename Derived>
9688 OMPClause *
9689 TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
9690 ExprResult E = getDerived().TransformExpr(C->getAllocator());
9691 if (E.isInvalid())
9692 return nullptr;
9693 return getDerived().RebuildOMPAllocatorClause(
9694 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9697 template <typename Derived>
9698 OMPClause *
9699 TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
9700 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
9701 if (E.isInvalid())
9702 return nullptr;
9703 return getDerived().RebuildOMPSimdlenClause(
9704 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9707 template <typename Derived>
9708 OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
9709 SmallVector<Expr *, 4> TransformedSizes;
9710 TransformedSizes.reserve(C->getNumSizes());
9711 bool Changed = false;
9712 for (Expr *E : C->getSizesRefs()) {
9713 if (!E) {
9714 TransformedSizes.push_back(nullptr);
9715 continue;
9718 ExprResult T = getDerived().TransformExpr(E);
9719 if (T.isInvalid())
9720 return nullptr;
9721 if (E != T.get())
9722 Changed = true;
9723 TransformedSizes.push_back(T.get());
9726 if (!Changed && !getDerived().AlwaysRebuild())
9727 return C;
9728 return RebuildOMPSizesClause(TransformedSizes, C->getBeginLoc(),
9729 C->getLParenLoc(), C->getEndLoc());
9732 template <typename Derived>
9733 OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
9734 if (!getDerived().AlwaysRebuild())
9735 return C;
9736 return RebuildOMPFullClause(C->getBeginLoc(), C->getEndLoc());
9739 template <typename Derived>
9740 OMPClause *
9741 TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
9742 ExprResult T = getDerived().TransformExpr(C->getFactor());
9743 if (T.isInvalid())
9744 return nullptr;
9745 Expr *Factor = T.get();
9746 bool Changed = Factor != C->getFactor();
9748 if (!Changed && !getDerived().AlwaysRebuild())
9749 return C;
9750 return RebuildOMPPartialClause(Factor, C->getBeginLoc(), C->getLParenLoc(),
9751 C->getEndLoc());
9754 template <typename Derived>
9755 OMPClause *
9756 TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
9757 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
9758 if (E.isInvalid())
9759 return nullptr;
9760 return getDerived().RebuildOMPCollapseClause(
9761 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9764 template <typename Derived>
9765 OMPClause *
9766 TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
9767 return getDerived().RebuildOMPDefaultClause(
9768 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
9769 C->getLParenLoc(), C->getEndLoc());
9772 template <typename Derived>
9773 OMPClause *
9774 TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
9775 return getDerived().RebuildOMPProcBindClause(
9776 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
9777 C->getLParenLoc(), C->getEndLoc());
9780 template <typename Derived>
9781 OMPClause *
9782 TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
9783 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
9784 if (E.isInvalid())
9785 return nullptr;
9786 return getDerived().RebuildOMPScheduleClause(
9787 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
9788 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
9789 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
9790 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
9793 template <typename Derived>
9794 OMPClause *
9795 TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
9796 ExprResult E;
9797 if (auto *Num = C->getNumForLoops()) {
9798 E = getDerived().TransformExpr(Num);
9799 if (E.isInvalid())
9800 return nullptr;
9802 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
9803 C->getLParenLoc(), E.get());
9806 template <typename Derived>
9807 OMPClause *
9808 TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
9809 ExprResult E;
9810 if (Expr *Evt = C->getEventHandler()) {
9811 E = getDerived().TransformExpr(Evt);
9812 if (E.isInvalid())
9813 return nullptr;
9815 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
9816 C->getLParenLoc(), C->getEndLoc());
9819 template <typename Derived>
9820 OMPClause *
9821 TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
9822 // No need to rebuild this clause, no template-dependent parameters.
9823 return C;
9826 template <typename Derived>
9827 OMPClause *
9828 TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
9829 // No need to rebuild this clause, no template-dependent parameters.
9830 return C;
9833 template <typename Derived>
9834 OMPClause *
9835 TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
9836 // No need to rebuild this clause, no template-dependent parameters.
9837 return C;
9840 template <typename Derived>
9841 OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
9842 // No need to rebuild this clause, no template-dependent parameters.
9843 return C;
9846 template <typename Derived>
9847 OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
9848 // No need to rebuild this clause, no template-dependent parameters.
9849 return C;
9852 template <typename Derived>
9853 OMPClause *
9854 TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
9855 // No need to rebuild this clause, no template-dependent parameters.
9856 return C;
9859 template <typename Derived>
9860 OMPClause *
9861 TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
9862 // No need to rebuild this clause, no template-dependent parameters.
9863 return C;
9866 template <typename Derived>
9867 OMPClause *
9868 TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
9869 // No need to rebuild this clause, no template-dependent parameters.
9870 return C;
9873 template <typename Derived>
9874 OMPClause *
9875 TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
9876 // No need to rebuild this clause, no template-dependent parameters.
9877 return C;
9880 template <typename Derived>
9881 OMPClause *
9882 TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
9883 // No need to rebuild this clause, no template-dependent parameters.
9884 return C;
9887 template <typename Derived>
9888 OMPClause *
9889 TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
9890 // No need to rebuild this clause, no template-dependent parameters.
9891 return C;
9894 template <typename Derived>
9895 OMPClause *
9896 TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
9897 // No need to rebuild this clause, no template-dependent parameters.
9898 return C;
9901 template <typename Derived>
9902 OMPClause *
9903 TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
9904 // No need to rebuild this clause, no template-dependent parameters.
9905 return C;
9908 template <typename Derived>
9909 OMPClause *
9910 TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
9911 // No need to rebuild this clause, no template-dependent parameters.
9912 return C;
9915 template <typename Derived>
9916 OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
9917 // No need to rebuild this clause, no template-dependent parameters.
9918 return C;
9921 template <typename Derived>
9922 OMPClause *
9923 TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
9924 // No need to rebuild this clause, no template-dependent parameters.
9925 return C;
9928 template <typename Derived>
9929 OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
9930 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
9931 if (IVR.isInvalid())
9932 return nullptr;
9934 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
9935 InteropInfo.PreferTypes.reserve(C->varlist_size() - 1);
9936 for (Expr *E : llvm::drop_begin(C->varlists())) {
9937 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
9938 if (ER.isInvalid())
9939 return nullptr;
9940 InteropInfo.PreferTypes.push_back(ER.get());
9942 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
9943 C->getBeginLoc(), C->getLParenLoc(),
9944 C->getVarLoc(), C->getEndLoc());
9947 template <typename Derived>
9948 OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
9949 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
9950 if (ER.isInvalid())
9951 return nullptr;
9952 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
9953 C->getLParenLoc(), C->getVarLoc(),
9954 C->getEndLoc());
9957 template <typename Derived>
9958 OMPClause *
9959 TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
9960 ExprResult ER;
9961 if (Expr *IV = C->getInteropVar()) {
9962 ER = getDerived().TransformExpr(IV);
9963 if (ER.isInvalid())
9964 return nullptr;
9966 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
9967 C->getLParenLoc(), C->getVarLoc(),
9968 C->getEndLoc());
9971 template <typename Derived>
9972 OMPClause *
9973 TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
9974 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9975 if (Cond.isInvalid())
9976 return nullptr;
9977 return getDerived().RebuildOMPNovariantsClause(
9978 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9981 template <typename Derived>
9982 OMPClause *
9983 TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
9984 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9985 if (Cond.isInvalid())
9986 return nullptr;
9987 return getDerived().RebuildOMPNocontextClause(
9988 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9991 template <typename Derived>
9992 OMPClause *
9993 TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
9994 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
9995 if (ThreadID.isInvalid())
9996 return nullptr;
9997 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
9998 C->getLParenLoc(), C->getEndLoc());
10001 template <typename Derived>
10002 OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10003 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10004 if (E.isInvalid())
10005 return nullptr;
10006 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10007 C->getLParenLoc(), C->getEndLoc());
10010 template <typename Derived>
10011 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10012 OMPUnifiedAddressClause *C) {
10013 llvm_unreachable("unified_address clause cannot appear in dependent context");
10016 template <typename Derived>
10017 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10018 OMPUnifiedSharedMemoryClause *C) {
10019 llvm_unreachable(
10020 "unified_shared_memory clause cannot appear in dependent context");
10023 template <typename Derived>
10024 OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10025 OMPReverseOffloadClause *C) {
10026 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10029 template <typename Derived>
10030 OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10031 OMPDynamicAllocatorsClause *C) {
10032 llvm_unreachable(
10033 "dynamic_allocators clause cannot appear in dependent context");
10036 template <typename Derived>
10037 OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10038 OMPAtomicDefaultMemOrderClause *C) {
10039 llvm_unreachable(
10040 "atomic_default_mem_order clause cannot appear in dependent context");
10043 template <typename Derived>
10044 OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10045 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10046 C->getBeginLoc(), C->getLParenLoc(),
10047 C->getEndLoc());
10050 template <typename Derived>
10051 OMPClause *
10052 TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10053 return getDerived().RebuildOMPSeverityClause(
10054 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10055 C->getLParenLoc(), C->getEndLoc());
10058 template <typename Derived>
10059 OMPClause *
10060 TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10061 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10062 if (E.isInvalid())
10063 return nullptr;
10064 return getDerived().RebuildOMPMessageClause(
10065 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10066 C->getEndLoc());
10069 template <typename Derived>
10070 OMPClause *
10071 TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10072 llvm::SmallVector<Expr *, 16> Vars;
10073 Vars.reserve(C->varlist_size());
10074 for (auto *VE : C->varlists()) {
10075 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10076 if (EVar.isInvalid())
10077 return nullptr;
10078 Vars.push_back(EVar.get());
10080 return getDerived().RebuildOMPPrivateClause(
10081 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10084 template <typename Derived>
10085 OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10086 OMPFirstprivateClause *C) {
10087 llvm::SmallVector<Expr *, 16> Vars;
10088 Vars.reserve(C->varlist_size());
10089 for (auto *VE : C->varlists()) {
10090 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10091 if (EVar.isInvalid())
10092 return nullptr;
10093 Vars.push_back(EVar.get());
10095 return getDerived().RebuildOMPFirstprivateClause(
10096 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10099 template <typename Derived>
10100 OMPClause *
10101 TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10102 llvm::SmallVector<Expr *, 16> Vars;
10103 Vars.reserve(C->varlist_size());
10104 for (auto *VE : C->varlists()) {
10105 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10106 if (EVar.isInvalid())
10107 return nullptr;
10108 Vars.push_back(EVar.get());
10110 return getDerived().RebuildOMPLastprivateClause(
10111 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10112 C->getLParenLoc(), C->getEndLoc());
10115 template <typename Derived>
10116 OMPClause *
10117 TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
10118 llvm::SmallVector<Expr *, 16> Vars;
10119 Vars.reserve(C->varlist_size());
10120 for (auto *VE : C->varlists()) {
10121 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10122 if (EVar.isInvalid())
10123 return nullptr;
10124 Vars.push_back(EVar.get());
10126 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
10127 C->getLParenLoc(), C->getEndLoc());
10130 template <typename Derived>
10131 OMPClause *
10132 TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
10133 llvm::SmallVector<Expr *, 16> Vars;
10134 Vars.reserve(C->varlist_size());
10135 for (auto *VE : C->varlists()) {
10136 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10137 if (EVar.isInvalid())
10138 return nullptr;
10139 Vars.push_back(EVar.get());
10141 CXXScopeSpec ReductionIdScopeSpec;
10142 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10144 DeclarationNameInfo NameInfo = C->getNameInfo();
10145 if (NameInfo.getName()) {
10146 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10147 if (!NameInfo.getName())
10148 return nullptr;
10150 // Build a list of all UDR decls with the same names ranged by the Scopes.
10151 // The Scope boundary is a duplication of the previous decl.
10152 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10153 for (auto *E : C->reduction_ops()) {
10154 // Transform all the decls.
10155 if (E) {
10156 auto *ULE = cast<UnresolvedLookupExpr>(E);
10157 UnresolvedSet<8> Decls;
10158 for (auto *D : ULE->decls()) {
10159 NamedDecl *InstD =
10160 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10161 Decls.addDecl(InstD, InstD->getAccess());
10163 UnresolvedReductions.push_back(
10164 UnresolvedLookupExpr::Create(
10165 SemaRef.Context, /*NamingClass=*/nullptr,
10166 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context),
10167 NameInfo, /*ADL=*/true, ULE->isOverloaded(),
10168 Decls.begin(), Decls.end()));
10169 } else
10170 UnresolvedReductions.push_back(nullptr);
10172 return getDerived().RebuildOMPReductionClause(
10173 Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(),
10174 C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
10175 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10178 template <typename Derived>
10179 OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
10180 OMPTaskReductionClause *C) {
10181 llvm::SmallVector<Expr *, 16> Vars;
10182 Vars.reserve(C->varlist_size());
10183 for (auto *VE : C->varlists()) {
10184 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10185 if (EVar.isInvalid())
10186 return nullptr;
10187 Vars.push_back(EVar.get());
10189 CXXScopeSpec ReductionIdScopeSpec;
10190 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10192 DeclarationNameInfo NameInfo = C->getNameInfo();
10193 if (NameInfo.getName()) {
10194 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10195 if (!NameInfo.getName())
10196 return nullptr;
10198 // Build a list of all UDR decls with the same names ranged by the Scopes.
10199 // The Scope boundary is a duplication of the previous decl.
10200 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10201 for (auto *E : C->reduction_ops()) {
10202 // Transform all the decls.
10203 if (E) {
10204 auto *ULE = cast<UnresolvedLookupExpr>(E);
10205 UnresolvedSet<8> Decls;
10206 for (auto *D : ULE->decls()) {
10207 NamedDecl *InstD =
10208 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10209 Decls.addDecl(InstD, InstD->getAccess());
10211 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10212 SemaRef.Context, /*NamingClass=*/nullptr,
10213 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10214 /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end()));
10215 } else
10216 UnresolvedReductions.push_back(nullptr);
10218 return getDerived().RebuildOMPTaskReductionClause(
10219 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10220 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10223 template <typename Derived>
10224 OMPClause *
10225 TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
10226 llvm::SmallVector<Expr *, 16> Vars;
10227 Vars.reserve(C->varlist_size());
10228 for (auto *VE : C->varlists()) {
10229 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10230 if (EVar.isInvalid())
10231 return nullptr;
10232 Vars.push_back(EVar.get());
10234 CXXScopeSpec ReductionIdScopeSpec;
10235 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10237 DeclarationNameInfo NameInfo = C->getNameInfo();
10238 if (NameInfo.getName()) {
10239 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10240 if (!NameInfo.getName())
10241 return nullptr;
10243 // Build a list of all UDR decls with the same names ranged by the Scopes.
10244 // The Scope boundary is a duplication of the previous decl.
10245 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10246 for (auto *E : C->reduction_ops()) {
10247 // Transform all the decls.
10248 if (E) {
10249 auto *ULE = cast<UnresolvedLookupExpr>(E);
10250 UnresolvedSet<8> Decls;
10251 for (auto *D : ULE->decls()) {
10252 NamedDecl *InstD =
10253 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10254 Decls.addDecl(InstD, InstD->getAccess());
10256 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10257 SemaRef.Context, /*NamingClass=*/nullptr,
10258 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10259 /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end()));
10260 } else
10261 UnresolvedReductions.push_back(nullptr);
10263 return getDerived().RebuildOMPInReductionClause(
10264 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10265 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10268 template <typename Derived>
10269 OMPClause *
10270 TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
10271 llvm::SmallVector<Expr *, 16> Vars;
10272 Vars.reserve(C->varlist_size());
10273 for (auto *VE : C->varlists()) {
10274 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10275 if (EVar.isInvalid())
10276 return nullptr;
10277 Vars.push_back(EVar.get());
10279 ExprResult Step = getDerived().TransformExpr(C->getStep());
10280 if (Step.isInvalid())
10281 return nullptr;
10282 return getDerived().RebuildOMPLinearClause(
10283 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
10284 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
10285 C->getEndLoc());
10288 template <typename Derived>
10289 OMPClause *
10290 TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
10291 llvm::SmallVector<Expr *, 16> Vars;
10292 Vars.reserve(C->varlist_size());
10293 for (auto *VE : C->varlists()) {
10294 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10295 if (EVar.isInvalid())
10296 return nullptr;
10297 Vars.push_back(EVar.get());
10299 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
10300 if (Alignment.isInvalid())
10301 return nullptr;
10302 return getDerived().RebuildOMPAlignedClause(
10303 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
10304 C->getColonLoc(), C->getEndLoc());
10307 template <typename Derived>
10308 OMPClause *
10309 TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
10310 llvm::SmallVector<Expr *, 16> Vars;
10311 Vars.reserve(C->varlist_size());
10312 for (auto *VE : C->varlists()) {
10313 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10314 if (EVar.isInvalid())
10315 return nullptr;
10316 Vars.push_back(EVar.get());
10318 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
10319 C->getLParenLoc(), C->getEndLoc());
10322 template <typename Derived>
10323 OMPClause *
10324 TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
10325 llvm::SmallVector<Expr *, 16> Vars;
10326 Vars.reserve(C->varlist_size());
10327 for (auto *VE : C->varlists()) {
10328 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10329 if (EVar.isInvalid())
10330 return nullptr;
10331 Vars.push_back(EVar.get());
10333 return getDerived().RebuildOMPCopyprivateClause(
10334 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10337 template <typename Derived>
10338 OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
10339 llvm::SmallVector<Expr *, 16> Vars;
10340 Vars.reserve(C->varlist_size());
10341 for (auto *VE : C->varlists()) {
10342 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10343 if (EVar.isInvalid())
10344 return nullptr;
10345 Vars.push_back(EVar.get());
10347 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
10348 C->getLParenLoc(), C->getEndLoc());
10351 template <typename Derived>
10352 OMPClause *
10353 TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
10354 ExprResult E = getDerived().TransformExpr(C->getDepobj());
10355 if (E.isInvalid())
10356 return nullptr;
10357 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
10358 C->getLParenLoc(), C->getEndLoc());
10361 template <typename Derived>
10362 OMPClause *
10363 TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
10364 llvm::SmallVector<Expr *, 16> Vars;
10365 Expr *DepModifier = C->getModifier();
10366 if (DepModifier) {
10367 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
10368 if (DepModRes.isInvalid())
10369 return nullptr;
10370 DepModifier = DepModRes.get();
10372 Vars.reserve(C->varlist_size());
10373 for (auto *VE : C->varlists()) {
10374 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10375 if (EVar.isInvalid())
10376 return nullptr;
10377 Vars.push_back(EVar.get());
10379 return getDerived().RebuildOMPDependClause(
10380 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
10381 C->getOmpAllMemoryLoc()},
10382 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10385 template <typename Derived>
10386 OMPClause *
10387 TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
10388 ExprResult E = getDerived().TransformExpr(C->getDevice());
10389 if (E.isInvalid())
10390 return nullptr;
10391 return getDerived().RebuildOMPDeviceClause(
10392 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10393 C->getModifierLoc(), C->getEndLoc());
10396 template <typename Derived, class T>
10397 bool transformOMPMappableExprListClause(
10398 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
10399 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
10400 DeclarationNameInfo &MapperIdInfo,
10401 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
10402 // Transform expressions in the list.
10403 Vars.reserve(C->varlist_size());
10404 for (auto *VE : C->varlists()) {
10405 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
10406 if (EVar.isInvalid())
10407 return true;
10408 Vars.push_back(EVar.get());
10410 // Transform mapper scope specifier and identifier.
10411 NestedNameSpecifierLoc QualifierLoc;
10412 if (C->getMapperQualifierLoc()) {
10413 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
10414 C->getMapperQualifierLoc());
10415 if (!QualifierLoc)
10416 return true;
10418 MapperIdScopeSpec.Adopt(QualifierLoc);
10419 MapperIdInfo = C->getMapperIdInfo();
10420 if (MapperIdInfo.getName()) {
10421 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
10422 if (!MapperIdInfo.getName())
10423 return true;
10425 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
10426 // the previous user-defined mapper lookup in dependent environment.
10427 for (auto *E : C->mapperlists()) {
10428 // Transform all the decls.
10429 if (E) {
10430 auto *ULE = cast<UnresolvedLookupExpr>(E);
10431 UnresolvedSet<8> Decls;
10432 for (auto *D : ULE->decls()) {
10433 NamedDecl *InstD =
10434 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
10435 Decls.addDecl(InstD, InstD->getAccess());
10437 UnresolvedMappers.push_back(UnresolvedLookupExpr::Create(
10438 TT.getSema().Context, /*NamingClass=*/nullptr,
10439 MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
10440 MapperIdInfo, /*ADL=*/true, ULE->isOverloaded(), Decls.begin(),
10441 Decls.end()));
10442 } else {
10443 UnresolvedMappers.push_back(nullptr);
10446 return false;
10449 template <typename Derived>
10450 OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
10451 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10452 llvm::SmallVector<Expr *, 16> Vars;
10453 Expr *IteratorModifier = C->getIteratorModifier();
10454 if (IteratorModifier) {
10455 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
10456 if (MapModRes.isInvalid())
10457 return nullptr;
10458 IteratorModifier = MapModRes.get();
10460 CXXScopeSpec MapperIdScopeSpec;
10461 DeclarationNameInfo MapperIdInfo;
10462 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10463 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
10464 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10465 return nullptr;
10466 return getDerived().RebuildOMPMapClause(
10467 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
10468 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
10469 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10472 template <typename Derived>
10473 OMPClause *
10474 TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
10475 Expr *Allocator = C->getAllocator();
10476 if (Allocator) {
10477 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
10478 if (AllocatorRes.isInvalid())
10479 return nullptr;
10480 Allocator = AllocatorRes.get();
10482 llvm::SmallVector<Expr *, 16> Vars;
10483 Vars.reserve(C->varlist_size());
10484 for (auto *VE : C->varlists()) {
10485 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10486 if (EVar.isInvalid())
10487 return nullptr;
10488 Vars.push_back(EVar.get());
10490 return getDerived().RebuildOMPAllocateClause(
10491 Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10492 C->getEndLoc());
10495 template <typename Derived>
10496 OMPClause *
10497 TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
10498 ExprResult E = getDerived().TransformExpr(C->getNumTeams());
10499 if (E.isInvalid())
10500 return nullptr;
10501 return getDerived().RebuildOMPNumTeamsClause(
10502 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10505 template <typename Derived>
10506 OMPClause *
10507 TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
10508 ExprResult E = getDerived().TransformExpr(C->getThreadLimit());
10509 if (E.isInvalid())
10510 return nullptr;
10511 return getDerived().RebuildOMPThreadLimitClause(
10512 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10515 template <typename Derived>
10516 OMPClause *
10517 TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
10518 ExprResult E = getDerived().TransformExpr(C->getPriority());
10519 if (E.isInvalid())
10520 return nullptr;
10521 return getDerived().RebuildOMPPriorityClause(
10522 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10525 template <typename Derived>
10526 OMPClause *
10527 TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
10528 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
10529 if (E.isInvalid())
10530 return nullptr;
10531 return getDerived().RebuildOMPGrainsizeClause(
10532 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10533 C->getModifierLoc(), C->getEndLoc());
10536 template <typename Derived>
10537 OMPClause *
10538 TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
10539 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
10540 if (E.isInvalid())
10541 return nullptr;
10542 return getDerived().RebuildOMPNumTasksClause(
10543 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10544 C->getModifierLoc(), C->getEndLoc());
10547 template <typename Derived>
10548 OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
10549 ExprResult E = getDerived().TransformExpr(C->getHint());
10550 if (E.isInvalid())
10551 return nullptr;
10552 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
10553 C->getLParenLoc(), C->getEndLoc());
10556 template <typename Derived>
10557 OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
10558 OMPDistScheduleClause *C) {
10559 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10560 if (E.isInvalid())
10561 return nullptr;
10562 return getDerived().RebuildOMPDistScheduleClause(
10563 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10564 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10567 template <typename Derived>
10568 OMPClause *
10569 TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
10570 // Rebuild Defaultmap Clause since we need to invoke the checking of
10571 // defaultmap(none:variable-category) after template initialization.
10572 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
10573 C->getDefaultmapKind(),
10574 C->getBeginLoc(),
10575 C->getLParenLoc(),
10576 C->getDefaultmapModifierLoc(),
10577 C->getDefaultmapKindLoc(),
10578 C->getEndLoc());
10581 template <typename Derived>
10582 OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
10583 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10584 llvm::SmallVector<Expr *, 16> Vars;
10585 CXXScopeSpec MapperIdScopeSpec;
10586 DeclarationNameInfo MapperIdInfo;
10587 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10588 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
10589 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10590 return nullptr;
10591 return getDerived().RebuildOMPToClause(
10592 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10593 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10596 template <typename Derived>
10597 OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
10598 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10599 llvm::SmallVector<Expr *, 16> Vars;
10600 CXXScopeSpec MapperIdScopeSpec;
10601 DeclarationNameInfo MapperIdInfo;
10602 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10603 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
10604 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10605 return nullptr;
10606 return getDerived().RebuildOMPFromClause(
10607 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10608 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10611 template <typename Derived>
10612 OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
10613 OMPUseDevicePtrClause *C) {
10614 llvm::SmallVector<Expr *, 16> Vars;
10615 Vars.reserve(C->varlist_size());
10616 for (auto *VE : C->varlists()) {
10617 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10618 if (EVar.isInvalid())
10619 return nullptr;
10620 Vars.push_back(EVar.get());
10622 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10623 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
10626 template <typename Derived>
10627 OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
10628 OMPUseDeviceAddrClause *C) {
10629 llvm::SmallVector<Expr *, 16> Vars;
10630 Vars.reserve(C->varlist_size());
10631 for (auto *VE : C->varlists()) {
10632 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10633 if (EVar.isInvalid())
10634 return nullptr;
10635 Vars.push_back(EVar.get());
10637 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10638 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
10641 template <typename Derived>
10642 OMPClause *
10643 TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
10644 llvm::SmallVector<Expr *, 16> Vars;
10645 Vars.reserve(C->varlist_size());
10646 for (auto *VE : C->varlists()) {
10647 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10648 if (EVar.isInvalid())
10649 return nullptr;
10650 Vars.push_back(EVar.get());
10652 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10653 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
10656 template <typename Derived>
10657 OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
10658 OMPHasDeviceAddrClause *C) {
10659 llvm::SmallVector<Expr *, 16> Vars;
10660 Vars.reserve(C->varlist_size());
10661 for (auto *VE : C->varlists()) {
10662 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10663 if (EVar.isInvalid())
10664 return nullptr;
10665 Vars.push_back(EVar.get());
10667 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10668 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
10671 template <typename Derived>
10672 OMPClause *
10673 TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
10674 llvm::SmallVector<Expr *, 16> Vars;
10675 Vars.reserve(C->varlist_size());
10676 for (auto *VE : C->varlists()) {
10677 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10678 if (EVar.isInvalid())
10679 return nullptr;
10680 Vars.push_back(EVar.get());
10682 return getDerived().RebuildOMPNontemporalClause(
10683 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10686 template <typename Derived>
10687 OMPClause *
10688 TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
10689 llvm::SmallVector<Expr *, 16> Vars;
10690 Vars.reserve(C->varlist_size());
10691 for (auto *VE : C->varlists()) {
10692 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10693 if (EVar.isInvalid())
10694 return nullptr;
10695 Vars.push_back(EVar.get());
10697 return getDerived().RebuildOMPInclusiveClause(
10698 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10701 template <typename Derived>
10702 OMPClause *
10703 TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
10704 llvm::SmallVector<Expr *, 16> Vars;
10705 Vars.reserve(C->varlist_size());
10706 for (auto *VE : C->varlists()) {
10707 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10708 if (EVar.isInvalid())
10709 return nullptr;
10710 Vars.push_back(EVar.get());
10712 return getDerived().RebuildOMPExclusiveClause(
10713 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10716 template <typename Derived>
10717 OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
10718 OMPUsesAllocatorsClause *C) {
10719 SmallVector<Sema::UsesAllocatorsData, 16> Data;
10720 Data.reserve(C->getNumberOfAllocators());
10721 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
10722 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
10723 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
10724 if (Allocator.isInvalid())
10725 continue;
10726 ExprResult AllocatorTraits;
10727 if (Expr *AT = D.AllocatorTraits) {
10728 AllocatorTraits = getDerived().TransformExpr(AT);
10729 if (AllocatorTraits.isInvalid())
10730 continue;
10732 Sema::UsesAllocatorsData &NewD = Data.emplace_back();
10733 NewD.Allocator = Allocator.get();
10734 NewD.AllocatorTraits = AllocatorTraits.get();
10735 NewD.LParenLoc = D.LParenLoc;
10736 NewD.RParenLoc = D.RParenLoc;
10738 return getDerived().RebuildOMPUsesAllocatorsClause(
10739 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10742 template <typename Derived>
10743 OMPClause *
10744 TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
10745 SmallVector<Expr *, 4> Locators;
10746 Locators.reserve(C->varlist_size());
10747 ExprResult ModifierRes;
10748 if (Expr *Modifier = C->getModifier()) {
10749 ModifierRes = getDerived().TransformExpr(Modifier);
10750 if (ModifierRes.isInvalid())
10751 return nullptr;
10753 for (Expr *E : C->varlists()) {
10754 ExprResult Locator = getDerived().TransformExpr(E);
10755 if (Locator.isInvalid())
10756 continue;
10757 Locators.push_back(Locator.get());
10759 return getDerived().RebuildOMPAffinityClause(
10760 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
10761 ModifierRes.get(), Locators);
10764 template <typename Derived>
10765 OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
10766 return getDerived().RebuildOMPOrderClause(
10767 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
10768 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
10771 template <typename Derived>
10772 OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
10773 return getDerived().RebuildOMPBindClause(
10774 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
10775 C->getLParenLoc(), C->getEndLoc());
10778 template <typename Derived>
10779 OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
10780 OMPXDynCGroupMemClause *C) {
10781 ExprResult Size = getDerived().TransformExpr(C->getSize());
10782 if (Size.isInvalid())
10783 return nullptr;
10784 return getDerived().RebuildOMPXDynCGroupMemClause(
10785 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10788 template <typename Derived>
10789 OMPClause *
10790 TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
10791 llvm::SmallVector<Expr *, 16> Vars;
10792 Vars.reserve(C->varlist_size());
10793 for (auto *VE : C->varlists()) {
10794 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10795 if (EVar.isInvalid())
10796 return nullptr;
10797 Vars.push_back(EVar.get());
10799 return getDerived().RebuildOMPDoacrossClause(
10800 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
10801 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10804 template <typename Derived>
10805 OMPClause *
10806 TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
10807 SmallVector<const Attr *> NewAttrs;
10808 for (auto *A : C->getAttrs())
10809 NewAttrs.push_back(getDerived().TransformAttr(A));
10810 return getDerived().RebuildOMPXAttributeClause(
10811 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10814 template <typename Derived>
10815 OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
10816 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
10819 //===----------------------------------------------------------------------===//
10820 // Expression transformation
10821 //===----------------------------------------------------------------------===//
10822 template<typename Derived>
10823 ExprResult
10824 TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
10825 return TransformExpr(E->getSubExpr());
10828 template <typename Derived>
10829 ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
10830 SYCLUniqueStableNameExpr *E) {
10831 if (!E->isTypeDependent())
10832 return E;
10834 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
10836 if (!NewT)
10837 return ExprError();
10839 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
10840 return E;
10842 return getDerived().RebuildSYCLUniqueStableNameExpr(
10843 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
10846 template<typename Derived>
10847 ExprResult
10848 TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
10849 if (!E->isTypeDependent())
10850 return E;
10852 return getDerived().RebuildPredefinedExpr(E->getLocation(),
10853 E->getIdentKind());
10856 template<typename Derived>
10857 ExprResult
10858 TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
10859 NestedNameSpecifierLoc QualifierLoc;
10860 if (E->getQualifierLoc()) {
10861 QualifierLoc
10862 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
10863 if (!QualifierLoc)
10864 return ExprError();
10867 ValueDecl *ND
10868 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
10869 E->getDecl()));
10870 if (!ND)
10871 return ExprError();
10873 NamedDecl *Found = ND;
10874 if (E->getFoundDecl() != E->getDecl()) {
10875 Found = cast_or_null<NamedDecl>(
10876 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
10877 if (!Found)
10878 return ExprError();
10881 DeclarationNameInfo NameInfo = E->getNameInfo();
10882 if (NameInfo.getName()) {
10883 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10884 if (!NameInfo.getName())
10885 return ExprError();
10888 if (!getDerived().AlwaysRebuild() &&
10889 QualifierLoc == E->getQualifierLoc() &&
10890 ND == E->getDecl() &&
10891 Found == E->getFoundDecl() &&
10892 NameInfo.getName() == E->getDecl()->getDeclName() &&
10893 !E->hasExplicitTemplateArgs()) {
10895 // Mark it referenced in the new context regardless.
10896 // FIXME: this is a bit instantiation-specific.
10897 SemaRef.MarkDeclRefReferenced(E);
10899 return E;
10902 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
10903 if (E->hasExplicitTemplateArgs()) {
10904 TemplateArgs = &TransArgs;
10905 TransArgs.setLAngleLoc(E->getLAngleLoc());
10906 TransArgs.setRAngleLoc(E->getRAngleLoc());
10907 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
10908 E->getNumTemplateArgs(),
10909 TransArgs))
10910 return ExprError();
10913 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
10914 Found, TemplateArgs);
10917 template<typename Derived>
10918 ExprResult
10919 TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
10920 return E;
10923 template <typename Derived>
10924 ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
10925 FixedPointLiteral *E) {
10926 return E;
10929 template<typename Derived>
10930 ExprResult
10931 TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
10932 return E;
10935 template<typename Derived>
10936 ExprResult
10937 TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
10938 return E;
10941 template<typename Derived>
10942 ExprResult
10943 TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
10944 return E;
10947 template<typename Derived>
10948 ExprResult
10949 TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
10950 return E;
10953 template<typename Derived>
10954 ExprResult
10955 TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
10956 return getDerived().TransformCallExpr(E);
10959 template<typename Derived>
10960 ExprResult
10961 TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
10962 ExprResult ControllingExpr;
10963 TypeSourceInfo *ControllingType = nullptr;
10964 if (E->isExprPredicate())
10965 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
10966 else
10967 ControllingType = getDerived().TransformType(E->getControllingType());
10969 if (ControllingExpr.isInvalid() && !ControllingType)
10970 return ExprError();
10972 SmallVector<Expr *, 4> AssocExprs;
10973 SmallVector<TypeSourceInfo *, 4> AssocTypes;
10974 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
10975 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
10976 if (TSI) {
10977 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
10978 if (!AssocType)
10979 return ExprError();
10980 AssocTypes.push_back(AssocType);
10981 } else {
10982 AssocTypes.push_back(nullptr);
10985 ExprResult AssocExpr =
10986 getDerived().TransformExpr(Assoc.getAssociationExpr());
10987 if (AssocExpr.isInvalid())
10988 return ExprError();
10989 AssocExprs.push_back(AssocExpr.get());
10992 if (!ControllingType)
10993 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
10994 E->getDefaultLoc(),
10995 E->getRParenLoc(),
10996 ControllingExpr.get(),
10997 AssocTypes,
10998 AssocExprs);
10999 return getDerived().RebuildGenericSelectionExpr(
11000 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
11001 ControllingType, AssocTypes, AssocExprs);
11004 template<typename Derived>
11005 ExprResult
11006 TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
11007 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
11008 if (SubExpr.isInvalid())
11009 return ExprError();
11011 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11012 return E;
11014 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
11015 E->getRParen());
11018 /// The operand of a unary address-of operator has special rules: it's
11019 /// allowed to refer to a non-static member of a class even if there's no 'this'
11020 /// object available.
11021 template<typename Derived>
11022 ExprResult
11023 TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
11024 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
11025 return getDerived().TransformDependentScopeDeclRefExpr(DRE, true, nullptr);
11026 else
11027 return getDerived().TransformExpr(E);
11030 template<typename Derived>
11031 ExprResult
11032 TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
11033 ExprResult SubExpr;
11034 if (E->getOpcode() == UO_AddrOf)
11035 SubExpr = TransformAddressOfOperand(E->getSubExpr());
11036 else
11037 SubExpr = TransformExpr(E->getSubExpr());
11038 if (SubExpr.isInvalid())
11039 return ExprError();
11041 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11042 return E;
11044 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
11045 E->getOpcode(),
11046 SubExpr.get());
11049 template<typename Derived>
11050 ExprResult
11051 TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
11052 // Transform the type.
11053 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
11054 if (!Type)
11055 return ExprError();
11057 // Transform all of the components into components similar to what the
11058 // parser uses.
11059 // FIXME: It would be slightly more efficient in the non-dependent case to
11060 // just map FieldDecls, rather than requiring the rebuilder to look for
11061 // the fields again. However, __builtin_offsetof is rare enough in
11062 // template code that we don't care.
11063 bool ExprChanged = false;
11064 typedef Sema::OffsetOfComponent Component;
11065 SmallVector<Component, 4> Components;
11066 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
11067 const OffsetOfNode &ON = E->getComponent(I);
11068 Component Comp;
11069 Comp.isBrackets = true;
11070 Comp.LocStart = ON.getSourceRange().getBegin();
11071 Comp.LocEnd = ON.getSourceRange().getEnd();
11072 switch (ON.getKind()) {
11073 case OffsetOfNode::Array: {
11074 Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
11075 ExprResult Index = getDerived().TransformExpr(FromIndex);
11076 if (Index.isInvalid())
11077 return ExprError();
11079 ExprChanged = ExprChanged || Index.get() != FromIndex;
11080 Comp.isBrackets = true;
11081 Comp.U.E = Index.get();
11082 break;
11085 case OffsetOfNode::Field:
11086 case OffsetOfNode::Identifier:
11087 Comp.isBrackets = false;
11088 Comp.U.IdentInfo = ON.getFieldName();
11089 if (!Comp.U.IdentInfo)
11090 continue;
11092 break;
11094 case OffsetOfNode::Base:
11095 // Will be recomputed during the rebuild.
11096 continue;
11099 Components.push_back(Comp);
11102 // If nothing changed, retain the existing expression.
11103 if (!getDerived().AlwaysRebuild() &&
11104 Type == E->getTypeSourceInfo() &&
11105 !ExprChanged)
11106 return E;
11108 // Build a new offsetof expression.
11109 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
11110 Components, E->getRParenLoc());
11113 template<typename Derived>
11114 ExprResult
11115 TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
11116 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
11117 "opaque value expression requires transformation");
11118 return E;
11121 template<typename Derived>
11122 ExprResult
11123 TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
11124 return E;
11127 template <typename Derived>
11128 ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
11129 llvm::SmallVector<Expr *, 8> Children;
11130 bool Changed = false;
11131 for (Expr *C : E->subExpressions()) {
11132 ExprResult NewC = getDerived().TransformExpr(C);
11133 if (NewC.isInvalid())
11134 return ExprError();
11135 Children.push_back(NewC.get());
11137 Changed |= NewC.get() != C;
11139 if (!getDerived().AlwaysRebuild() && !Changed)
11140 return E;
11141 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
11142 Children, E->getType());
11145 template<typename Derived>
11146 ExprResult
11147 TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
11148 // Rebuild the syntactic form. The original syntactic form has
11149 // opaque-value expressions in it, so strip those away and rebuild
11150 // the result. This is a really awful way of doing this, but the
11151 // better solution (rebuilding the semantic expressions and
11152 // rebinding OVEs as necessary) doesn't work; we'd need
11153 // TreeTransform to not strip away implicit conversions.
11154 Expr *newSyntacticForm = SemaRef.recreateSyntacticForm(E);
11155 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
11156 if (result.isInvalid()) return ExprError();
11158 // If that gives us a pseudo-object result back, the pseudo-object
11159 // expression must have been an lvalue-to-rvalue conversion which we
11160 // should reapply.
11161 if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
11162 result = SemaRef.checkPseudoObjectRValue(result.get());
11164 return result;
11167 template<typename Derived>
11168 ExprResult
11169 TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
11170 UnaryExprOrTypeTraitExpr *E) {
11171 if (E->isArgumentType()) {
11172 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
11174 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
11175 if (!NewT)
11176 return ExprError();
11178 if (!getDerived().AlwaysRebuild() && OldT == NewT)
11179 return E;
11181 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
11182 E->getKind(),
11183 E->getSourceRange());
11186 // C++0x [expr.sizeof]p1:
11187 // The operand is either an expression, which is an unevaluated operand
11188 // [...]
11189 EnterExpressionEvaluationContext Unevaluated(
11190 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
11191 Sema::ReuseLambdaContextDecl);
11193 // Try to recover if we have something like sizeof(T::X) where X is a type.
11194 // Notably, there must be *exactly* one set of parens if X is a type.
11195 TypeSourceInfo *RecoveryTSI = nullptr;
11196 ExprResult SubExpr;
11197 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
11198 if (auto *DRE =
11199 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
11200 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
11201 PE, DRE, false, &RecoveryTSI);
11202 else
11203 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
11205 if (RecoveryTSI) {
11206 return getDerived().RebuildUnaryExprOrTypeTrait(
11207 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
11208 } else if (SubExpr.isInvalid())
11209 return ExprError();
11211 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
11212 return E;
11214 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
11215 E->getOperatorLoc(),
11216 E->getKind(),
11217 E->getSourceRange());
11220 template<typename Derived>
11221 ExprResult
11222 TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
11223 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11224 if (LHS.isInvalid())
11225 return ExprError();
11227 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11228 if (RHS.isInvalid())
11229 return ExprError();
11232 if (!getDerived().AlwaysRebuild() &&
11233 LHS.get() == E->getLHS() &&
11234 RHS.get() == E->getRHS())
11235 return E;
11237 return getDerived().RebuildArraySubscriptExpr(
11238 LHS.get(),
11239 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
11242 template <typename Derived>
11243 ExprResult
11244 TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
11245 ExprResult Base = getDerived().TransformExpr(E->getBase());
11246 if (Base.isInvalid())
11247 return ExprError();
11249 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
11250 if (RowIdx.isInvalid())
11251 return ExprError();
11253 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
11254 if (ColumnIdx.isInvalid())
11255 return ExprError();
11257 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
11258 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
11259 return E;
11261 return getDerived().RebuildMatrixSubscriptExpr(
11262 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
11265 template <typename Derived>
11266 ExprResult
11267 TreeTransform<Derived>::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) {
11268 ExprResult Base = getDerived().TransformExpr(E->getBase());
11269 if (Base.isInvalid())
11270 return ExprError();
11272 ExprResult LowerBound;
11273 if (E->getLowerBound()) {
11274 LowerBound = getDerived().TransformExpr(E->getLowerBound());
11275 if (LowerBound.isInvalid())
11276 return ExprError();
11279 ExprResult Length;
11280 if (E->getLength()) {
11281 Length = getDerived().TransformExpr(E->getLength());
11282 if (Length.isInvalid())
11283 return ExprError();
11286 ExprResult Stride;
11287 if (Expr *Str = E->getStride()) {
11288 Stride = getDerived().TransformExpr(Str);
11289 if (Stride.isInvalid())
11290 return ExprError();
11293 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
11294 LowerBound.get() == E->getLowerBound() && Length.get() == E->getLength())
11295 return E;
11297 return getDerived().RebuildOMPArraySectionExpr(
11298 Base.get(), E->getBase()->getEndLoc(), LowerBound.get(),
11299 E->getColonLocFirst(), E->getColonLocSecond(), Length.get(), Stride.get(),
11300 E->getRBracketLoc());
11303 template <typename Derived>
11304 ExprResult
11305 TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
11306 ExprResult Base = getDerived().TransformExpr(E->getBase());
11307 if (Base.isInvalid())
11308 return ExprError();
11310 SmallVector<Expr *, 4> Dims;
11311 bool ErrorFound = false;
11312 for (Expr *Dim : E->getDimensions()) {
11313 ExprResult DimRes = getDerived().TransformExpr(Dim);
11314 if (DimRes.isInvalid()) {
11315 ErrorFound = true;
11316 continue;
11318 Dims.push_back(DimRes.get());
11321 if (ErrorFound)
11322 return ExprError();
11323 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
11324 E->getRParenLoc(), Dims,
11325 E->getBracketsRanges());
11328 template <typename Derived>
11329 ExprResult
11330 TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
11331 unsigned NumIterators = E->numOfIterators();
11332 SmallVector<Sema::OMPIteratorData, 4> Data(NumIterators);
11334 bool ErrorFound = false;
11335 bool NeedToRebuild = getDerived().AlwaysRebuild();
11336 for (unsigned I = 0; I < NumIterators; ++I) {
11337 auto *D = cast<VarDecl>(E->getIteratorDecl(I));
11338 Data[I].DeclIdent = D->getIdentifier();
11339 Data[I].DeclIdentLoc = D->getLocation();
11340 if (D->getLocation() == D->getBeginLoc()) {
11341 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
11342 "Implicit type must be int.");
11343 } else {
11344 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
11345 QualType DeclTy = getDerived().TransformType(D->getType());
11346 Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI);
11348 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
11349 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
11350 ExprResult End = getDerived().TransformExpr(Range.End);
11351 ExprResult Step = getDerived().TransformExpr(Range.Step);
11352 ErrorFound = ErrorFound ||
11353 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
11354 !Data[I].Type.get().isNull())) ||
11355 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
11356 if (ErrorFound)
11357 continue;
11358 Data[I].Range.Begin = Begin.get();
11359 Data[I].Range.End = End.get();
11360 Data[I].Range.Step = Step.get();
11361 Data[I].AssignLoc = E->getAssignLoc(I);
11362 Data[I].ColonLoc = E->getColonLoc(I);
11363 Data[I].SecColonLoc = E->getSecondColonLoc(I);
11364 NeedToRebuild =
11365 NeedToRebuild ||
11366 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
11367 D->getType().getTypePtrOrNull()) ||
11368 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
11369 Range.Step != Data[I].Range.Step;
11371 if (ErrorFound)
11372 return ExprError();
11373 if (!NeedToRebuild)
11374 return E;
11376 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
11377 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
11378 if (!Res.isUsable())
11379 return Res;
11380 auto *IE = cast<OMPIteratorExpr>(Res.get());
11381 for (unsigned I = 0; I < NumIterators; ++I)
11382 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
11383 IE->getIteratorDecl(I));
11384 return Res;
11387 template<typename Derived>
11388 ExprResult
11389 TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
11390 // Transform the callee.
11391 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
11392 if (Callee.isInvalid())
11393 return ExprError();
11395 // Transform arguments.
11396 bool ArgChanged = false;
11397 SmallVector<Expr*, 8> Args;
11398 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
11399 &ArgChanged))
11400 return ExprError();
11402 if (!getDerived().AlwaysRebuild() &&
11403 Callee.get() == E->getCallee() &&
11404 !ArgChanged)
11405 return SemaRef.MaybeBindToTemporary(E);
11407 // FIXME: Wrong source location information for the '('.
11408 SourceLocation FakeLParenLoc
11409 = ((Expr *)Callee.get())->getSourceRange().getBegin();
11411 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11412 if (E->hasStoredFPFeatures()) {
11413 FPOptionsOverride NewOverrides = E->getFPFeatures();
11414 getSema().CurFPFeatures =
11415 NewOverrides.applyOverrides(getSema().getLangOpts());
11416 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11419 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
11420 Args,
11421 E->getRParenLoc());
11424 template<typename Derived>
11425 ExprResult
11426 TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
11427 ExprResult Base = getDerived().TransformExpr(E->getBase());
11428 if (Base.isInvalid())
11429 return ExprError();
11431 NestedNameSpecifierLoc QualifierLoc;
11432 if (E->hasQualifier()) {
11433 QualifierLoc
11434 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
11436 if (!QualifierLoc)
11437 return ExprError();
11439 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
11441 ValueDecl *Member
11442 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
11443 E->getMemberDecl()));
11444 if (!Member)
11445 return ExprError();
11447 NamedDecl *FoundDecl = E->getFoundDecl();
11448 if (FoundDecl == E->getMemberDecl()) {
11449 FoundDecl = Member;
11450 } else {
11451 FoundDecl = cast_or_null<NamedDecl>(
11452 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
11453 if (!FoundDecl)
11454 return ExprError();
11457 if (!getDerived().AlwaysRebuild() &&
11458 Base.get() == E->getBase() &&
11459 QualifierLoc == E->getQualifierLoc() &&
11460 Member == E->getMemberDecl() &&
11461 FoundDecl == E->getFoundDecl() &&
11462 !E->hasExplicitTemplateArgs()) {
11464 // Skip for member expression of (this->f), rebuilt thisi->f is needed
11465 // for Openmp where the field need to be privatizized in the case.
11466 if (!(isa<CXXThisExpr>(E->getBase()) &&
11467 getSema().isOpenMPRebuildMemberExpr(cast<ValueDecl>(Member)))) {
11468 // Mark it referenced in the new context regardless.
11469 // FIXME: this is a bit instantiation-specific.
11470 SemaRef.MarkMemberReferenced(E);
11471 return E;
11475 TemplateArgumentListInfo TransArgs;
11476 if (E->hasExplicitTemplateArgs()) {
11477 TransArgs.setLAngleLoc(E->getLAngleLoc());
11478 TransArgs.setRAngleLoc(E->getRAngleLoc());
11479 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
11480 E->getNumTemplateArgs(),
11481 TransArgs))
11482 return ExprError();
11485 // FIXME: Bogus source location for the operator
11486 SourceLocation FakeOperatorLoc =
11487 SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
11489 // FIXME: to do this check properly, we will need to preserve the
11490 // first-qualifier-in-scope here, just in case we had a dependent
11491 // base (and therefore couldn't do the check) and a
11492 // nested-name-qualifier (and therefore could do the lookup).
11493 NamedDecl *FirstQualifierInScope = nullptr;
11494 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
11495 if (MemberNameInfo.getName()) {
11496 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
11497 if (!MemberNameInfo.getName())
11498 return ExprError();
11501 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
11502 E->isArrow(),
11503 QualifierLoc,
11504 TemplateKWLoc,
11505 MemberNameInfo,
11506 Member,
11507 FoundDecl,
11508 (E->hasExplicitTemplateArgs()
11509 ? &TransArgs : nullptr),
11510 FirstQualifierInScope);
11513 template<typename Derived>
11514 ExprResult
11515 TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
11516 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11517 if (LHS.isInvalid())
11518 return ExprError();
11520 ExprResult RHS =
11521 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
11522 if (RHS.isInvalid())
11523 return ExprError();
11525 if (!getDerived().AlwaysRebuild() &&
11526 LHS.get() == E->getLHS() &&
11527 RHS.get() == E->getRHS())
11528 return E;
11530 if (E->isCompoundAssignmentOp())
11531 // FPFeatures has already been established from trailing storage
11532 return getDerived().RebuildBinaryOperator(
11533 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
11534 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11535 FPOptionsOverride NewOverrides(E->getFPFeatures());
11536 getSema().CurFPFeatures =
11537 NewOverrides.applyOverrides(getSema().getLangOpts());
11538 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11539 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
11540 LHS.get(), RHS.get());
11543 template <typename Derived>
11544 ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
11545 CXXRewrittenBinaryOperator *E) {
11546 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
11548 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
11549 if (LHS.isInvalid())
11550 return ExprError();
11552 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
11553 if (RHS.isInvalid())
11554 return ExprError();
11556 // Extract the already-resolved callee declarations so that we can restrict
11557 // ourselves to using them as the unqualified lookup results when rebuilding.
11558 UnresolvedSet<2> UnqualLookups;
11559 bool ChangedAnyLookups = false;
11560 Expr *PossibleBinOps[] = {E->getSemanticForm(),
11561 const_cast<Expr *>(Decomp.InnerBinOp)};
11562 for (Expr *PossibleBinOp : PossibleBinOps) {
11563 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());
11564 if (!Op)
11565 continue;
11566 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());
11567 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))
11568 continue;
11570 // Transform the callee in case we built a call to a local extern
11571 // declaration.
11572 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
11573 E->getOperatorLoc(), Callee->getFoundDecl()));
11574 if (!Found)
11575 return ExprError();
11576 if (Found != Callee->getFoundDecl())
11577 ChangedAnyLookups = true;
11578 UnqualLookups.addDecl(Found);
11581 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
11582 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
11583 // Mark all functions used in the rewrite as referenced. Note that when
11584 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
11585 // function calls, and/or there might be a user-defined conversion sequence
11586 // applied to the operands of the <.
11587 // FIXME: this is a bit instantiation-specific.
11588 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
11589 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);
11590 return E;
11593 return getDerived().RebuildCXXRewrittenBinaryOperator(
11594 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
11597 template<typename Derived>
11598 ExprResult
11599 TreeTransform<Derived>::TransformCompoundAssignOperator(
11600 CompoundAssignOperator *E) {
11601 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11602 FPOptionsOverride NewOverrides(E->getFPFeatures());
11603 getSema().CurFPFeatures =
11604 NewOverrides.applyOverrides(getSema().getLangOpts());
11605 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11606 return getDerived().TransformBinaryOperator(E);
11609 template<typename Derived>
11610 ExprResult TreeTransform<Derived>::
11611 TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
11612 // Just rebuild the common and RHS expressions and see whether we
11613 // get any changes.
11615 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
11616 if (commonExpr.isInvalid())
11617 return ExprError();
11619 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
11620 if (rhs.isInvalid())
11621 return ExprError();
11623 if (!getDerived().AlwaysRebuild() &&
11624 commonExpr.get() == e->getCommon() &&
11625 rhs.get() == e->getFalseExpr())
11626 return e;
11628 return getDerived().RebuildConditionalOperator(commonExpr.get(),
11629 e->getQuestionLoc(),
11630 nullptr,
11631 e->getColonLoc(),
11632 rhs.get());
11635 template<typename Derived>
11636 ExprResult
11637 TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
11638 ExprResult Cond = getDerived().TransformExpr(E->getCond());
11639 if (Cond.isInvalid())
11640 return ExprError();
11642 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11643 if (LHS.isInvalid())
11644 return ExprError();
11646 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11647 if (RHS.isInvalid())
11648 return ExprError();
11650 if (!getDerived().AlwaysRebuild() &&
11651 Cond.get() == E->getCond() &&
11652 LHS.get() == E->getLHS() &&
11653 RHS.get() == E->getRHS())
11654 return E;
11656 return getDerived().RebuildConditionalOperator(Cond.get(),
11657 E->getQuestionLoc(),
11658 LHS.get(),
11659 E->getColonLoc(),
11660 RHS.get());
11663 template<typename Derived>
11664 ExprResult
11665 TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
11666 // Implicit casts are eliminated during transformation, since they
11667 // will be recomputed by semantic analysis after transformation.
11668 return getDerived().TransformExpr(E->getSubExprAsWritten());
11671 template<typename Derived>
11672 ExprResult
11673 TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
11674 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
11675 if (!Type)
11676 return ExprError();
11678 ExprResult SubExpr
11679 = getDerived().TransformExpr(E->getSubExprAsWritten());
11680 if (SubExpr.isInvalid())
11681 return ExprError();
11683 if (!getDerived().AlwaysRebuild() &&
11684 Type == E->getTypeInfoAsWritten() &&
11685 SubExpr.get() == E->getSubExpr())
11686 return E;
11688 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
11689 Type,
11690 E->getRParenLoc(),
11691 SubExpr.get());
11694 template<typename Derived>
11695 ExprResult
11696 TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
11697 TypeSourceInfo *OldT = E->getTypeSourceInfo();
11698 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
11699 if (!NewT)
11700 return ExprError();
11702 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
11703 if (Init.isInvalid())
11704 return ExprError();
11706 if (!getDerived().AlwaysRebuild() &&
11707 OldT == NewT &&
11708 Init.get() == E->getInitializer())
11709 return SemaRef.MaybeBindToTemporary(E);
11711 // Note: the expression type doesn't necessarily match the
11712 // type-as-written, but that's okay, because it should always be
11713 // derivable from the initializer.
11715 return getDerived().RebuildCompoundLiteralExpr(
11716 E->getLParenLoc(), NewT,
11717 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
11720 template<typename Derived>
11721 ExprResult
11722 TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
11723 ExprResult Base = getDerived().TransformExpr(E->getBase());
11724 if (Base.isInvalid())
11725 return ExprError();
11727 if (!getDerived().AlwaysRebuild() &&
11728 Base.get() == E->getBase())
11729 return E;
11731 // FIXME: Bad source location
11732 SourceLocation FakeOperatorLoc =
11733 SemaRef.getLocForEndOfToken(E->getBase()->getEndLoc());
11734 return getDerived().RebuildExtVectorElementExpr(
11735 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
11736 E->getAccessor());
11739 template<typename Derived>
11740 ExprResult
11741 TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
11742 if (InitListExpr *Syntactic = E->getSyntacticForm())
11743 E = Syntactic;
11745 bool InitChanged = false;
11747 EnterExpressionEvaluationContext Context(
11748 getSema(), EnterExpressionEvaluationContext::InitList);
11750 SmallVector<Expr*, 4> Inits;
11751 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
11752 Inits, &InitChanged))
11753 return ExprError();
11755 if (!getDerived().AlwaysRebuild() && !InitChanged) {
11756 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
11757 // in some cases. We can't reuse it in general, because the syntactic and
11758 // semantic forms are linked, and we can't know that semantic form will
11759 // match even if the syntactic form does.
11762 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
11763 E->getRBraceLoc());
11766 template<typename Derived>
11767 ExprResult
11768 TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
11769 Designation Desig;
11771 // transform the initializer value
11772 ExprResult Init = getDerived().TransformExpr(E->getInit());
11773 if (Init.isInvalid())
11774 return ExprError();
11776 // transform the designators.
11777 SmallVector<Expr*, 4> ArrayExprs;
11778 bool ExprChanged = false;
11779 for (const DesignatedInitExpr::Designator &D : E->designators()) {
11780 if (D.isFieldDesignator()) {
11781 if (D.getFieldDecl()) {
11782 FieldDecl *Field = cast_or_null<FieldDecl>(
11783 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
11784 if (Field != D.getFieldDecl())
11785 // Rebuild the expression when the transformed FieldDecl is
11786 // different to the already assigned FieldDecl.
11787 ExprChanged = true;
11788 if (Field->isAnonymousStructOrUnion())
11789 continue;
11790 } else {
11791 // Ensure that the designator expression is rebuilt when there isn't
11792 // a resolved FieldDecl in the designator as we don't want to assign
11793 // a FieldDecl to a pattern designator that will be instantiated again.
11794 ExprChanged = true;
11796 Desig.AddDesignator(Designator::CreateFieldDesignator(
11797 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
11798 continue;
11801 if (D.isArrayDesignator()) {
11802 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
11803 if (Index.isInvalid())
11804 return ExprError();
11806 Desig.AddDesignator(
11807 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
11809 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
11810 ArrayExprs.push_back(Index.get());
11811 continue;
11814 assert(D.isArrayRangeDesignator() && "New kind of designator?");
11815 ExprResult Start
11816 = getDerived().TransformExpr(E->getArrayRangeStart(D));
11817 if (Start.isInvalid())
11818 return ExprError();
11820 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
11821 if (End.isInvalid())
11822 return ExprError();
11824 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
11825 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
11827 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
11828 End.get() != E->getArrayRangeEnd(D);
11830 ArrayExprs.push_back(Start.get());
11831 ArrayExprs.push_back(End.get());
11834 if (!getDerived().AlwaysRebuild() &&
11835 Init.get() == E->getInit() &&
11836 !ExprChanged)
11837 return E;
11839 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
11840 E->getEqualOrColonLoc(),
11841 E->usesGNUSyntax(), Init.get());
11844 // Seems that if TransformInitListExpr() only works on the syntactic form of an
11845 // InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
11846 template<typename Derived>
11847 ExprResult
11848 TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
11849 DesignatedInitUpdateExpr *E) {
11850 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
11851 "initializer");
11852 return ExprError();
11855 template<typename Derived>
11856 ExprResult
11857 TreeTransform<Derived>::TransformNoInitExpr(
11858 NoInitExpr *E) {
11859 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
11860 return ExprError();
11863 template<typename Derived>
11864 ExprResult
11865 TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
11866 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
11867 return ExprError();
11870 template<typename Derived>
11871 ExprResult
11872 TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
11873 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
11874 return ExprError();
11877 template<typename Derived>
11878 ExprResult
11879 TreeTransform<Derived>::TransformImplicitValueInitExpr(
11880 ImplicitValueInitExpr *E) {
11881 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
11883 // FIXME: Will we ever have proper type location here? Will we actually
11884 // need to transform the type?
11885 QualType T = getDerived().TransformType(E->getType());
11886 if (T.isNull())
11887 return ExprError();
11889 if (!getDerived().AlwaysRebuild() &&
11890 T == E->getType())
11891 return E;
11893 return getDerived().RebuildImplicitValueInitExpr(T);
11896 template<typename Derived>
11897 ExprResult
11898 TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
11899 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
11900 if (!TInfo)
11901 return ExprError();
11903 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
11904 if (SubExpr.isInvalid())
11905 return ExprError();
11907 if (!getDerived().AlwaysRebuild() &&
11908 TInfo == E->getWrittenTypeInfo() &&
11909 SubExpr.get() == E->getSubExpr())
11910 return E;
11912 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
11913 TInfo, E->getRParenLoc());
11916 template<typename Derived>
11917 ExprResult
11918 TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
11919 bool ArgumentChanged = false;
11920 SmallVector<Expr*, 4> Inits;
11921 if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits,
11922 &ArgumentChanged))
11923 return ExprError();
11925 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
11926 Inits,
11927 E->getRParenLoc());
11930 /// Transform an address-of-label expression.
11932 /// By default, the transformation of an address-of-label expression always
11933 /// rebuilds the expression, so that the label identifier can be resolved to
11934 /// the corresponding label statement by semantic analysis.
11935 template<typename Derived>
11936 ExprResult
11937 TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
11938 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
11939 E->getLabel());
11940 if (!LD)
11941 return ExprError();
11943 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
11944 cast<LabelDecl>(LD));
11947 template<typename Derived>
11948 ExprResult
11949 TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
11950 SemaRef.ActOnStartStmtExpr();
11951 StmtResult SubStmt
11952 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
11953 if (SubStmt.isInvalid()) {
11954 SemaRef.ActOnStmtExprError();
11955 return ExprError();
11958 unsigned OldDepth = E->getTemplateDepth();
11959 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
11961 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
11962 SubStmt.get() == E->getSubStmt()) {
11963 // Calling this an 'error' is unintuitive, but it does the right thing.
11964 SemaRef.ActOnStmtExprError();
11965 return SemaRef.MaybeBindToTemporary(E);
11968 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
11969 E->getRParenLoc(), NewDepth);
11972 template<typename Derived>
11973 ExprResult
11974 TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
11975 ExprResult Cond = getDerived().TransformExpr(E->getCond());
11976 if (Cond.isInvalid())
11977 return ExprError();
11979 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11980 if (LHS.isInvalid())
11981 return ExprError();
11983 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11984 if (RHS.isInvalid())
11985 return ExprError();
11987 if (!getDerived().AlwaysRebuild() &&
11988 Cond.get() == E->getCond() &&
11989 LHS.get() == E->getLHS() &&
11990 RHS.get() == E->getRHS())
11991 return E;
11993 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
11994 Cond.get(), LHS.get(), RHS.get(),
11995 E->getRParenLoc());
11998 template<typename Derived>
11999 ExprResult
12000 TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
12001 return E;
12004 template<typename Derived>
12005 ExprResult
12006 TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
12007 switch (E->getOperator()) {
12008 case OO_New:
12009 case OO_Delete:
12010 case OO_Array_New:
12011 case OO_Array_Delete:
12012 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
12014 case OO_Subscript:
12015 case OO_Call: {
12016 // This is a call to an object's operator().
12017 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
12019 // Transform the object itself.
12020 ExprResult Object = getDerived().TransformExpr(E->getArg(0));
12021 if (Object.isInvalid())
12022 return ExprError();
12024 // FIXME: Poor location information
12025 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
12026 static_cast<Expr *>(Object.get())->getEndLoc());
12028 // Transform the call arguments.
12029 SmallVector<Expr*, 8> Args;
12030 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
12031 Args))
12032 return ExprError();
12034 if (E->getOperator() == OO_Subscript)
12035 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
12036 Args, E->getEndLoc());
12038 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
12039 E->getEndLoc());
12042 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
12043 case OO_##Name: \
12044 break;
12046 #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
12047 #include "clang/Basic/OperatorKinds.def"
12049 case OO_Conditional:
12050 llvm_unreachable("conditional operator is not actually overloadable");
12052 case OO_None:
12053 case NUM_OVERLOADED_OPERATORS:
12054 llvm_unreachable("not an overloaded operator?");
12057 ExprResult First;
12058 if (E->getOperator() == OO_Amp)
12059 First = getDerived().TransformAddressOfOperand(E->getArg(0));
12060 else
12061 First = getDerived().TransformExpr(E->getArg(0));
12062 if (First.isInvalid())
12063 return ExprError();
12065 ExprResult Second;
12066 if (E->getNumArgs() == 2) {
12067 Second =
12068 getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);
12069 if (Second.isInvalid())
12070 return ExprError();
12073 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12074 FPOptionsOverride NewOverrides(E->getFPFeatures());
12075 getSema().CurFPFeatures =
12076 NewOverrides.applyOverrides(getSema().getLangOpts());
12077 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12079 Expr *Callee = E->getCallee();
12080 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
12081 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
12082 Sema::LookupOrdinaryName);
12083 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
12084 return ExprError();
12086 return getDerived().RebuildCXXOperatorCallExpr(
12087 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
12088 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
12091 UnresolvedSet<1> Functions;
12092 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
12093 Callee = ICE->getSubExprAsWritten();
12094 NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();
12095 ValueDecl *VD = cast_or_null<ValueDecl>(
12096 getDerived().TransformDecl(DR->getLocation(), DR));
12097 if (!VD)
12098 return ExprError();
12100 if (!isa<CXXMethodDecl>(VD))
12101 Functions.addDecl(VD);
12103 return getDerived().RebuildCXXOperatorCallExpr(
12104 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
12105 /*RequiresADL=*/false, Functions, First.get(), Second.get());
12108 template<typename Derived>
12109 ExprResult
12110 TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
12111 return getDerived().TransformCallExpr(E);
12114 template <typename Derived>
12115 ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
12116 bool NeedRebuildFunc = E->getIdentKind() == SourceLocExpr::Function &&
12117 getSema().CurContext != E->getParentContext();
12119 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
12120 return E;
12122 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
12123 E->getBeginLoc(), E->getEndLoc(),
12124 getSema().CurContext);
12127 template<typename Derived>
12128 ExprResult
12129 TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
12130 // Transform the callee.
12131 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
12132 if (Callee.isInvalid())
12133 return ExprError();
12135 // Transform exec config.
12136 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
12137 if (EC.isInvalid())
12138 return ExprError();
12140 // Transform arguments.
12141 bool ArgChanged = false;
12142 SmallVector<Expr*, 8> Args;
12143 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
12144 &ArgChanged))
12145 return ExprError();
12147 if (!getDerived().AlwaysRebuild() &&
12148 Callee.get() == E->getCallee() &&
12149 !ArgChanged)
12150 return SemaRef.MaybeBindToTemporary(E);
12152 // FIXME: Wrong source location information for the '('.
12153 SourceLocation FakeLParenLoc
12154 = ((Expr *)Callee.get())->getSourceRange().getBegin();
12155 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
12156 Args,
12157 E->getRParenLoc(), EC.get());
12160 template<typename Derived>
12161 ExprResult
12162 TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
12163 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
12164 if (!Type)
12165 return ExprError();
12167 ExprResult SubExpr
12168 = getDerived().TransformExpr(E->getSubExprAsWritten());
12169 if (SubExpr.isInvalid())
12170 return ExprError();
12172 if (!getDerived().AlwaysRebuild() &&
12173 Type == E->getTypeInfoAsWritten() &&
12174 SubExpr.get() == E->getSubExpr())
12175 return E;
12176 return getDerived().RebuildCXXNamedCastExpr(
12177 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
12178 Type, E->getAngleBrackets().getEnd(),
12179 // FIXME. this should be '(' location
12180 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
12183 template<typename Derived>
12184 ExprResult
12185 TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
12186 TypeSourceInfo *TSI =
12187 getDerived().TransformType(BCE->getTypeInfoAsWritten());
12188 if (!TSI)
12189 return ExprError();
12191 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
12192 if (Sub.isInvalid())
12193 return ExprError();
12195 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
12196 Sub.get(), BCE->getEndLoc());
12199 template<typename Derived>
12200 ExprResult
12201 TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
12202 return getDerived().TransformCXXNamedCastExpr(E);
12205 template<typename Derived>
12206 ExprResult
12207 TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
12208 return getDerived().TransformCXXNamedCastExpr(E);
12211 template<typename Derived>
12212 ExprResult
12213 TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
12214 CXXReinterpretCastExpr *E) {
12215 return getDerived().TransformCXXNamedCastExpr(E);
12218 template<typename Derived>
12219 ExprResult
12220 TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
12221 return getDerived().TransformCXXNamedCastExpr(E);
12224 template<typename Derived>
12225 ExprResult
12226 TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
12227 return getDerived().TransformCXXNamedCastExpr(E);
12230 template<typename Derived>
12231 ExprResult
12232 TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
12233 CXXFunctionalCastExpr *E) {
12234 TypeSourceInfo *Type =
12235 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
12236 if (!Type)
12237 return ExprError();
12239 ExprResult SubExpr
12240 = getDerived().TransformExpr(E->getSubExprAsWritten());
12241 if (SubExpr.isInvalid())
12242 return ExprError();
12244 if (!getDerived().AlwaysRebuild() &&
12245 Type == E->getTypeInfoAsWritten() &&
12246 SubExpr.get() == E->getSubExpr())
12247 return E;
12249 return getDerived().RebuildCXXFunctionalCastExpr(Type,
12250 E->getLParenLoc(),
12251 SubExpr.get(),
12252 E->getRParenLoc(),
12253 E->isListInitialization());
12256 template<typename Derived>
12257 ExprResult
12258 TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
12259 if (E->isTypeOperand()) {
12260 TypeSourceInfo *TInfo
12261 = getDerived().TransformType(E->getTypeOperandSourceInfo());
12262 if (!TInfo)
12263 return ExprError();
12265 if (!getDerived().AlwaysRebuild() &&
12266 TInfo == E->getTypeOperandSourceInfo())
12267 return E;
12269 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
12270 TInfo, E->getEndLoc());
12273 // Typeid's operand is an unevaluated context, unless it's a polymorphic
12274 // type. We must not unilaterally enter unevaluated context here, as then
12275 // semantic processing can re-transform an already transformed operand.
12276 Expr *Op = E->getExprOperand();
12277 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
12278 if (E->isGLValue())
12279 if (auto *RecordT = Op->getType()->getAs<RecordType>())
12280 if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
12281 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
12283 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
12284 Sema::ReuseLambdaContextDecl);
12286 ExprResult SubExpr = getDerived().TransformExpr(Op);
12287 if (SubExpr.isInvalid())
12288 return ExprError();
12290 if (!getDerived().AlwaysRebuild() &&
12291 SubExpr.get() == E->getExprOperand())
12292 return E;
12294 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
12295 SubExpr.get(), E->getEndLoc());
12298 template<typename Derived>
12299 ExprResult
12300 TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
12301 if (E->isTypeOperand()) {
12302 TypeSourceInfo *TInfo
12303 = getDerived().TransformType(E->getTypeOperandSourceInfo());
12304 if (!TInfo)
12305 return ExprError();
12307 if (!getDerived().AlwaysRebuild() &&
12308 TInfo == E->getTypeOperandSourceInfo())
12309 return E;
12311 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
12312 TInfo, E->getEndLoc());
12315 EnterExpressionEvaluationContext Unevaluated(
12316 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
12318 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
12319 if (SubExpr.isInvalid())
12320 return ExprError();
12322 if (!getDerived().AlwaysRebuild() &&
12323 SubExpr.get() == E->getExprOperand())
12324 return E;
12326 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
12327 SubExpr.get(), E->getEndLoc());
12330 template<typename Derived>
12331 ExprResult
12332 TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
12333 return E;
12336 template<typename Derived>
12337 ExprResult
12338 TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
12339 CXXNullPtrLiteralExpr *E) {
12340 return E;
12343 template<typename Derived>
12344 ExprResult
12345 TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
12347 // In lambdas, the qualifiers of the type depends of where in
12348 // the call operator `this` appear, and we do not have a good way to
12349 // rebuild this information, so we transform the type.
12351 // In other contexts, the type of `this` may be overrided
12352 // for type deduction, so we need to recompute it.
12353 QualType T = getSema().getCurLambda() ?
12354 getDerived().TransformType(E->getType())
12355 : getSema().getCurrentThisType();
12357 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
12358 // Mark it referenced in the new context regardless.
12359 // FIXME: this is a bit instantiation-specific.
12360 getSema().MarkThisReferenced(E);
12361 return E;
12364 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
12367 template<typename Derived>
12368 ExprResult
12369 TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
12370 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12371 if (SubExpr.isInvalid())
12372 return ExprError();
12374 if (!getDerived().AlwaysRebuild() &&
12375 SubExpr.get() == E->getSubExpr())
12376 return E;
12378 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
12379 E->isThrownVariableInScope());
12382 template<typename Derived>
12383 ExprResult
12384 TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
12385 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
12386 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
12387 if (!Param)
12388 return ExprError();
12390 ExprResult InitRes;
12391 if (E->hasRewrittenInit()) {
12392 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
12393 if (InitRes.isInvalid())
12394 return ExprError();
12397 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
12398 E->getUsedContext() == SemaRef.CurContext &&
12399 InitRes.get() == E->getRewrittenExpr())
12400 return E;
12402 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
12403 InitRes.get());
12406 template<typename Derived>
12407 ExprResult
12408 TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
12409 FieldDecl *Field = cast_or_null<FieldDecl>(
12410 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
12411 if (!Field)
12412 return ExprError();
12414 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
12415 E->getUsedContext() == SemaRef.CurContext)
12416 return E;
12418 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
12421 template<typename Derived>
12422 ExprResult
12423 TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
12424 CXXScalarValueInitExpr *E) {
12425 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
12426 if (!T)
12427 return ExprError();
12429 if (!getDerived().AlwaysRebuild() &&
12430 T == E->getTypeSourceInfo())
12431 return E;
12433 return getDerived().RebuildCXXScalarValueInitExpr(T,
12434 /*FIXME:*/T->getTypeLoc().getEndLoc(),
12435 E->getRParenLoc());
12438 template<typename Derived>
12439 ExprResult
12440 TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
12441 // Transform the type that we're allocating
12442 TypeSourceInfo *AllocTypeInfo =
12443 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
12444 if (!AllocTypeInfo)
12445 return ExprError();
12447 // Transform the size of the array we're allocating (if any).
12448 std::optional<Expr *> ArraySize;
12449 if (E->isArray()) {
12450 ExprResult NewArraySize;
12451 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
12452 NewArraySize = getDerived().TransformExpr(*OldArraySize);
12453 if (NewArraySize.isInvalid())
12454 return ExprError();
12456 ArraySize = NewArraySize.get();
12459 // Transform the placement arguments (if any).
12460 bool ArgumentChanged = false;
12461 SmallVector<Expr*, 8> PlacementArgs;
12462 if (getDerived().TransformExprs(E->getPlacementArgs(),
12463 E->getNumPlacementArgs(), true,
12464 PlacementArgs, &ArgumentChanged))
12465 return ExprError();
12467 // Transform the initializer (if any).
12468 Expr *OldInit = E->getInitializer();
12469 ExprResult NewInit;
12470 if (OldInit)
12471 NewInit = getDerived().TransformInitializer(OldInit, true);
12472 if (NewInit.isInvalid())
12473 return ExprError();
12475 // Transform new operator and delete operator.
12476 FunctionDecl *OperatorNew = nullptr;
12477 if (E->getOperatorNew()) {
12478 OperatorNew = cast_or_null<FunctionDecl>(
12479 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
12480 if (!OperatorNew)
12481 return ExprError();
12484 FunctionDecl *OperatorDelete = nullptr;
12485 if (E->getOperatorDelete()) {
12486 OperatorDelete = cast_or_null<FunctionDecl>(
12487 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
12488 if (!OperatorDelete)
12489 return ExprError();
12492 if (!getDerived().AlwaysRebuild() &&
12493 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
12494 ArraySize == E->getArraySize() &&
12495 NewInit.get() == OldInit &&
12496 OperatorNew == E->getOperatorNew() &&
12497 OperatorDelete == E->getOperatorDelete() &&
12498 !ArgumentChanged) {
12499 // Mark any declarations we need as referenced.
12500 // FIXME: instantiation-specific.
12501 if (OperatorNew)
12502 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorNew);
12503 if (OperatorDelete)
12504 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
12506 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
12507 QualType ElementType
12508 = SemaRef.Context.getBaseElementType(E->getAllocatedType());
12509 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
12510 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
12511 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
12512 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor);
12517 return E;
12520 QualType AllocType = AllocTypeInfo->getType();
12521 if (!ArraySize) {
12522 // If no array size was specified, but the new expression was
12523 // instantiated with an array type (e.g., "new T" where T is
12524 // instantiated with "int[4]"), extract the outer bound from the
12525 // array type as our array size. We do this with constant and
12526 // dependently-sized array types.
12527 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);
12528 if (!ArrayT) {
12529 // Do nothing
12530 } else if (const ConstantArrayType *ConsArrayT
12531 = dyn_cast<ConstantArrayType>(ArrayT)) {
12532 ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),
12533 SemaRef.Context.getSizeType(),
12534 /*FIXME:*/ E->getBeginLoc());
12535 AllocType = ConsArrayT->getElementType();
12536 } else if (const DependentSizedArrayType *DepArrayT
12537 = dyn_cast<DependentSizedArrayType>(ArrayT)) {
12538 if (DepArrayT->getSizeExpr()) {
12539 ArraySize = DepArrayT->getSizeExpr();
12540 AllocType = DepArrayT->getElementType();
12545 return getDerived().RebuildCXXNewExpr(
12546 E->getBeginLoc(), E->isGlobalNew(),
12547 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
12548 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
12549 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
12552 template<typename Derived>
12553 ExprResult
12554 TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
12555 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
12556 if (Operand.isInvalid())
12557 return ExprError();
12559 // Transform the delete operator, if known.
12560 FunctionDecl *OperatorDelete = nullptr;
12561 if (E->getOperatorDelete()) {
12562 OperatorDelete = cast_or_null<FunctionDecl>(
12563 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
12564 if (!OperatorDelete)
12565 return ExprError();
12568 if (!getDerived().AlwaysRebuild() &&
12569 Operand.get() == E->getArgument() &&
12570 OperatorDelete == E->getOperatorDelete()) {
12571 // Mark any declarations we need as referenced.
12572 // FIXME: instantiation-specific.
12573 if (OperatorDelete)
12574 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
12576 if (!E->getArgument()->isTypeDependent()) {
12577 QualType Destroyed = SemaRef.Context.getBaseElementType(
12578 E->getDestroyedType());
12579 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
12580 CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
12581 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
12582 SemaRef.LookupDestructor(Record));
12586 return E;
12589 return getDerived().RebuildCXXDeleteExpr(
12590 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
12593 template<typename Derived>
12594 ExprResult
12595 TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
12596 CXXPseudoDestructorExpr *E) {
12597 ExprResult Base = getDerived().TransformExpr(E->getBase());
12598 if (Base.isInvalid())
12599 return ExprError();
12601 ParsedType ObjectTypePtr;
12602 bool MayBePseudoDestructor = false;
12603 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
12604 E->getOperatorLoc(),
12605 E->isArrow()? tok::arrow : tok::period,
12606 ObjectTypePtr,
12607 MayBePseudoDestructor);
12608 if (Base.isInvalid())
12609 return ExprError();
12611 QualType ObjectType = ObjectTypePtr.get();
12612 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
12613 if (QualifierLoc) {
12614 QualifierLoc
12615 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
12616 if (!QualifierLoc)
12617 return ExprError();
12619 CXXScopeSpec SS;
12620 SS.Adopt(QualifierLoc);
12622 PseudoDestructorTypeStorage Destroyed;
12623 if (E->getDestroyedTypeInfo()) {
12624 TypeSourceInfo *DestroyedTypeInfo
12625 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
12626 ObjectType, nullptr, SS);
12627 if (!DestroyedTypeInfo)
12628 return ExprError();
12629 Destroyed = DestroyedTypeInfo;
12630 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
12631 // We aren't likely to be able to resolve the identifier down to a type
12632 // now anyway, so just retain the identifier.
12633 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
12634 E->getDestroyedTypeLoc());
12635 } else {
12636 // Look for a destructor known with the given name.
12637 ParsedType T = SemaRef.getDestructorName(
12638 *E->getDestroyedTypeIdentifier(), E->getDestroyedTypeLoc(),
12639 /*Scope=*/nullptr, SS, ObjectTypePtr, false);
12640 if (!T)
12641 return ExprError();
12643 Destroyed
12644 = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),
12645 E->getDestroyedTypeLoc());
12648 TypeSourceInfo *ScopeTypeInfo = nullptr;
12649 if (E->getScopeTypeInfo()) {
12650 CXXScopeSpec EmptySS;
12651 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
12652 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
12653 if (!ScopeTypeInfo)
12654 return ExprError();
12657 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
12658 E->getOperatorLoc(),
12659 E->isArrow(),
12661 ScopeTypeInfo,
12662 E->getColonColonLoc(),
12663 E->getTildeLoc(),
12664 Destroyed);
12667 template <typename Derived>
12668 bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
12669 bool RequiresADL,
12670 LookupResult &R) {
12671 // Transform all the decls.
12672 bool AllEmptyPacks = true;
12673 for (auto *OldD : Old->decls()) {
12674 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
12675 if (!InstD) {
12676 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
12677 // This can happen because of dependent hiding.
12678 if (isa<UsingShadowDecl>(OldD))
12679 continue;
12680 else {
12681 R.clear();
12682 return true;
12686 // Expand using pack declarations.
12687 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
12688 ArrayRef<NamedDecl*> Decls = SingleDecl;
12689 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
12690 Decls = UPD->expansions();
12692 // Expand using declarations.
12693 for (auto *D : Decls) {
12694 if (auto *UD = dyn_cast<UsingDecl>(D)) {
12695 for (auto *SD : UD->shadows())
12696 R.addDecl(SD);
12697 } else {
12698 R.addDecl(D);
12702 AllEmptyPacks &= Decls.empty();
12705 // C++ [temp.res]/8.4.2:
12706 // The program is ill-formed, no diagnostic required, if [...] lookup for
12707 // a name in the template definition found a using-declaration, but the
12708 // lookup in the corresponding scope in the instantiation odoes not find
12709 // any declarations because the using-declaration was a pack expansion and
12710 // the corresponding pack is empty
12711 if (AllEmptyPacks && !RequiresADL) {
12712 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
12713 << isa<UnresolvedMemberExpr>(Old) << Old->getName();
12714 return true;
12717 // Resolve a kind, but don't do any further analysis. If it's
12718 // ambiguous, the callee needs to deal with it.
12719 R.resolveKind();
12720 return false;
12723 template<typename Derived>
12724 ExprResult
12725 TreeTransform<Derived>::TransformUnresolvedLookupExpr(
12726 UnresolvedLookupExpr *Old) {
12727 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
12728 Sema::LookupOrdinaryName);
12730 // Transform the declaration set.
12731 if (TransformOverloadExprDecls(Old, Old->requiresADL(), R))
12732 return ExprError();
12734 // Rebuild the nested-name qualifier, if present.
12735 CXXScopeSpec SS;
12736 if (Old->getQualifierLoc()) {
12737 NestedNameSpecifierLoc QualifierLoc
12738 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
12739 if (!QualifierLoc)
12740 return ExprError();
12742 SS.Adopt(QualifierLoc);
12745 if (Old->getNamingClass()) {
12746 CXXRecordDecl *NamingClass
12747 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
12748 Old->getNameLoc(),
12749 Old->getNamingClass()));
12750 if (!NamingClass) {
12751 R.clear();
12752 return ExprError();
12755 R.setNamingClass(NamingClass);
12758 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
12760 // If we have neither explicit template arguments, nor the template keyword,
12761 // it's a normal declaration name or member reference.
12762 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) {
12763 NamedDecl *D = R.getAsSingle<NamedDecl>();
12764 // In a C++11 unevaluated context, an UnresolvedLookupExpr might refer to an
12765 // instance member. In other contexts, BuildPossibleImplicitMemberExpr will
12766 // give a good diagnostic.
12767 if (D && D->isCXXInstanceMember()) {
12768 return SemaRef.BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, R,
12769 /*TemplateArgs=*/nullptr,
12770 /*Scope=*/nullptr);
12773 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
12776 // If we have template arguments, rebuild them, then rebuild the
12777 // templateid expression.
12778 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
12779 if (Old->hasExplicitTemplateArgs() &&
12780 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
12781 Old->getNumTemplateArgs(),
12782 TransArgs)) {
12783 R.clear();
12784 return ExprError();
12787 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
12788 Old->requiresADL(), &TransArgs);
12791 template<typename Derived>
12792 ExprResult
12793 TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
12794 bool ArgChanged = false;
12795 SmallVector<TypeSourceInfo *, 4> Args;
12796 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
12797 TypeSourceInfo *From = E->getArg(I);
12798 TypeLoc FromTL = From->getTypeLoc();
12799 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
12800 TypeLocBuilder TLB;
12801 TLB.reserve(FromTL.getFullDataSize());
12802 QualType To = getDerived().TransformType(TLB, FromTL);
12803 if (To.isNull())
12804 return ExprError();
12806 if (To == From->getType())
12807 Args.push_back(From);
12808 else {
12809 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12810 ArgChanged = true;
12812 continue;
12815 ArgChanged = true;
12817 // We have a pack expansion. Instantiate it.
12818 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
12819 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
12820 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
12821 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
12823 // Determine whether the set of unexpanded parameter packs can and should
12824 // be expanded.
12825 bool Expand = true;
12826 bool RetainExpansion = false;
12827 std::optional<unsigned> OrigNumExpansions =
12828 ExpansionTL.getTypePtr()->getNumExpansions();
12829 std::optional<unsigned> NumExpansions = OrigNumExpansions;
12830 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
12831 PatternTL.getSourceRange(),
12832 Unexpanded,
12833 Expand, RetainExpansion,
12834 NumExpansions))
12835 return ExprError();
12837 if (!Expand) {
12838 // The transform has determined that we should perform a simple
12839 // transformation on the pack expansion, producing another pack
12840 // expansion.
12841 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
12843 TypeLocBuilder TLB;
12844 TLB.reserve(From->getTypeLoc().getFullDataSize());
12846 QualType To = getDerived().TransformType(TLB, PatternTL);
12847 if (To.isNull())
12848 return ExprError();
12850 To = getDerived().RebuildPackExpansionType(To,
12851 PatternTL.getSourceRange(),
12852 ExpansionTL.getEllipsisLoc(),
12853 NumExpansions);
12854 if (To.isNull())
12855 return ExprError();
12857 PackExpansionTypeLoc ToExpansionTL
12858 = TLB.push<PackExpansionTypeLoc>(To);
12859 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
12860 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12861 continue;
12864 // Expand the pack expansion by substituting for each argument in the
12865 // pack(s).
12866 for (unsigned I = 0; I != *NumExpansions; ++I) {
12867 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
12868 TypeLocBuilder TLB;
12869 TLB.reserve(PatternTL.getFullDataSize());
12870 QualType To = getDerived().TransformType(TLB, PatternTL);
12871 if (To.isNull())
12872 return ExprError();
12874 if (To->containsUnexpandedParameterPack()) {
12875 To = getDerived().RebuildPackExpansionType(To,
12876 PatternTL.getSourceRange(),
12877 ExpansionTL.getEllipsisLoc(),
12878 NumExpansions);
12879 if (To.isNull())
12880 return ExprError();
12882 PackExpansionTypeLoc ToExpansionTL
12883 = TLB.push<PackExpansionTypeLoc>(To);
12884 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
12887 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12890 if (!RetainExpansion)
12891 continue;
12893 // If we're supposed to retain a pack expansion, do so by temporarily
12894 // forgetting the partially-substituted parameter pack.
12895 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
12897 TypeLocBuilder TLB;
12898 TLB.reserve(From->getTypeLoc().getFullDataSize());
12900 QualType To = getDerived().TransformType(TLB, PatternTL);
12901 if (To.isNull())
12902 return ExprError();
12904 To = getDerived().RebuildPackExpansionType(To,
12905 PatternTL.getSourceRange(),
12906 ExpansionTL.getEllipsisLoc(),
12907 NumExpansions);
12908 if (To.isNull())
12909 return ExprError();
12911 PackExpansionTypeLoc ToExpansionTL
12912 = TLB.push<PackExpansionTypeLoc>(To);
12913 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
12914 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12917 if (!getDerived().AlwaysRebuild() && !ArgChanged)
12918 return E;
12920 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
12921 E->getEndLoc());
12924 template<typename Derived>
12925 ExprResult
12926 TreeTransform<Derived>::TransformConceptSpecializationExpr(
12927 ConceptSpecializationExpr *E) {
12928 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
12929 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
12930 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
12931 Old->NumTemplateArgs, TransArgs))
12932 return ExprError();
12934 return getDerived().RebuildConceptSpecializationExpr(
12935 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
12936 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
12937 &TransArgs);
12940 template<typename Derived>
12941 ExprResult
12942 TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
12943 SmallVector<ParmVarDecl*, 4> TransParams;
12944 SmallVector<QualType, 4> TransParamTypes;
12945 Sema::ExtParameterInfoBuilder ExtParamInfos;
12947 // C++2a [expr.prim.req]p2
12948 // Expressions appearing within a requirement-body are unevaluated operands.
12949 EnterExpressionEvaluationContext Ctx(
12950 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
12951 Sema::ReuseLambdaContextDecl);
12953 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
12954 getSema().Context, getSema().CurContext,
12955 E->getBody()->getBeginLoc());
12957 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
12959 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
12960 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
12961 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
12963 for (ParmVarDecl *Param : TransParams)
12964 if (Param)
12965 Param->setDeclContext(Body);
12967 // On failure to transform, TransformRequiresTypeParams returns an expression
12968 // in the event that the transformation of the type params failed in some way.
12969 // It is expected that this will result in a 'not satisfied' Requires clause
12970 // when instantiating.
12971 if (!TypeParamResult.isUnset())
12972 return TypeParamResult;
12974 SmallVector<concepts::Requirement *, 4> TransReqs;
12975 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
12976 TransReqs))
12977 return ExprError();
12979 for (concepts::Requirement *Req : TransReqs) {
12980 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
12981 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
12982 ER->getReturnTypeRequirement()
12983 .getTypeConstraintTemplateParameterList()->getParam(0)
12984 ->setDeclContext(Body);
12989 return getDerived().RebuildRequiresExpr(
12990 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
12991 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
12994 template<typename Derived>
12995 bool TreeTransform<Derived>::TransformRequiresExprRequirements(
12996 ArrayRef<concepts::Requirement *> Reqs,
12997 SmallVectorImpl<concepts::Requirement *> &Transformed) {
12998 for (concepts::Requirement *Req : Reqs) {
12999 concepts::Requirement *TransReq = nullptr;
13000 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
13001 TransReq = getDerived().TransformTypeRequirement(TypeReq);
13002 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
13003 TransReq = getDerived().TransformExprRequirement(ExprReq);
13004 else
13005 TransReq = getDerived().TransformNestedRequirement(
13006 cast<concepts::NestedRequirement>(Req));
13007 if (!TransReq)
13008 return true;
13009 Transformed.push_back(TransReq);
13011 return false;
13014 template<typename Derived>
13015 concepts::TypeRequirement *
13016 TreeTransform<Derived>::TransformTypeRequirement(
13017 concepts::TypeRequirement *Req) {
13018 if (Req->isSubstitutionFailure()) {
13019 if (getDerived().AlwaysRebuild())
13020 return getDerived().RebuildTypeRequirement(
13021 Req->getSubstitutionDiagnostic());
13022 return Req;
13024 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
13025 if (!TransType)
13026 return nullptr;
13027 return getDerived().RebuildTypeRequirement(TransType);
13030 template<typename Derived>
13031 concepts::ExprRequirement *
13032 TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
13033 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
13034 if (Req->isExprSubstitutionFailure())
13035 TransExpr = Req->getExprSubstitutionDiagnostic();
13036 else {
13037 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
13038 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
13039 TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
13040 if (TransExprRes.isInvalid())
13041 return nullptr;
13042 TransExpr = TransExprRes.get();
13045 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
13046 const auto &RetReq = Req->getReturnTypeRequirement();
13047 if (RetReq.isEmpty())
13048 TransRetReq.emplace();
13049 else if (RetReq.isSubstitutionFailure())
13050 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
13051 else if (RetReq.isTypeConstraint()) {
13052 TemplateParameterList *OrigTPL =
13053 RetReq.getTypeConstraintTemplateParameterList();
13054 TemplateParameterList *TPL =
13055 getDerived().TransformTemplateParameterList(OrigTPL);
13056 if (!TPL)
13057 return nullptr;
13058 TransRetReq.emplace(TPL);
13060 assert(TransRetReq && "All code paths leading here must set TransRetReq");
13061 if (Expr *E = TransExpr.dyn_cast<Expr *>())
13062 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
13063 Req->getNoexceptLoc(),
13064 std::move(*TransRetReq));
13065 return getDerived().RebuildExprRequirement(
13066 TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(),
13067 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
13070 template<typename Derived>
13071 concepts::NestedRequirement *
13072 TreeTransform<Derived>::TransformNestedRequirement(
13073 concepts::NestedRequirement *Req) {
13074 if (Req->hasInvalidConstraint()) {
13075 if (getDerived().AlwaysRebuild())
13076 return getDerived().RebuildNestedRequirement(
13077 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
13078 return Req;
13080 ExprResult TransConstraint =
13081 getDerived().TransformExpr(Req->getConstraintExpr());
13082 if (TransConstraint.isInvalid())
13083 return nullptr;
13084 return getDerived().RebuildNestedRequirement(TransConstraint.get());
13087 template<typename Derived>
13088 ExprResult
13089 TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
13090 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
13091 if (!T)
13092 return ExprError();
13094 if (!getDerived().AlwaysRebuild() &&
13095 T == E->getQueriedTypeSourceInfo())
13096 return E;
13098 ExprResult SubExpr;
13100 EnterExpressionEvaluationContext Unevaluated(
13101 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13102 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
13103 if (SubExpr.isInvalid())
13104 return ExprError();
13106 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
13107 return E;
13110 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
13111 SubExpr.get(), E->getEndLoc());
13114 template<typename Derived>
13115 ExprResult
13116 TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
13117 ExprResult SubExpr;
13119 EnterExpressionEvaluationContext Unevaluated(
13120 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13121 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
13122 if (SubExpr.isInvalid())
13123 return ExprError();
13125 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
13126 return E;
13129 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
13130 SubExpr.get(), E->getEndLoc());
13133 template <typename Derived>
13134 ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
13135 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
13136 TypeSourceInfo **RecoveryTSI) {
13137 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
13138 DRE, AddrTaken, RecoveryTSI);
13140 // Propagate both errors and recovered types, which return ExprEmpty.
13141 if (!NewDRE.isUsable())
13142 return NewDRE;
13144 // We got an expr, wrap it up in parens.
13145 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
13146 return PE;
13147 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
13148 PE->getRParen());
13151 template <typename Derived>
13152 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
13153 DependentScopeDeclRefExpr *E) {
13154 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
13155 nullptr);
13158 template <typename Derived>
13159 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
13160 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
13161 TypeSourceInfo **RecoveryTSI) {
13162 assert(E->getQualifierLoc());
13163 NestedNameSpecifierLoc QualifierLoc =
13164 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13165 if (!QualifierLoc)
13166 return ExprError();
13167 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13169 // TODO: If this is a conversion-function-id, verify that the
13170 // destination type name (if present) resolves the same way after
13171 // instantiation as it did in the local scope.
13173 DeclarationNameInfo NameInfo =
13174 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
13175 if (!NameInfo.getName())
13176 return ExprError();
13178 if (!E->hasExplicitTemplateArgs()) {
13179 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
13180 // Note: it is sufficient to compare the Name component of NameInfo:
13181 // if name has not changed, DNLoc has not changed either.
13182 NameInfo.getName() == E->getDeclName())
13183 return E;
13185 return getDerived().RebuildDependentScopeDeclRefExpr(
13186 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
13187 IsAddressOfOperand, RecoveryTSI);
13190 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
13191 if (getDerived().TransformTemplateArguments(
13192 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
13193 return ExprError();
13195 return getDerived().RebuildDependentScopeDeclRefExpr(
13196 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
13197 RecoveryTSI);
13200 template<typename Derived>
13201 ExprResult
13202 TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
13203 // CXXConstructExprs other than for list-initialization and
13204 // CXXTemporaryObjectExpr are always implicit, so when we have
13205 // a 1-argument construction we just transform that argument.
13206 if (getDerived().AllowSkippingCXXConstructExpr() &&
13207 ((E->getNumArgs() == 1 ||
13208 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) &&
13209 (!getDerived().DropCallArgument(E->getArg(0))) &&
13210 !E->isListInitialization()))
13211 return getDerived().TransformInitializer(E->getArg(0),
13212 /*DirectInit*/ false);
13214 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
13216 QualType T = getDerived().TransformType(E->getType());
13217 if (T.isNull())
13218 return ExprError();
13220 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13221 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13222 if (!Constructor)
13223 return ExprError();
13225 bool ArgumentChanged = false;
13226 SmallVector<Expr*, 8> Args;
13228 EnterExpressionEvaluationContext Context(
13229 getSema(), EnterExpressionEvaluationContext::InitList,
13230 E->isListInitialization());
13231 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13232 &ArgumentChanged))
13233 return ExprError();
13236 if (!getDerived().AlwaysRebuild() &&
13237 T == E->getType() &&
13238 Constructor == E->getConstructor() &&
13239 !ArgumentChanged) {
13240 // Mark the constructor as referenced.
13241 // FIXME: Instantiation-specific
13242 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13243 return E;
13246 return getDerived().RebuildCXXConstructExpr(
13247 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
13248 E->hadMultipleCandidates(), E->isListInitialization(),
13249 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
13250 E->getConstructionKind(), E->getParenOrBraceRange());
13253 template<typename Derived>
13254 ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
13255 CXXInheritedCtorInitExpr *E) {
13256 QualType T = getDerived().TransformType(E->getType());
13257 if (T.isNull())
13258 return ExprError();
13260 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13261 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13262 if (!Constructor)
13263 return ExprError();
13265 if (!getDerived().AlwaysRebuild() &&
13266 T == E->getType() &&
13267 Constructor == E->getConstructor()) {
13268 // Mark the constructor as referenced.
13269 // FIXME: Instantiation-specific
13270 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13271 return E;
13274 return getDerived().RebuildCXXInheritedCtorInitExpr(
13275 T, E->getLocation(), Constructor,
13276 E->constructsVBase(), E->inheritedFromVBase());
13279 /// Transform a C++ temporary-binding expression.
13281 /// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
13282 /// transform the subexpression and return that.
13283 template<typename Derived>
13284 ExprResult
13285 TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
13286 if (auto *Dtor = E->getTemporary()->getDestructor())
13287 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
13288 const_cast<CXXDestructorDecl *>(Dtor));
13289 return getDerived().TransformExpr(E->getSubExpr());
13292 /// Transform a C++ expression that contains cleanups that should
13293 /// be run after the expression is evaluated.
13295 /// Since ExprWithCleanups nodes are implicitly generated, we
13296 /// just transform the subexpression and return that.
13297 template<typename Derived>
13298 ExprResult
13299 TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
13300 return getDerived().TransformExpr(E->getSubExpr());
13303 template<typename Derived>
13304 ExprResult
13305 TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
13306 CXXTemporaryObjectExpr *E) {
13307 TypeSourceInfo *T =
13308 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
13309 if (!T)
13310 return ExprError();
13312 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13313 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13314 if (!Constructor)
13315 return ExprError();
13317 bool ArgumentChanged = false;
13318 SmallVector<Expr*, 8> Args;
13319 Args.reserve(E->getNumArgs());
13321 EnterExpressionEvaluationContext Context(
13322 getSema(), EnterExpressionEvaluationContext::InitList,
13323 E->isListInitialization());
13324 if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13325 &ArgumentChanged))
13326 return ExprError();
13329 if (!getDerived().AlwaysRebuild() &&
13330 T == E->getTypeSourceInfo() &&
13331 Constructor == E->getConstructor() &&
13332 !ArgumentChanged) {
13333 // FIXME: Instantiation-specific
13334 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13335 return SemaRef.MaybeBindToTemporary(E);
13338 // FIXME: We should just pass E->isListInitialization(), but we're not
13339 // prepared to handle list-initialization without a child InitListExpr.
13340 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
13341 return getDerived().RebuildCXXTemporaryObjectExpr(
13342 T, LParenLoc, Args, E->getEndLoc(),
13343 /*ListInitialization=*/LParenLoc.isInvalid());
13346 template<typename Derived>
13347 ExprResult
13348 TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
13349 // Transform any init-capture expressions before entering the scope of the
13350 // lambda body, because they are not semantically within that scope.
13351 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
13352 struct TransformedInitCapture {
13353 // The location of the ... if the result is retaining a pack expansion.
13354 SourceLocation EllipsisLoc;
13355 // Zero or more expansions of the init-capture.
13356 SmallVector<InitCaptureInfoTy, 4> Expansions;
13358 SmallVector<TransformedInitCapture, 4> InitCaptures;
13359 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
13360 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13361 CEnd = E->capture_end();
13362 C != CEnd; ++C) {
13363 if (!E->isInitCapture(C))
13364 continue;
13366 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
13367 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
13369 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
13370 std::optional<unsigned> NumExpansions) {
13371 ExprResult NewExprInitResult = getDerived().TransformInitializer(
13372 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
13374 if (NewExprInitResult.isInvalid()) {
13375 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
13376 return;
13378 Expr *NewExprInit = NewExprInitResult.get();
13380 QualType NewInitCaptureType =
13381 getSema().buildLambdaInitCaptureInitialization(
13382 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
13383 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
13384 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=
13385 VarDecl::CInit,
13386 NewExprInit);
13387 Result.Expansions.push_back(
13388 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
13391 // If this is an init-capture pack, consider expanding the pack now.
13392 if (OldVD->isParameterPack()) {
13393 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
13394 ->getTypeLoc()
13395 .castAs<PackExpansionTypeLoc>();
13396 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
13397 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
13399 // Determine whether the set of unexpanded parameter packs can and should
13400 // be expanded.
13401 bool Expand = true;
13402 bool RetainExpansion = false;
13403 std::optional<unsigned> OrigNumExpansions =
13404 ExpansionTL.getTypePtr()->getNumExpansions();
13405 std::optional<unsigned> NumExpansions = OrigNumExpansions;
13406 if (getDerived().TryExpandParameterPacks(
13407 ExpansionTL.getEllipsisLoc(),
13408 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
13409 RetainExpansion, NumExpansions))
13410 return ExprError();
13411 if (Expand) {
13412 for (unsigned I = 0; I != *NumExpansions; ++I) {
13413 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
13414 SubstInitCapture(SourceLocation(), std::nullopt);
13417 if (!Expand || RetainExpansion) {
13418 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
13419 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
13420 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
13422 } else {
13423 SubstInitCapture(SourceLocation(), std::nullopt);
13427 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
13428 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
13430 // Create the local class that will describe the lambda.
13432 // FIXME: DependencyKind below is wrong when substituting inside a templated
13433 // context that isn't a DeclContext (such as a variable template), or when
13434 // substituting an unevaluated lambda inside of a function's parameter's type
13435 // - as parameter types are not instantiated from within a function's DC. We
13436 // use evaluation contexts to distinguish the function parameter case.
13437 CXXRecordDecl::LambdaDependencyKind DependencyKind =
13438 CXXRecordDecl::LDK_Unknown;
13439 if ((getSema().isUnevaluatedContext() ||
13440 getSema().isConstantEvaluatedContext()) &&
13441 (getSema().CurContext->isFileContext() ||
13442 !getSema().CurContext->getParent()->isDependentContext()))
13443 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
13445 CXXRecordDecl *OldClass = E->getLambdaClass();
13446 CXXRecordDecl *Class = getSema().createLambdaClosureType(
13447 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
13448 E->getCaptureDefault());
13449 getDerived().transformedLocalDecl(OldClass, {Class});
13451 CXXMethodDecl *NewCallOperator =
13452 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
13453 NewCallOperator->setLexicalDeclContext(getSema().CurContext);
13455 // Enter the scope of the lambda.
13456 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
13457 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
13458 E->hasExplicitParameters(), E->isMutable());
13460 // Introduce the context of the call operator.
13461 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
13462 /*NewThisContext*/false);
13464 bool Invalid = false;
13466 // Transform captures.
13467 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13468 CEnd = E->capture_end();
13469 C != CEnd; ++C) {
13470 // When we hit the first implicit capture, tell Sema that we've finished
13471 // the list of explicit captures.
13472 if (C->isImplicit())
13473 break;
13475 // Capturing 'this' is trivial.
13476 if (C->capturesThis()) {
13477 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
13478 /*BuildAndDiagnose*/ true, nullptr,
13479 C->getCaptureKind() == LCK_StarThis);
13480 continue;
13482 // Captured expression will be recaptured during captured variables
13483 // rebuilding.
13484 if (C->capturesVLAType())
13485 continue;
13487 // Rebuild init-captures, including the implied field declaration.
13488 if (E->isInitCapture(C)) {
13489 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
13491 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
13492 llvm::SmallVector<Decl*, 4> NewVDs;
13494 for (InitCaptureInfoTy &Info : NewC.Expansions) {
13495 ExprResult Init = Info.first;
13496 QualType InitQualType = Info.second;
13497 if (Init.isInvalid() || InitQualType.isNull()) {
13498 Invalid = true;
13499 break;
13501 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
13502 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
13503 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
13504 getSema().CurContext);
13505 if (!NewVD) {
13506 Invalid = true;
13507 break;
13509 NewVDs.push_back(NewVD);
13510 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
13513 if (Invalid)
13514 break;
13516 getDerived().transformedLocalDecl(OldVD, NewVDs);
13517 continue;
13520 assert(C->capturesVariable() && "unexpected kind of lambda capture");
13522 // Determine the capture kind for Sema.
13523 Sema::TryCaptureKind Kind
13524 = C->isImplicit()? Sema::TryCapture_Implicit
13525 : C->getCaptureKind() == LCK_ByCopy
13526 ? Sema::TryCapture_ExplicitByVal
13527 : Sema::TryCapture_ExplicitByRef;
13528 SourceLocation EllipsisLoc;
13529 if (C->isPackExpansion()) {
13530 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
13531 bool ShouldExpand = false;
13532 bool RetainExpansion = false;
13533 std::optional<unsigned> NumExpansions;
13534 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
13535 C->getLocation(),
13536 Unexpanded,
13537 ShouldExpand, RetainExpansion,
13538 NumExpansions)) {
13539 Invalid = true;
13540 continue;
13543 if (ShouldExpand) {
13544 // The transform has determined that we should perform an expansion;
13545 // transform and capture each of the arguments.
13546 // expansion of the pattern. Do so.
13547 auto *Pack = cast<VarDecl>(C->getCapturedVar());
13548 for (unsigned I = 0; I != *NumExpansions; ++I) {
13549 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
13550 VarDecl *CapturedVar
13551 = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
13552 Pack));
13553 if (!CapturedVar) {
13554 Invalid = true;
13555 continue;
13558 // Capture the transformed variable.
13559 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
13562 // FIXME: Retain a pack expansion if RetainExpansion is true.
13564 continue;
13567 EllipsisLoc = C->getEllipsisLoc();
13570 // Transform the captured variable.
13571 auto *CapturedVar = cast_or_null<ValueDecl>(
13572 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
13573 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
13574 Invalid = true;
13575 continue;
13578 // Capture the transformed variable.
13579 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
13580 EllipsisLoc);
13582 getSema().finishLambdaExplicitCaptures(LSI);
13584 // Transform the template parameters, and add them to the current
13585 // instantiation scope. The null case is handled correctly.
13586 auto TPL = getDerived().TransformTemplateParameterList(
13587 E->getTemplateParameterList());
13588 LSI->GLTemplateParameterList = TPL;
13589 if (TPL)
13590 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
13591 TPL);
13593 // Transform the type of the original lambda's call operator.
13594 // The transformation MUST be done in the CurrentInstantiationScope since
13595 // it introduces a mapping of the original to the newly created
13596 // transformed parameters.
13597 TypeSourceInfo *NewCallOpTSI = nullptr;
13599 TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo();
13600 auto OldCallOpFPTL =
13601 OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
13603 TypeLocBuilder NewCallOpTLBuilder;
13604 SmallVector<QualType, 4> ExceptionStorage;
13605 TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
13606 QualType NewCallOpType = TransformFunctionProtoType(
13607 NewCallOpTLBuilder, OldCallOpFPTL, nullptr, Qualifiers(),
13608 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
13609 return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI,
13610 ExceptionStorage, Changed);
13612 if (NewCallOpType.isNull())
13613 return ExprError();
13614 NewCallOpTSI =
13615 NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
13618 getSema().CompleteLambdaCallOperator(
13619 NewCallOperator, E->getCallOperator()->getLocation(),
13620 E->getCallOperator()->getInnerLocStart(),
13621 E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
13622 E->getCallOperator()->getConstexprKind(),
13623 E->getCallOperator()->getStorageClass(),
13624 NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
13625 E->hasExplicitResultType());
13627 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
13628 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
13631 // Number the lambda for linkage purposes if necessary.
13632 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
13634 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
13635 if (getDerived().ReplacingOriginal()) {
13636 Numbering = OldClass->getLambdaNumbering();
13639 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
13642 // FIXME: Sema's lambda-building mechanism expects us to push an expression
13643 // evaluation context even if we're not transforming the function body.
13644 getSema().PushExpressionEvaluationContext(
13645 Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
13647 // Instantiate the body of the lambda expression.
13648 StmtResult Body =
13649 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
13651 // ActOnLambda* will pop the function scope for us.
13652 FuncScopeCleanup.disable();
13654 if (Body.isInvalid()) {
13655 SavedContext.pop();
13656 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
13657 /*IsInstantiation=*/true);
13658 return ExprError();
13661 // Copy the LSI before ActOnFinishFunctionBody removes it.
13662 // FIXME: This is dumb. Store the lambda information somewhere that outlives
13663 // the call operator.
13664 auto LSICopy = *LSI;
13665 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
13666 /*IsInstantiation*/ true);
13667 SavedContext.pop();
13669 return getSema().BuildLambdaExpr(E->getBeginLoc(), Body.get()->getEndLoc(),
13670 &LSICopy);
13673 template<typename Derived>
13674 StmtResult
13675 TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
13676 return TransformStmt(S);
13679 template<typename Derived>
13680 StmtResult
13681 TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
13682 // Transform captures.
13683 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13684 CEnd = E->capture_end();
13685 C != CEnd; ++C) {
13686 // When we hit the first implicit capture, tell Sema that we've finished
13687 // the list of explicit captures.
13688 if (!C->isImplicit())
13689 continue;
13691 // Capturing 'this' is trivial.
13692 if (C->capturesThis()) {
13693 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
13694 /*BuildAndDiagnose*/ true, nullptr,
13695 C->getCaptureKind() == LCK_StarThis);
13696 continue;
13698 // Captured expression will be recaptured during captured variables
13699 // rebuilding.
13700 if (C->capturesVLAType())
13701 continue;
13703 assert(C->capturesVariable() && "unexpected kind of lambda capture");
13704 assert(!E->isInitCapture(C) && "implicit init-capture?");
13706 // Transform the captured variable.
13707 VarDecl *CapturedVar = cast_or_null<VarDecl>(
13708 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
13709 if (!CapturedVar || CapturedVar->isInvalidDecl())
13710 return StmtError();
13712 // Capture the transformed variable.
13713 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
13716 return S;
13719 template<typename Derived>
13720 ExprResult
13721 TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
13722 CXXUnresolvedConstructExpr *E) {
13723 TypeSourceInfo *T =
13724 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
13725 if (!T)
13726 return ExprError();
13728 bool ArgumentChanged = false;
13729 SmallVector<Expr*, 8> Args;
13730 Args.reserve(E->getNumArgs());
13732 EnterExpressionEvaluationContext Context(
13733 getSema(), EnterExpressionEvaluationContext::InitList,
13734 E->isListInitialization());
13735 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
13736 &ArgumentChanged))
13737 return ExprError();
13740 if (!getDerived().AlwaysRebuild() &&
13741 T == E->getTypeSourceInfo() &&
13742 !ArgumentChanged)
13743 return E;
13745 // FIXME: we're faking the locations of the commas
13746 return getDerived().RebuildCXXUnresolvedConstructExpr(
13747 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
13750 template<typename Derived>
13751 ExprResult
13752 TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
13753 CXXDependentScopeMemberExpr *E) {
13754 // Transform the base of the expression.
13755 ExprResult Base((Expr*) nullptr);
13756 Expr *OldBase;
13757 QualType BaseType;
13758 QualType ObjectType;
13759 if (!E->isImplicitAccess()) {
13760 OldBase = E->getBase();
13761 Base = getDerived().TransformExpr(OldBase);
13762 if (Base.isInvalid())
13763 return ExprError();
13765 // Start the member reference and compute the object's type.
13766 ParsedType ObjectTy;
13767 bool MayBePseudoDestructor = false;
13768 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
13769 E->getOperatorLoc(),
13770 E->isArrow()? tok::arrow : tok::period,
13771 ObjectTy,
13772 MayBePseudoDestructor);
13773 if (Base.isInvalid())
13774 return ExprError();
13776 ObjectType = ObjectTy.get();
13777 BaseType = ((Expr*) Base.get())->getType();
13778 } else {
13779 OldBase = nullptr;
13780 BaseType = getDerived().TransformType(E->getBaseType());
13781 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
13784 // Transform the first part of the nested-name-specifier that qualifies
13785 // the member name.
13786 NamedDecl *FirstQualifierInScope
13787 = getDerived().TransformFirstQualifierInScope(
13788 E->getFirstQualifierFoundInScope(),
13789 E->getQualifierLoc().getBeginLoc());
13791 NestedNameSpecifierLoc QualifierLoc;
13792 if (E->getQualifier()) {
13793 QualifierLoc
13794 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
13795 ObjectType,
13796 FirstQualifierInScope);
13797 if (!QualifierLoc)
13798 return ExprError();
13801 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13803 // TODO: If this is a conversion-function-id, verify that the
13804 // destination type name (if present) resolves the same way after
13805 // instantiation as it did in the local scope.
13807 DeclarationNameInfo NameInfo
13808 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
13809 if (!NameInfo.getName())
13810 return ExprError();
13812 if (!E->hasExplicitTemplateArgs()) {
13813 // This is a reference to a member without an explicitly-specified
13814 // template argument list. Optimize for this common case.
13815 if (!getDerived().AlwaysRebuild() &&
13816 Base.get() == OldBase &&
13817 BaseType == E->getBaseType() &&
13818 QualifierLoc == E->getQualifierLoc() &&
13819 NameInfo.getName() == E->getMember() &&
13820 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
13821 return E;
13823 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
13824 BaseType,
13825 E->isArrow(),
13826 E->getOperatorLoc(),
13827 QualifierLoc,
13828 TemplateKWLoc,
13829 FirstQualifierInScope,
13830 NameInfo,
13831 /*TemplateArgs*/nullptr);
13834 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
13835 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13836 E->getNumTemplateArgs(),
13837 TransArgs))
13838 return ExprError();
13840 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
13841 BaseType,
13842 E->isArrow(),
13843 E->getOperatorLoc(),
13844 QualifierLoc,
13845 TemplateKWLoc,
13846 FirstQualifierInScope,
13847 NameInfo,
13848 &TransArgs);
13851 template <typename Derived>
13852 ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
13853 UnresolvedMemberExpr *Old) {
13854 // Transform the base of the expression.
13855 ExprResult Base((Expr *)nullptr);
13856 QualType BaseType;
13857 if (!Old->isImplicitAccess()) {
13858 Base = getDerived().TransformExpr(Old->getBase());
13859 if (Base.isInvalid())
13860 return ExprError();
13861 Base =
13862 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
13863 if (Base.isInvalid())
13864 return ExprError();
13865 BaseType = Base.get()->getType();
13866 } else {
13867 BaseType = getDerived().TransformType(Old->getBaseType());
13870 NestedNameSpecifierLoc QualifierLoc;
13871 if (Old->getQualifierLoc()) {
13872 QualifierLoc =
13873 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
13874 if (!QualifierLoc)
13875 return ExprError();
13878 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
13880 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
13882 // Transform the declaration set.
13883 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ false, R))
13884 return ExprError();
13886 // Determine the naming class.
13887 if (Old->getNamingClass()) {
13888 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
13889 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
13890 if (!NamingClass)
13891 return ExprError();
13893 R.setNamingClass(NamingClass);
13896 TemplateArgumentListInfo TransArgs;
13897 if (Old->hasExplicitTemplateArgs()) {
13898 TransArgs.setLAngleLoc(Old->getLAngleLoc());
13899 TransArgs.setRAngleLoc(Old->getRAngleLoc());
13900 if (getDerived().TransformTemplateArguments(
13901 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
13902 return ExprError();
13905 // FIXME: to do this check properly, we will need to preserve the
13906 // first-qualifier-in-scope here, just in case we had a dependent
13907 // base (and therefore couldn't do the check) and a
13908 // nested-name-qualifier (and therefore could do the lookup).
13909 NamedDecl *FirstQualifierInScope = nullptr;
13911 return getDerived().RebuildUnresolvedMemberExpr(
13912 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
13913 TemplateKWLoc, FirstQualifierInScope, R,
13914 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
13917 template<typename Derived>
13918 ExprResult
13919 TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
13920 EnterExpressionEvaluationContext Unevaluated(
13921 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13922 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
13923 if (SubExpr.isInvalid())
13924 return ExprError();
13926 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
13927 return E;
13929 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
13932 template<typename Derived>
13933 ExprResult
13934 TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
13935 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
13936 if (Pattern.isInvalid())
13937 return ExprError();
13939 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
13940 return E;
13942 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
13943 E->getNumExpansions());
13946 template<typename Derived>
13947 ExprResult
13948 TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
13949 // If E is not value-dependent, then nothing will change when we transform it.
13950 // Note: This is an instantiation-centric view.
13951 if (!E->isValueDependent())
13952 return E;
13954 EnterExpressionEvaluationContext Unevaluated(
13955 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
13957 ArrayRef<TemplateArgument> PackArgs;
13958 TemplateArgument ArgStorage;
13960 // Find the argument list to transform.
13961 if (E->isPartiallySubstituted()) {
13962 PackArgs = E->getPartialArguments();
13963 } else if (E->isValueDependent()) {
13964 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
13965 bool ShouldExpand = false;
13966 bool RetainExpansion = false;
13967 std::optional<unsigned> NumExpansions;
13968 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
13969 Unexpanded,
13970 ShouldExpand, RetainExpansion,
13971 NumExpansions))
13972 return ExprError();
13974 // If we need to expand the pack, build a template argument from it and
13975 // expand that.
13976 if (ShouldExpand) {
13977 auto *Pack = E->getPack();
13978 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) {
13979 ArgStorage = getSema().Context.getPackExpansionType(
13980 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
13981 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {
13982 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
13983 } else {
13984 auto *VD = cast<ValueDecl>(Pack);
13985 ExprResult DRE = getSema().BuildDeclRefExpr(
13986 VD, VD->getType().getNonLValueExprType(getSema().Context),
13987 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
13988 E->getPackLoc());
13989 if (DRE.isInvalid())
13990 return ExprError();
13991 ArgStorage = new (getSema().Context)
13992 PackExpansionExpr(getSema().Context.DependentTy, DRE.get(),
13993 E->getPackLoc(), std::nullopt);
13995 PackArgs = ArgStorage;
13999 // If we're not expanding the pack, just transform the decl.
14000 if (!PackArgs.size()) {
14001 auto *Pack = cast_or_null<NamedDecl>(
14002 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
14003 if (!Pack)
14004 return ExprError();
14005 return getDerived().RebuildSizeOfPackExpr(
14006 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
14007 std::nullopt, std::nullopt);
14010 // Try to compute the result without performing a partial substitution.
14011 std::optional<unsigned> Result = 0;
14012 for (const TemplateArgument &Arg : PackArgs) {
14013 if (!Arg.isPackExpansion()) {
14014 Result = *Result + 1;
14015 continue;
14018 TemplateArgumentLoc ArgLoc;
14019 InventTemplateArgumentLoc(Arg, ArgLoc);
14021 // Find the pattern of the pack expansion.
14022 SourceLocation Ellipsis;
14023 std::optional<unsigned> OrigNumExpansions;
14024 TemplateArgumentLoc Pattern =
14025 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
14026 OrigNumExpansions);
14028 // Substitute under the pack expansion. Do not expand the pack (yet).
14029 TemplateArgumentLoc OutPattern;
14030 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14031 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
14032 /*Uneval*/ true))
14033 return true;
14035 // See if we can determine the number of arguments from the result.
14036 std::optional<unsigned> NumExpansions =
14037 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
14038 if (!NumExpansions) {
14039 // No: we must be in an alias template expansion, and we're going to need
14040 // to actually expand the packs.
14041 Result = std::nullopt;
14042 break;
14045 Result = *Result + *NumExpansions;
14048 // Common case: we could determine the number of expansions without
14049 // substituting.
14050 if (Result)
14051 return getDerived().RebuildSizeOfPackExpr(
14052 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
14053 *Result, std::nullopt);
14055 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
14056 E->getPackLoc());
14058 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
14059 typedef TemplateArgumentLocInventIterator<
14060 Derived, const TemplateArgument*> PackLocIterator;
14061 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
14062 PackLocIterator(*this, PackArgs.end()),
14063 TransformedPackArgs, /*Uneval*/true))
14064 return ExprError();
14067 // Check whether we managed to fully-expand the pack.
14068 // FIXME: Is it possible for us to do so and not hit the early exit path?
14069 SmallVector<TemplateArgument, 8> Args;
14070 bool PartialSubstitution = false;
14071 for (auto &Loc : TransformedPackArgs.arguments()) {
14072 Args.push_back(Loc.getArgument());
14073 if (Loc.getArgument().isPackExpansion())
14074 PartialSubstitution = true;
14077 if (PartialSubstitution)
14078 return getDerived().RebuildSizeOfPackExpr(
14079 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
14080 std::nullopt, Args);
14082 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
14083 E->getPackLoc(), E->getRParenLoc(),
14084 Args.size(), std::nullopt);
14087 template<typename Derived>
14088 ExprResult
14089 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
14090 SubstNonTypeTemplateParmPackExpr *E) {
14091 // Default behavior is to do nothing with this transformation.
14092 return E;
14095 template<typename Derived>
14096 ExprResult
14097 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
14098 SubstNonTypeTemplateParmExpr *E) {
14099 // Default behavior is to do nothing with this transformation.
14100 return E;
14103 template<typename Derived>
14104 ExprResult
14105 TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
14106 // Default behavior is to do nothing with this transformation.
14107 return E;
14110 template<typename Derived>
14111 ExprResult
14112 TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
14113 MaterializeTemporaryExpr *E) {
14114 return getDerived().TransformExpr(E->getSubExpr());
14117 template<typename Derived>
14118 ExprResult
14119 TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
14120 UnresolvedLookupExpr *Callee = nullptr;
14121 if (Expr *OldCallee = E->getCallee()) {
14122 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
14123 if (CalleeResult.isInvalid())
14124 return ExprError();
14125 Callee = cast<UnresolvedLookupExpr>(CalleeResult.get());
14128 Expr *Pattern = E->getPattern();
14130 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14131 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
14132 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
14134 // Determine whether the set of unexpanded parameter packs can and should
14135 // be expanded.
14136 bool Expand = true;
14137 bool RetainExpansion = false;
14138 std::optional<unsigned> OrigNumExpansions = E->getNumExpansions(),
14139 NumExpansions = OrigNumExpansions;
14140 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
14141 Pattern->getSourceRange(),
14142 Unexpanded,
14143 Expand, RetainExpansion,
14144 NumExpansions))
14145 return true;
14147 if (!Expand) {
14148 // Do not expand any packs here, just transform and rebuild a fold
14149 // expression.
14150 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14152 ExprResult LHS =
14153 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
14154 if (LHS.isInvalid())
14155 return true;
14157 ExprResult RHS =
14158 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
14159 if (RHS.isInvalid())
14160 return true;
14162 if (!getDerived().AlwaysRebuild() &&
14163 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
14164 return E;
14166 return getDerived().RebuildCXXFoldExpr(
14167 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
14168 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
14171 // Formally a fold expression expands to nested parenthesized expressions.
14172 // Enforce this limit to avoid creating trees so deep we can't safely traverse
14173 // them.
14174 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) {
14175 SemaRef.Diag(E->getEllipsisLoc(),
14176 clang::diag::err_fold_expression_limit_exceeded)
14177 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
14178 << E->getSourceRange();
14179 SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);
14180 return ExprError();
14183 // The transform has determined that we should perform an elementwise
14184 // expansion of the pattern. Do so.
14185 ExprResult Result = getDerived().TransformExpr(E->getInit());
14186 if (Result.isInvalid())
14187 return true;
14188 bool LeftFold = E->isLeftFold();
14190 // If we're retaining an expansion for a right fold, it is the innermost
14191 // component and takes the init (if any).
14192 if (!LeftFold && RetainExpansion) {
14193 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14195 ExprResult Out = getDerived().TransformExpr(Pattern);
14196 if (Out.isInvalid())
14197 return true;
14199 Result = getDerived().RebuildCXXFoldExpr(
14200 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
14201 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
14202 if (Result.isInvalid())
14203 return true;
14206 for (unsigned I = 0; I != *NumExpansions; ++I) {
14207 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(
14208 getSema(), LeftFold ? I : *NumExpansions - I - 1);
14209 ExprResult Out = getDerived().TransformExpr(Pattern);
14210 if (Out.isInvalid())
14211 return true;
14213 if (Out.get()->containsUnexpandedParameterPack()) {
14214 // We still have a pack; retain a pack expansion for this slice.
14215 Result = getDerived().RebuildCXXFoldExpr(
14216 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
14217 E->getOperator(), E->getEllipsisLoc(),
14218 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
14219 OrigNumExpansions);
14220 } else if (Result.isUsable()) {
14221 // We've got down to a single element; build a binary operator.
14222 Expr *LHS = LeftFold ? Result.get() : Out.get();
14223 Expr *RHS = LeftFold ? Out.get() : Result.get();
14224 if (Callee) {
14225 UnresolvedSet<16> Functions;
14226 Functions.append(Callee->decls_begin(), Callee->decls_end());
14227 Result = getDerived().RebuildCXXOperatorCallExpr(
14228 BinaryOperator::getOverloadedOperator(E->getOperator()),
14229 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
14230 Functions, LHS, RHS);
14231 } else {
14232 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
14233 E->getOperator(), LHS, RHS);
14235 } else
14236 Result = Out;
14238 if (Result.isInvalid())
14239 return true;
14242 // If we're retaining an expansion for a left fold, it is the outermost
14243 // component and takes the complete expansion so far as its init (if any).
14244 if (LeftFold && RetainExpansion) {
14245 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14247 ExprResult Out = getDerived().TransformExpr(Pattern);
14248 if (Out.isInvalid())
14249 return true;
14251 Result = getDerived().RebuildCXXFoldExpr(
14252 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
14253 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
14254 if (Result.isInvalid())
14255 return true;
14258 // If we had no init and an empty pack, and we're not retaining an expansion,
14259 // then produce a fallback value or error.
14260 if (Result.isUnset())
14261 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
14262 E->getOperator());
14264 return Result;
14267 template <typename Derived>
14268 ExprResult
14269 TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
14270 SmallVector<Expr *, 4> TransformedInits;
14271 ArrayRef<Expr *> InitExprs = E->getInitExprs();
14272 if (TransformExprs(InitExprs.data(), InitExprs.size(), true,
14273 TransformedInits))
14274 return ExprError();
14276 return getDerived().RebuildParenListExpr(E->getBeginLoc(), TransformedInits,
14277 E->getEndLoc());
14280 template<typename Derived>
14281 ExprResult
14282 TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
14283 CXXStdInitializerListExpr *E) {
14284 return getDerived().TransformExpr(E->getSubExpr());
14287 template<typename Derived>
14288 ExprResult
14289 TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
14290 return SemaRef.MaybeBindToTemporary(E);
14293 template<typename Derived>
14294 ExprResult
14295 TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
14296 return E;
14299 template<typename Derived>
14300 ExprResult
14301 TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
14302 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14303 if (SubExpr.isInvalid())
14304 return ExprError();
14306 if (!getDerived().AlwaysRebuild() &&
14307 SubExpr.get() == E->getSubExpr())
14308 return E;
14310 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
14313 template<typename Derived>
14314 ExprResult
14315 TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
14316 // Transform each of the elements.
14317 SmallVector<Expr *, 8> Elements;
14318 bool ArgChanged = false;
14319 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
14320 /*IsCall=*/false, Elements, &ArgChanged))
14321 return ExprError();
14323 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14324 return SemaRef.MaybeBindToTemporary(E);
14326 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
14327 Elements.data(),
14328 Elements.size());
14331 template<typename Derived>
14332 ExprResult
14333 TreeTransform<Derived>::TransformObjCDictionaryLiteral(
14334 ObjCDictionaryLiteral *E) {
14335 // Transform each of the elements.
14336 SmallVector<ObjCDictionaryElement, 8> Elements;
14337 bool ArgChanged = false;
14338 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
14339 ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);
14341 if (OrigElement.isPackExpansion()) {
14342 // This key/value element is a pack expansion.
14343 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14344 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
14345 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
14346 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
14348 // Determine whether the set of unexpanded parameter packs can
14349 // and should be expanded.
14350 bool Expand = true;
14351 bool RetainExpansion = false;
14352 std::optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
14353 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14354 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
14355 OrigElement.Value->getEndLoc());
14356 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
14357 PatternRange, Unexpanded, Expand,
14358 RetainExpansion, NumExpansions))
14359 return ExprError();
14361 if (!Expand) {
14362 // The transform has determined that we should perform a simple
14363 // transformation on the pack expansion, producing another pack
14364 // expansion.
14365 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14366 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14367 if (Key.isInvalid())
14368 return ExprError();
14370 if (Key.get() != OrigElement.Key)
14371 ArgChanged = true;
14373 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
14374 if (Value.isInvalid())
14375 return ExprError();
14377 if (Value.get() != OrigElement.Value)
14378 ArgChanged = true;
14380 ObjCDictionaryElement Expansion = {
14381 Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions
14383 Elements.push_back(Expansion);
14384 continue;
14387 // Record right away that the argument was changed. This needs
14388 // to happen even if the array expands to nothing.
14389 ArgChanged = true;
14391 // The transform has determined that we should perform an elementwise
14392 // expansion of the pattern. Do so.
14393 for (unsigned I = 0; I != *NumExpansions; ++I) {
14394 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14395 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14396 if (Key.isInvalid())
14397 return ExprError();
14399 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
14400 if (Value.isInvalid())
14401 return ExprError();
14403 ObjCDictionaryElement Element = {
14404 Key.get(), Value.get(), SourceLocation(), NumExpansions
14407 // If any unexpanded parameter packs remain, we still have a
14408 // pack expansion.
14409 // FIXME: Can this really happen?
14410 if (Key.get()->containsUnexpandedParameterPack() ||
14411 Value.get()->containsUnexpandedParameterPack())
14412 Element.EllipsisLoc = OrigElement.EllipsisLoc;
14414 Elements.push_back(Element);
14417 // FIXME: Retain a pack expansion if RetainExpansion is true.
14419 // We've finished with this pack expansion.
14420 continue;
14423 // Transform and check key.
14424 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14425 if (Key.isInvalid())
14426 return ExprError();
14428 if (Key.get() != OrigElement.Key)
14429 ArgChanged = true;
14431 // Transform and check value.
14432 ExprResult Value
14433 = getDerived().TransformExpr(OrigElement.Value);
14434 if (Value.isInvalid())
14435 return ExprError();
14437 if (Value.get() != OrigElement.Value)
14438 ArgChanged = true;
14440 ObjCDictionaryElement Element = {Key.get(), Value.get(), SourceLocation(),
14441 std::nullopt};
14442 Elements.push_back(Element);
14445 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14446 return SemaRef.MaybeBindToTemporary(E);
14448 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
14449 Elements);
14452 template<typename Derived>
14453 ExprResult
14454 TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
14455 TypeSourceInfo *EncodedTypeInfo
14456 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
14457 if (!EncodedTypeInfo)
14458 return ExprError();
14460 if (!getDerived().AlwaysRebuild() &&
14461 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
14462 return E;
14464 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
14465 EncodedTypeInfo,
14466 E->getRParenLoc());
14469 template<typename Derived>
14470 ExprResult TreeTransform<Derived>::
14471 TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
14472 // This is a kind of implicit conversion, and it needs to get dropped
14473 // and recomputed for the same general reasons that ImplicitCastExprs
14474 // do, as well a more specific one: this expression is only valid when
14475 // it appears *immediately* as an argument expression.
14476 return getDerived().TransformExpr(E->getSubExpr());
14479 template<typename Derived>
14480 ExprResult TreeTransform<Derived>::
14481 TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
14482 TypeSourceInfo *TSInfo
14483 = getDerived().TransformType(E->getTypeInfoAsWritten());
14484 if (!TSInfo)
14485 return ExprError();
14487 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
14488 if (Result.isInvalid())
14489 return ExprError();
14491 if (!getDerived().AlwaysRebuild() &&
14492 TSInfo == E->getTypeInfoAsWritten() &&
14493 Result.get() == E->getSubExpr())
14494 return E;
14496 return SemaRef.BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(),
14497 E->getBridgeKeywordLoc(), TSInfo,
14498 Result.get());
14501 template <typename Derived>
14502 ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
14503 ObjCAvailabilityCheckExpr *E) {
14504 return E;
14507 template<typename Derived>
14508 ExprResult
14509 TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
14510 // Transform arguments.
14511 bool ArgChanged = false;
14512 SmallVector<Expr*, 8> Args;
14513 Args.reserve(E->getNumArgs());
14514 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
14515 &ArgChanged))
14516 return ExprError();
14518 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
14519 // Class message: transform the receiver type.
14520 TypeSourceInfo *ReceiverTypeInfo
14521 = getDerived().TransformType(E->getClassReceiverTypeInfo());
14522 if (!ReceiverTypeInfo)
14523 return ExprError();
14525 // If nothing changed, just retain the existing message send.
14526 if (!getDerived().AlwaysRebuild() &&
14527 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
14528 return SemaRef.MaybeBindToTemporary(E);
14530 // Build a new class message send.
14531 SmallVector<SourceLocation, 16> SelLocs;
14532 E->getSelectorLocs(SelLocs);
14533 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
14534 E->getSelector(),
14535 SelLocs,
14536 E->getMethodDecl(),
14537 E->getLeftLoc(),
14538 Args,
14539 E->getRightLoc());
14541 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
14542 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
14543 if (!E->getMethodDecl())
14544 return ExprError();
14546 // Build a new class message send to 'super'.
14547 SmallVector<SourceLocation, 16> SelLocs;
14548 E->getSelectorLocs(SelLocs);
14549 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
14550 E->getSelector(),
14551 SelLocs,
14552 E->getReceiverType(),
14553 E->getMethodDecl(),
14554 E->getLeftLoc(),
14555 Args,
14556 E->getRightLoc());
14559 // Instance message: transform the receiver
14560 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
14561 "Only class and instance messages may be instantiated");
14562 ExprResult Receiver
14563 = getDerived().TransformExpr(E->getInstanceReceiver());
14564 if (Receiver.isInvalid())
14565 return ExprError();
14567 // If nothing changed, just retain the existing message send.
14568 if (!getDerived().AlwaysRebuild() &&
14569 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
14570 return SemaRef.MaybeBindToTemporary(E);
14572 // Build a new instance message send.
14573 SmallVector<SourceLocation, 16> SelLocs;
14574 E->getSelectorLocs(SelLocs);
14575 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
14576 E->getSelector(),
14577 SelLocs,
14578 E->getMethodDecl(),
14579 E->getLeftLoc(),
14580 Args,
14581 E->getRightLoc());
14584 template<typename Derived>
14585 ExprResult
14586 TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
14587 return E;
14590 template<typename Derived>
14591 ExprResult
14592 TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
14593 return E;
14596 template<typename Derived>
14597 ExprResult
14598 TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
14599 // Transform the base expression.
14600 ExprResult Base = getDerived().TransformExpr(E->getBase());
14601 if (Base.isInvalid())
14602 return ExprError();
14604 // We don't need to transform the ivar; it will never change.
14606 // If nothing changed, just retain the existing expression.
14607 if (!getDerived().AlwaysRebuild() &&
14608 Base.get() == E->getBase())
14609 return E;
14611 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
14612 E->getLocation(),
14613 E->isArrow(), E->isFreeIvar());
14616 template<typename Derived>
14617 ExprResult
14618 TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
14619 // 'super' and types never change. Property never changes. Just
14620 // retain the existing expression.
14621 if (!E->isObjectReceiver())
14622 return E;
14624 // Transform the base expression.
14625 ExprResult Base = getDerived().TransformExpr(E->getBase());
14626 if (Base.isInvalid())
14627 return ExprError();
14629 // We don't need to transform the property; it will never change.
14631 // If nothing changed, just retain the existing expression.
14632 if (!getDerived().AlwaysRebuild() &&
14633 Base.get() == E->getBase())
14634 return E;
14636 if (E->isExplicitProperty())
14637 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
14638 E->getExplicitProperty(),
14639 E->getLocation());
14641 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
14642 SemaRef.Context.PseudoObjectTy,
14643 E->getImplicitPropertyGetter(),
14644 E->getImplicitPropertySetter(),
14645 E->getLocation());
14648 template<typename Derived>
14649 ExprResult
14650 TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
14651 // Transform the base expression.
14652 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
14653 if (Base.isInvalid())
14654 return ExprError();
14656 // Transform the key expression.
14657 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
14658 if (Key.isInvalid())
14659 return ExprError();
14661 // If nothing changed, just retain the existing expression.
14662 if (!getDerived().AlwaysRebuild() &&
14663 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
14664 return E;
14666 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
14667 Base.get(), Key.get(),
14668 E->getAtIndexMethodDecl(),
14669 E->setAtIndexMethodDecl());
14672 template<typename Derived>
14673 ExprResult
14674 TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
14675 // Transform the base expression.
14676 ExprResult Base = getDerived().TransformExpr(E->getBase());
14677 if (Base.isInvalid())
14678 return ExprError();
14680 // If nothing changed, just retain the existing expression.
14681 if (!getDerived().AlwaysRebuild() &&
14682 Base.get() == E->getBase())
14683 return E;
14685 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
14686 E->getOpLoc(),
14687 E->isArrow());
14690 template<typename Derived>
14691 ExprResult
14692 TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
14693 bool ArgumentChanged = false;
14694 SmallVector<Expr*, 8> SubExprs;
14695 SubExprs.reserve(E->getNumSubExprs());
14696 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
14697 SubExprs, &ArgumentChanged))
14698 return ExprError();
14700 if (!getDerived().AlwaysRebuild() &&
14701 !ArgumentChanged)
14702 return E;
14704 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
14705 SubExprs,
14706 E->getRParenLoc());
14709 template<typename Derived>
14710 ExprResult
14711 TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
14712 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
14713 if (SrcExpr.isInvalid())
14714 return ExprError();
14716 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
14717 if (!Type)
14718 return ExprError();
14720 if (!getDerived().AlwaysRebuild() &&
14721 Type == E->getTypeSourceInfo() &&
14722 SrcExpr.get() == E->getSrcExpr())
14723 return E;
14725 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
14726 SrcExpr.get(), Type,
14727 E->getRParenLoc());
14730 template<typename Derived>
14731 ExprResult
14732 TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
14733 BlockDecl *oldBlock = E->getBlockDecl();
14735 SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr);
14736 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
14738 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
14739 blockScope->TheDecl->setBlockMissingReturnType(
14740 oldBlock->blockMissingReturnType());
14742 SmallVector<ParmVarDecl*, 4> params;
14743 SmallVector<QualType, 4> paramTypes;
14745 const FunctionProtoType *exprFunctionType = E->getFunctionType();
14747 // Parameter substitution.
14748 Sema::ExtParameterInfoBuilder extParamInfos;
14749 if (getDerived().TransformFunctionTypeParams(
14750 E->getCaretLocation(), oldBlock->parameters(), nullptr,
14751 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
14752 extParamInfos)) {
14753 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
14754 return ExprError();
14757 QualType exprResultType =
14758 getDerived().TransformType(exprFunctionType->getReturnType());
14760 auto epi = exprFunctionType->getExtProtoInfo();
14761 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size());
14763 QualType functionType =
14764 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
14765 blockScope->FunctionType = functionType;
14767 // Set the parameters on the block decl.
14768 if (!params.empty())
14769 blockScope->TheDecl->setParams(params);
14771 if (!oldBlock->blockMissingReturnType()) {
14772 blockScope->HasImplicitReturnType = false;
14773 blockScope->ReturnType = exprResultType;
14776 // Transform the body
14777 StmtResult body = getDerived().TransformStmt(E->getBody());
14778 if (body.isInvalid()) {
14779 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
14780 return ExprError();
14783 #ifndef NDEBUG
14784 // In builds with assertions, make sure that we captured everything we
14785 // captured before.
14786 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
14787 for (const auto &I : oldBlock->captures()) {
14788 VarDecl *oldCapture = I.getVariable();
14790 // Ignore parameter packs.
14791 if (oldCapture->isParameterPack())
14792 continue;
14794 VarDecl *newCapture =
14795 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
14796 oldCapture));
14797 assert(blockScope->CaptureMap.count(newCapture));
14800 // The this pointer may not be captured by the instantiated block, even when
14801 // it's captured by the original block, if the expression causing the
14802 // capture is in the discarded branch of a constexpr if statement.
14803 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
14804 "this pointer isn't captured in the old block");
14806 #endif
14808 return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(),
14809 /*Scope=*/nullptr);
14812 template<typename Derived>
14813 ExprResult
14814 TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
14815 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
14816 if (SrcExpr.isInvalid())
14817 return ExprError();
14819 QualType Type = getDerived().TransformType(E->getType());
14821 return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(),
14822 E->getRParenLoc());
14825 template<typename Derived>
14826 ExprResult
14827 TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
14828 bool ArgumentChanged = false;
14829 SmallVector<Expr*, 8> SubExprs;
14830 SubExprs.reserve(E->getNumSubExprs());
14831 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
14832 SubExprs, &ArgumentChanged))
14833 return ExprError();
14835 if (!getDerived().AlwaysRebuild() &&
14836 !ArgumentChanged)
14837 return E;
14839 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
14840 E->getOp(), E->getRParenLoc());
14843 //===----------------------------------------------------------------------===//
14844 // Type reconstruction
14845 //===----------------------------------------------------------------------===//
14847 template<typename Derived>
14848 QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
14849 SourceLocation Star) {
14850 return SemaRef.BuildPointerType(PointeeType, Star,
14851 getDerived().getBaseEntity());
14854 template<typename Derived>
14855 QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
14856 SourceLocation Star) {
14857 return SemaRef.BuildBlockPointerType(PointeeType, Star,
14858 getDerived().getBaseEntity());
14861 template<typename Derived>
14862 QualType
14863 TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
14864 bool WrittenAsLValue,
14865 SourceLocation Sigil) {
14866 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue,
14867 Sigil, getDerived().getBaseEntity());
14870 template<typename Derived>
14871 QualType
14872 TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
14873 QualType ClassType,
14874 SourceLocation Sigil) {
14875 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil,
14876 getDerived().getBaseEntity());
14879 template<typename Derived>
14880 QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
14881 const ObjCTypeParamDecl *Decl,
14882 SourceLocation ProtocolLAngleLoc,
14883 ArrayRef<ObjCProtocolDecl *> Protocols,
14884 ArrayRef<SourceLocation> ProtocolLocs,
14885 SourceLocation ProtocolRAngleLoc) {
14886 return SemaRef.BuildObjCTypeParamType(Decl,
14887 ProtocolLAngleLoc, Protocols,
14888 ProtocolLocs, ProtocolRAngleLoc,
14889 /*FailOnError=*/true);
14892 template<typename Derived>
14893 QualType TreeTransform<Derived>::RebuildObjCObjectType(
14894 QualType BaseType,
14895 SourceLocation Loc,
14896 SourceLocation TypeArgsLAngleLoc,
14897 ArrayRef<TypeSourceInfo *> TypeArgs,
14898 SourceLocation TypeArgsRAngleLoc,
14899 SourceLocation ProtocolLAngleLoc,
14900 ArrayRef<ObjCProtocolDecl *> Protocols,
14901 ArrayRef<SourceLocation> ProtocolLocs,
14902 SourceLocation ProtocolRAngleLoc) {
14903 return SemaRef.BuildObjCObjectType(BaseType, Loc, TypeArgsLAngleLoc, TypeArgs,
14904 TypeArgsRAngleLoc, ProtocolLAngleLoc,
14905 Protocols, ProtocolLocs, ProtocolRAngleLoc,
14906 /*FailOnError=*/true,
14907 /*Rebuilding=*/true);
14910 template<typename Derived>
14911 QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
14912 QualType PointeeType,
14913 SourceLocation Star) {
14914 return SemaRef.Context.getObjCObjectPointerType(PointeeType);
14917 template <typename Derived>
14918 QualType TreeTransform<Derived>::RebuildArrayType(
14919 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
14920 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
14921 if (SizeExpr || !Size)
14922 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
14923 IndexTypeQuals, BracketsRange,
14924 getDerived().getBaseEntity());
14926 QualType Types[] = {
14927 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
14928 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
14929 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
14931 QualType SizeType;
14932 for (const auto &T : Types)
14933 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
14934 SizeType = T;
14935 break;
14938 // Note that we can return a VariableArrayType here in the case where
14939 // the element type was a dependent VariableArrayType.
14940 IntegerLiteral *ArraySize
14941 = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType,
14942 /*FIXME*/BracketsRange.getBegin());
14943 return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize,
14944 IndexTypeQuals, BracketsRange,
14945 getDerived().getBaseEntity());
14948 template <typename Derived>
14949 QualType TreeTransform<Derived>::RebuildConstantArrayType(
14950 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
14951 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
14952 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
14953 IndexTypeQuals, BracketsRange);
14956 template <typename Derived>
14957 QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
14958 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
14959 SourceRange BracketsRange) {
14960 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
14961 IndexTypeQuals, BracketsRange);
14964 template <typename Derived>
14965 QualType TreeTransform<Derived>::RebuildVariableArrayType(
14966 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
14967 unsigned IndexTypeQuals, SourceRange BracketsRange) {
14968 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
14969 SizeExpr,
14970 IndexTypeQuals, BracketsRange);
14973 template <typename Derived>
14974 QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
14975 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
14976 unsigned IndexTypeQuals, SourceRange BracketsRange) {
14977 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
14978 SizeExpr,
14979 IndexTypeQuals, BracketsRange);
14982 template <typename Derived>
14983 QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
14984 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
14985 return SemaRef.BuildAddressSpaceAttr(PointeeType, AddrSpaceExpr,
14986 AttributeLoc);
14989 template <typename Derived>
14990 QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
14991 unsigned NumElements,
14992 VectorKind VecKind) {
14993 // FIXME: semantic checking!
14994 return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);
14997 template <typename Derived>
14998 QualType TreeTransform<Derived>::RebuildDependentVectorType(
14999 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
15000 VectorKind VecKind) {
15001 return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc);
15004 template<typename Derived>
15005 QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
15006 unsigned NumElements,
15007 SourceLocation AttributeLoc) {
15008 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
15009 NumElements, true);
15010 IntegerLiteral *VectorSize
15011 = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
15012 AttributeLoc);
15013 return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
15016 template<typename Derived>
15017 QualType
15018 TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
15019 Expr *SizeExpr,
15020 SourceLocation AttributeLoc) {
15021 return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
15024 template <typename Derived>
15025 QualType TreeTransform<Derived>::RebuildConstantMatrixType(
15026 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
15027 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
15028 NumColumns);
15031 template <typename Derived>
15032 QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
15033 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
15034 SourceLocation AttributeLoc) {
15035 return SemaRef.BuildMatrixType(ElementType, RowExpr, ColumnExpr,
15036 AttributeLoc);
15039 template<typename Derived>
15040 QualType TreeTransform<Derived>::RebuildFunctionProtoType(
15041 QualType T,
15042 MutableArrayRef<QualType> ParamTypes,
15043 const FunctionProtoType::ExtProtoInfo &EPI) {
15044 return SemaRef.BuildFunctionType(T, ParamTypes,
15045 getDerived().getBaseLocation(),
15046 getDerived().getBaseEntity(),
15047 EPI);
15050 template<typename Derived>
15051 QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
15052 return SemaRef.Context.getFunctionNoProtoType(T);
15055 template<typename Derived>
15056 QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
15057 Decl *D) {
15058 assert(D && "no decl found");
15059 if (D->isInvalidDecl()) return QualType();
15061 // FIXME: Doesn't account for ObjCInterfaceDecl!
15062 if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
15063 // A valid resolved using typename pack expansion decl can have multiple
15064 // UsingDecls, but they must each have exactly one type, and it must be
15065 // the same type in every case. But we must have at least one expansion!
15066 if (UPD->expansions().empty()) {
15067 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
15068 << UPD->isCXXClassMember() << UPD;
15069 return QualType();
15072 // We might still have some unresolved types. Try to pick a resolved type
15073 // if we can. The final instantiation will check that the remaining
15074 // unresolved types instantiate to the type we pick.
15075 QualType FallbackT;
15076 QualType T;
15077 for (auto *E : UPD->expansions()) {
15078 QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
15079 if (ThisT.isNull())
15080 continue;
15081 else if (ThisT->getAs<UnresolvedUsingType>())
15082 FallbackT = ThisT;
15083 else if (T.isNull())
15084 T = ThisT;
15085 else
15086 assert(getSema().Context.hasSameType(ThisT, T) &&
15087 "mismatched resolved types in using pack expansion");
15089 return T.isNull() ? FallbackT : T;
15090 } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
15091 assert(Using->hasTypename() &&
15092 "UnresolvedUsingTypenameDecl transformed to non-typename using");
15094 // A valid resolved using typename decl points to exactly one type decl.
15095 assert(++Using->shadow_begin() == Using->shadow_end());
15097 UsingShadowDecl *Shadow = *Using->shadow_begin();
15098 if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), Loc))
15099 return QualType();
15100 return SemaRef.Context.getUsingType(
15101 Shadow, SemaRef.Context.getTypeDeclType(
15102 cast<TypeDecl>(Shadow->getTargetDecl())));
15103 } else {
15104 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
15105 "UnresolvedUsingTypenameDecl transformed to non-using decl");
15106 return SemaRef.Context.getTypeDeclType(
15107 cast<UnresolvedUsingTypenameDecl>(D));
15111 template <typename Derived>
15112 QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
15113 TypeOfKind Kind) {
15114 return SemaRef.BuildTypeofExprType(E, Kind);
15117 template<typename Derived>
15118 QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
15119 TypeOfKind Kind) {
15120 return SemaRef.Context.getTypeOfType(Underlying, Kind);
15123 template <typename Derived>
15124 QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
15125 return SemaRef.BuildDecltypeType(E);
15128 template<typename Derived>
15129 QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
15130 UnaryTransformType::UTTKind UKind,
15131 SourceLocation Loc) {
15132 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
15135 template<typename Derived>
15136 QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
15137 TemplateName Template,
15138 SourceLocation TemplateNameLoc,
15139 TemplateArgumentListInfo &TemplateArgs) {
15140 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
15143 template<typename Derived>
15144 QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
15145 SourceLocation KWLoc) {
15146 return SemaRef.BuildAtomicType(ValueType, KWLoc);
15149 template<typename Derived>
15150 QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
15151 SourceLocation KWLoc,
15152 bool isReadPipe) {
15153 return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc)
15154 : SemaRef.BuildWritePipeType(ValueType, KWLoc);
15157 template <typename Derived>
15158 QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
15159 unsigned NumBits,
15160 SourceLocation Loc) {
15161 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
15162 NumBits, true);
15163 IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,
15164 SemaRef.Context.IntTy, Loc);
15165 return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc);
15168 template <typename Derived>
15169 QualType TreeTransform<Derived>::RebuildDependentBitIntType(
15170 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
15171 return SemaRef.BuildBitIntType(IsUnsigned, NumBitsExpr, Loc);
15174 template<typename Derived>
15175 TemplateName
15176 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15177 bool TemplateKW,
15178 TemplateDecl *Template) {
15179 return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW,
15180 TemplateName(Template));
15183 template<typename Derived>
15184 TemplateName
15185 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15186 SourceLocation TemplateKWLoc,
15187 const IdentifierInfo &Name,
15188 SourceLocation NameLoc,
15189 QualType ObjectType,
15190 NamedDecl *FirstQualifierInScope,
15191 bool AllowInjectedClassName) {
15192 UnqualifiedId TemplateName;
15193 TemplateName.setIdentifier(&Name, NameLoc);
15194 Sema::TemplateTy Template;
15195 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
15196 TemplateName, ParsedType::make(ObjectType),
15197 /*EnteringContext=*/false, Template,
15198 AllowInjectedClassName);
15199 return Template.get();
15202 template<typename Derived>
15203 TemplateName
15204 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15205 SourceLocation TemplateKWLoc,
15206 OverloadedOperatorKind Operator,
15207 SourceLocation NameLoc,
15208 QualType ObjectType,
15209 bool AllowInjectedClassName) {
15210 UnqualifiedId Name;
15211 // FIXME: Bogus location information.
15212 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
15213 Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);
15214 Sema::TemplateTy Template;
15215 getSema().ActOnTemplateName(
15216 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(ObjectType),
15217 /*EnteringContext=*/false, Template, AllowInjectedClassName);
15218 return Template.get();
15221 template <typename Derived>
15222 ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
15223 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
15224 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
15225 Expr *Second) {
15226 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
15228 if (First->getObjectKind() == OK_ObjCProperty) {
15229 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
15230 if (BinaryOperator::isAssignmentOp(Opc))
15231 return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc, Opc,
15232 First, Second);
15233 ExprResult Result = SemaRef.CheckPlaceholderExpr(First);
15234 if (Result.isInvalid())
15235 return ExprError();
15236 First = Result.get();
15239 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
15240 ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
15241 if (Result.isInvalid())
15242 return ExprError();
15243 Second = Result.get();
15246 // Determine whether this should be a builtin operation.
15247 if (Op == OO_Subscript) {
15248 if (!First->getType()->isOverloadableType() &&
15249 !Second->getType()->isOverloadableType())
15250 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
15251 OpLoc);
15252 } else if (Op == OO_Arrow) {
15253 // It is possible that the type refers to a RecoveryExpr created earlier
15254 // in the tree transformation.
15255 if (First->getType()->isDependentType())
15256 return ExprError();
15257 // -> is never a builtin operation.
15258 return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);
15259 } else if (Second == nullptr || isPostIncDec) {
15260 if (!First->getType()->isOverloadableType() ||
15261 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
15262 // The argument is not of overloadable type, or this is an expression
15263 // of the form &Class::member, so try to create a built-in unary
15264 // operation.
15265 UnaryOperatorKind Opc
15266 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
15268 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
15270 } else {
15271 if (!First->getType()->isOverloadableType() &&
15272 !Second->getType()->isOverloadableType()) {
15273 // Neither of the arguments is an overloadable type, so try to
15274 // create a built-in binary operation.
15275 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
15276 ExprResult Result
15277 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
15278 if (Result.isInvalid())
15279 return ExprError();
15281 return Result;
15285 // Add any functions found via argument-dependent lookup.
15286 Expr *Args[2] = { First, Second };
15287 unsigned NumArgs = 1 + (Second != nullptr);
15289 // Create the overloaded operator invocation for unary operators.
15290 if (NumArgs == 1 || isPostIncDec) {
15291 UnaryOperatorKind Opc
15292 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
15293 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First,
15294 RequiresADL);
15297 // Create the overloaded operator invocation for binary operators.
15298 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
15299 ExprResult Result = SemaRef.CreateOverloadedBinOp(
15300 OpLoc, Opc, Functions, Args[0], Args[1], RequiresADL);
15301 if (Result.isInvalid())
15302 return ExprError();
15304 return Result;
15307 template<typename Derived>
15308 ExprResult
15309 TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
15310 SourceLocation OperatorLoc,
15311 bool isArrow,
15312 CXXScopeSpec &SS,
15313 TypeSourceInfo *ScopeType,
15314 SourceLocation CCLoc,
15315 SourceLocation TildeLoc,
15316 PseudoDestructorTypeStorage Destroyed) {
15317 QualType BaseType = Base->getType();
15318 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
15319 (!isArrow && !BaseType->getAs<RecordType>()) ||
15320 (isArrow && BaseType->getAs<PointerType>() &&
15321 !BaseType->castAs<PointerType>()->getPointeeType()
15322 ->template getAs<RecordType>())){
15323 // This pseudo-destructor expression is still a pseudo-destructor.
15324 return SemaRef.BuildPseudoDestructorExpr(
15325 Base, OperatorLoc, isArrow ? tok::arrow : tok::period, SS, ScopeType,
15326 CCLoc, TildeLoc, Destroyed);
15329 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
15330 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
15331 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
15332 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
15333 NameInfo.setNamedTypeInfo(DestroyedType);
15335 // The scope type is now known to be a valid nested name specifier
15336 // component. Tack it on to the end of the nested name specifier.
15337 if (ScopeType) {
15338 if (!ScopeType->getType()->getAs<TagType>()) {
15339 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
15340 diag::err_expected_class_or_namespace)
15341 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
15342 return ExprError();
15344 SS.Extend(SemaRef.Context, SourceLocation(), ScopeType->getTypeLoc(),
15345 CCLoc);
15348 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
15349 return getSema().BuildMemberReferenceExpr(Base, BaseType,
15350 OperatorLoc, isArrow,
15351 SS, TemplateKWLoc,
15352 /*FIXME: FirstQualifier*/ nullptr,
15353 NameInfo,
15354 /*TemplateArgs*/ nullptr,
15355 /*S*/nullptr);
15358 template<typename Derived>
15359 StmtResult
15360 TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
15361 SourceLocation Loc = S->getBeginLoc();
15362 CapturedDecl *CD = S->getCapturedDecl();
15363 unsigned NumParams = CD->getNumParams();
15364 unsigned ContextParamPos = CD->getContextParamPosition();
15365 SmallVector<Sema::CapturedParamNameType, 4> Params;
15366 for (unsigned I = 0; I < NumParams; ++I) {
15367 if (I != ContextParamPos) {
15368 Params.push_back(
15369 std::make_pair(
15370 CD->getParam(I)->getName(),
15371 getDerived().TransformType(CD->getParam(I)->getType())));
15372 } else {
15373 Params.push_back(std::make_pair(StringRef(), QualType()));
15376 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
15377 S->getCapturedRegionKind(), Params);
15378 StmtResult Body;
15380 Sema::CompoundScopeRAII CompoundScope(getSema());
15381 Body = getDerived().TransformStmt(S->getCapturedStmt());
15384 if (Body.isInvalid()) {
15385 getSema().ActOnCapturedRegionError();
15386 return StmtError();
15389 return getSema().ActOnCapturedRegionEnd(Body.get());
15392 } // end namespace clang
15394 #endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H