[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / lib / Sema / TreeTransform.h
blob25b3034a5efac083e35bbaebf6485b17e4e8d518
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/Designator.h"
22 #include "clang/AST/Expr.h"
23 #include "clang/AST/ExprCXX.h"
24 #include "clang/AST/ExprConcepts.h"
25 #include "clang/AST/ExprObjC.h"
26 #include "clang/AST/ExprOpenMP.h"
27 #include "clang/AST/OpenMPClause.h"
28 #include "clang/AST/Stmt.h"
29 #include "clang/AST/StmtCXX.h"
30 #include "clang/AST/StmtObjC.h"
31 #include "clang/AST/StmtOpenMP.h"
32 #include "clang/Basic/DiagnosticParse.h"
33 #include "clang/Basic/OpenMPKinds.h"
34 #include "clang/Sema/Lookup.h"
35 #include "clang/Sema/Ownership.h"
36 #include "clang/Sema/ParsedTemplate.h"
37 #include "clang/Sema/ScopeInfo.h"
38 #include "clang/Sema/SemaDiagnostic.h"
39 #include "clang/Sema/SemaInternal.h"
40 #include "llvm/ADT/ArrayRef.h"
41 #include "llvm/Support/ErrorHandling.h"
42 #include <algorithm>
43 #include <optional>
45 using namespace llvm::omp;
47 namespace clang {
48 using namespace sema;
50 /// A semantic tree transformation that allows one to transform one
51 /// abstract syntax tree into another.
52 ///
53 /// A new tree transformation is defined by creating a new subclass \c X of
54 /// \c TreeTransform<X> and then overriding certain operations to provide
55 /// behavior specific to that transformation. For example, template
56 /// instantiation is implemented as a tree transformation where the
57 /// transformation of TemplateTypeParmType nodes involves substituting the
58 /// template arguments for their corresponding template parameters; a similar
59 /// transformation is performed for non-type template parameters and
60 /// template template parameters.
61 ///
62 /// This tree-transformation template uses static polymorphism to allow
63 /// subclasses to customize any of its operations. Thus, a subclass can
64 /// override any of the transformation or rebuild operators by providing an
65 /// operation with the same signature as the default implementation. The
66 /// overriding function should not be virtual.
67 ///
68 /// Semantic tree transformations are split into two stages, either of which
69 /// can be replaced by a subclass. The "transform" step transforms an AST node
70 /// or the parts of an AST node using the various transformation functions,
71 /// then passes the pieces on to the "rebuild" step, which constructs a new AST
72 /// node of the appropriate kind from the pieces. The default transformation
73 /// routines recursively transform the operands to composite AST nodes (e.g.,
74 /// the pointee type of a PointerType node) and, if any of those operand nodes
75 /// were changed by the transformation, invokes the rebuild operation to create
76 /// a new AST node.
77 ///
78 /// Subclasses can customize the transformation at various levels. The
79 /// most coarse-grained transformations involve replacing TransformType(),
80 /// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
81 /// TransformTemplateName(), or TransformTemplateArgument() with entirely
82 /// new implementations.
83 ///
84 /// For more fine-grained transformations, subclasses can replace any of the
85 /// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
86 /// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
87 /// replacing TransformTemplateTypeParmType() allows template instantiation
88 /// to substitute template arguments for their corresponding template
89 /// parameters. Additionally, subclasses can override the \c RebuildXXX
90 /// functions to control how AST nodes are rebuilt when their operands change.
91 /// By default, \c TreeTransform will invoke semantic analysis to rebuild
92 /// AST nodes. However, certain other tree transformations (e.g, cloning) may
93 /// be able to use more efficient rebuild steps.
94 ///
95 /// There are a handful of other functions that can be overridden, allowing one
96 /// to avoid traversing nodes that don't need any transformation
97 /// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
98 /// operands have not changed (\c AlwaysRebuild()), and customize the
99 /// default locations and entity names used for type-checking
100 /// (\c getBaseLocation(), \c getBaseEntity()).
101 template<typename Derived>
102 class TreeTransform {
103 /// Private RAII object that helps us forget and then re-remember
104 /// the template argument corresponding to a partially-substituted parameter
105 /// pack.
106 class ForgetPartiallySubstitutedPackRAII {
107 Derived &Self;
108 TemplateArgument Old;
110 public:
111 ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) {
112 Old = Self.ForgetPartiallySubstitutedPack();
115 ~ForgetPartiallySubstitutedPackRAII() {
116 Self.RememberPartiallySubstitutedPack(Old);
120 protected:
121 Sema &SemaRef;
123 /// The set of local declarations that have been transformed, for
124 /// cases where we are forced to build new declarations within the transformer
125 /// rather than in the subclass (e.g., lambda closure types).
126 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
128 public:
129 /// Initializes a new tree transformer.
130 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
132 /// Retrieves a reference to the derived class.
133 Derived &getDerived() { return static_cast<Derived&>(*this); }
135 /// Retrieves a reference to the derived class.
136 const Derived &getDerived() const {
137 return static_cast<const Derived&>(*this);
140 static inline ExprResult Owned(Expr *E) { return E; }
141 static inline StmtResult Owned(Stmt *S) { return S; }
143 /// Retrieves a reference to the semantic analysis object used for
144 /// this tree transform.
145 Sema &getSema() const { return SemaRef; }
147 /// Whether the transformation should always rebuild AST nodes, even
148 /// if none of the children have changed.
150 /// Subclasses may override this function to specify when the transformation
151 /// should rebuild all AST nodes.
153 /// We must always rebuild all AST nodes when performing variadic template
154 /// pack expansion, in order to avoid violating the AST invariant that each
155 /// statement node appears at most once in its containing declaration.
156 bool AlwaysRebuild() { return SemaRef.ArgumentPackSubstitutionIndex != -1; }
158 /// Whether the transformation is forming an expression or statement that
159 /// replaces the original. In this case, we'll reuse mangling numbers from
160 /// existing lambdas.
161 bool ReplacingOriginal() { return false; }
163 /// Wether CXXConstructExpr can be skipped when they are implicit.
164 /// They will be reconstructed when used if needed.
165 /// This is useful when the user that cause rebuilding of the
166 /// CXXConstructExpr is outside of the expression at which the TreeTransform
167 /// started.
168 bool AllowSkippingCXXConstructExpr() { return true; }
170 /// Returns the location of the entity being transformed, if that
171 /// information was not available elsewhere in the AST.
173 /// By default, returns no source-location information. Subclasses can
174 /// provide an alternative implementation that provides better location
175 /// information.
176 SourceLocation getBaseLocation() { return SourceLocation(); }
178 /// Returns the name of the entity being transformed, if that
179 /// information was not available elsewhere in the AST.
181 /// By default, returns an empty name. Subclasses can provide an alternative
182 /// implementation with a more precise name.
183 DeclarationName getBaseEntity() { return DeclarationName(); }
185 /// Sets the "base" location and entity when that
186 /// information is known based on another transformation.
188 /// By default, the source location and entity are ignored. Subclasses can
189 /// override this function to provide a customized implementation.
190 void setBase(SourceLocation Loc, DeclarationName Entity) { }
192 /// RAII object that temporarily sets the base location and entity
193 /// used for reporting diagnostics in types.
194 class TemporaryBase {
195 TreeTransform &Self;
196 SourceLocation OldLocation;
197 DeclarationName OldEntity;
199 public:
200 TemporaryBase(TreeTransform &Self, SourceLocation Location,
201 DeclarationName Entity) : Self(Self) {
202 OldLocation = Self.getDerived().getBaseLocation();
203 OldEntity = Self.getDerived().getBaseEntity();
205 if (Location.isValid())
206 Self.getDerived().setBase(Location, Entity);
209 ~TemporaryBase() {
210 Self.getDerived().setBase(OldLocation, OldEntity);
214 /// Determine whether the given type \p T has already been
215 /// transformed.
217 /// Subclasses can provide an alternative implementation of this routine
218 /// to short-circuit evaluation when it is known that a given type will
219 /// not change. For example, template instantiation need not traverse
220 /// non-dependent types.
221 bool AlreadyTransformed(QualType T) {
222 return T.isNull();
225 /// Transform a template parameter depth level.
227 /// During a transformation that transforms template parameters, this maps
228 /// an old template parameter depth to a new depth.
229 unsigned TransformTemplateDepth(unsigned Depth) {
230 return Depth;
233 /// Determine whether the given call argument should be dropped, e.g.,
234 /// because it is a default argument.
236 /// Subclasses can provide an alternative implementation of this routine to
237 /// determine which kinds of call arguments get dropped. By default,
238 /// CXXDefaultArgument nodes are dropped (prior to transformation).
239 bool DropCallArgument(Expr *E) {
240 return E->isDefaultArgument();
243 /// Determine whether we should expand a pack expansion with the
244 /// given set of parameter packs into separate arguments by repeatedly
245 /// transforming the pattern.
247 /// By default, the transformer never tries to expand pack expansions.
248 /// Subclasses can override this routine to provide different behavior.
250 /// \param EllipsisLoc The location of the ellipsis that identifies the
251 /// pack expansion.
253 /// \param PatternRange The source range that covers the entire pattern of
254 /// the pack expansion.
256 /// \param Unexpanded The set of unexpanded parameter packs within the
257 /// pattern.
259 /// \param ShouldExpand Will be set to \c true if the transformer should
260 /// expand the corresponding pack expansions into separate arguments. When
261 /// set, \c NumExpansions must also be set.
263 /// \param RetainExpansion Whether the caller should add an unexpanded
264 /// pack expansion after all of the expanded arguments. This is used
265 /// when extending explicitly-specified template argument packs per
266 /// C++0x [temp.arg.explicit]p9.
268 /// \param NumExpansions The number of separate arguments that will be in
269 /// the expanded form of the corresponding pack expansion. This is both an
270 /// input and an output parameter, which can be set by the caller if the
271 /// number of expansions is known a priori (e.g., due to a prior substitution)
272 /// and will be set by the callee when the number of expansions is known.
273 /// The callee must set this value when \c ShouldExpand is \c true; it may
274 /// set this value in other cases.
276 /// \returns true if an error occurred (e.g., because the parameter packs
277 /// are to be instantiated with arguments of different lengths), false
278 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
279 /// must be set.
280 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
281 SourceRange PatternRange,
282 ArrayRef<UnexpandedParameterPack> Unexpanded,
283 bool &ShouldExpand, bool &RetainExpansion,
284 std::optional<unsigned> &NumExpansions) {
285 ShouldExpand = false;
286 return false;
289 /// "Forget" about the partially-substituted pack template argument,
290 /// when performing an instantiation that must preserve the parameter pack
291 /// use.
293 /// This routine is meant to be overridden by the template instantiator.
294 TemplateArgument ForgetPartiallySubstitutedPack() {
295 return TemplateArgument();
298 /// "Remember" the partially-substituted pack template argument
299 /// after performing an instantiation that must preserve the parameter pack
300 /// use.
302 /// This routine is meant to be overridden by the template instantiator.
303 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
305 /// Note to the derived class when a function parameter pack is
306 /// being expanded.
307 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
309 /// Transforms the given type into another type.
311 /// By default, this routine transforms a type by creating a
312 /// TypeSourceInfo for it and delegating to the appropriate
313 /// function. This is expensive, but we don't mind, because
314 /// this method is deprecated anyway; all users should be
315 /// switched to storing TypeSourceInfos.
317 /// \returns the transformed type.
318 QualType TransformType(QualType T);
320 /// Transforms the given type-with-location into a new
321 /// type-with-location.
323 /// By default, this routine transforms a type by delegating to the
324 /// appropriate TransformXXXType to build a new type. Subclasses
325 /// may override this function (to take over all type
326 /// transformations) or some set of the TransformXXXType functions
327 /// to alter the transformation.
328 TypeSourceInfo *TransformType(TypeSourceInfo *DI);
330 /// Transform the given type-with-location into a new
331 /// type, collecting location information in the given builder
332 /// as necessary.
334 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
336 /// Transform a type that is permitted to produce a
337 /// DeducedTemplateSpecializationType.
339 /// This is used in the (relatively rare) contexts where it is acceptable
340 /// for transformation to produce a class template type with deduced
341 /// template arguments.
342 /// @{
343 QualType TransformTypeWithDeducedTST(QualType T);
344 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *DI);
345 /// @}
347 /// The reason why the value of a statement is not discarded, if any.
348 enum StmtDiscardKind {
349 SDK_Discarded,
350 SDK_NotDiscarded,
351 SDK_StmtExprResult,
354 /// Transform the given statement.
356 /// By default, this routine transforms a statement by delegating to the
357 /// appropriate TransformXXXStmt function to transform a specific kind of
358 /// statement or the TransformExpr() function to transform an expression.
359 /// Subclasses may override this function to transform statements using some
360 /// other mechanism.
362 /// \returns the transformed statement.
363 StmtResult TransformStmt(Stmt *S, StmtDiscardKind SDK = SDK_Discarded);
365 /// Transform the given statement.
367 /// By default, this routine transforms a statement by delegating to the
368 /// appropriate TransformOMPXXXClause function to transform a specific kind
369 /// of clause. Subclasses may override this function to transform statements
370 /// using some other mechanism.
372 /// \returns the transformed OpenMP clause.
373 OMPClause *TransformOMPClause(OMPClause *S);
375 /// Transform the given attribute.
377 /// By default, this routine transforms a statement by delegating to the
378 /// appropriate TransformXXXAttr function to transform a specific kind
379 /// of attribute. Subclasses may override this function to transform
380 /// attributed statements using some other mechanism.
382 /// \returns the transformed attribute
383 const Attr *TransformAttr(const Attr *S);
385 /// Transform the specified attribute.
387 /// Subclasses should override the transformation of attributes with a pragma
388 /// spelling to transform expressions stored within the attribute.
390 /// \returns the transformed attribute.
391 #define ATTR(X)
392 #define PRAGMA_SPELLING_ATTR(X) \
393 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
394 #include "clang/Basic/AttrList.inc"
396 /// Transform the given expression.
398 /// By default, this routine transforms an expression by delegating to the
399 /// appropriate TransformXXXExpr function to build a new expression.
400 /// Subclasses may override this function to transform expressions using some
401 /// other mechanism.
403 /// \returns the transformed expression.
404 ExprResult TransformExpr(Expr *E);
406 /// Transform the given initializer.
408 /// By default, this routine transforms an initializer by stripping off the
409 /// semantic nodes added by initialization, then passing the result to
410 /// TransformExpr or TransformExprs.
412 /// \returns the transformed initializer.
413 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
415 /// Transform the given list of expressions.
417 /// This routine transforms a list of expressions by invoking
418 /// \c TransformExpr() for each subexpression. However, it also provides
419 /// support for variadic templates by expanding any pack expansions (if the
420 /// derived class permits such expansion) along the way. When pack expansions
421 /// are present, the number of outputs may not equal the number of inputs.
423 /// \param Inputs The set of expressions to be transformed.
425 /// \param NumInputs The number of expressions in \c Inputs.
427 /// \param IsCall If \c true, then this transform is being performed on
428 /// function-call arguments, and any arguments that should be dropped, will
429 /// be.
431 /// \param Outputs The transformed input expressions will be added to this
432 /// vector.
434 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
435 /// due to transformation.
437 /// \returns true if an error occurred, false otherwise.
438 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
439 SmallVectorImpl<Expr *> &Outputs,
440 bool *ArgChanged = nullptr);
442 /// Transform the given declaration, which is referenced from a type
443 /// or expression.
445 /// By default, acts as the identity function on declarations, unless the
446 /// transformer has had to transform the declaration itself. Subclasses
447 /// may override this function to provide alternate behavior.
448 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
449 llvm::DenseMap<Decl *, Decl *>::iterator Known
450 = TransformedLocalDecls.find(D);
451 if (Known != TransformedLocalDecls.end())
452 return Known->second;
454 return D;
457 /// Transform the specified condition.
459 /// By default, this transforms the variable and expression and rebuilds
460 /// the condition.
461 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
462 Expr *Expr,
463 Sema::ConditionKind Kind);
465 /// Transform the attributes associated with the given declaration and
466 /// place them on the new declaration.
468 /// By default, this operation does nothing. Subclasses may override this
469 /// behavior to transform attributes.
470 void transformAttrs(Decl *Old, Decl *New) { }
472 /// Note that a local declaration has been transformed by this
473 /// transformer.
475 /// Local declarations are typically transformed via a call to
476 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
477 /// the transformer itself has to transform the declarations. This routine
478 /// can be overridden by a subclass that keeps track of such mappings.
479 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
480 assert(New.size() == 1 &&
481 "must override transformedLocalDecl if performing pack expansion");
482 TransformedLocalDecls[Old] = New.front();
485 /// Transform the definition of the given declaration.
487 /// By default, invokes TransformDecl() to transform the declaration.
488 /// Subclasses may override this function to provide alternate behavior.
489 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
490 return getDerived().TransformDecl(Loc, D);
493 /// Transform the given declaration, which was the first part of a
494 /// nested-name-specifier in a member access expression.
496 /// This specific declaration transformation only applies to the first
497 /// identifier in a nested-name-specifier of a member access expression, e.g.,
498 /// the \c T in \c x->T::member
500 /// By default, invokes TransformDecl() to transform the declaration.
501 /// Subclasses may override this function to provide alternate behavior.
502 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
503 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
506 /// Transform the set of declarations in an OverloadExpr.
507 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
508 LookupResult &R);
510 /// Transform the given nested-name-specifier with source-location
511 /// information.
513 /// By default, transforms all of the types and declarations within the
514 /// nested-name-specifier. Subclasses may override this function to provide
515 /// alternate behavior.
516 NestedNameSpecifierLoc
517 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
518 QualType ObjectType = QualType(),
519 NamedDecl *FirstQualifierInScope = nullptr);
521 /// Transform the given declaration name.
523 /// By default, transforms the types of conversion function, constructor,
524 /// and destructor names and then (if needed) rebuilds the declaration name.
525 /// Identifiers and selectors are returned unmodified. Subclasses may
526 /// override this function to provide alternate behavior.
527 DeclarationNameInfo
528 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
530 bool TransformRequiresExprRequirements(ArrayRef<concepts::Requirement *> Reqs,
531 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
532 concepts::TypeRequirement *
533 TransformTypeRequirement(concepts::TypeRequirement *Req);
534 concepts::ExprRequirement *
535 TransformExprRequirement(concepts::ExprRequirement *Req);
536 concepts::NestedRequirement *
537 TransformNestedRequirement(concepts::NestedRequirement *Req);
539 /// Transform the given template name.
541 /// \param SS The nested-name-specifier that qualifies the template
542 /// name. This nested-name-specifier must already have been transformed.
544 /// \param Name The template name to transform.
546 /// \param NameLoc The source location of the template name.
548 /// \param ObjectType If we're translating a template name within a member
549 /// access expression, this is the type of the object whose member template
550 /// is being referenced.
552 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
553 /// also refers to a name within the current (lexical) scope, this is the
554 /// declaration it refers to.
556 /// By default, transforms the template name by transforming the declarations
557 /// and nested-name-specifiers that occur within the template name.
558 /// Subclasses may override this function to provide alternate behavior.
559 TemplateName
560 TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
561 SourceLocation NameLoc,
562 QualType ObjectType = QualType(),
563 NamedDecl *FirstQualifierInScope = nullptr,
564 bool AllowInjectedClassName = false);
566 /// Transform the given template argument.
568 /// By default, this operation transforms the type, expression, or
569 /// declaration stored within the template argument and constructs a
570 /// new template argument from the transformed result. Subclasses may
571 /// override this function to provide alternate behavior.
573 /// Returns true if there was an error.
574 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
575 TemplateArgumentLoc &Output,
576 bool Uneval = false);
578 /// Transform the given set of template arguments.
580 /// By default, this operation transforms all of the template arguments
581 /// in the input set using \c TransformTemplateArgument(), and appends
582 /// the transformed arguments to the output list.
584 /// Note that this overload of \c TransformTemplateArguments() is merely
585 /// a convenience function. Subclasses that wish to override this behavior
586 /// should override the iterator-based member template version.
588 /// \param Inputs The set of template arguments to be transformed.
590 /// \param NumInputs The number of template arguments in \p Inputs.
592 /// \param Outputs The set of transformed template arguments output by this
593 /// routine.
595 /// Returns true if an error occurred.
596 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
597 unsigned NumInputs,
598 TemplateArgumentListInfo &Outputs,
599 bool Uneval = false) {
600 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
601 Uneval);
604 /// Transform the given set of template arguments.
606 /// By default, this operation transforms all of the template arguments
607 /// in the input set using \c TransformTemplateArgument(), and appends
608 /// the transformed arguments to the output list.
610 /// \param First An iterator to the first template argument.
612 /// \param Last An iterator one step past the last template argument.
614 /// \param Outputs The set of transformed template arguments output by this
615 /// routine.
617 /// Returns true if an error occurred.
618 template<typename InputIterator>
619 bool TransformTemplateArguments(InputIterator First,
620 InputIterator Last,
621 TemplateArgumentListInfo &Outputs,
622 bool Uneval = false);
624 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
625 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
626 TemplateArgumentLoc &ArgLoc);
628 /// Fakes up a TypeSourceInfo for a type.
629 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
630 return SemaRef.Context.getTrivialTypeSourceInfo(T,
631 getDerived().getBaseLocation());
634 #define ABSTRACT_TYPELOC(CLASS, PARENT)
635 #define TYPELOC(CLASS, PARENT) \
636 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
637 #include "clang/AST/TypeLocNodes.def"
639 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
640 TemplateTypeParmTypeLoc TL,
641 bool SuppressObjCLifetime);
642 QualType
643 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
644 SubstTemplateTypeParmPackTypeLoc TL,
645 bool SuppressObjCLifetime);
647 template<typename Fn>
648 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
649 FunctionProtoTypeLoc TL,
650 CXXRecordDecl *ThisContext,
651 Qualifiers ThisTypeQuals,
652 Fn TransformExceptionSpec);
654 bool TransformExceptionSpec(SourceLocation Loc,
655 FunctionProtoType::ExceptionSpecInfo &ESI,
656 SmallVectorImpl<QualType> &Exceptions,
657 bool &Changed);
659 StmtResult TransformSEHHandler(Stmt *Handler);
661 QualType
662 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
663 TemplateSpecializationTypeLoc TL,
664 TemplateName Template);
666 QualType
667 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
668 DependentTemplateSpecializationTypeLoc TL,
669 TemplateName Template,
670 CXXScopeSpec &SS);
672 QualType TransformDependentTemplateSpecializationType(
673 TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
674 NestedNameSpecifierLoc QualifierLoc);
676 /// Transforms the parameters of a function type into the
677 /// given vectors.
679 /// The result vectors should be kept in sync; null entries in the
680 /// variables vector are acceptable.
682 /// LastParamTransformed, if non-null, will be set to the index of the last
683 /// parameter on which transfromation was started. In the event of an error,
684 /// this will contain the parameter which failed to instantiate.
686 /// Return true on error.
687 bool TransformFunctionTypeParams(
688 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
689 const QualType *ParamTypes,
690 const FunctionProtoType::ExtParameterInfo *ParamInfos,
691 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
692 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
694 bool TransformFunctionTypeParams(
695 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
696 const QualType *ParamTypes,
697 const FunctionProtoType::ExtParameterInfo *ParamInfos,
698 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
699 Sema::ExtParameterInfoBuilder &PInfos) {
700 return getDerived().TransformFunctionTypeParams(
701 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
704 /// Transforms the parameters of a requires expresison into the given vectors.
706 /// The result vectors should be kept in sync; null entries in the
707 /// variables vector are acceptable.
709 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
710 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
711 /// which are cases where transformation shouldn't continue.
712 ExprResult TransformRequiresTypeParams(
713 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
714 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
715 SmallVectorImpl<QualType> &PTypes,
716 SmallVectorImpl<ParmVarDecl *> &TransParams,
717 Sema::ExtParameterInfoBuilder &PInfos) {
718 if (getDerived().TransformFunctionTypeParams(
719 KWLoc, Params, /*ParamTypes=*/nullptr,
720 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
721 return ExprError();
723 return ExprResult{};
726 /// Transforms a single function-type parameter. Return null
727 /// on error.
729 /// \param indexAdjustment - A number to add to the parameter's
730 /// scope index; can be negative
731 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
732 int indexAdjustment,
733 std::optional<unsigned> NumExpansions,
734 bool ExpectParameterPack);
736 /// Transform the body of a lambda-expression.
737 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
738 /// Alternative implementation of TransformLambdaBody that skips transforming
739 /// the body.
740 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
742 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
744 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
745 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
747 TemplateParameterList *TransformTemplateParameterList(
748 TemplateParameterList *TPL) {
749 return TPL;
752 ExprResult TransformAddressOfOperand(Expr *E);
754 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
755 bool IsAddressOfOperand,
756 TypeSourceInfo **RecoveryTSI);
758 ExprResult TransformParenDependentScopeDeclRefExpr(
759 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
760 TypeSourceInfo **RecoveryTSI);
762 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
764 // FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
765 // amount of stack usage with clang.
766 #define STMT(Node, Parent) \
767 LLVM_ATTRIBUTE_NOINLINE \
768 StmtResult Transform##Node(Node *S);
769 #define VALUESTMT(Node, Parent) \
770 LLVM_ATTRIBUTE_NOINLINE \
771 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
772 #define EXPR(Node, Parent) \
773 LLVM_ATTRIBUTE_NOINLINE \
774 ExprResult Transform##Node(Node *E);
775 #define ABSTRACT_STMT(Stmt)
776 #include "clang/AST/StmtNodes.inc"
778 #define GEN_CLANG_CLAUSE_CLASS
779 #define CLAUSE_CLASS(Enum, Str, Class) \
780 LLVM_ATTRIBUTE_NOINLINE \
781 OMPClause *Transform##Class(Class *S);
782 #include "llvm/Frontend/OpenMP/OMP.inc"
784 /// Build a new qualified type given its unqualified type and type location.
786 /// By default, this routine adds type qualifiers only to types that can
787 /// have qualifiers, and silently suppresses those qualifiers that are not
788 /// permitted. Subclasses may override this routine to provide different
789 /// behavior.
790 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
792 /// Build a new pointer type given its pointee type.
794 /// By default, performs semantic analysis when building the pointer type.
795 /// Subclasses may override this routine to provide different behavior.
796 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
798 /// Build a new block pointer type given its pointee type.
800 /// By default, performs semantic analysis when building the block pointer
801 /// type. Subclasses may override this routine to provide different behavior.
802 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
804 /// Build a new reference type given the type it references.
806 /// By default, performs semantic analysis when building the
807 /// reference type. Subclasses may override this routine to provide
808 /// different behavior.
810 /// \param LValue whether the type was written with an lvalue sigil
811 /// or an rvalue sigil.
812 QualType RebuildReferenceType(QualType ReferentType,
813 bool LValue,
814 SourceLocation Sigil);
816 /// Build a new member pointer type given the pointee type and the
817 /// class type it refers into.
819 /// By default, performs semantic analysis when building the member pointer
820 /// type. Subclasses may override this routine to provide different behavior.
821 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
822 SourceLocation Sigil);
824 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
825 SourceLocation ProtocolLAngleLoc,
826 ArrayRef<ObjCProtocolDecl *> Protocols,
827 ArrayRef<SourceLocation> ProtocolLocs,
828 SourceLocation ProtocolRAngleLoc);
830 /// Build an Objective-C object type.
832 /// By default, performs semantic analysis when building the object type.
833 /// Subclasses may override this routine to provide different behavior.
834 QualType RebuildObjCObjectType(QualType BaseType,
835 SourceLocation Loc,
836 SourceLocation TypeArgsLAngleLoc,
837 ArrayRef<TypeSourceInfo *> TypeArgs,
838 SourceLocation TypeArgsRAngleLoc,
839 SourceLocation ProtocolLAngleLoc,
840 ArrayRef<ObjCProtocolDecl *> Protocols,
841 ArrayRef<SourceLocation> ProtocolLocs,
842 SourceLocation ProtocolRAngleLoc);
844 /// Build a new Objective-C object pointer type given the pointee type.
846 /// By default, directly builds the pointer type, with no additional semantic
847 /// analysis.
848 QualType RebuildObjCObjectPointerType(QualType PointeeType,
849 SourceLocation Star);
851 /// Build a new array type given the element type, size
852 /// modifier, size of the array (if known), size expression, and index type
853 /// qualifiers.
855 /// By default, performs semantic analysis when building the array type.
856 /// Subclasses may override this routine to provide different behavior.
857 /// Also by default, all of the other Rebuild*Array
858 QualType RebuildArrayType(QualType ElementType,
859 ArrayType::ArraySizeModifier SizeMod,
860 const llvm::APInt *Size,
861 Expr *SizeExpr,
862 unsigned IndexTypeQuals,
863 SourceRange BracketsRange);
865 /// Build a new constant array type given the element type, size
866 /// modifier, (known) size of the array, and index type qualifiers.
868 /// By default, performs semantic analysis when building the array type.
869 /// Subclasses may override this routine to provide different behavior.
870 QualType RebuildConstantArrayType(QualType ElementType,
871 ArrayType::ArraySizeModifier SizeMod,
872 const llvm::APInt &Size,
873 Expr *SizeExpr,
874 unsigned IndexTypeQuals,
875 SourceRange BracketsRange);
877 /// Build a new incomplete array type given the element type, size
878 /// modifier, and index type qualifiers.
880 /// By default, performs semantic analysis when building the array type.
881 /// Subclasses may override this routine to provide different behavior.
882 QualType RebuildIncompleteArrayType(QualType ElementType,
883 ArrayType::ArraySizeModifier SizeMod,
884 unsigned IndexTypeQuals,
885 SourceRange BracketsRange);
887 /// Build a new variable-length array type given the element type,
888 /// size modifier, size expression, and index type qualifiers.
890 /// By default, performs semantic analysis when building the array type.
891 /// Subclasses may override this routine to provide different behavior.
892 QualType RebuildVariableArrayType(QualType ElementType,
893 ArrayType::ArraySizeModifier SizeMod,
894 Expr *SizeExpr,
895 unsigned IndexTypeQuals,
896 SourceRange BracketsRange);
898 /// Build a new dependent-sized array type given the element type,
899 /// size modifier, size expression, and index type qualifiers.
901 /// By default, performs semantic analysis when building the array type.
902 /// Subclasses may override this routine to provide different behavior.
903 QualType RebuildDependentSizedArrayType(QualType ElementType,
904 ArrayType::ArraySizeModifier SizeMod,
905 Expr *SizeExpr,
906 unsigned IndexTypeQuals,
907 SourceRange BracketsRange);
909 /// Build a new vector type given the element type and
910 /// number of elements.
912 /// By default, performs semantic analysis when building the vector type.
913 /// Subclasses may override this routine to provide different behavior.
914 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
915 VectorType::VectorKind VecKind);
917 /// Build a new potentially dependently-sized extended vector type
918 /// given the element type and number of elements.
920 /// By default, performs semantic analysis when building the vector type.
921 /// Subclasses may override this routine to provide different behavior.
922 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
923 SourceLocation AttributeLoc,
924 VectorType::VectorKind);
926 /// Build a new extended vector type given the element type and
927 /// number of elements.
929 /// By default, performs semantic analysis when building the vector type.
930 /// Subclasses may override this routine to provide different behavior.
931 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
932 SourceLocation AttributeLoc);
934 /// Build a new potentially dependently-sized extended vector type
935 /// given the element type and number of elements.
937 /// By default, performs semantic analysis when building the vector type.
938 /// Subclasses may override this routine to provide different behavior.
939 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
940 Expr *SizeExpr,
941 SourceLocation AttributeLoc);
943 /// Build a new matrix type given the element type and dimensions.
944 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
945 unsigned NumColumns);
947 /// Build a new matrix type given the type and dependently-defined
948 /// dimensions.
949 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
950 Expr *ColumnExpr,
951 SourceLocation AttributeLoc);
953 /// Build a new DependentAddressSpaceType or return the pointee
954 /// type variable with the correct address space (retrieved from
955 /// AddrSpaceExpr) applied to it. The former will be returned in cases
956 /// where the address space remains dependent.
958 /// By default, performs semantic analysis when building the type with address
959 /// space applied. Subclasses may override this routine to provide different
960 /// behavior.
961 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
962 Expr *AddrSpaceExpr,
963 SourceLocation AttributeLoc);
965 /// Build a new function type.
967 /// By default, performs semantic analysis when building the function type.
968 /// Subclasses may override this routine to provide different behavior.
969 QualType RebuildFunctionProtoType(QualType T,
970 MutableArrayRef<QualType> ParamTypes,
971 const FunctionProtoType::ExtProtoInfo &EPI);
973 /// Build a new unprototyped function type.
974 QualType RebuildFunctionNoProtoType(QualType ResultType);
976 /// Rebuild an unresolved typename type, given the decl that
977 /// the UnresolvedUsingTypenameDecl was transformed to.
978 QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D);
980 /// Build a new type found via an alias.
981 QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying) {
982 return SemaRef.Context.getUsingType(Found, Underlying);
985 /// Build a new typedef type.
986 QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
987 return SemaRef.Context.getTypeDeclType(Typedef);
990 /// Build a new MacroDefined type.
991 QualType RebuildMacroQualifiedType(QualType T,
992 const IdentifierInfo *MacroII) {
993 return SemaRef.Context.getMacroQualifiedType(T, MacroII);
996 /// Build a new class/struct/union type.
997 QualType RebuildRecordType(RecordDecl *Record) {
998 return SemaRef.Context.getTypeDeclType(Record);
1001 /// Build a new Enum type.
1002 QualType RebuildEnumType(EnumDecl *Enum) {
1003 return SemaRef.Context.getTypeDeclType(Enum);
1006 /// Build a new typeof(expr) type.
1008 /// By default, performs semantic analysis when building the typeof type.
1009 /// Subclasses may override this routine to provide different behavior.
1010 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1011 TypeOfKind Kind);
1013 /// Build a new typeof(type) type.
1015 /// By default, builds a new TypeOfType with the given underlying type.
1016 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1018 /// Build a new unary transform type.
1019 QualType RebuildUnaryTransformType(QualType BaseType,
1020 UnaryTransformType::UTTKind UKind,
1021 SourceLocation Loc);
1023 /// Build a new C++11 decltype type.
1025 /// By default, performs semantic analysis when building the decltype type.
1026 /// Subclasses may override this routine to provide different behavior.
1027 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1029 /// Build a new C++11 auto type.
1031 /// By default, builds a new AutoType with the given deduced type.
1032 QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword,
1033 ConceptDecl *TypeConstraintConcept,
1034 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1035 // Note, IsDependent is always false here: we implicitly convert an 'auto'
1036 // which has been deduced to a dependent type into an undeduced 'auto', so
1037 // that we'll retry deduction after the transformation.
1038 return SemaRef.Context.getAutoType(Deduced, Keyword,
1039 /*IsDependent*/ false, /*IsPack=*/false,
1040 TypeConstraintConcept,
1041 TypeConstraintArgs);
1044 /// By default, builds a new DeducedTemplateSpecializationType with the given
1045 /// deduced type.
1046 QualType RebuildDeducedTemplateSpecializationType(TemplateName Template,
1047 QualType Deduced) {
1048 return SemaRef.Context.getDeducedTemplateSpecializationType(
1049 Template, Deduced, /*IsDependent*/ false);
1052 /// Build a new template specialization type.
1054 /// By default, performs semantic analysis when building the template
1055 /// specialization type. Subclasses may override this routine to provide
1056 /// different behavior.
1057 QualType RebuildTemplateSpecializationType(TemplateName Template,
1058 SourceLocation TemplateLoc,
1059 TemplateArgumentListInfo &Args);
1061 /// Build a new parenthesized type.
1063 /// By default, builds a new ParenType type from the inner type.
1064 /// Subclasses may override this routine to provide different behavior.
1065 QualType RebuildParenType(QualType InnerType) {
1066 return SemaRef.BuildParenType(InnerType);
1069 /// Build a new qualified name type.
1071 /// By default, builds a new ElaboratedType type from the keyword,
1072 /// the nested-name-specifier and the named type.
1073 /// Subclasses may override this routine to provide different behavior.
1074 QualType RebuildElaboratedType(SourceLocation KeywordLoc,
1075 ElaboratedTypeKeyword Keyword,
1076 NestedNameSpecifierLoc QualifierLoc,
1077 QualType Named) {
1078 return SemaRef.Context.getElaboratedType(Keyword,
1079 QualifierLoc.getNestedNameSpecifier(),
1080 Named);
1083 /// Build a new typename type that refers to a template-id.
1085 /// By default, builds a new DependentNameType type from the
1086 /// nested-name-specifier and the given type. Subclasses may override
1087 /// this routine to provide different behavior.
1088 QualType RebuildDependentTemplateSpecializationType(
1089 ElaboratedTypeKeyword Keyword,
1090 NestedNameSpecifierLoc QualifierLoc,
1091 SourceLocation TemplateKWLoc,
1092 const IdentifierInfo *Name,
1093 SourceLocation NameLoc,
1094 TemplateArgumentListInfo &Args,
1095 bool AllowInjectedClassName) {
1096 // Rebuild the template name.
1097 // TODO: avoid TemplateName abstraction
1098 CXXScopeSpec SS;
1099 SS.Adopt(QualifierLoc);
1100 TemplateName InstName = getDerived().RebuildTemplateName(
1101 SS, TemplateKWLoc, *Name, NameLoc, QualType(), nullptr,
1102 AllowInjectedClassName);
1104 if (InstName.isNull())
1105 return QualType();
1107 // If it's still dependent, make a dependent specialization.
1108 if (InstName.getAsDependentTemplateName())
1109 return SemaRef.Context.getDependentTemplateSpecializationType(
1110 Keyword, QualifierLoc.getNestedNameSpecifier(), Name,
1111 Args.arguments());
1113 // Otherwise, make an elaborated type wrapping a non-dependent
1114 // specialization.
1115 QualType T =
1116 getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
1117 if (T.isNull())
1118 return QualType();
1119 return SemaRef.Context.getElaboratedType(
1120 Keyword, QualifierLoc.getNestedNameSpecifier(), T);
1123 /// Build a new typename type that refers to an identifier.
1125 /// By default, performs semantic analysis when building the typename type
1126 /// (or elaborated type). Subclasses may override this routine to provide
1127 /// different behavior.
1128 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1129 SourceLocation KeywordLoc,
1130 NestedNameSpecifierLoc QualifierLoc,
1131 const IdentifierInfo *Id,
1132 SourceLocation IdLoc,
1133 bool DeducedTSTContext) {
1134 CXXScopeSpec SS;
1135 SS.Adopt(QualifierLoc);
1137 if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
1138 // If the name is still dependent, just build a new dependent name type.
1139 if (!SemaRef.computeDeclContext(SS))
1140 return SemaRef.Context.getDependentNameType(Keyword,
1141 QualifierLoc.getNestedNameSpecifier(),
1142 Id);
1145 if (Keyword == ETK_None || Keyword == ETK_Typename) {
1146 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1147 *Id, IdLoc, DeducedTSTContext);
1150 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1152 // We had a dependent elaborated-type-specifier that has been transformed
1153 // into a non-dependent elaborated-type-specifier. Find the tag we're
1154 // referring to.
1155 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1156 DeclContext *DC = SemaRef.computeDeclContext(SS, false);
1157 if (!DC)
1158 return QualType();
1160 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1161 return QualType();
1163 TagDecl *Tag = nullptr;
1164 SemaRef.LookupQualifiedName(Result, DC);
1165 switch (Result.getResultKind()) {
1166 case LookupResult::NotFound:
1167 case LookupResult::NotFoundInCurrentInstantiation:
1168 break;
1170 case LookupResult::Found:
1171 Tag = Result.getAsSingle<TagDecl>();
1172 break;
1174 case LookupResult::FoundOverloaded:
1175 case LookupResult::FoundUnresolvedValue:
1176 llvm_unreachable("Tag lookup cannot find non-tags");
1178 case LookupResult::Ambiguous:
1179 // Let the LookupResult structure handle ambiguities.
1180 return QualType();
1183 if (!Tag) {
1184 // Check where the name exists but isn't a tag type and use that to emit
1185 // better diagnostics.
1186 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1187 SemaRef.LookupQualifiedName(Result, DC);
1188 switch (Result.getResultKind()) {
1189 case LookupResult::Found:
1190 case LookupResult::FoundOverloaded:
1191 case LookupResult::FoundUnresolvedValue: {
1192 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1193 Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind);
1194 SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag) << SomeDecl
1195 << NTK << Kind;
1196 SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
1197 break;
1199 default:
1200 SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
1201 << Kind << Id << DC << QualifierLoc.getSourceRange();
1202 break;
1204 return QualType();
1207 if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false,
1208 IdLoc, Id)) {
1209 SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
1210 SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
1211 return QualType();
1214 // Build the elaborated-type-specifier type.
1215 QualType T = SemaRef.Context.getTypeDeclType(Tag);
1216 return SemaRef.Context.getElaboratedType(Keyword,
1217 QualifierLoc.getNestedNameSpecifier(),
1221 /// Build a new pack expansion type.
1223 /// By default, builds a new PackExpansionType type from the given pattern.
1224 /// Subclasses may override this routine to provide different behavior.
1225 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1226 SourceLocation EllipsisLoc,
1227 std::optional<unsigned> NumExpansions) {
1228 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1229 NumExpansions);
1232 /// Build a new atomic type given its value type.
1234 /// By default, performs semantic analysis when building the atomic type.
1235 /// Subclasses may override this routine to provide different behavior.
1236 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1238 /// Build a new pipe type given its value type.
1239 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1240 bool isReadPipe);
1242 /// Build a bit-precise int given its value type.
1243 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1244 SourceLocation Loc);
1246 /// Build a dependent bit-precise int given its value type.
1247 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1248 SourceLocation Loc);
1250 /// Build a new template name given a nested name specifier, a flag
1251 /// indicating whether the "template" keyword was provided, and the template
1252 /// that the template name refers to.
1254 /// By default, builds the new template name directly. Subclasses may override
1255 /// this routine to provide different behavior.
1256 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1257 bool TemplateKW,
1258 TemplateDecl *Template);
1260 /// Build a new template name given a nested name specifier and the
1261 /// name that is referred to as a template.
1263 /// By default, performs semantic analysis to determine whether the name can
1264 /// be resolved to a specific template, then builds the appropriate kind of
1265 /// template name. Subclasses may override this routine to provide different
1266 /// behavior.
1267 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1268 SourceLocation TemplateKWLoc,
1269 const IdentifierInfo &Name,
1270 SourceLocation NameLoc, QualType ObjectType,
1271 NamedDecl *FirstQualifierInScope,
1272 bool AllowInjectedClassName);
1274 /// Build a new template name given a nested name specifier and the
1275 /// overloaded operator name that is referred to as a template.
1277 /// By default, performs semantic analysis to determine whether the name can
1278 /// be resolved to a specific template, then builds the appropriate kind of
1279 /// template name. Subclasses may override this routine to provide different
1280 /// behavior.
1281 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1282 SourceLocation TemplateKWLoc,
1283 OverloadedOperatorKind Operator,
1284 SourceLocation NameLoc, QualType ObjectType,
1285 bool AllowInjectedClassName);
1287 /// Build a new template name given a template template parameter pack
1288 /// and the
1290 /// By default, performs semantic analysis to determine whether the name can
1291 /// be resolved to a specific template, then builds the appropriate kind of
1292 /// template name. Subclasses may override this routine to provide different
1293 /// behavior.
1294 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1295 Decl *AssociatedDecl, unsigned Index,
1296 bool Final) {
1297 return getSema().Context.getSubstTemplateTemplateParmPack(
1298 ArgPack, AssociatedDecl, Index, Final);
1301 /// Build a new compound statement.
1303 /// By default, performs semantic analysis to build the new statement.
1304 /// Subclasses may override this routine to provide different behavior.
1305 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1306 MultiStmtArg Statements,
1307 SourceLocation RBraceLoc,
1308 bool IsStmtExpr) {
1309 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1310 IsStmtExpr);
1313 /// Build a new case statement.
1315 /// By default, performs semantic analysis to build the new statement.
1316 /// Subclasses may override this routine to provide different behavior.
1317 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1318 Expr *LHS,
1319 SourceLocation EllipsisLoc,
1320 Expr *RHS,
1321 SourceLocation ColonLoc) {
1322 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1323 ColonLoc);
1326 /// Attach the body to a new case statement.
1328 /// By default, performs semantic analysis to build the new statement.
1329 /// Subclasses may override this routine to provide different behavior.
1330 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1331 getSema().ActOnCaseStmtBody(S, Body);
1332 return S;
1335 /// Build a new default statement.
1337 /// By default, performs semantic analysis to build the new statement.
1338 /// Subclasses may override this routine to provide different behavior.
1339 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1340 SourceLocation ColonLoc,
1341 Stmt *SubStmt) {
1342 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1343 /*CurScope=*/nullptr);
1346 /// Build a new label statement.
1348 /// By default, performs semantic analysis to build the new statement.
1349 /// Subclasses may override this routine to provide different behavior.
1350 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1351 SourceLocation ColonLoc, Stmt *SubStmt) {
1352 return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt);
1355 /// Build a new attributed statement.
1357 /// By default, performs semantic analysis to build the new statement.
1358 /// Subclasses may override this routine to provide different behavior.
1359 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1360 ArrayRef<const Attr *> Attrs,
1361 Stmt *SubStmt) {
1362 return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt);
1365 /// Build a new "if" statement.
1367 /// By default, performs semantic analysis to build the new statement.
1368 /// Subclasses may override this routine to provide different behavior.
1369 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1370 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1371 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1372 SourceLocation ElseLoc, Stmt *Else) {
1373 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1374 Then, ElseLoc, Else);
1377 /// Start building a new switch statement.
1379 /// By default, performs semantic analysis to build the new statement.
1380 /// Subclasses may override this routine to provide different behavior.
1381 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1382 SourceLocation LParenLoc, Stmt *Init,
1383 Sema::ConditionResult Cond,
1384 SourceLocation RParenLoc) {
1385 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1386 RParenLoc);
1389 /// Attach the body to the switch statement.
1391 /// By default, performs semantic analysis to build the new statement.
1392 /// Subclasses may override this routine to provide different behavior.
1393 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1394 Stmt *Switch, Stmt *Body) {
1395 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1398 /// Build a new while statement.
1400 /// By default, performs semantic analysis to build the new statement.
1401 /// Subclasses may override this routine to provide different behavior.
1402 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1403 Sema::ConditionResult Cond,
1404 SourceLocation RParenLoc, Stmt *Body) {
1405 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1408 /// Build a new do-while statement.
1410 /// By default, performs semantic analysis to build the new statement.
1411 /// Subclasses may override this routine to provide different behavior.
1412 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1413 SourceLocation WhileLoc, SourceLocation LParenLoc,
1414 Expr *Cond, SourceLocation RParenLoc) {
1415 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1416 Cond, RParenLoc);
1419 /// Build a new for statement.
1421 /// By default, performs semantic analysis to build the new statement.
1422 /// Subclasses may override this routine to provide different behavior.
1423 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1424 Stmt *Init, Sema::ConditionResult Cond,
1425 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1426 Stmt *Body) {
1427 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1428 Inc, RParenLoc, Body);
1431 /// Build a new goto statement.
1433 /// By default, performs semantic analysis to build the new statement.
1434 /// Subclasses may override this routine to provide different behavior.
1435 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1436 LabelDecl *Label) {
1437 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1440 /// Build a new indirect goto statement.
1442 /// By default, performs semantic analysis to build the new statement.
1443 /// Subclasses may override this routine to provide different behavior.
1444 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1445 SourceLocation StarLoc,
1446 Expr *Target) {
1447 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1450 /// Build a new return statement.
1452 /// By default, performs semantic analysis to build the new statement.
1453 /// Subclasses may override this routine to provide different behavior.
1454 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1455 return getSema().BuildReturnStmt(ReturnLoc, Result);
1458 /// Build a new declaration statement.
1460 /// By default, performs semantic analysis to build the new statement.
1461 /// Subclasses may override this routine to provide different behavior.
1462 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1463 SourceLocation StartLoc, SourceLocation EndLoc) {
1464 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1465 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1468 /// Build a new inline asm statement.
1470 /// By default, performs semantic analysis to build the new statement.
1471 /// Subclasses may override this routine to provide different behavior.
1472 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1473 bool IsVolatile, unsigned NumOutputs,
1474 unsigned NumInputs, IdentifierInfo **Names,
1475 MultiExprArg Constraints, MultiExprArg Exprs,
1476 Expr *AsmString, MultiExprArg Clobbers,
1477 unsigned NumLabels,
1478 SourceLocation RParenLoc) {
1479 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1480 NumInputs, Names, Constraints, Exprs,
1481 AsmString, Clobbers, NumLabels, RParenLoc);
1484 /// Build a new MS style inline asm statement.
1486 /// By default, performs semantic analysis to build the new statement.
1487 /// Subclasses may override this routine to provide different behavior.
1488 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1489 ArrayRef<Token> AsmToks,
1490 StringRef AsmString,
1491 unsigned NumOutputs, unsigned NumInputs,
1492 ArrayRef<StringRef> Constraints,
1493 ArrayRef<StringRef> Clobbers,
1494 ArrayRef<Expr*> Exprs,
1495 SourceLocation EndLoc) {
1496 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1497 NumOutputs, NumInputs,
1498 Constraints, Clobbers, Exprs, EndLoc);
1501 /// Build a new co_return statement.
1503 /// By default, performs semantic analysis to build the new statement.
1504 /// Subclasses may override this routine to provide different behavior.
1505 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1506 bool IsImplicit) {
1507 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1510 /// Build a new co_await expression.
1512 /// By default, performs semantic analysis to build the new expression.
1513 /// Subclasses may override this routine to provide different behavior.
1514 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1515 UnresolvedLookupExpr *OpCoawaitLookup,
1516 bool IsImplicit) {
1517 // This function rebuilds a coawait-expr given its operator.
1518 // For an explicit coawait-expr, the rebuild involves the full set
1519 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1520 // including calling await_transform().
1521 // For an implicit coawait-expr, we need to rebuild the "operator
1522 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1523 // This mirrors how the implicit CoawaitExpr is originally created
1524 // in Sema::ActOnCoroutineBodyStart().
1525 if (IsImplicit) {
1526 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1527 CoawaitLoc, Operand, OpCoawaitLookup);
1528 if (Suspend.isInvalid())
1529 return ExprError();
1530 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1531 Suspend.get(), true);
1534 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1535 OpCoawaitLookup);
1538 /// Build a new co_await expression.
1540 /// By default, performs semantic analysis to build the new expression.
1541 /// Subclasses may override this routine to provide different behavior.
1542 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1543 Expr *Result,
1544 UnresolvedLookupExpr *Lookup) {
1545 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1548 /// Build a new co_yield expression.
1550 /// By default, performs semantic analysis to build the new expression.
1551 /// Subclasses may override this routine to provide different behavior.
1552 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1553 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1556 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1557 return getSema().BuildCoroutineBodyStmt(Args);
1560 /// Build a new Objective-C \@try statement.
1562 /// By default, performs semantic analysis to build the new statement.
1563 /// Subclasses may override this routine to provide different behavior.
1564 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1565 Stmt *TryBody,
1566 MultiStmtArg CatchStmts,
1567 Stmt *Finally) {
1568 return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1569 Finally);
1572 /// Rebuild an Objective-C exception declaration.
1574 /// By default, performs semantic analysis to build the new declaration.
1575 /// Subclasses may override this routine to provide different behavior.
1576 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1577 TypeSourceInfo *TInfo, QualType T) {
1578 return getSema().BuildObjCExceptionDecl(TInfo, T,
1579 ExceptionDecl->getInnerLocStart(),
1580 ExceptionDecl->getLocation(),
1581 ExceptionDecl->getIdentifier());
1584 /// Build a new Objective-C \@catch statement.
1586 /// By default, performs semantic analysis to build the new statement.
1587 /// Subclasses may override this routine to provide different behavior.
1588 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1589 SourceLocation RParenLoc,
1590 VarDecl *Var,
1591 Stmt *Body) {
1592 return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
1593 Var, Body);
1596 /// Build a new Objective-C \@finally statement.
1598 /// By default, performs semantic analysis to build the new statement.
1599 /// Subclasses may override this routine to provide different behavior.
1600 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1601 Stmt *Body) {
1602 return getSema().ActOnObjCAtFinallyStmt(AtLoc, Body);
1605 /// Build a new Objective-C \@throw statement.
1607 /// By default, performs semantic analysis to build the new statement.
1608 /// Subclasses may override this routine to provide different behavior.
1609 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1610 Expr *Operand) {
1611 return getSema().BuildObjCAtThrowStmt(AtLoc, Operand);
1614 /// Build a new OpenMP Canonical loop.
1616 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1617 /// OMPCanonicalLoop.
1618 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1619 return getSema().ActOnOpenMPCanonicalLoop(LoopStmt);
1622 /// Build a new OpenMP executable directive.
1624 /// By default, performs semantic analysis to build the new statement.
1625 /// Subclasses may override this routine to provide different behavior.
1626 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
1627 DeclarationNameInfo DirName,
1628 OpenMPDirectiveKind CancelRegion,
1629 ArrayRef<OMPClause *> Clauses,
1630 Stmt *AStmt, SourceLocation StartLoc,
1631 SourceLocation EndLoc) {
1632 return getSema().ActOnOpenMPExecutableDirective(
1633 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1636 /// Build a new OpenMP 'if' clause.
1638 /// By default, performs semantic analysis to build the new OpenMP clause.
1639 /// Subclasses may override this routine to provide different behavior.
1640 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1641 Expr *Condition, SourceLocation StartLoc,
1642 SourceLocation LParenLoc,
1643 SourceLocation NameModifierLoc,
1644 SourceLocation ColonLoc,
1645 SourceLocation EndLoc) {
1646 return getSema().ActOnOpenMPIfClause(NameModifier, Condition, StartLoc,
1647 LParenLoc, NameModifierLoc, ColonLoc,
1648 EndLoc);
1651 /// Build a new OpenMP 'final' clause.
1653 /// By default, performs semantic analysis to build the new OpenMP clause.
1654 /// Subclasses may override this routine to provide different behavior.
1655 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1656 SourceLocation LParenLoc,
1657 SourceLocation EndLoc) {
1658 return getSema().ActOnOpenMPFinalClause(Condition, StartLoc, LParenLoc,
1659 EndLoc);
1662 /// Build a new OpenMP 'num_threads' clause.
1664 /// By default, performs semantic analysis to build the new OpenMP clause.
1665 /// Subclasses may override this routine to provide different behavior.
1666 OMPClause *RebuildOMPNumThreadsClause(Expr *NumThreads,
1667 SourceLocation StartLoc,
1668 SourceLocation LParenLoc,
1669 SourceLocation EndLoc) {
1670 return getSema().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc,
1671 LParenLoc, EndLoc);
1674 /// Build a new OpenMP 'safelen' clause.
1676 /// By default, performs semantic analysis to build the new OpenMP clause.
1677 /// Subclasses may override this routine to provide different behavior.
1678 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1679 SourceLocation LParenLoc,
1680 SourceLocation EndLoc) {
1681 return getSema().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc, EndLoc);
1684 /// Build a new OpenMP 'simdlen' clause.
1686 /// By default, performs semantic analysis to build the new OpenMP clause.
1687 /// Subclasses may override this routine to provide different behavior.
1688 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1689 SourceLocation LParenLoc,
1690 SourceLocation EndLoc) {
1691 return getSema().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc, EndLoc);
1694 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1695 SourceLocation StartLoc,
1696 SourceLocation LParenLoc,
1697 SourceLocation EndLoc) {
1698 return getSema().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc, EndLoc);
1701 /// Build a new OpenMP 'full' clause.
1702 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1703 SourceLocation EndLoc) {
1704 return getSema().ActOnOpenMPFullClause(StartLoc, EndLoc);
1707 /// Build a new OpenMP 'partial' clause.
1708 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1709 SourceLocation LParenLoc,
1710 SourceLocation EndLoc) {
1711 return getSema().ActOnOpenMPPartialClause(Factor, StartLoc, LParenLoc,
1712 EndLoc);
1715 /// Build a new OpenMP 'allocator' clause.
1717 /// By default, performs semantic analysis to build the new OpenMP clause.
1718 /// Subclasses may override this routine to provide different behavior.
1719 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1720 SourceLocation LParenLoc,
1721 SourceLocation EndLoc) {
1722 return getSema().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc, EndLoc);
1725 /// Build a new OpenMP 'collapse' clause.
1727 /// By default, performs semantic analysis to build the new OpenMP clause.
1728 /// Subclasses may override this routine to provide different behavior.
1729 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1730 SourceLocation LParenLoc,
1731 SourceLocation EndLoc) {
1732 return getSema().ActOnOpenMPCollapseClause(Num, StartLoc, LParenLoc,
1733 EndLoc);
1736 /// Build a new OpenMP 'default' clause.
1738 /// By default, performs semantic analysis to build the new OpenMP clause.
1739 /// Subclasses may override this routine to provide different behavior.
1740 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1741 SourceLocation StartLoc,
1742 SourceLocation LParenLoc,
1743 SourceLocation EndLoc) {
1744 return getSema().ActOnOpenMPDefaultClause(Kind, KindKwLoc,
1745 StartLoc, LParenLoc, EndLoc);
1748 /// Build a new OpenMP 'proc_bind' clause.
1750 /// By default, performs semantic analysis to build the new OpenMP clause.
1751 /// Subclasses may override this routine to provide different behavior.
1752 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1753 SourceLocation KindKwLoc,
1754 SourceLocation StartLoc,
1755 SourceLocation LParenLoc,
1756 SourceLocation EndLoc) {
1757 return getSema().ActOnOpenMPProcBindClause(Kind, KindKwLoc,
1758 StartLoc, LParenLoc, EndLoc);
1761 /// Build a new OpenMP 'schedule' clause.
1763 /// By default, performs semantic analysis to build the new OpenMP clause.
1764 /// Subclasses may override this routine to provide different behavior.
1765 OMPClause *RebuildOMPScheduleClause(
1766 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1767 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1768 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1769 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1770 return getSema().ActOnOpenMPScheduleClause(
1771 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1772 CommaLoc, EndLoc);
1775 /// Build a new OpenMP 'ordered' clause.
1777 /// By default, performs semantic analysis to build the new OpenMP clause.
1778 /// Subclasses may override this routine to provide different behavior.
1779 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1780 SourceLocation EndLoc,
1781 SourceLocation LParenLoc, Expr *Num) {
1782 return getSema().ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Num);
1785 /// Build a new OpenMP 'private' clause.
1787 /// By default, performs semantic analysis to build the new OpenMP clause.
1788 /// Subclasses may override this routine to provide different behavior.
1789 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1790 SourceLocation StartLoc,
1791 SourceLocation LParenLoc,
1792 SourceLocation EndLoc) {
1793 return getSema().ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc,
1794 EndLoc);
1797 /// Build a new OpenMP 'firstprivate' clause.
1799 /// By default, performs semantic analysis to build the new OpenMP clause.
1800 /// Subclasses may override this routine to provide different behavior.
1801 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1802 SourceLocation StartLoc,
1803 SourceLocation LParenLoc,
1804 SourceLocation EndLoc) {
1805 return getSema().ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc,
1806 EndLoc);
1809 /// Build a new OpenMP 'lastprivate' clause.
1811 /// By default, performs semantic analysis to build the new OpenMP clause.
1812 /// Subclasses may override this routine to provide different behavior.
1813 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1814 OpenMPLastprivateModifier LPKind,
1815 SourceLocation LPKindLoc,
1816 SourceLocation ColonLoc,
1817 SourceLocation StartLoc,
1818 SourceLocation LParenLoc,
1819 SourceLocation EndLoc) {
1820 return getSema().ActOnOpenMPLastprivateClause(
1821 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1824 /// Build a new OpenMP 'shared' clause.
1826 /// By default, performs semantic analysis to build the new OpenMP clause.
1827 /// Subclasses may override this routine to provide different behavior.
1828 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1829 SourceLocation StartLoc,
1830 SourceLocation LParenLoc,
1831 SourceLocation EndLoc) {
1832 return getSema().ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc,
1833 EndLoc);
1836 /// Build a new OpenMP 'reduction' clause.
1838 /// By default, performs semantic analysis to build the new statement.
1839 /// Subclasses may override this routine to provide different behavior.
1840 OMPClause *RebuildOMPReductionClause(
1841 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1842 SourceLocation StartLoc, SourceLocation LParenLoc,
1843 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1844 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1845 const DeclarationNameInfo &ReductionId,
1846 ArrayRef<Expr *> UnresolvedReductions) {
1847 return getSema().ActOnOpenMPReductionClause(
1848 VarList, Modifier, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
1849 ReductionIdScopeSpec, ReductionId, UnresolvedReductions);
1852 /// Build a new OpenMP 'task_reduction' clause.
1854 /// By default, performs semantic analysis to build the new statement.
1855 /// Subclasses may override this routine to provide different behavior.
1856 OMPClause *RebuildOMPTaskReductionClause(
1857 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1858 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1859 CXXScopeSpec &ReductionIdScopeSpec,
1860 const DeclarationNameInfo &ReductionId,
1861 ArrayRef<Expr *> UnresolvedReductions) {
1862 return getSema().ActOnOpenMPTaskReductionClause(
1863 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1864 ReductionId, UnresolvedReductions);
1867 /// Build a new OpenMP 'in_reduction' clause.
1869 /// By default, performs semantic analysis to build the new statement.
1870 /// Subclasses may override this routine to provide different behavior.
1871 OMPClause *
1872 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1873 SourceLocation LParenLoc, SourceLocation ColonLoc,
1874 SourceLocation EndLoc,
1875 CXXScopeSpec &ReductionIdScopeSpec,
1876 const DeclarationNameInfo &ReductionId,
1877 ArrayRef<Expr *> UnresolvedReductions) {
1878 return getSema().ActOnOpenMPInReductionClause(
1879 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1880 ReductionId, UnresolvedReductions);
1883 /// Build a new OpenMP 'linear' clause.
1885 /// By default, performs semantic analysis to build the new OpenMP clause.
1886 /// Subclasses may override this routine to provide different behavior.
1887 OMPClause *RebuildOMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
1888 SourceLocation StartLoc,
1889 SourceLocation LParenLoc,
1890 OpenMPLinearClauseKind Modifier,
1891 SourceLocation ModifierLoc,
1892 SourceLocation ColonLoc,
1893 SourceLocation EndLoc) {
1894 return getSema().ActOnOpenMPLinearClause(VarList, Step, StartLoc, LParenLoc,
1895 Modifier, ModifierLoc, ColonLoc,
1896 EndLoc);
1899 /// Build a new OpenMP 'aligned' clause.
1901 /// By default, performs semantic analysis to build the new OpenMP clause.
1902 /// Subclasses may override this routine to provide different behavior.
1903 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
1904 SourceLocation StartLoc,
1905 SourceLocation LParenLoc,
1906 SourceLocation ColonLoc,
1907 SourceLocation EndLoc) {
1908 return getSema().ActOnOpenMPAlignedClause(VarList, Alignment, StartLoc,
1909 LParenLoc, ColonLoc, EndLoc);
1912 /// Build a new OpenMP 'copyin' clause.
1914 /// By default, performs semantic analysis to build the new OpenMP clause.
1915 /// Subclasses may override this routine to provide different behavior.
1916 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
1917 SourceLocation StartLoc,
1918 SourceLocation LParenLoc,
1919 SourceLocation EndLoc) {
1920 return getSema().ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc,
1921 EndLoc);
1924 /// Build a new OpenMP 'copyprivate' clause.
1926 /// By default, performs semantic analysis to build the new OpenMP clause.
1927 /// Subclasses may override this routine to provide different behavior.
1928 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
1929 SourceLocation StartLoc,
1930 SourceLocation LParenLoc,
1931 SourceLocation EndLoc) {
1932 return getSema().ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc,
1933 EndLoc);
1936 /// Build a new OpenMP 'flush' pseudo clause.
1938 /// By default, performs semantic analysis to build the new OpenMP clause.
1939 /// Subclasses may override this routine to provide different behavior.
1940 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
1941 SourceLocation StartLoc,
1942 SourceLocation LParenLoc,
1943 SourceLocation EndLoc) {
1944 return getSema().ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc,
1945 EndLoc);
1948 /// Build a new OpenMP 'depobj' pseudo clause.
1950 /// By default, performs semantic analysis to build the new OpenMP clause.
1951 /// Subclasses may override this routine to provide different behavior.
1952 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
1953 SourceLocation LParenLoc,
1954 SourceLocation EndLoc) {
1955 return getSema().ActOnOpenMPDepobjClause(Depobj, StartLoc, LParenLoc,
1956 EndLoc);
1959 /// Build a new OpenMP 'depend' pseudo clause.
1961 /// By default, performs semantic analysis to build the new OpenMP clause.
1962 /// Subclasses may override this routine to provide different behavior.
1963 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
1964 Expr *DepModifier, ArrayRef<Expr *> VarList,
1965 SourceLocation StartLoc,
1966 SourceLocation LParenLoc,
1967 SourceLocation EndLoc) {
1968 return getSema().ActOnOpenMPDependClause(Data, DepModifier, VarList,
1969 StartLoc, LParenLoc, EndLoc);
1972 /// Build a new OpenMP 'device' clause.
1974 /// By default, performs semantic analysis to build the new statement.
1975 /// Subclasses may override this routine to provide different behavior.
1976 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
1977 Expr *Device, SourceLocation StartLoc,
1978 SourceLocation LParenLoc,
1979 SourceLocation ModifierLoc,
1980 SourceLocation EndLoc) {
1981 return getSema().ActOnOpenMPDeviceClause(Modifier, Device, StartLoc,
1982 LParenLoc, ModifierLoc, EndLoc);
1985 /// Build a new OpenMP 'map' clause.
1987 /// By default, performs semantic analysis to build the new OpenMP clause.
1988 /// Subclasses may override this routine to provide different behavior.
1989 OMPClause *RebuildOMPMapClause(
1990 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
1991 ArrayRef<SourceLocation> MapTypeModifiersLoc,
1992 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
1993 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
1994 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
1995 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
1996 return getSema().ActOnOpenMPMapClause(
1997 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
1998 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
1999 ColonLoc, VarList, Locs,
2000 /*NoDiagnose=*/false, UnresolvedMappers);
2003 /// Build a new OpenMP 'allocate' clause.
2005 /// By default, performs semantic analysis to build the new OpenMP clause.
2006 /// Subclasses may override this routine to provide different behavior.
2007 OMPClause *RebuildOMPAllocateClause(Expr *Allocate, ArrayRef<Expr *> VarList,
2008 SourceLocation StartLoc,
2009 SourceLocation LParenLoc,
2010 SourceLocation ColonLoc,
2011 SourceLocation EndLoc) {
2012 return getSema().ActOnOpenMPAllocateClause(Allocate, VarList, StartLoc,
2013 LParenLoc, ColonLoc, EndLoc);
2016 /// Build a new OpenMP 'num_teams' clause.
2018 /// By default, performs semantic analysis to build the new statement.
2019 /// Subclasses may override this routine to provide different behavior.
2020 OMPClause *RebuildOMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc,
2021 SourceLocation LParenLoc,
2022 SourceLocation EndLoc) {
2023 return getSema().ActOnOpenMPNumTeamsClause(NumTeams, StartLoc, LParenLoc,
2024 EndLoc);
2027 /// Build a new OpenMP 'thread_limit' clause.
2029 /// By default, performs semantic analysis to build the new statement.
2030 /// Subclasses may override this routine to provide different behavior.
2031 OMPClause *RebuildOMPThreadLimitClause(Expr *ThreadLimit,
2032 SourceLocation StartLoc,
2033 SourceLocation LParenLoc,
2034 SourceLocation EndLoc) {
2035 return getSema().ActOnOpenMPThreadLimitClause(ThreadLimit, StartLoc,
2036 LParenLoc, EndLoc);
2039 /// Build a new OpenMP 'priority' clause.
2041 /// By default, performs semantic analysis to build the new statement.
2042 /// Subclasses may override this routine to provide different behavior.
2043 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2044 SourceLocation LParenLoc,
2045 SourceLocation EndLoc) {
2046 return getSema().ActOnOpenMPPriorityClause(Priority, StartLoc, LParenLoc,
2047 EndLoc);
2050 /// Build a new OpenMP 'grainsize' clause.
2052 /// By default, performs semantic analysis to build the new statement.
2053 /// Subclasses may override this routine to provide different behavior.
2054 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2055 Expr *Device, SourceLocation StartLoc,
2056 SourceLocation LParenLoc,
2057 SourceLocation ModifierLoc,
2058 SourceLocation EndLoc) {
2059 return getSema().ActOnOpenMPGrainsizeClause(Modifier, Device, StartLoc,
2060 LParenLoc, ModifierLoc, EndLoc);
2063 /// Build a new OpenMP 'num_tasks' clause.
2065 /// By default, performs semantic analysis to build the new statement.
2066 /// Subclasses may override this routine to provide different behavior.
2067 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2068 Expr *NumTasks, SourceLocation StartLoc,
2069 SourceLocation LParenLoc,
2070 SourceLocation ModifierLoc,
2071 SourceLocation EndLoc) {
2072 return getSema().ActOnOpenMPNumTasksClause(Modifier, NumTasks, StartLoc,
2073 LParenLoc, ModifierLoc, EndLoc);
2076 /// Build a new OpenMP 'hint' clause.
2078 /// By default, performs semantic analysis to build the new statement.
2079 /// Subclasses may override this routine to provide different behavior.
2080 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2081 SourceLocation LParenLoc,
2082 SourceLocation EndLoc) {
2083 return getSema().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc, EndLoc);
2086 /// Build a new OpenMP 'detach' clause.
2088 /// By default, performs semantic analysis to build the new statement.
2089 /// Subclasses may override this routine to provide different behavior.
2090 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2091 SourceLocation LParenLoc,
2092 SourceLocation EndLoc) {
2093 return getSema().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
2096 /// Build a new OpenMP 'dist_schedule' clause.
2098 /// By default, performs semantic analysis to build the new OpenMP clause.
2099 /// Subclasses may override this routine to provide different behavior.
2100 OMPClause *
2101 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2102 Expr *ChunkSize, SourceLocation StartLoc,
2103 SourceLocation LParenLoc, SourceLocation KindLoc,
2104 SourceLocation CommaLoc, SourceLocation EndLoc) {
2105 return getSema().ActOnOpenMPDistScheduleClause(
2106 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2109 /// Build a new OpenMP 'to' clause.
2111 /// By default, performs semantic analysis to build the new statement.
2112 /// Subclasses may override this routine to provide different behavior.
2113 OMPClause *
2114 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2115 ArrayRef<SourceLocation> MotionModifiersLoc,
2116 CXXScopeSpec &MapperIdScopeSpec,
2117 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2118 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2119 ArrayRef<Expr *> UnresolvedMappers) {
2120 return getSema().ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
2121 MapperIdScopeSpec, MapperId, ColonLoc,
2122 VarList, Locs, UnresolvedMappers);
2125 /// Build a new OpenMP 'from' clause.
2127 /// By default, performs semantic analysis to build the new statement.
2128 /// Subclasses may override this routine to provide different behavior.
2129 OMPClause *
2130 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2131 ArrayRef<SourceLocation> MotionModifiersLoc,
2132 CXXScopeSpec &MapperIdScopeSpec,
2133 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2134 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2135 ArrayRef<Expr *> UnresolvedMappers) {
2136 return getSema().ActOnOpenMPFromClause(
2137 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2138 ColonLoc, VarList, Locs, UnresolvedMappers);
2141 /// Build a new OpenMP 'use_device_ptr' clause.
2143 /// By default, performs semantic analysis to build the new OpenMP clause.
2144 /// Subclasses may override this routine to provide different behavior.
2145 OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
2146 const OMPVarListLocTy &Locs) {
2147 return getSema().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2150 /// Build a new OpenMP 'use_device_addr' clause.
2152 /// By default, performs semantic analysis to build the new OpenMP clause.
2153 /// Subclasses may override this routine to provide different behavior.
2154 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2155 const OMPVarListLocTy &Locs) {
2156 return getSema().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2159 /// Build a new OpenMP 'is_device_ptr' clause.
2161 /// By default, performs semantic analysis to build the new OpenMP clause.
2162 /// Subclasses may override this routine to provide different behavior.
2163 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2164 const OMPVarListLocTy &Locs) {
2165 return getSema().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2168 /// Build a new OpenMP 'has_device_addr' clause.
2170 /// By default, performs semantic analysis to build the new OpenMP clause.
2171 /// Subclasses may override this routine to provide different behavior.
2172 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2173 const OMPVarListLocTy &Locs) {
2174 return getSema().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2177 /// Build a new OpenMP 'defaultmap' clause.
2179 /// By default, performs semantic analysis to build the new OpenMP clause.
2180 /// Subclasses may override this routine to provide different behavior.
2181 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2182 OpenMPDefaultmapClauseKind Kind,
2183 SourceLocation StartLoc,
2184 SourceLocation LParenLoc,
2185 SourceLocation MLoc,
2186 SourceLocation KindLoc,
2187 SourceLocation EndLoc) {
2188 return getSema().ActOnOpenMPDefaultmapClause(M, Kind, StartLoc, LParenLoc,
2189 MLoc, KindLoc, EndLoc);
2192 /// Build a new OpenMP 'nontemporal' clause.
2194 /// By default, performs semantic analysis to build the new OpenMP clause.
2195 /// Subclasses may override this routine to provide different behavior.
2196 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2197 SourceLocation StartLoc,
2198 SourceLocation LParenLoc,
2199 SourceLocation EndLoc) {
2200 return getSema().ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc,
2201 EndLoc);
2204 /// Build a new OpenMP 'inclusive' clause.
2206 /// By default, performs semantic analysis to build the new OpenMP clause.
2207 /// Subclasses may override this routine to provide different behavior.
2208 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2209 SourceLocation StartLoc,
2210 SourceLocation LParenLoc,
2211 SourceLocation EndLoc) {
2212 return getSema().ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc,
2213 EndLoc);
2216 /// Build a new OpenMP 'exclusive' clause.
2218 /// By default, performs semantic analysis to build the new OpenMP clause.
2219 /// Subclasses may override this routine to provide different behavior.
2220 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2221 SourceLocation StartLoc,
2222 SourceLocation LParenLoc,
2223 SourceLocation EndLoc) {
2224 return getSema().ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc,
2225 EndLoc);
2228 /// Build a new OpenMP 'uses_allocators' clause.
2230 /// By default, performs semantic analysis to build the new OpenMP clause.
2231 /// Subclasses may override this routine to provide different behavior.
2232 OMPClause *RebuildOMPUsesAllocatorsClause(
2233 ArrayRef<Sema::UsesAllocatorsData> Data, SourceLocation StartLoc,
2234 SourceLocation LParenLoc, SourceLocation EndLoc) {
2235 return getSema().ActOnOpenMPUsesAllocatorClause(StartLoc, LParenLoc, EndLoc,
2236 Data);
2239 /// Build a new OpenMP 'affinity' clause.
2241 /// By default, performs semantic analysis to build the new OpenMP clause.
2242 /// Subclasses may override this routine to provide different behavior.
2243 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2244 SourceLocation LParenLoc,
2245 SourceLocation ColonLoc,
2246 SourceLocation EndLoc, Expr *Modifier,
2247 ArrayRef<Expr *> Locators) {
2248 return getSema().ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc,
2249 EndLoc, Modifier, Locators);
2252 /// Build a new OpenMP 'order' clause.
2254 /// By default, performs semantic analysis to build the new OpenMP clause.
2255 /// Subclasses may override this routine to provide different behavior.
2256 OMPClause *RebuildOMPOrderClause(
2257 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2258 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2259 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2260 return getSema().ActOnOpenMPOrderClause(Modifier, Kind, StartLoc, LParenLoc,
2261 ModifierKwLoc, KindKwLoc, EndLoc);
2264 /// Build a new OpenMP 'init' clause.
2266 /// By default, performs semantic analysis to build the new OpenMP clause.
2267 /// Subclasses may override this routine to provide different behavior.
2268 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2269 SourceLocation StartLoc,
2270 SourceLocation LParenLoc,
2271 SourceLocation VarLoc,
2272 SourceLocation EndLoc) {
2273 return getSema().ActOnOpenMPInitClause(InteropVar, InteropInfo, StartLoc,
2274 LParenLoc, VarLoc, EndLoc);
2277 /// Build a new OpenMP 'use' clause.
2279 /// By default, performs semantic analysis to build the new OpenMP clause.
2280 /// Subclasses may override this routine to provide different behavior.
2281 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2282 SourceLocation LParenLoc,
2283 SourceLocation VarLoc, SourceLocation EndLoc) {
2284 return getSema().ActOnOpenMPUseClause(InteropVar, StartLoc, LParenLoc,
2285 VarLoc, EndLoc);
2288 /// Build a new OpenMP 'destroy' clause.
2290 /// By default, performs semantic analysis to build the new OpenMP clause.
2291 /// Subclasses may override this routine to provide different behavior.
2292 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2293 SourceLocation LParenLoc,
2294 SourceLocation VarLoc,
2295 SourceLocation EndLoc) {
2296 return getSema().ActOnOpenMPDestroyClause(InteropVar, StartLoc, LParenLoc,
2297 VarLoc, EndLoc);
2300 /// Build a new OpenMP 'novariants' clause.
2302 /// By default, performs semantic analysis to build the new OpenMP clause.
2303 /// Subclasses may override this routine to provide different behavior.
2304 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2305 SourceLocation StartLoc,
2306 SourceLocation LParenLoc,
2307 SourceLocation EndLoc) {
2308 return getSema().ActOnOpenMPNovariantsClause(Condition, StartLoc, LParenLoc,
2309 EndLoc);
2312 /// Build a new OpenMP 'nocontext' clause.
2314 /// By default, performs semantic analysis to build the new OpenMP clause.
2315 /// Subclasses may override this routine to provide different behavior.
2316 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2317 SourceLocation LParenLoc,
2318 SourceLocation EndLoc) {
2319 return getSema().ActOnOpenMPNocontextClause(Condition, StartLoc, LParenLoc,
2320 EndLoc);
2323 /// Build a new OpenMP 'filter' clause.
2325 /// By default, performs semantic analysis to build the new OpenMP clause.
2326 /// Subclasses may override this routine to provide different behavior.
2327 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2328 SourceLocation LParenLoc,
2329 SourceLocation EndLoc) {
2330 return getSema().ActOnOpenMPFilterClause(ThreadID, StartLoc, LParenLoc,
2331 EndLoc);
2334 /// Build a new OpenMP 'bind' clause.
2336 /// By default, performs semantic analysis to build the new OpenMP clause.
2337 /// Subclasses may override this routine to provide different behavior.
2338 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2339 SourceLocation KindLoc,
2340 SourceLocation StartLoc,
2341 SourceLocation LParenLoc,
2342 SourceLocation EndLoc) {
2343 return getSema().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc, LParenLoc,
2344 EndLoc);
2347 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2349 /// By default, performs semantic analysis to build the new OpenMP clause.
2350 /// Subclasses may override this routine to provide different behavior.
2351 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2352 SourceLocation LParenLoc,
2353 SourceLocation EndLoc) {
2354 return getSema().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc, LParenLoc,
2355 EndLoc);
2358 /// Build a new OpenMP 'align' clause.
2360 /// By default, performs semantic analysis to build the new OpenMP clause.
2361 /// Subclasses may override this routine to provide different behavior.
2362 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2363 SourceLocation LParenLoc,
2364 SourceLocation EndLoc) {
2365 return getSema().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc, EndLoc);
2368 /// Build a new OpenMP 'at' clause.
2370 /// By default, performs semantic analysis to build the new OpenMP clause.
2371 /// Subclasses may override this routine to provide different behavior.
2372 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2373 SourceLocation StartLoc,
2374 SourceLocation LParenLoc,
2375 SourceLocation EndLoc) {
2376 return getSema().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc, LParenLoc,
2377 EndLoc);
2380 /// Build a new OpenMP 'severity' clause.
2382 /// By default, performs semantic analysis to build the new OpenMP clause.
2383 /// Subclasses may override this routine to provide different behavior.
2384 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2385 SourceLocation KwLoc,
2386 SourceLocation StartLoc,
2387 SourceLocation LParenLoc,
2388 SourceLocation EndLoc) {
2389 return getSema().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc, LParenLoc,
2390 EndLoc);
2393 /// Build a new OpenMP 'message' clause.
2395 /// By default, performs semantic analysis to build the new OpenMP clause.
2396 /// Subclasses may override this routine to provide different behavior.
2397 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2398 SourceLocation LParenLoc,
2399 SourceLocation EndLoc) {
2400 return getSema().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc, EndLoc);
2403 /// Rebuild the operand to an Objective-C \@synchronized statement.
2405 /// By default, performs semantic analysis to build the new statement.
2406 /// Subclasses may override this routine to provide different behavior.
2407 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2408 Expr *object) {
2409 return getSema().ActOnObjCAtSynchronizedOperand(atLoc, object);
2412 /// Build a new Objective-C \@synchronized statement.
2414 /// By default, performs semantic analysis to build the new statement.
2415 /// Subclasses may override this routine to provide different behavior.
2416 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2417 Expr *Object, Stmt *Body) {
2418 return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2421 /// Build a new Objective-C \@autoreleasepool statement.
2423 /// By default, performs semantic analysis to build the new statement.
2424 /// Subclasses may override this routine to provide different behavior.
2425 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2426 Stmt *Body) {
2427 return getSema().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2430 /// Build a new Objective-C fast enumeration statement.
2432 /// By default, performs semantic analysis to build the new statement.
2433 /// Subclasses may override this routine to provide different behavior.
2434 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2435 Stmt *Element,
2436 Expr *Collection,
2437 SourceLocation RParenLoc,
2438 Stmt *Body) {
2439 StmtResult ForEachStmt = getSema().ActOnObjCForCollectionStmt(ForLoc,
2440 Element,
2441 Collection,
2442 RParenLoc);
2443 if (ForEachStmt.isInvalid())
2444 return StmtError();
2446 return getSema().FinishObjCForCollectionStmt(ForEachStmt.get(), Body);
2449 /// Build a new C++ exception declaration.
2451 /// By default, performs semantic analysis to build the new decaration.
2452 /// Subclasses may override this routine to provide different behavior.
2453 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2454 TypeSourceInfo *Declarator,
2455 SourceLocation StartLoc,
2456 SourceLocation IdLoc,
2457 IdentifierInfo *Id) {
2458 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2459 StartLoc, IdLoc, Id);
2460 if (Var)
2461 getSema().CurContext->addDecl(Var);
2462 return Var;
2465 /// Build a new C++ catch statement.
2467 /// By default, performs semantic analysis to build the new statement.
2468 /// Subclasses may override this routine to provide different behavior.
2469 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2470 VarDecl *ExceptionDecl,
2471 Stmt *Handler) {
2472 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2473 Handler));
2476 /// Build a new C++ try statement.
2478 /// By default, performs semantic analysis to build the new statement.
2479 /// Subclasses may override this routine to provide different behavior.
2480 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2481 ArrayRef<Stmt *> Handlers) {
2482 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2485 /// Build a new C++0x range-based for statement.
2487 /// By default, performs semantic analysis to build the new statement.
2488 /// Subclasses may override this routine to provide different behavior.
2489 StmtResult RebuildCXXForRangeStmt(SourceLocation ForLoc,
2490 SourceLocation CoawaitLoc, Stmt *Init,
2491 SourceLocation ColonLoc, Stmt *Range,
2492 Stmt *Begin, Stmt *End, Expr *Cond,
2493 Expr *Inc, Stmt *LoopVar,
2494 SourceLocation RParenLoc) {
2495 // If we've just learned that the range is actually an Objective-C
2496 // collection, treat this as an Objective-C fast enumeration loop.
2497 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
2498 if (RangeStmt->isSingleDecl()) {
2499 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
2500 if (RangeVar->isInvalidDecl())
2501 return StmtError();
2503 Expr *RangeExpr = RangeVar->getInit();
2504 if (!RangeExpr->isTypeDependent() &&
2505 RangeExpr->getType()->isObjCObjectPointerType()) {
2506 // FIXME: Support init-statements in Objective-C++20 ranged for
2507 // statement.
2508 if (Init) {
2509 return SemaRef.Diag(Init->getBeginLoc(),
2510 diag::err_objc_for_range_init_stmt)
2511 << Init->getSourceRange();
2513 return getSema().ActOnObjCForCollectionStmt(ForLoc, LoopVar,
2514 RangeExpr, RParenLoc);
2520 return getSema().BuildCXXForRangeStmt(ForLoc, CoawaitLoc, Init, ColonLoc,
2521 Range, Begin, End, Cond, Inc, LoopVar,
2522 RParenLoc, Sema::BFRK_Rebuild);
2525 /// Build a new C++0x range-based for statement.
2527 /// By default, performs semantic analysis to build the new statement.
2528 /// Subclasses may override this routine to provide different behavior.
2529 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2530 bool IsIfExists,
2531 NestedNameSpecifierLoc QualifierLoc,
2532 DeclarationNameInfo NameInfo,
2533 Stmt *Nested) {
2534 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2535 QualifierLoc, NameInfo, Nested);
2538 /// Attach body to a C++0x range-based for statement.
2540 /// By default, performs semantic analysis to finish the new statement.
2541 /// Subclasses may override this routine to provide different behavior.
2542 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2543 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2546 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2547 Stmt *TryBlock, Stmt *Handler) {
2548 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2551 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2552 Stmt *Block) {
2553 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2556 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2557 return SEHFinallyStmt::Create(getSema().getASTContext(), Loc, Block);
2560 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2561 SourceLocation LParen,
2562 SourceLocation RParen,
2563 TypeSourceInfo *TSI) {
2564 return getSema().BuildSYCLUniqueStableNameExpr(OpLoc, LParen, RParen, TSI);
2567 /// Build a new predefined expression.
2569 /// By default, performs semantic analysis to build the new expression.
2570 /// Subclasses may override this routine to provide different behavior.
2571 ExprResult RebuildPredefinedExpr(SourceLocation Loc,
2572 PredefinedExpr::IdentKind IK) {
2573 return getSema().BuildPredefinedExpr(Loc, IK);
2576 /// Build a new expression that references a declaration.
2578 /// By default, performs semantic analysis to build the new expression.
2579 /// Subclasses may override this routine to provide different behavior.
2580 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2581 LookupResult &R,
2582 bool RequiresADL) {
2583 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2587 /// Build a new expression that references a declaration.
2589 /// By default, performs semantic analysis to build the new expression.
2590 /// Subclasses may override this routine to provide different behavior.
2591 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2592 ValueDecl *VD,
2593 const DeclarationNameInfo &NameInfo,
2594 NamedDecl *Found,
2595 TemplateArgumentListInfo *TemplateArgs) {
2596 CXXScopeSpec SS;
2597 SS.Adopt(QualifierLoc);
2598 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2599 TemplateArgs);
2602 /// Build a new expression in parentheses.
2604 /// By default, performs semantic analysis to build the new expression.
2605 /// Subclasses may override this routine to provide different behavior.
2606 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2607 SourceLocation RParen) {
2608 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2611 /// Build a new pseudo-destructor expression.
2613 /// By default, performs semantic analysis to build the new expression.
2614 /// Subclasses may override this routine to provide different behavior.
2615 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2616 SourceLocation OperatorLoc,
2617 bool isArrow,
2618 CXXScopeSpec &SS,
2619 TypeSourceInfo *ScopeType,
2620 SourceLocation CCLoc,
2621 SourceLocation TildeLoc,
2622 PseudoDestructorTypeStorage Destroyed);
2624 /// Build a new unary operator expression.
2626 /// By default, performs semantic analysis to build the new expression.
2627 /// Subclasses may override this routine to provide different behavior.
2628 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2629 UnaryOperatorKind Opc,
2630 Expr *SubExpr) {
2631 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2634 /// Build a new builtin offsetof expression.
2636 /// By default, performs semantic analysis to build the new expression.
2637 /// Subclasses may override this routine to provide different behavior.
2638 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2639 TypeSourceInfo *Type,
2640 ArrayRef<Sema::OffsetOfComponent> Components,
2641 SourceLocation RParenLoc) {
2642 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2643 RParenLoc);
2646 /// Build a new sizeof, alignof or vec_step expression with a
2647 /// type argument.
2649 /// By default, performs semantic analysis to build the new expression.
2650 /// Subclasses may override this routine to provide different behavior.
2651 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2652 SourceLocation OpLoc,
2653 UnaryExprOrTypeTrait ExprKind,
2654 SourceRange R) {
2655 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2658 /// Build a new sizeof, alignof or vec step expression with an
2659 /// expression argument.
2661 /// By default, performs semantic analysis to build the new expression.
2662 /// Subclasses may override this routine to provide different behavior.
2663 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2664 UnaryExprOrTypeTrait ExprKind,
2665 SourceRange R) {
2666 ExprResult Result
2667 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2668 if (Result.isInvalid())
2669 return ExprError();
2671 return Result;
2674 /// Build a new array subscript expression.
2676 /// By default, performs semantic analysis to build the new expression.
2677 /// Subclasses may override this routine to provide different behavior.
2678 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2679 SourceLocation LBracketLoc,
2680 Expr *RHS,
2681 SourceLocation RBracketLoc) {
2682 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2683 LBracketLoc, RHS,
2684 RBracketLoc);
2687 /// Build a new matrix subscript expression.
2689 /// By default, performs semantic analysis to build the new expression.
2690 /// Subclasses may override this routine to provide different behavior.
2691 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2692 Expr *ColumnIdx,
2693 SourceLocation RBracketLoc) {
2694 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2695 RBracketLoc);
2698 /// Build a new array section expression.
2700 /// By default, performs semantic analysis to build the new expression.
2701 /// Subclasses may override this routine to provide different behavior.
2702 ExprResult RebuildOMPArraySectionExpr(Expr *Base, SourceLocation LBracketLoc,
2703 Expr *LowerBound,
2704 SourceLocation ColonLocFirst,
2705 SourceLocation ColonLocSecond,
2706 Expr *Length, Expr *Stride,
2707 SourceLocation RBracketLoc) {
2708 return getSema().ActOnOMPArraySectionExpr(Base, LBracketLoc, LowerBound,
2709 ColonLocFirst, ColonLocSecond,
2710 Length, Stride, RBracketLoc);
2713 /// Build a new array shaping expression.
2715 /// By default, performs semantic analysis to build the new expression.
2716 /// Subclasses may override this routine to provide different behavior.
2717 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2718 SourceLocation RParenLoc,
2719 ArrayRef<Expr *> Dims,
2720 ArrayRef<SourceRange> BracketsRanges) {
2721 return getSema().ActOnOMPArrayShapingExpr(Base, LParenLoc, RParenLoc, Dims,
2722 BracketsRanges);
2725 /// Build a new iterator expression.
2727 /// By default, performs semantic analysis to build the new expression.
2728 /// Subclasses may override this routine to provide different behavior.
2729 ExprResult RebuildOMPIteratorExpr(
2730 SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc,
2731 ArrayRef<Sema::OMPIteratorData> Data) {
2732 return getSema().ActOnOMPIteratorExpr(/*Scope=*/nullptr, IteratorKwLoc,
2733 LLoc, RLoc, Data);
2736 /// Build a new call expression.
2738 /// By default, performs semantic analysis to build the new expression.
2739 /// Subclasses may override this routine to provide different behavior.
2740 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2741 MultiExprArg Args,
2742 SourceLocation RParenLoc,
2743 Expr *ExecConfig = nullptr) {
2744 return getSema().ActOnCallExpr(
2745 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2748 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2749 MultiExprArg Args,
2750 SourceLocation RParenLoc) {
2751 return getSema().ActOnArraySubscriptExpr(
2752 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2755 /// Build a new member access expression.
2757 /// By default, performs semantic analysis to build the new expression.
2758 /// Subclasses may override this routine to provide different behavior.
2759 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2760 bool isArrow,
2761 NestedNameSpecifierLoc QualifierLoc,
2762 SourceLocation TemplateKWLoc,
2763 const DeclarationNameInfo &MemberNameInfo,
2764 ValueDecl *Member,
2765 NamedDecl *FoundDecl,
2766 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2767 NamedDecl *FirstQualifierInScope) {
2768 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2769 isArrow);
2770 if (!Member->getDeclName()) {
2771 // We have a reference to an unnamed field. This is always the
2772 // base of an anonymous struct/union member access, i.e. the
2773 // field is always of record type.
2774 assert(Member->getType()->isRecordType() &&
2775 "unnamed member not of record type?");
2777 BaseResult =
2778 getSema().PerformObjectMemberConversion(BaseResult.get(),
2779 QualifierLoc.getNestedNameSpecifier(),
2780 FoundDecl, Member);
2781 if (BaseResult.isInvalid())
2782 return ExprError();
2783 Base = BaseResult.get();
2785 CXXScopeSpec EmptySS;
2786 return getSema().BuildFieldReferenceExpr(
2787 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
2788 DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()), MemberNameInfo);
2791 CXXScopeSpec SS;
2792 SS.Adopt(QualifierLoc);
2794 Base = BaseResult.get();
2795 QualType BaseType = Base->getType();
2797 if (isArrow && !BaseType->isPointerType())
2798 return ExprError();
2800 // FIXME: this involves duplicating earlier analysis in a lot of
2801 // cases; we should avoid this when possible.
2802 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2803 R.addDecl(FoundDecl);
2804 R.resolveKind();
2806 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2807 SS, TemplateKWLoc,
2808 FirstQualifierInScope,
2809 R, ExplicitTemplateArgs,
2810 /*S*/nullptr);
2813 /// Build a new binary operator expression.
2815 /// By default, performs semantic analysis to build the new expression.
2816 /// Subclasses may override this routine to provide different behavior.
2817 ExprResult RebuildBinaryOperator(SourceLocation OpLoc,
2818 BinaryOperatorKind Opc,
2819 Expr *LHS, Expr *RHS) {
2820 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS);
2823 /// Build a new rewritten operator expression.
2825 /// By default, performs semantic analysis to build the new expression.
2826 /// Subclasses may override this routine to provide different behavior.
2827 ExprResult RebuildCXXRewrittenBinaryOperator(
2828 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2829 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2830 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2831 RHS, /*RequiresADL*/false);
2834 /// Build a new conditional operator expression.
2836 /// By default, performs semantic analysis to build the new expression.
2837 /// Subclasses may override this routine to provide different behavior.
2838 ExprResult RebuildConditionalOperator(Expr *Cond,
2839 SourceLocation QuestionLoc,
2840 Expr *LHS,
2841 SourceLocation ColonLoc,
2842 Expr *RHS) {
2843 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
2844 LHS, RHS);
2847 /// Build a new C-style cast expression.
2849 /// By default, performs semantic analysis to build the new expression.
2850 /// Subclasses may override this routine to provide different behavior.
2851 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
2852 TypeSourceInfo *TInfo,
2853 SourceLocation RParenLoc,
2854 Expr *SubExpr) {
2855 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
2856 SubExpr);
2859 /// Build a new compound literal expression.
2861 /// By default, performs semantic analysis to build the new expression.
2862 /// Subclasses may override this routine to provide different behavior.
2863 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
2864 TypeSourceInfo *TInfo,
2865 SourceLocation RParenLoc,
2866 Expr *Init) {
2867 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
2868 Init);
2871 /// Build a new extended vector element access expression.
2873 /// By default, performs semantic analysis to build the new expression.
2874 /// Subclasses may override this routine to provide different behavior.
2875 ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,
2876 bool IsArrow,
2877 SourceLocation AccessorLoc,
2878 IdentifierInfo &Accessor) {
2880 CXXScopeSpec SS;
2881 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
2882 return getSema().BuildMemberReferenceExpr(
2883 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
2884 /*FirstQualifierInScope*/ nullptr, NameInfo,
2885 /* TemplateArgs */ nullptr,
2886 /*S*/ nullptr);
2889 /// Build a new initializer list expression.
2891 /// By default, performs semantic analysis to build the new expression.
2892 /// Subclasses may override this routine to provide different behavior.
2893 ExprResult RebuildInitList(SourceLocation LBraceLoc,
2894 MultiExprArg Inits,
2895 SourceLocation RBraceLoc) {
2896 return SemaRef.BuildInitList(LBraceLoc, Inits, RBraceLoc);
2899 /// Build a new designated initializer expression.
2901 /// By default, performs semantic analysis to build the new expression.
2902 /// Subclasses may override this routine to provide different behavior.
2903 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
2904 MultiExprArg ArrayExprs,
2905 SourceLocation EqualOrColonLoc,
2906 bool GNUSyntax,
2907 Expr *Init) {
2908 ExprResult Result
2909 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
2910 Init);
2911 if (Result.isInvalid())
2912 return ExprError();
2914 return Result;
2917 /// Build a new value-initialized expression.
2919 /// By default, builds the implicit value initialization without performing
2920 /// any semantic analysis. Subclasses may override this routine to provide
2921 /// different behavior.
2922 ExprResult RebuildImplicitValueInitExpr(QualType T) {
2923 return new (SemaRef.Context) ImplicitValueInitExpr(T);
2926 /// Build a new \c va_arg expression.
2928 /// By default, performs semantic analysis to build the new expression.
2929 /// Subclasses may override this routine to provide different behavior.
2930 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
2931 Expr *SubExpr, TypeSourceInfo *TInfo,
2932 SourceLocation RParenLoc) {
2933 return getSema().BuildVAArgExpr(BuiltinLoc,
2934 SubExpr, TInfo,
2935 RParenLoc);
2938 /// Build a new expression list in parentheses.
2940 /// By default, performs semantic analysis to build the new expression.
2941 /// Subclasses may override this routine to provide different behavior.
2942 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
2943 MultiExprArg SubExprs,
2944 SourceLocation RParenLoc) {
2945 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
2948 /// Build a new address-of-label expression.
2950 /// By default, performs semantic analysis, using the name of the label
2951 /// rather than attempting to map the label statement itself.
2952 /// Subclasses may override this routine to provide different behavior.
2953 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
2954 SourceLocation LabelLoc, LabelDecl *Label) {
2955 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
2958 /// Build a new GNU statement expression.
2960 /// By default, performs semantic analysis to build the new expression.
2961 /// Subclasses may override this routine to provide different behavior.
2962 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
2963 SourceLocation RParenLoc, unsigned TemplateDepth) {
2964 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
2965 TemplateDepth);
2968 /// Build a new __builtin_choose_expr expression.
2970 /// By default, performs semantic analysis to build the new expression.
2971 /// Subclasses may override this routine to provide different behavior.
2972 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
2973 Expr *Cond, Expr *LHS, Expr *RHS,
2974 SourceLocation RParenLoc) {
2975 return SemaRef.ActOnChooseExpr(BuiltinLoc,
2976 Cond, LHS, RHS,
2977 RParenLoc);
2980 /// Build a new generic selection expression.
2982 /// By default, performs semantic analysis to build the new expression.
2983 /// Subclasses may override this routine to provide different behavior.
2984 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
2985 SourceLocation DefaultLoc,
2986 SourceLocation RParenLoc,
2987 Expr *ControllingExpr,
2988 ArrayRef<TypeSourceInfo *> Types,
2989 ArrayRef<Expr *> Exprs) {
2990 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
2991 ControllingExpr, Types, Exprs);
2994 /// Build a new overloaded operator call expression.
2996 /// By default, performs semantic analysis to build the new expression.
2997 /// The semantic analysis provides the behavior of template instantiation,
2998 /// copying with transformations that turn what looks like an overloaded
2999 /// operator call into a use of a builtin operator, performing
3000 /// argument-dependent lookup, etc. Subclasses may override this routine to
3001 /// provide different behavior.
3002 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3003 SourceLocation OpLoc,
3004 Expr *Callee,
3005 Expr *First,
3006 Expr *Second);
3008 /// Build a new C++ "named" cast expression, such as static_cast or
3009 /// reinterpret_cast.
3011 /// By default, this routine dispatches to one of the more-specific routines
3012 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3013 /// Subclasses may override this routine to provide different behavior.
3014 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3015 Stmt::StmtClass Class,
3016 SourceLocation LAngleLoc,
3017 TypeSourceInfo *TInfo,
3018 SourceLocation RAngleLoc,
3019 SourceLocation LParenLoc,
3020 Expr *SubExpr,
3021 SourceLocation RParenLoc) {
3022 switch (Class) {
3023 case Stmt::CXXStaticCastExprClass:
3024 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3025 RAngleLoc, LParenLoc,
3026 SubExpr, RParenLoc);
3028 case Stmt::CXXDynamicCastExprClass:
3029 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3030 RAngleLoc, LParenLoc,
3031 SubExpr, RParenLoc);
3033 case Stmt::CXXReinterpretCastExprClass:
3034 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3035 RAngleLoc, LParenLoc,
3036 SubExpr,
3037 RParenLoc);
3039 case Stmt::CXXConstCastExprClass:
3040 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3041 RAngleLoc, LParenLoc,
3042 SubExpr, RParenLoc);
3044 case Stmt::CXXAddrspaceCastExprClass:
3045 return getDerived().RebuildCXXAddrspaceCastExpr(
3046 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3048 default:
3049 llvm_unreachable("Invalid C++ named cast");
3053 /// Build a new C++ static_cast expression.
3055 /// By default, performs semantic analysis to build the new expression.
3056 /// Subclasses may override this routine to provide different behavior.
3057 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3058 SourceLocation LAngleLoc,
3059 TypeSourceInfo *TInfo,
3060 SourceLocation RAngleLoc,
3061 SourceLocation LParenLoc,
3062 Expr *SubExpr,
3063 SourceLocation RParenLoc) {
3064 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3065 TInfo, SubExpr,
3066 SourceRange(LAngleLoc, RAngleLoc),
3067 SourceRange(LParenLoc, RParenLoc));
3070 /// Build a new C++ dynamic_cast expression.
3072 /// By default, performs semantic analysis to build the new expression.
3073 /// Subclasses may override this routine to provide different behavior.
3074 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3075 SourceLocation LAngleLoc,
3076 TypeSourceInfo *TInfo,
3077 SourceLocation RAngleLoc,
3078 SourceLocation LParenLoc,
3079 Expr *SubExpr,
3080 SourceLocation RParenLoc) {
3081 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3082 TInfo, SubExpr,
3083 SourceRange(LAngleLoc, RAngleLoc),
3084 SourceRange(LParenLoc, RParenLoc));
3087 /// Build a new C++ reinterpret_cast expression.
3089 /// By default, performs semantic analysis to build the new expression.
3090 /// Subclasses may override this routine to provide different behavior.
3091 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3092 SourceLocation LAngleLoc,
3093 TypeSourceInfo *TInfo,
3094 SourceLocation RAngleLoc,
3095 SourceLocation LParenLoc,
3096 Expr *SubExpr,
3097 SourceLocation RParenLoc) {
3098 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3099 TInfo, SubExpr,
3100 SourceRange(LAngleLoc, RAngleLoc),
3101 SourceRange(LParenLoc, RParenLoc));
3104 /// Build a new C++ const_cast expression.
3106 /// By default, performs semantic analysis to build the new expression.
3107 /// Subclasses may override this routine to provide different behavior.
3108 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3109 SourceLocation LAngleLoc,
3110 TypeSourceInfo *TInfo,
3111 SourceLocation RAngleLoc,
3112 SourceLocation LParenLoc,
3113 Expr *SubExpr,
3114 SourceLocation RParenLoc) {
3115 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3116 TInfo, SubExpr,
3117 SourceRange(LAngleLoc, RAngleLoc),
3118 SourceRange(LParenLoc, RParenLoc));
3121 ExprResult
3122 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3123 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3124 SourceLocation LParenLoc, Expr *SubExpr,
3125 SourceLocation RParenLoc) {
3126 return getSema().BuildCXXNamedCast(
3127 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3128 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3131 /// Build a new C++ functional-style cast expression.
3133 /// By default, performs semantic analysis to build the new expression.
3134 /// Subclasses may override this routine to provide different behavior.
3135 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3136 SourceLocation LParenLoc,
3137 Expr *Sub,
3138 SourceLocation RParenLoc,
3139 bool ListInitialization) {
3140 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3141 MultiExprArg(&Sub, 1), RParenLoc,
3142 ListInitialization);
3145 /// Build a new C++ __builtin_bit_cast expression.
3147 /// By default, performs semantic analysis to build the new expression.
3148 /// Subclasses may override this routine to provide different behavior.
3149 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3150 TypeSourceInfo *TSI, Expr *Sub,
3151 SourceLocation RParenLoc) {
3152 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3155 /// Build a new C++ typeid(type) expression.
3157 /// By default, performs semantic analysis to build the new expression.
3158 /// Subclasses may override this routine to provide different behavior.
3159 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3160 SourceLocation TypeidLoc,
3161 TypeSourceInfo *Operand,
3162 SourceLocation RParenLoc) {
3163 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3164 RParenLoc);
3168 /// Build a new C++ typeid(expr) expression.
3170 /// By default, performs semantic analysis to build the new expression.
3171 /// Subclasses may override this routine to provide different behavior.
3172 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3173 SourceLocation TypeidLoc,
3174 Expr *Operand,
3175 SourceLocation RParenLoc) {
3176 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3177 RParenLoc);
3180 /// Build a new C++ __uuidof(type) expression.
3182 /// By default, performs semantic analysis to build the new expression.
3183 /// Subclasses may override this routine to provide different behavior.
3184 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3185 TypeSourceInfo *Operand,
3186 SourceLocation RParenLoc) {
3187 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3190 /// Build a new C++ __uuidof(expr) expression.
3192 /// By default, performs semantic analysis to build the new expression.
3193 /// Subclasses may override this routine to provide different behavior.
3194 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3195 Expr *Operand, SourceLocation RParenLoc) {
3196 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3199 /// Build a new C++ "this" expression.
3201 /// By default, builds a new "this" expression without performing any
3202 /// semantic analysis. Subclasses may override this routine to provide
3203 /// different behavior.
3204 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3205 QualType ThisType,
3206 bool isImplicit) {
3207 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3210 /// Build a new C++ throw expression.
3212 /// By default, performs semantic analysis to build the new expression.
3213 /// Subclasses may override this routine to provide different behavior.
3214 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3215 bool IsThrownVariableInScope) {
3216 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3219 /// Build a new C++ default-argument expression.
3221 /// By default, builds a new default-argument expression, which does not
3222 /// require any semantic analysis. Subclasses may override this routine to
3223 /// provide different behavior.
3224 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3225 Expr *RewrittenExpr) {
3226 return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param,
3227 RewrittenExpr, getSema().CurContext);
3230 /// Build a new C++11 default-initialization expression.
3232 /// By default, builds a new default field initialization expression, which
3233 /// does not require any semantic analysis. Subclasses may override this
3234 /// routine to provide different behavior.
3235 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3236 FieldDecl *Field) {
3237 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3240 /// Build a new C++ zero-initialization expression.
3242 /// By default, performs semantic analysis to build the new expression.
3243 /// Subclasses may override this routine to provide different behavior.
3244 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3245 SourceLocation LParenLoc,
3246 SourceLocation RParenLoc) {
3247 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, std::nullopt,
3248 RParenLoc,
3249 /*ListInitialization=*/false);
3252 /// Build a new C++ "new" expression.
3254 /// By default, performs semantic analysis to build the new expression.
3255 /// Subclasses may override this routine to provide different behavior.
3256 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3257 SourceLocation PlacementLParen,
3258 MultiExprArg PlacementArgs,
3259 SourceLocation PlacementRParen,
3260 SourceRange TypeIdParens, QualType AllocatedType,
3261 TypeSourceInfo *AllocatedTypeInfo,
3262 std::optional<Expr *> ArraySize,
3263 SourceRange DirectInitRange, Expr *Initializer) {
3264 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3265 PlacementLParen,
3266 PlacementArgs,
3267 PlacementRParen,
3268 TypeIdParens,
3269 AllocatedType,
3270 AllocatedTypeInfo,
3271 ArraySize,
3272 DirectInitRange,
3273 Initializer);
3276 /// Build a new C++ "delete" expression.
3278 /// By default, performs semantic analysis to build the new expression.
3279 /// Subclasses may override this routine to provide different behavior.
3280 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3281 bool IsGlobalDelete,
3282 bool IsArrayForm,
3283 Expr *Operand) {
3284 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3285 Operand);
3288 /// Build a new type trait expression.
3290 /// By default, performs semantic analysis to build the new expression.
3291 /// Subclasses may override this routine to provide different behavior.
3292 ExprResult RebuildTypeTrait(TypeTrait Trait,
3293 SourceLocation StartLoc,
3294 ArrayRef<TypeSourceInfo *> Args,
3295 SourceLocation RParenLoc) {
3296 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3299 /// Build a new array type trait expression.
3301 /// By default, performs semantic analysis to build the new expression.
3302 /// Subclasses may override this routine to provide different behavior.
3303 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3304 SourceLocation StartLoc,
3305 TypeSourceInfo *TSInfo,
3306 Expr *DimExpr,
3307 SourceLocation RParenLoc) {
3308 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3311 /// Build a new expression trait expression.
3313 /// By default, performs semantic analysis to build the new expression.
3314 /// Subclasses may override this routine to provide different behavior.
3315 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3316 SourceLocation StartLoc,
3317 Expr *Queried,
3318 SourceLocation RParenLoc) {
3319 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3322 /// Build a new (previously unresolved) declaration reference
3323 /// expression.
3325 /// By default, performs semantic analysis to build the new expression.
3326 /// Subclasses may override this routine to provide different behavior.
3327 ExprResult RebuildDependentScopeDeclRefExpr(
3328 NestedNameSpecifierLoc QualifierLoc,
3329 SourceLocation TemplateKWLoc,
3330 const DeclarationNameInfo &NameInfo,
3331 const TemplateArgumentListInfo *TemplateArgs,
3332 bool IsAddressOfOperand,
3333 TypeSourceInfo **RecoveryTSI) {
3334 CXXScopeSpec SS;
3335 SS.Adopt(QualifierLoc);
3337 if (TemplateArgs || TemplateKWLoc.isValid())
3338 return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, NameInfo,
3339 TemplateArgs);
3341 return getSema().BuildQualifiedDeclarationNameExpr(
3342 SS, NameInfo, IsAddressOfOperand, /*S*/nullptr, RecoveryTSI);
3345 /// Build a new template-id expression.
3347 /// By default, performs semantic analysis to build the new expression.
3348 /// Subclasses may override this routine to provide different behavior.
3349 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3350 SourceLocation TemplateKWLoc,
3351 LookupResult &R,
3352 bool RequiresADL,
3353 const TemplateArgumentListInfo *TemplateArgs) {
3354 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3355 TemplateArgs);
3358 /// Build a new object-construction expression.
3360 /// By default, performs semantic analysis to build the new expression.
3361 /// Subclasses may override this routine to provide different behavior.
3362 ExprResult RebuildCXXConstructExpr(QualType T,
3363 SourceLocation Loc,
3364 CXXConstructorDecl *Constructor,
3365 bool IsElidable,
3366 MultiExprArg Args,
3367 bool HadMultipleCandidates,
3368 bool ListInitialization,
3369 bool StdInitListInitialization,
3370 bool RequiresZeroInit,
3371 CXXConstructExpr::ConstructionKind ConstructKind,
3372 SourceRange ParenRange) {
3373 // Reconstruct the constructor we originally found, which might be
3374 // different if this is a call to an inherited constructor.
3375 CXXConstructorDecl *FoundCtor = Constructor;
3376 if (Constructor->isInheritingConstructor())
3377 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3379 SmallVector<Expr *, 8> ConvertedArgs;
3380 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3381 ConvertedArgs))
3382 return ExprError();
3384 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3385 IsElidable,
3386 ConvertedArgs,
3387 HadMultipleCandidates,
3388 ListInitialization,
3389 StdInitListInitialization,
3390 RequiresZeroInit, ConstructKind,
3391 ParenRange);
3394 /// Build a new implicit construction via inherited constructor
3395 /// expression.
3396 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3397 CXXConstructorDecl *Constructor,
3398 bool ConstructsVBase,
3399 bool InheritedFromVBase) {
3400 return new (getSema().Context) CXXInheritedCtorInitExpr(
3401 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3404 /// Build a new object-construction expression.
3406 /// By default, performs semantic analysis to build the new expression.
3407 /// Subclasses may override this routine to provide different behavior.
3408 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3409 SourceLocation LParenOrBraceLoc,
3410 MultiExprArg Args,
3411 SourceLocation RParenOrBraceLoc,
3412 bool ListInitialization) {
3413 return getSema().BuildCXXTypeConstructExpr(
3414 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3417 /// Build a new object-construction expression.
3419 /// By default, performs semantic analysis to build the new expression.
3420 /// Subclasses may override this routine to provide different behavior.
3421 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3422 SourceLocation LParenLoc,
3423 MultiExprArg Args,
3424 SourceLocation RParenLoc,
3425 bool ListInitialization) {
3426 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3427 RParenLoc, ListInitialization);
3430 /// Build a new member reference expression.
3432 /// By default, performs semantic analysis to build the new expression.
3433 /// Subclasses may override this routine to provide different behavior.
3434 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3435 QualType BaseType,
3436 bool IsArrow,
3437 SourceLocation OperatorLoc,
3438 NestedNameSpecifierLoc QualifierLoc,
3439 SourceLocation TemplateKWLoc,
3440 NamedDecl *FirstQualifierInScope,
3441 const DeclarationNameInfo &MemberNameInfo,
3442 const TemplateArgumentListInfo *TemplateArgs) {
3443 CXXScopeSpec SS;
3444 SS.Adopt(QualifierLoc);
3446 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3447 OperatorLoc, IsArrow,
3448 SS, TemplateKWLoc,
3449 FirstQualifierInScope,
3450 MemberNameInfo,
3451 TemplateArgs, /*S*/nullptr);
3454 /// Build a new member reference expression.
3456 /// By default, performs semantic analysis to build the new expression.
3457 /// Subclasses may override this routine to provide different behavior.
3458 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3459 SourceLocation OperatorLoc,
3460 bool IsArrow,
3461 NestedNameSpecifierLoc QualifierLoc,
3462 SourceLocation TemplateKWLoc,
3463 NamedDecl *FirstQualifierInScope,
3464 LookupResult &R,
3465 const TemplateArgumentListInfo *TemplateArgs) {
3466 CXXScopeSpec SS;
3467 SS.Adopt(QualifierLoc);
3469 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3470 OperatorLoc, IsArrow,
3471 SS, TemplateKWLoc,
3472 FirstQualifierInScope,
3473 R, TemplateArgs, /*S*/nullptr);
3476 /// Build a new noexcept expression.
3478 /// By default, performs semantic analysis to build the new expression.
3479 /// Subclasses may override this routine to provide different behavior.
3480 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3481 return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd());
3484 /// Build a new expression to compute the length of a parameter pack.
3485 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3486 SourceLocation PackLoc,
3487 SourceLocation RParenLoc,
3488 std::optional<unsigned> Length,
3489 ArrayRef<TemplateArgument> PartialArgs) {
3490 return SizeOfPackExpr::Create(SemaRef.Context, OperatorLoc, Pack, PackLoc,
3491 RParenLoc, Length, PartialArgs);
3494 /// Build a new expression representing a call to a source location
3495 /// builtin.
3497 /// By default, performs semantic analysis to build the new expression.
3498 /// Subclasses may override this routine to provide different behavior.
3499 ExprResult RebuildSourceLocExpr(SourceLocExpr::IdentKind Kind,
3500 QualType ResultTy, SourceLocation BuiltinLoc,
3501 SourceLocation RPLoc,
3502 DeclContext *ParentContext) {
3503 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3504 ParentContext);
3507 /// Build a new Objective-C boxed expression.
3509 /// By default, performs semantic analysis to build the new expression.
3510 /// Subclasses may override this routine to provide different behavior.
3511 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3512 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3513 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3514 TemplateArgumentListInfo *TALI) {
3515 CXXScopeSpec SS;
3516 SS.Adopt(NNS);
3517 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3518 ConceptNameInfo,
3519 FoundDecl,
3520 NamedConcept, TALI);
3521 if (Result.isInvalid())
3522 return ExprError();
3523 return Result;
3526 /// \brief Build a new requires expression.
3528 /// By default, performs semantic analysis to build the new expression.
3529 /// Subclasses may override this routine to provide different behavior.
3530 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3531 RequiresExprBodyDecl *Body,
3532 ArrayRef<ParmVarDecl *> LocalParameters,
3533 ArrayRef<concepts::Requirement *> Requirements,
3534 SourceLocation ClosingBraceLoc) {
3535 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body,
3536 LocalParameters, Requirements, ClosingBraceLoc);
3539 concepts::TypeRequirement *
3540 RebuildTypeRequirement(
3541 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3542 return SemaRef.BuildTypeRequirement(SubstDiag);
3545 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3546 return SemaRef.BuildTypeRequirement(T);
3549 concepts::ExprRequirement *
3550 RebuildExprRequirement(
3551 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3552 SourceLocation NoexceptLoc,
3553 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3554 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
3555 std::move(Ret));
3558 concepts::ExprRequirement *
3559 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3560 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3561 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
3562 std::move(Ret));
3565 concepts::NestedRequirement *
3566 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3567 const ASTConstraintSatisfaction &Satisfaction) {
3568 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3569 Satisfaction);
3572 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3573 return SemaRef.BuildNestedRequirement(Constraint);
3576 /// \brief Build a new Objective-C boxed expression.
3578 /// By default, performs semantic analysis to build the new expression.
3579 /// Subclasses may override this routine to provide different behavior.
3580 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3581 return getSema().BuildObjCBoxedExpr(SR, ValueExpr);
3584 /// Build a new Objective-C array literal.
3586 /// By default, performs semantic analysis to build the new expression.
3587 /// Subclasses may override this routine to provide different behavior.
3588 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3589 Expr **Elements, unsigned NumElements) {
3590 return getSema().BuildObjCArrayLiteral(Range,
3591 MultiExprArg(Elements, NumElements));
3594 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3595 Expr *Base, Expr *Key,
3596 ObjCMethodDecl *getterMethod,
3597 ObjCMethodDecl *setterMethod) {
3598 return getSema().BuildObjCSubscriptExpression(RB, Base, Key,
3599 getterMethod, setterMethod);
3602 /// Build a new Objective-C dictionary literal.
3604 /// By default, performs semantic analysis to build the new expression.
3605 /// Subclasses may override this routine to provide different behavior.
3606 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3607 MutableArrayRef<ObjCDictionaryElement> Elements) {
3608 return getSema().BuildObjCDictionaryLiteral(Range, Elements);
3611 /// Build a new Objective-C \@encode expression.
3613 /// By default, performs semantic analysis to build the new expression.
3614 /// Subclasses may override this routine to provide different behavior.
3615 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3616 TypeSourceInfo *EncodeTypeInfo,
3617 SourceLocation RParenLoc) {
3618 return SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, RParenLoc);
3621 /// Build a new Objective-C class message.
3622 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3623 Selector Sel,
3624 ArrayRef<SourceLocation> SelectorLocs,
3625 ObjCMethodDecl *Method,
3626 SourceLocation LBracLoc,
3627 MultiExprArg Args,
3628 SourceLocation RBracLoc) {
3629 return SemaRef.BuildClassMessage(ReceiverTypeInfo,
3630 ReceiverTypeInfo->getType(),
3631 /*SuperLoc=*/SourceLocation(),
3632 Sel, Method, LBracLoc, SelectorLocs,
3633 RBracLoc, Args);
3636 /// Build a new Objective-C instance message.
3637 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3638 Selector Sel,
3639 ArrayRef<SourceLocation> SelectorLocs,
3640 ObjCMethodDecl *Method,
3641 SourceLocation LBracLoc,
3642 MultiExprArg Args,
3643 SourceLocation RBracLoc) {
3644 return SemaRef.BuildInstanceMessage(Receiver,
3645 Receiver->getType(),
3646 /*SuperLoc=*/SourceLocation(),
3647 Sel, Method, LBracLoc, SelectorLocs,
3648 RBracLoc, Args);
3651 /// Build a new Objective-C instance/class message to 'super'.
3652 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3653 Selector Sel,
3654 ArrayRef<SourceLocation> SelectorLocs,
3655 QualType SuperType,
3656 ObjCMethodDecl *Method,
3657 SourceLocation LBracLoc,
3658 MultiExprArg Args,
3659 SourceLocation RBracLoc) {
3660 return Method->isInstanceMethod() ? SemaRef.BuildInstanceMessage(nullptr,
3661 SuperType,
3662 SuperLoc,
3663 Sel, Method, LBracLoc, SelectorLocs,
3664 RBracLoc, Args)
3665 : SemaRef.BuildClassMessage(nullptr,
3666 SuperType,
3667 SuperLoc,
3668 Sel, Method, LBracLoc, SelectorLocs,
3669 RBracLoc, Args);
3674 /// Build a new Objective-C ivar reference expression.
3676 /// By default, performs semantic analysis to build the new expression.
3677 /// Subclasses may override this routine to provide different behavior.
3678 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3679 SourceLocation IvarLoc,
3680 bool IsArrow, bool IsFreeIvar) {
3681 CXXScopeSpec SS;
3682 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3683 ExprResult Result = getSema().BuildMemberReferenceExpr(
3684 BaseArg, BaseArg->getType(),
3685 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3686 /*FirstQualifierInScope=*/nullptr, NameInfo,
3687 /*TemplateArgs=*/nullptr,
3688 /*S=*/nullptr);
3689 if (IsFreeIvar && Result.isUsable())
3690 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
3691 return Result;
3694 /// Build a new Objective-C property reference expression.
3696 /// By default, performs semantic analysis to build the new expression.
3697 /// Subclasses may override this routine to provide different behavior.
3698 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3699 ObjCPropertyDecl *Property,
3700 SourceLocation PropertyLoc) {
3701 CXXScopeSpec SS;
3702 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3703 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3704 /*FIXME:*/PropertyLoc,
3705 /*IsArrow=*/false,
3706 SS, SourceLocation(),
3707 /*FirstQualifierInScope=*/nullptr,
3708 NameInfo,
3709 /*TemplateArgs=*/nullptr,
3710 /*S=*/nullptr);
3713 /// Build a new Objective-C property reference expression.
3715 /// By default, performs semantic analysis to build the new expression.
3716 /// Subclasses may override this routine to provide different behavior.
3717 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3718 ObjCMethodDecl *Getter,
3719 ObjCMethodDecl *Setter,
3720 SourceLocation PropertyLoc) {
3721 // Since these expressions can only be value-dependent, we do not
3722 // need to perform semantic analysis again.
3723 return Owned(
3724 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3725 VK_LValue, OK_ObjCProperty,
3726 PropertyLoc, Base));
3729 /// Build a new Objective-C "isa" expression.
3731 /// By default, performs semantic analysis to build the new expression.
3732 /// Subclasses may override this routine to provide different behavior.
3733 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
3734 SourceLocation OpLoc, bool IsArrow) {
3735 CXXScopeSpec SS;
3736 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3737 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3738 OpLoc, IsArrow,
3739 SS, SourceLocation(),
3740 /*FirstQualifierInScope=*/nullptr,
3741 NameInfo,
3742 /*TemplateArgs=*/nullptr,
3743 /*S=*/nullptr);
3746 /// Build a new shuffle vector expression.
3748 /// By default, performs semantic analysis to build the new expression.
3749 /// Subclasses may override this routine to provide different behavior.
3750 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
3751 MultiExprArg SubExprs,
3752 SourceLocation RParenLoc) {
3753 // Find the declaration for __builtin_shufflevector
3754 const IdentifierInfo &Name
3755 = SemaRef.Context.Idents.get("__builtin_shufflevector");
3756 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
3757 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
3758 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3760 // Build a reference to the __builtin_shufflevector builtin
3761 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
3762 Expr *Callee = new (SemaRef.Context)
3763 DeclRefExpr(SemaRef.Context, Builtin, false,
3764 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3765 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
3766 Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
3767 CK_BuiltinFnToFnPtr).get();
3769 // Build the CallExpr
3770 ExprResult TheCall = CallExpr::Create(
3771 SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
3772 Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc,
3773 FPOptionsOverride());
3775 // Type-check the __builtin_shufflevector expression.
3776 return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
3779 /// Build a new convert vector expression.
3780 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
3781 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3782 SourceLocation RParenLoc) {
3783 return SemaRef.SemaConvertVectorExpr(SrcExpr, DstTInfo,
3784 BuiltinLoc, RParenLoc);
3787 /// Build a new template argument pack expansion.
3789 /// By default, performs semantic analysis to build a new pack expansion
3790 /// for a template argument. Subclasses may override this routine to provide
3791 /// different behavior.
3792 TemplateArgumentLoc
3793 RebuildPackExpansion(TemplateArgumentLoc Pattern, SourceLocation EllipsisLoc,
3794 std::optional<unsigned> NumExpansions) {
3795 switch (Pattern.getArgument().getKind()) {
3796 case TemplateArgument::Expression: {
3797 ExprResult Result
3798 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
3799 EllipsisLoc, NumExpansions);
3800 if (Result.isInvalid())
3801 return TemplateArgumentLoc();
3803 return TemplateArgumentLoc(Result.get(), Result.get());
3806 case TemplateArgument::Template:
3807 return TemplateArgumentLoc(
3808 SemaRef.Context,
3809 TemplateArgument(Pattern.getArgument().getAsTemplate(),
3810 NumExpansions),
3811 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
3812 EllipsisLoc);
3814 case TemplateArgument::Null:
3815 case TemplateArgument::Integral:
3816 case TemplateArgument::Declaration:
3817 case TemplateArgument::Pack:
3818 case TemplateArgument::TemplateExpansion:
3819 case TemplateArgument::NullPtr:
3820 llvm_unreachable("Pack expansion pattern has no parameter packs");
3822 case TemplateArgument::Type:
3823 if (TypeSourceInfo *Expansion
3824 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
3825 EllipsisLoc,
3826 NumExpansions))
3827 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
3828 Expansion);
3829 break;
3832 return TemplateArgumentLoc();
3835 /// Build a new expression pack expansion.
3837 /// By default, performs semantic analysis to build a new pack expansion
3838 /// for an expression. Subclasses may override this routine to provide
3839 /// different behavior.
3840 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
3841 std::optional<unsigned> NumExpansions) {
3842 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
3845 /// Build a new C++1z fold-expression.
3847 /// By default, performs semantic analysis in order to build a new fold
3848 /// expression.
3849 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
3850 SourceLocation LParenLoc, Expr *LHS,
3851 BinaryOperatorKind Operator,
3852 SourceLocation EllipsisLoc, Expr *RHS,
3853 SourceLocation RParenLoc,
3854 std::optional<unsigned> NumExpansions) {
3855 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
3856 EllipsisLoc, RHS, RParenLoc,
3857 NumExpansions);
3860 /// Build an empty C++1z fold-expression with the given operator.
3862 /// By default, produces the fallback value for the fold-expression, or
3863 /// produce an error if there is no fallback value.
3864 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
3865 BinaryOperatorKind Operator) {
3866 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
3869 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
3870 unsigned NumUserSpecifiedExprs,
3871 SourceLocation InitLoc,
3872 SourceLocation LParenLoc,
3873 SourceLocation RParenLoc) {
3874 return CXXParenListInitExpr::Create(getSema().Context, Args, T,
3875 NumUserSpecifiedExprs, InitLoc,
3876 LParenLoc, RParenLoc);
3879 /// Build a new atomic operation expression.
3881 /// By default, performs semantic analysis to build the new expression.
3882 /// Subclasses may override this routine to provide different behavior.
3883 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
3884 AtomicExpr::AtomicOp Op,
3885 SourceLocation RParenLoc) {
3886 // Use this for all of the locations, since we don't know the difference
3887 // between the call and the expr at this point.
3888 SourceRange Range{BuiltinLoc, RParenLoc};
3889 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
3890 Sema::AtomicArgumentOrder::AST);
3893 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
3894 ArrayRef<Expr *> SubExprs, QualType Type) {
3895 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
3898 private:
3899 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
3900 QualType ObjectType,
3901 NamedDecl *FirstQualifierInScope,
3902 CXXScopeSpec &SS);
3904 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
3905 QualType ObjectType,
3906 NamedDecl *FirstQualifierInScope,
3907 CXXScopeSpec &SS);
3909 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
3910 NamedDecl *FirstQualifierInScope,
3911 CXXScopeSpec &SS);
3913 QualType TransformDependentNameType(TypeLocBuilder &TLB,
3914 DependentNameTypeLoc TL,
3915 bool DeducibleTSTContext);
3918 template <typename Derived>
3919 StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
3920 if (!S)
3921 return S;
3923 switch (S->getStmtClass()) {
3924 case Stmt::NoStmtClass: break;
3926 // Transform individual statement nodes
3927 // Pass SDK into statements that can produce a value
3928 #define STMT(Node, Parent) \
3929 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
3930 #define VALUESTMT(Node, Parent) \
3931 case Stmt::Node##Class: \
3932 return getDerived().Transform##Node(cast<Node>(S), SDK);
3933 #define ABSTRACT_STMT(Node)
3934 #define EXPR(Node, Parent)
3935 #include "clang/AST/StmtNodes.inc"
3937 // Transform expressions by calling TransformExpr.
3938 #define STMT(Node, Parent)
3939 #define ABSTRACT_STMT(Stmt)
3940 #define EXPR(Node, Parent) case Stmt::Node##Class:
3941 #include "clang/AST/StmtNodes.inc"
3943 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
3945 if (SDK == SDK_StmtExprResult)
3946 E = getSema().ActOnStmtExprResult(E);
3947 return getSema().ActOnExprStmt(E, SDK == SDK_Discarded);
3951 return S;
3954 template<typename Derived>
3955 OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
3956 if (!S)
3957 return S;
3959 switch (S->getClauseKind()) {
3960 default: break;
3961 // Transform individual clause nodes
3962 #define GEN_CLANG_CLAUSE_CLASS
3963 #define CLAUSE_CLASS(Enum, Str, Class) \
3964 case Enum: \
3965 return getDerived().Transform##Class(cast<Class>(S));
3966 #include "llvm/Frontend/OpenMP/OMP.inc"
3969 return S;
3973 template<typename Derived>
3974 ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
3975 if (!E)
3976 return E;
3978 switch (E->getStmtClass()) {
3979 case Stmt::NoStmtClass: break;
3980 #define STMT(Node, Parent) case Stmt::Node##Class: break;
3981 #define ABSTRACT_STMT(Stmt)
3982 #define EXPR(Node, Parent) \
3983 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
3984 #include "clang/AST/StmtNodes.inc"
3987 return E;
3990 template<typename Derived>
3991 ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
3992 bool NotCopyInit) {
3993 // Initializers are instantiated like expressions, except that various outer
3994 // layers are stripped.
3995 if (!Init)
3996 return Init;
3998 if (auto *FE = dyn_cast<FullExpr>(Init))
3999 Init = FE->getSubExpr();
4001 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {
4002 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4003 Init = OVE->getSourceExpr();
4006 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
4007 Init = MTE->getSubExpr();
4009 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
4010 Init = Binder->getSubExpr();
4012 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
4013 Init = ICE->getSubExprAsWritten();
4015 if (CXXStdInitializerListExpr *ILE =
4016 dyn_cast<CXXStdInitializerListExpr>(Init))
4017 return TransformInitializer(ILE->getSubExpr(), NotCopyInit);
4019 // If this is copy-initialization, we only need to reconstruct
4020 // InitListExprs. Other forms of copy-initialization will be a no-op if
4021 // the initializer is already the right type.
4022 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
4023 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4024 return getDerived().TransformExpr(Init);
4026 // Revert value-initialization back to empty parens.
4027 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
4028 SourceRange Parens = VIE->getSourceRange();
4029 return getDerived().RebuildParenListExpr(Parens.getBegin(), std::nullopt,
4030 Parens.getEnd());
4033 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4034 if (isa<ImplicitValueInitExpr>(Init))
4035 return getDerived().RebuildParenListExpr(SourceLocation(), std::nullopt,
4036 SourceLocation());
4038 // Revert initialization by constructor back to a parenthesized or braced list
4039 // of expressions. Any other form of initializer can just be reused directly.
4040 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
4041 return getDerived().TransformExpr(Init);
4043 // If the initialization implicitly converted an initializer list to a
4044 // std::initializer_list object, unwrap the std::initializer_list too.
4045 if (Construct && Construct->isStdInitListInitialization())
4046 return TransformInitializer(Construct->getArg(0), NotCopyInit);
4048 // Enter a list-init context if this was list initialization.
4049 EnterExpressionEvaluationContext Context(
4050 getSema(), EnterExpressionEvaluationContext::InitList,
4051 Construct->isListInitialization());
4053 SmallVector<Expr*, 8> NewArgs;
4054 bool ArgChanged = false;
4055 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4056 /*IsCall*/true, NewArgs, &ArgChanged))
4057 return ExprError();
4059 // If this was list initialization, revert to syntactic list form.
4060 if (Construct->isListInitialization())
4061 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4062 Construct->getEndLoc());
4064 // Build a ParenListExpr to represent anything else.
4065 SourceRange Parens = Construct->getParenOrBraceRange();
4066 if (Parens.isInvalid()) {
4067 // This was a variable declaration's initialization for which no initializer
4068 // was specified.
4069 assert(NewArgs.empty() &&
4070 "no parens or braces but have direct init with arguments?");
4071 return ExprEmpty();
4073 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4074 Parens.getEnd());
4077 template<typename Derived>
4078 bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4079 unsigned NumInputs,
4080 bool IsCall,
4081 SmallVectorImpl<Expr *> &Outputs,
4082 bool *ArgChanged) {
4083 for (unsigned I = 0; I != NumInputs; ++I) {
4084 // If requested, drop call arguments that need to be dropped.
4085 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4086 if (ArgChanged)
4087 *ArgChanged = true;
4089 break;
4092 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
4093 Expr *Pattern = Expansion->getPattern();
4095 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4096 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4097 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4099 // Determine whether the set of unexpanded parameter packs can and should
4100 // be expanded.
4101 bool Expand = true;
4102 bool RetainExpansion = false;
4103 std::optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions();
4104 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4105 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4106 Pattern->getSourceRange(),
4107 Unexpanded,
4108 Expand, RetainExpansion,
4109 NumExpansions))
4110 return true;
4112 if (!Expand) {
4113 // The transform has determined that we should perform a simple
4114 // transformation on the pack expansion, producing another pack
4115 // expansion.
4116 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4117 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4118 if (OutPattern.isInvalid())
4119 return true;
4121 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4122 Expansion->getEllipsisLoc(),
4123 NumExpansions);
4124 if (Out.isInvalid())
4125 return true;
4127 if (ArgChanged)
4128 *ArgChanged = true;
4129 Outputs.push_back(Out.get());
4130 continue;
4133 // Record right away that the argument was changed. This needs
4134 // to happen even if the array expands to nothing.
4135 if (ArgChanged) *ArgChanged = true;
4137 // The transform has determined that we should perform an elementwise
4138 // expansion of the pattern. Do so.
4139 for (unsigned I = 0; I != *NumExpansions; ++I) {
4140 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4141 ExprResult Out = getDerived().TransformExpr(Pattern);
4142 if (Out.isInvalid())
4143 return true;
4145 if (Out.get()->containsUnexpandedParameterPack()) {
4146 Out = getDerived().RebuildPackExpansion(
4147 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4148 if (Out.isInvalid())
4149 return true;
4152 Outputs.push_back(Out.get());
4155 // If we're supposed to retain a pack expansion, do so by temporarily
4156 // forgetting the partially-substituted parameter pack.
4157 if (RetainExpansion) {
4158 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4160 ExprResult Out = getDerived().TransformExpr(Pattern);
4161 if (Out.isInvalid())
4162 return true;
4164 Out = getDerived().RebuildPackExpansion(
4165 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4166 if (Out.isInvalid())
4167 return true;
4169 Outputs.push_back(Out.get());
4172 continue;
4175 ExprResult Result =
4176 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4177 : getDerived().TransformExpr(Inputs[I]);
4178 if (Result.isInvalid())
4179 return true;
4181 if (Result.get() != Inputs[I] && ArgChanged)
4182 *ArgChanged = true;
4184 Outputs.push_back(Result.get());
4187 return false;
4190 template <typename Derived>
4191 Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4192 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4193 if (Var) {
4194 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4195 getDerived().TransformDefinition(Var->getLocation(), Var));
4197 if (!ConditionVar)
4198 return Sema::ConditionError();
4200 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4203 if (Expr) {
4204 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4206 if (CondExpr.isInvalid())
4207 return Sema::ConditionError();
4209 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4210 /*MissingOK=*/true);
4213 return Sema::ConditionResult();
4216 template <typename Derived>
4217 NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4218 NestedNameSpecifierLoc NNS, QualType ObjectType,
4219 NamedDecl *FirstQualifierInScope) {
4220 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4222 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4223 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4224 Qualifier = Qualifier.getPrefix())
4225 Qualifiers.push_back(Qualifier);
4227 insertNNS(NNS);
4229 CXXScopeSpec SS;
4230 while (!Qualifiers.empty()) {
4231 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4232 NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
4234 switch (QNNS->getKind()) {
4235 case NestedNameSpecifier::Identifier: {
4236 Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
4237 Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
4238 ObjectType);
4239 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false,
4240 SS, FirstQualifierInScope, false))
4241 return NestedNameSpecifierLoc();
4242 break;
4245 case NestedNameSpecifier::Namespace: {
4246 NamespaceDecl *NS =
4247 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4248 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4249 SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
4250 break;
4253 case NestedNameSpecifier::NamespaceAlias: {
4254 NamespaceAliasDecl *Alias =
4255 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4256 Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
4257 SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
4258 Q.getLocalEndLoc());
4259 break;
4262 case NestedNameSpecifier::Global:
4263 // There is no meaningful transformation that one could perform on the
4264 // global scope.
4265 SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
4266 break;
4268 case NestedNameSpecifier::Super: {
4269 CXXRecordDecl *RD =
4270 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4271 SourceLocation(), QNNS->getAsRecordDecl()));
4272 SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc());
4273 break;
4276 case NestedNameSpecifier::TypeSpecWithTemplate:
4277 case NestedNameSpecifier::TypeSpec: {
4278 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4279 FirstQualifierInScope, SS);
4281 if (!TL)
4282 return NestedNameSpecifierLoc();
4284 QualType T = TL.getType();
4285 if (T->isDependentType() || T->isRecordType() ||
4286 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4287 if (T->isEnumeralType())
4288 SemaRef.Diag(TL.getBeginLoc(),
4289 diag::warn_cxx98_compat_enum_nested_name_spec);
4291 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4292 SS.Adopt(ETL.getQualifierLoc());
4293 TL = ETL.getNamedTypeLoc();
4295 SS.Extend(SemaRef.Context, /*FIXME:*/ SourceLocation(), TL,
4296 Q.getLocalEndLoc());
4297 break;
4299 // If the nested-name-specifier is an invalid type def, don't emit an
4300 // error because a previous error should have already been emitted.
4301 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4302 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4303 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
4304 << T << SS.getRange();
4306 return NestedNameSpecifierLoc();
4310 // The qualifier-in-scope and object type only apply to the leftmost entity.
4311 FirstQualifierInScope = nullptr;
4312 ObjectType = QualType();
4315 // Don't rebuild the nested-name-specifier if we don't have to.
4316 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4317 !getDerived().AlwaysRebuild())
4318 return NNS;
4320 // If we can re-use the source-location data from the original
4321 // nested-name-specifier, do so.
4322 if (SS.location_size() == NNS.getDataLength() &&
4323 memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)
4324 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4326 // Allocate new nested-name-specifier location information.
4327 return SS.getWithLocInContext(SemaRef.Context);
4330 template<typename Derived>
4331 DeclarationNameInfo
4332 TreeTransform<Derived>
4333 ::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4334 DeclarationName Name = NameInfo.getName();
4335 if (!Name)
4336 return DeclarationNameInfo();
4338 switch (Name.getNameKind()) {
4339 case DeclarationName::Identifier:
4340 case DeclarationName::ObjCZeroArgSelector:
4341 case DeclarationName::ObjCOneArgSelector:
4342 case DeclarationName::ObjCMultiArgSelector:
4343 case DeclarationName::CXXOperatorName:
4344 case DeclarationName::CXXLiteralOperatorName:
4345 case DeclarationName::CXXUsingDirective:
4346 return NameInfo;
4348 case DeclarationName::CXXDeductionGuideName: {
4349 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4350 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4351 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4352 if (!NewTemplate)
4353 return DeclarationNameInfo();
4355 DeclarationNameInfo NewNameInfo(NameInfo);
4356 NewNameInfo.setName(
4357 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(NewTemplate));
4358 return NewNameInfo;
4361 case DeclarationName::CXXConstructorName:
4362 case DeclarationName::CXXDestructorName:
4363 case DeclarationName::CXXConversionFunctionName: {
4364 TypeSourceInfo *NewTInfo;
4365 CanQualType NewCanTy;
4366 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4367 NewTInfo = getDerived().TransformType(OldTInfo);
4368 if (!NewTInfo)
4369 return DeclarationNameInfo();
4370 NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
4372 else {
4373 NewTInfo = nullptr;
4374 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4375 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4376 if (NewT.isNull())
4377 return DeclarationNameInfo();
4378 NewCanTy = SemaRef.Context.getCanonicalType(NewT);
4381 DeclarationName NewName
4382 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
4383 NewCanTy);
4384 DeclarationNameInfo NewNameInfo(NameInfo);
4385 NewNameInfo.setName(NewName);
4386 NewNameInfo.setNamedTypeInfo(NewTInfo);
4387 return NewNameInfo;
4391 llvm_unreachable("Unknown name kind.");
4394 template<typename Derived>
4395 TemplateName
4396 TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
4397 TemplateName Name,
4398 SourceLocation NameLoc,
4399 QualType ObjectType,
4400 NamedDecl *FirstQualifierInScope,
4401 bool AllowInjectedClassName) {
4402 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4403 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4404 assert(Template && "qualified template name must refer to a template");
4406 TemplateDecl *TransTemplate
4407 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4408 Template));
4409 if (!TransTemplate)
4410 return TemplateName();
4412 if (!getDerived().AlwaysRebuild() &&
4413 SS.getScopeRep() == QTN->getQualifier() &&
4414 TransTemplate == Template)
4415 return Name;
4417 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4418 TransTemplate);
4421 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4422 if (SS.getScopeRep()) {
4423 // These apply to the scope specifier, not the template.
4424 ObjectType = QualType();
4425 FirstQualifierInScope = nullptr;
4428 if (!getDerived().AlwaysRebuild() &&
4429 SS.getScopeRep() == DTN->getQualifier() &&
4430 ObjectType.isNull())
4431 return Name;
4433 // FIXME: Preserve the location of the "template" keyword.
4434 SourceLocation TemplateKWLoc = NameLoc;
4436 if (DTN->isIdentifier()) {
4437 return getDerived().RebuildTemplateName(SS,
4438 TemplateKWLoc,
4439 *DTN->getIdentifier(),
4440 NameLoc,
4441 ObjectType,
4442 FirstQualifierInScope,
4443 AllowInjectedClassName);
4446 return getDerived().RebuildTemplateName(SS, TemplateKWLoc,
4447 DTN->getOperator(), NameLoc,
4448 ObjectType, AllowInjectedClassName);
4451 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4452 TemplateDecl *TransTemplate
4453 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4454 Template));
4455 if (!TransTemplate)
4456 return TemplateName();
4458 if (!getDerived().AlwaysRebuild() &&
4459 TransTemplate == Template)
4460 return Name;
4462 return TemplateName(TransTemplate);
4465 if (SubstTemplateTemplateParmPackStorage *SubstPack
4466 = Name.getAsSubstTemplateTemplateParmPack()) {
4467 return getDerived().RebuildTemplateName(
4468 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4469 SubstPack->getIndex(), SubstPack->getFinal());
4472 // These should be getting filtered out before they reach the AST.
4473 llvm_unreachable("overloaded function decl survived to here");
4476 template<typename Derived>
4477 void TreeTransform<Derived>::InventTemplateArgumentLoc(
4478 const TemplateArgument &Arg,
4479 TemplateArgumentLoc &Output) {
4480 Output = getSema().getTrivialTemplateArgumentLoc(
4481 Arg, QualType(), getDerived().getBaseLocation());
4484 template <typename Derived>
4485 bool TreeTransform<Derived>::TransformTemplateArgument(
4486 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4487 bool Uneval) {
4488 const TemplateArgument &Arg = Input.getArgument();
4489 switch (Arg.getKind()) {
4490 case TemplateArgument::Null:
4491 case TemplateArgument::Pack:
4492 llvm_unreachable("Unexpected TemplateArgument");
4494 case TemplateArgument::Integral:
4495 case TemplateArgument::NullPtr:
4496 case TemplateArgument::Declaration: {
4497 // Transform a resolved template argument straight to a resolved template
4498 // argument. We get here when substituting into an already-substituted
4499 // template type argument during concept satisfaction checking.
4500 QualType T = Arg.getNonTypeTemplateArgumentType();
4501 QualType NewT = getDerived().TransformType(T);
4502 if (NewT.isNull())
4503 return true;
4505 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
4506 ? Arg.getAsDecl()
4507 : nullptr;
4508 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4509 getDerived().getBaseLocation(), D))
4510 : nullptr;
4511 if (D && !NewD)
4512 return true;
4514 if (NewT == T && D == NewD)
4515 Output = Input;
4516 else if (Arg.getKind() == TemplateArgument::Integral)
4517 Output = TemplateArgumentLoc(
4518 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4519 TemplateArgumentLocInfo());
4520 else if (Arg.getKind() == TemplateArgument::NullPtr)
4521 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4522 TemplateArgumentLocInfo());
4523 else
4524 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4525 TemplateArgumentLocInfo());
4527 return false;
4530 case TemplateArgument::Type: {
4531 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4532 if (!DI)
4533 DI = InventTypeSourceInfo(Input.getArgument().getAsType());
4535 DI = getDerived().TransformType(DI);
4536 if (!DI)
4537 return true;
4539 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4540 return false;
4543 case TemplateArgument::Template: {
4544 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4545 if (QualifierLoc) {
4546 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4547 if (!QualifierLoc)
4548 return true;
4551 CXXScopeSpec SS;
4552 SS.Adopt(QualifierLoc);
4553 TemplateName Template = getDerived().TransformTemplateName(
4554 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4555 if (Template.isNull())
4556 return true;
4558 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4559 QualifierLoc, Input.getTemplateNameLoc());
4560 return false;
4563 case TemplateArgument::TemplateExpansion:
4564 llvm_unreachable("Caller should expand pack expansions");
4566 case TemplateArgument::Expression: {
4567 // Template argument expressions are constant expressions.
4568 EnterExpressionEvaluationContext Unevaluated(
4569 getSema(),
4570 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
4571 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
4572 /*LambdaContextDecl=*/nullptr, /*ExprContext=*/
4573 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
4575 Expr *InputExpr = Input.getSourceExpression();
4576 if (!InputExpr)
4577 InputExpr = Input.getArgument().getAsExpr();
4579 ExprResult E = getDerived().TransformExpr(InputExpr);
4580 E = SemaRef.ActOnConstantExpression(E);
4581 if (E.isInvalid())
4582 return true;
4583 Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
4584 return false;
4588 // Work around bogus GCC warning
4589 return true;
4592 /// Iterator adaptor that invents template argument location information
4593 /// for each of the template arguments in its underlying iterator.
4594 template<typename Derived, typename InputIterator>
4595 class TemplateArgumentLocInventIterator {
4596 TreeTransform<Derived> &Self;
4597 InputIterator Iter;
4599 public:
4600 typedef TemplateArgumentLoc value_type;
4601 typedef TemplateArgumentLoc reference;
4602 typedef typename std::iterator_traits<InputIterator>::difference_type
4603 difference_type;
4604 typedef std::input_iterator_tag iterator_category;
4606 class pointer {
4607 TemplateArgumentLoc Arg;
4609 public:
4610 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4612 const TemplateArgumentLoc *operator->() const { return &Arg; }
4615 TemplateArgumentLocInventIterator() { }
4617 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
4618 InputIterator Iter)
4619 : Self(Self), Iter(Iter) { }
4621 TemplateArgumentLocInventIterator &operator++() {
4622 ++Iter;
4623 return *this;
4626 TemplateArgumentLocInventIterator operator++(int) {
4627 TemplateArgumentLocInventIterator Old(*this);
4628 ++(*this);
4629 return Old;
4632 reference operator*() const {
4633 TemplateArgumentLoc Result;
4634 Self.InventTemplateArgumentLoc(*Iter, Result);
4635 return Result;
4638 pointer operator->() const { return pointer(**this); }
4640 friend bool operator==(const TemplateArgumentLocInventIterator &X,
4641 const TemplateArgumentLocInventIterator &Y) {
4642 return X.Iter == Y.Iter;
4645 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
4646 const TemplateArgumentLocInventIterator &Y) {
4647 return X.Iter != Y.Iter;
4651 template<typename Derived>
4652 template<typename InputIterator>
4653 bool TreeTransform<Derived>::TransformTemplateArguments(
4654 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
4655 bool Uneval) {
4656 for (; First != Last; ++First) {
4657 TemplateArgumentLoc Out;
4658 TemplateArgumentLoc In = *First;
4660 if (In.getArgument().getKind() == TemplateArgument::Pack) {
4661 // Unpack argument packs, which we translate them into separate
4662 // arguments.
4663 // FIXME: We could do much better if we could guarantee that the
4664 // TemplateArgumentLocInfo for the pack expansion would be usable for
4665 // all of the template arguments in the argument pack.
4666 typedef TemplateArgumentLocInventIterator<Derived,
4667 TemplateArgument::pack_iterator>
4668 PackLocIterator;
4669 if (TransformTemplateArguments(PackLocIterator(*this,
4670 In.getArgument().pack_begin()),
4671 PackLocIterator(*this,
4672 In.getArgument().pack_end()),
4673 Outputs, Uneval))
4674 return true;
4676 continue;
4679 if (In.getArgument().isPackExpansion()) {
4680 // We have a pack expansion, for which we will be substituting into
4681 // the pattern.
4682 SourceLocation Ellipsis;
4683 std::optional<unsigned> OrigNumExpansions;
4684 TemplateArgumentLoc Pattern
4685 = getSema().getTemplateArgumentPackExpansionPattern(
4686 In, Ellipsis, OrigNumExpansions);
4688 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4689 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4690 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4692 // Determine whether the set of unexpanded parameter packs can and should
4693 // be expanded.
4694 bool Expand = true;
4695 bool RetainExpansion = false;
4696 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4697 if (getDerived().TryExpandParameterPacks(Ellipsis,
4698 Pattern.getSourceRange(),
4699 Unexpanded,
4700 Expand,
4701 RetainExpansion,
4702 NumExpansions))
4703 return true;
4705 if (!Expand) {
4706 // The transform has determined that we should perform a simple
4707 // transformation on the pack expansion, producing another pack
4708 // expansion.
4709 TemplateArgumentLoc OutPattern;
4710 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4711 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
4712 return true;
4714 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
4715 NumExpansions);
4716 if (Out.getArgument().isNull())
4717 return true;
4719 Outputs.addArgument(Out);
4720 continue;
4723 // The transform has determined that we should perform an elementwise
4724 // expansion of the pattern. Do so.
4725 for (unsigned I = 0; I != *NumExpansions; ++I) {
4726 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4728 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4729 return true;
4731 if (Out.getArgument().containsUnexpandedParameterPack()) {
4732 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4733 OrigNumExpansions);
4734 if (Out.getArgument().isNull())
4735 return true;
4738 Outputs.addArgument(Out);
4741 // If we're supposed to retain a pack expansion, do so by temporarily
4742 // forgetting the partially-substituted parameter pack.
4743 if (RetainExpansion) {
4744 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4746 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4747 return true;
4749 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4750 OrigNumExpansions);
4751 if (Out.getArgument().isNull())
4752 return true;
4754 Outputs.addArgument(Out);
4757 continue;
4760 // The simple case:
4761 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
4762 return true;
4764 Outputs.addArgument(Out);
4767 return false;
4771 //===----------------------------------------------------------------------===//
4772 // Type transformation
4773 //===----------------------------------------------------------------------===//
4775 template<typename Derived>
4776 QualType TreeTransform<Derived>::TransformType(QualType T) {
4777 if (getDerived().AlreadyTransformed(T))
4778 return T;
4780 // Temporary workaround. All of these transformations should
4781 // eventually turn into transformations on TypeLocs.
4782 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4783 getDerived().getBaseLocation());
4785 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
4787 if (!NewDI)
4788 return QualType();
4790 return NewDI->getType();
4793 template<typename Derived>
4794 TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
4795 // Refine the base location to the type's location.
4796 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
4797 getDerived().getBaseEntity());
4798 if (getDerived().AlreadyTransformed(DI->getType()))
4799 return DI;
4801 TypeLocBuilder TLB;
4803 TypeLoc TL = DI->getTypeLoc();
4804 TLB.reserve(TL.getFullDataSize());
4806 QualType Result = getDerived().TransformType(TLB, TL);
4807 if (Result.isNull())
4808 return nullptr;
4810 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
4813 template<typename Derived>
4814 QualType
4815 TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
4816 switch (T.getTypeLocClass()) {
4817 #define ABSTRACT_TYPELOC(CLASS, PARENT)
4818 #define TYPELOC(CLASS, PARENT) \
4819 case TypeLoc::CLASS: \
4820 return getDerived().Transform##CLASS##Type(TLB, \
4821 T.castAs<CLASS##TypeLoc>());
4822 #include "clang/AST/TypeLocNodes.def"
4825 llvm_unreachable("unhandled type loc!");
4828 template<typename Derived>
4829 QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
4830 if (!isa<DependentNameType>(T))
4831 return TransformType(T);
4833 if (getDerived().AlreadyTransformed(T))
4834 return T;
4835 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4836 getDerived().getBaseLocation());
4837 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
4838 return NewDI ? NewDI->getType() : QualType();
4841 template<typename Derived>
4842 TypeSourceInfo *
4843 TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
4844 if (!isa<DependentNameType>(DI->getType()))
4845 return TransformType(DI);
4847 // Refine the base location to the type's location.
4848 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
4849 getDerived().getBaseEntity());
4850 if (getDerived().AlreadyTransformed(DI->getType()))
4851 return DI;
4853 TypeLocBuilder TLB;
4855 TypeLoc TL = DI->getTypeLoc();
4856 TLB.reserve(TL.getFullDataSize());
4858 auto QTL = TL.getAs<QualifiedTypeLoc>();
4859 if (QTL)
4860 TL = QTL.getUnqualifiedLoc();
4862 auto DNTL = TL.castAs<DependentNameTypeLoc>();
4864 QualType Result = getDerived().TransformDependentNameType(
4865 TLB, DNTL, /*DeducedTSTContext*/true);
4866 if (Result.isNull())
4867 return nullptr;
4869 if (QTL) {
4870 Result = getDerived().RebuildQualifiedType(Result, QTL);
4871 if (Result.isNull())
4872 return nullptr;
4873 TLB.TypeWasModifiedSafely(Result);
4876 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
4879 template<typename Derived>
4880 QualType
4881 TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
4882 QualifiedTypeLoc T) {
4883 QualType Result;
4884 TypeLoc UnqualTL = T.getUnqualifiedLoc();
4885 auto SuppressObjCLifetime =
4886 T.getType().getLocalQualifiers().hasObjCLifetime();
4887 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
4888 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
4889 SuppressObjCLifetime);
4890 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
4891 Result = getDerived().TransformSubstTemplateTypeParmPackType(
4892 TLB, STTP, SuppressObjCLifetime);
4893 } else {
4894 Result = getDerived().TransformType(TLB, UnqualTL);
4897 if (Result.isNull())
4898 return QualType();
4900 Result = getDerived().RebuildQualifiedType(Result, T);
4902 if (Result.isNull())
4903 return QualType();
4905 // RebuildQualifiedType might have updated the type, but not in a way
4906 // that invalidates the TypeLoc. (There's no location information for
4907 // qualifiers.)
4908 TLB.TypeWasModifiedSafely(Result);
4910 return Result;
4913 template <typename Derived>
4914 QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
4915 QualifiedTypeLoc TL) {
4917 SourceLocation Loc = TL.getBeginLoc();
4918 Qualifiers Quals = TL.getType().getLocalQualifiers();
4920 if ((T.getAddressSpace() != LangAS::Default &&
4921 Quals.getAddressSpace() != LangAS::Default) &&
4922 T.getAddressSpace() != Quals.getAddressSpace()) {
4923 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)
4924 << TL.getType() << T;
4925 return QualType();
4928 // C++ [dcl.fct]p7:
4929 // [When] adding cv-qualifications on top of the function type [...] the
4930 // cv-qualifiers are ignored.
4931 if (T->isFunctionType()) {
4932 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
4933 Quals.getAddressSpace());
4934 return T;
4937 // C++ [dcl.ref]p1:
4938 // when the cv-qualifiers are introduced through the use of a typedef-name
4939 // or decltype-specifier [...] the cv-qualifiers are ignored.
4940 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
4941 // applied to a reference type.
4942 if (T->isReferenceType()) {
4943 // The only qualifier that applies to a reference type is restrict.
4944 if (!Quals.hasRestrict())
4945 return T;
4946 Quals = Qualifiers::fromCVRMask(Qualifiers::Restrict);
4949 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
4950 // resulting type.
4951 if (Quals.hasObjCLifetime()) {
4952 if (!T->isObjCLifetimeType() && !T->isDependentType())
4953 Quals.removeObjCLifetime();
4954 else if (T.getObjCLifetime()) {
4955 // Objective-C ARC:
4956 // A lifetime qualifier applied to a substituted template parameter
4957 // overrides the lifetime qualifier from the template argument.
4958 const AutoType *AutoTy;
4959 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
4960 // 'auto' types behave the same way as template parameters.
4961 QualType Deduced = AutoTy->getDeducedType();
4962 Qualifiers Qs = Deduced.getQualifiers();
4963 Qs.removeObjCLifetime();
4964 Deduced =
4965 SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);
4966 T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),
4967 AutoTy->isDependentType(),
4968 /*isPack=*/false,
4969 AutoTy->getTypeConstraintConcept(),
4970 AutoTy->getTypeConstraintArguments());
4971 } else {
4972 // Otherwise, complain about the addition of a qualifier to an
4973 // already-qualified type.
4974 // FIXME: Why is this check not in Sema::BuildQualifiedType?
4975 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
4976 Quals.removeObjCLifetime();
4981 return SemaRef.BuildQualifiedType(T, Loc, Quals);
4984 template<typename Derived>
4985 TypeLoc
4986 TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
4987 QualType ObjectType,
4988 NamedDecl *UnqualLookup,
4989 CXXScopeSpec &SS) {
4990 if (getDerived().AlreadyTransformed(TL.getType()))
4991 return TL;
4993 TypeSourceInfo *TSI =
4994 TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS);
4995 if (TSI)
4996 return TSI->getTypeLoc();
4997 return TypeLoc();
5000 template<typename Derived>
5001 TypeSourceInfo *
5002 TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5003 QualType ObjectType,
5004 NamedDecl *UnqualLookup,
5005 CXXScopeSpec &SS) {
5006 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5007 return TSInfo;
5009 return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType,
5010 UnqualLookup, SS);
5013 template <typename Derived>
5014 TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5015 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5016 CXXScopeSpec &SS) {
5017 QualType T = TL.getType();
5018 assert(!getDerived().AlreadyTransformed(T));
5020 TypeLocBuilder TLB;
5021 QualType Result;
5023 if (isa<TemplateSpecializationType>(T)) {
5024 TemplateSpecializationTypeLoc SpecTL =
5025 TL.castAs<TemplateSpecializationTypeLoc>();
5027 TemplateName Template = getDerived().TransformTemplateName(
5028 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5029 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5030 if (Template.isNull())
5031 return nullptr;
5033 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5034 Template);
5035 } else if (isa<DependentTemplateSpecializationType>(T)) {
5036 DependentTemplateSpecializationTypeLoc SpecTL =
5037 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5039 TemplateName Template
5040 = getDerived().RebuildTemplateName(SS,
5041 SpecTL.getTemplateKeywordLoc(),
5042 *SpecTL.getTypePtr()->getIdentifier(),
5043 SpecTL.getTemplateNameLoc(),
5044 ObjectType, UnqualLookup,
5045 /*AllowInjectedClassName*/true);
5046 if (Template.isNull())
5047 return nullptr;
5049 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5050 SpecTL,
5051 Template,
5052 SS);
5053 } else {
5054 // Nothing special needs to be done for these.
5055 Result = getDerived().TransformType(TLB, TL);
5058 if (Result.isNull())
5059 return nullptr;
5061 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5064 template <class TyLoc> static inline
5065 QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5066 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5067 NewT.setNameLoc(T.getNameLoc());
5068 return T.getType();
5071 template<typename Derived>
5072 QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5073 BuiltinTypeLoc T) {
5074 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
5075 NewT.setBuiltinLoc(T.getBuiltinLoc());
5076 if (T.needsExtraLocalData())
5077 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5078 return T.getType();
5081 template<typename Derived>
5082 QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5083 ComplexTypeLoc T) {
5084 // FIXME: recurse?
5085 return TransformTypeSpecType(TLB, T);
5088 template <typename Derived>
5089 QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5090 AdjustedTypeLoc TL) {
5091 // Adjustments applied during transformation are handled elsewhere.
5092 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5095 template<typename Derived>
5096 QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5097 DecayedTypeLoc TL) {
5098 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5099 if (OriginalType.isNull())
5100 return QualType();
5102 QualType Result = TL.getType();
5103 if (getDerived().AlwaysRebuild() ||
5104 OriginalType != TL.getOriginalLoc().getType())
5105 Result = SemaRef.Context.getDecayedType(OriginalType);
5106 TLB.push<DecayedTypeLoc>(Result);
5107 // Nothing to set for DecayedTypeLoc.
5108 return Result;
5111 template<typename Derived>
5112 QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5113 PointerTypeLoc TL) {
5114 QualType PointeeType
5115 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5116 if (PointeeType.isNull())
5117 return QualType();
5119 QualType Result = TL.getType();
5120 if (PointeeType->getAs<ObjCObjectType>()) {
5121 // A dependent pointer type 'T *' has is being transformed such
5122 // that an Objective-C class type is being replaced for 'T'. The
5123 // resulting pointer type is an ObjCObjectPointerType, not a
5124 // PointerType.
5125 Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
5127 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
5128 NewT.setStarLoc(TL.getStarLoc());
5129 return Result;
5132 if (getDerived().AlwaysRebuild() ||
5133 PointeeType != TL.getPointeeLoc().getType()) {
5134 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5135 if (Result.isNull())
5136 return QualType();
5139 // Objective-C ARC can add lifetime qualifiers to the type that we're
5140 // pointing to.
5141 TLB.TypeWasModifiedSafely(Result->getPointeeType());
5143 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
5144 NewT.setSigilLoc(TL.getSigilLoc());
5145 return Result;
5148 template<typename Derived>
5149 QualType
5150 TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5151 BlockPointerTypeLoc TL) {
5152 QualType PointeeType
5153 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5154 if (PointeeType.isNull())
5155 return QualType();
5157 QualType Result = TL.getType();
5158 if (getDerived().AlwaysRebuild() ||
5159 PointeeType != TL.getPointeeLoc().getType()) {
5160 Result = getDerived().RebuildBlockPointerType(PointeeType,
5161 TL.getSigilLoc());
5162 if (Result.isNull())
5163 return QualType();
5166 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
5167 NewT.setSigilLoc(TL.getSigilLoc());
5168 return Result;
5171 /// Transforms a reference type. Note that somewhat paradoxically we
5172 /// don't care whether the type itself is an l-value type or an r-value
5173 /// type; we only care if the type was *written* as an l-value type
5174 /// or an r-value type.
5175 template<typename Derived>
5176 QualType
5177 TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5178 ReferenceTypeLoc TL) {
5179 const ReferenceType *T = TL.getTypePtr();
5181 // Note that this works with the pointee-as-written.
5182 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5183 if (PointeeType.isNull())
5184 return QualType();
5186 QualType Result = TL.getType();
5187 if (getDerived().AlwaysRebuild() ||
5188 PointeeType != T->getPointeeTypeAsWritten()) {
5189 Result = getDerived().RebuildReferenceType(PointeeType,
5190 T->isSpelledAsLValue(),
5191 TL.getSigilLoc());
5192 if (Result.isNull())
5193 return QualType();
5196 // Objective-C ARC can add lifetime qualifiers to the type that we're
5197 // referring to.
5198 TLB.TypeWasModifiedSafely(
5199 Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5201 // r-value references can be rebuilt as l-value references.
5202 ReferenceTypeLoc NewTL;
5203 if (isa<LValueReferenceType>(Result))
5204 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
5205 else
5206 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
5207 NewTL.setSigilLoc(TL.getSigilLoc());
5209 return Result;
5212 template<typename Derived>
5213 QualType
5214 TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5215 LValueReferenceTypeLoc TL) {
5216 return TransformReferenceType(TLB, TL);
5219 template<typename Derived>
5220 QualType
5221 TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5222 RValueReferenceTypeLoc TL) {
5223 return TransformReferenceType(TLB, TL);
5226 template<typename Derived>
5227 QualType
5228 TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5229 MemberPointerTypeLoc TL) {
5230 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5231 if (PointeeType.isNull())
5232 return QualType();
5234 TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
5235 TypeSourceInfo *NewClsTInfo = nullptr;
5236 if (OldClsTInfo) {
5237 NewClsTInfo = getDerived().TransformType(OldClsTInfo);
5238 if (!NewClsTInfo)
5239 return QualType();
5242 const MemberPointerType *T = TL.getTypePtr();
5243 QualType OldClsType = QualType(T->getClass(), 0);
5244 QualType NewClsType;
5245 if (NewClsTInfo)
5246 NewClsType = NewClsTInfo->getType();
5247 else {
5248 NewClsType = getDerived().TransformType(OldClsType);
5249 if (NewClsType.isNull())
5250 return QualType();
5253 QualType Result = TL.getType();
5254 if (getDerived().AlwaysRebuild() ||
5255 PointeeType != T->getPointeeType() ||
5256 NewClsType != OldClsType) {
5257 Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
5258 TL.getStarLoc());
5259 if (Result.isNull())
5260 return QualType();
5263 // If we had to adjust the pointee type when building a member pointer, make
5264 // sure to push TypeLoc info for it.
5265 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5266 if (MPT && PointeeType != MPT->getPointeeType()) {
5267 assert(isa<AdjustedType>(MPT->getPointeeType()));
5268 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
5271 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
5272 NewTL.setSigilLoc(TL.getSigilLoc());
5273 NewTL.setClassTInfo(NewClsTInfo);
5275 return Result;
5278 template<typename Derived>
5279 QualType
5280 TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5281 ConstantArrayTypeLoc TL) {
5282 const ConstantArrayType *T = TL.getTypePtr();
5283 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5284 if (ElementType.isNull())
5285 return QualType();
5287 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5288 Expr *OldSize = TL.getSizeExpr();
5289 if (!OldSize)
5290 OldSize = const_cast<Expr*>(T->getSizeExpr());
5291 Expr *NewSize = nullptr;
5292 if (OldSize) {
5293 EnterExpressionEvaluationContext Unevaluated(
5294 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5295 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5296 NewSize = SemaRef.ActOnConstantExpression(NewSize).get();
5299 QualType Result = TL.getType();
5300 if (getDerived().AlwaysRebuild() ||
5301 ElementType != T->getElementType() ||
5302 (T->getSizeExpr() && NewSize != OldSize)) {
5303 Result = getDerived().RebuildConstantArrayType(ElementType,
5304 T->getSizeModifier(),
5305 T->getSize(), NewSize,
5306 T->getIndexTypeCVRQualifiers(),
5307 TL.getBracketsRange());
5308 if (Result.isNull())
5309 return QualType();
5312 // We might have either a ConstantArrayType or a VariableArrayType now:
5313 // a ConstantArrayType is allowed to have an element type which is a
5314 // VariableArrayType if the type is dependent. Fortunately, all array
5315 // types have the same location layout.
5316 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5317 NewTL.setLBracketLoc(TL.getLBracketLoc());
5318 NewTL.setRBracketLoc(TL.getRBracketLoc());
5319 NewTL.setSizeExpr(NewSize);
5321 return Result;
5324 template<typename Derived>
5325 QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5326 TypeLocBuilder &TLB,
5327 IncompleteArrayTypeLoc TL) {
5328 const IncompleteArrayType *T = TL.getTypePtr();
5329 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5330 if (ElementType.isNull())
5331 return QualType();
5333 QualType Result = TL.getType();
5334 if (getDerived().AlwaysRebuild() ||
5335 ElementType != T->getElementType()) {
5336 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5337 T->getSizeModifier(),
5338 T->getIndexTypeCVRQualifiers(),
5339 TL.getBracketsRange());
5340 if (Result.isNull())
5341 return QualType();
5344 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
5345 NewTL.setLBracketLoc(TL.getLBracketLoc());
5346 NewTL.setRBracketLoc(TL.getRBracketLoc());
5347 NewTL.setSizeExpr(nullptr);
5349 return Result;
5352 template<typename Derived>
5353 QualType
5354 TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5355 VariableArrayTypeLoc TL) {
5356 const VariableArrayType *T = TL.getTypePtr();
5357 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5358 if (ElementType.isNull())
5359 return QualType();
5361 ExprResult SizeResult;
5363 EnterExpressionEvaluationContext Context(
5364 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5365 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5367 if (SizeResult.isInvalid())
5368 return QualType();
5369 SizeResult =
5370 SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);
5371 if (SizeResult.isInvalid())
5372 return QualType();
5374 Expr *Size = SizeResult.get();
5376 QualType Result = TL.getType();
5377 if (getDerived().AlwaysRebuild() ||
5378 ElementType != T->getElementType() ||
5379 Size != T->getSizeExpr()) {
5380 Result = getDerived().RebuildVariableArrayType(ElementType,
5381 T->getSizeModifier(),
5382 Size,
5383 T->getIndexTypeCVRQualifiers(),
5384 TL.getBracketsRange());
5385 if (Result.isNull())
5386 return QualType();
5389 // We might have constant size array now, but fortunately it has the same
5390 // location layout.
5391 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5392 NewTL.setLBracketLoc(TL.getLBracketLoc());
5393 NewTL.setRBracketLoc(TL.getRBracketLoc());
5394 NewTL.setSizeExpr(Size);
5396 return Result;
5399 template<typename Derived>
5400 QualType
5401 TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5402 DependentSizedArrayTypeLoc TL) {
5403 const DependentSizedArrayType *T = TL.getTypePtr();
5404 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5405 if (ElementType.isNull())
5406 return QualType();
5408 // Array bounds are constant expressions.
5409 EnterExpressionEvaluationContext Unevaluated(
5410 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5412 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5413 Expr *origSize = TL.getSizeExpr();
5414 if (!origSize) origSize = T->getSizeExpr();
5416 ExprResult sizeResult
5417 = getDerived().TransformExpr(origSize);
5418 sizeResult = SemaRef.ActOnConstantExpression(sizeResult);
5419 if (sizeResult.isInvalid())
5420 return QualType();
5422 Expr *size = sizeResult.get();
5424 QualType Result = TL.getType();
5425 if (getDerived().AlwaysRebuild() ||
5426 ElementType != T->getElementType() ||
5427 size != origSize) {
5428 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5429 T->getSizeModifier(),
5430 size,
5431 T->getIndexTypeCVRQualifiers(),
5432 TL.getBracketsRange());
5433 if (Result.isNull())
5434 return QualType();
5437 // We might have any sort of array type now, but fortunately they
5438 // all have the same location layout.
5439 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5440 NewTL.setLBracketLoc(TL.getLBracketLoc());
5441 NewTL.setRBracketLoc(TL.getRBracketLoc());
5442 NewTL.setSizeExpr(size);
5444 return Result;
5447 template <typename Derived>
5448 QualType TreeTransform<Derived>::TransformDependentVectorType(
5449 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5450 const DependentVectorType *T = TL.getTypePtr();
5451 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5452 if (ElementType.isNull())
5453 return QualType();
5455 EnterExpressionEvaluationContext Unevaluated(
5456 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5458 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5459 Size = SemaRef.ActOnConstantExpression(Size);
5460 if (Size.isInvalid())
5461 return QualType();
5463 QualType Result = TL.getType();
5464 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5465 Size.get() != T->getSizeExpr()) {
5466 Result = getDerived().RebuildDependentVectorType(
5467 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5468 if (Result.isNull())
5469 return QualType();
5472 // Result might be dependent or not.
5473 if (isa<DependentVectorType>(Result)) {
5474 DependentVectorTypeLoc NewTL =
5475 TLB.push<DependentVectorTypeLoc>(Result);
5476 NewTL.setNameLoc(TL.getNameLoc());
5477 } else {
5478 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5479 NewTL.setNameLoc(TL.getNameLoc());
5482 return Result;
5485 template<typename Derived>
5486 QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5487 TypeLocBuilder &TLB,
5488 DependentSizedExtVectorTypeLoc TL) {
5489 const DependentSizedExtVectorType *T = TL.getTypePtr();
5491 // FIXME: ext vector locs should be nested
5492 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5493 if (ElementType.isNull())
5494 return QualType();
5496 // Vector sizes are constant expressions.
5497 EnterExpressionEvaluationContext Unevaluated(
5498 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5500 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5501 Size = SemaRef.ActOnConstantExpression(Size);
5502 if (Size.isInvalid())
5503 return QualType();
5505 QualType Result = TL.getType();
5506 if (getDerived().AlwaysRebuild() ||
5507 ElementType != T->getElementType() ||
5508 Size.get() != T->getSizeExpr()) {
5509 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5510 Size.get(),
5511 T->getAttributeLoc());
5512 if (Result.isNull())
5513 return QualType();
5516 // Result might be dependent or not.
5517 if (isa<DependentSizedExtVectorType>(Result)) {
5518 DependentSizedExtVectorTypeLoc NewTL
5519 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
5520 NewTL.setNameLoc(TL.getNameLoc());
5521 } else {
5522 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5523 NewTL.setNameLoc(TL.getNameLoc());
5526 return Result;
5529 template <typename Derived>
5530 QualType
5531 TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5532 ConstantMatrixTypeLoc TL) {
5533 const ConstantMatrixType *T = TL.getTypePtr();
5534 QualType ElementType = getDerived().TransformType(T->getElementType());
5535 if (ElementType.isNull())
5536 return QualType();
5538 QualType Result = TL.getType();
5539 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5540 Result = getDerived().RebuildConstantMatrixType(
5541 ElementType, T->getNumRows(), T->getNumColumns());
5542 if (Result.isNull())
5543 return QualType();
5546 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);
5547 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5548 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5549 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5550 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5552 return Result;
5555 template <typename Derived>
5556 QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5557 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5558 const DependentSizedMatrixType *T = TL.getTypePtr();
5560 QualType ElementType = getDerived().TransformType(T->getElementType());
5561 if (ElementType.isNull()) {
5562 return QualType();
5565 // Matrix dimensions are constant expressions.
5566 EnterExpressionEvaluationContext Unevaluated(
5567 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5569 Expr *origRows = TL.getAttrRowOperand();
5570 if (!origRows)
5571 origRows = T->getRowExpr();
5572 Expr *origColumns = TL.getAttrColumnOperand();
5573 if (!origColumns)
5574 origColumns = T->getColumnExpr();
5576 ExprResult rowResult = getDerived().TransformExpr(origRows);
5577 rowResult = SemaRef.ActOnConstantExpression(rowResult);
5578 if (rowResult.isInvalid())
5579 return QualType();
5581 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5582 columnResult = SemaRef.ActOnConstantExpression(columnResult);
5583 if (columnResult.isInvalid())
5584 return QualType();
5586 Expr *rows = rowResult.get();
5587 Expr *columns = columnResult.get();
5589 QualType Result = TL.getType();
5590 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5591 rows != origRows || columns != origColumns) {
5592 Result = getDerived().RebuildDependentSizedMatrixType(
5593 ElementType, rows, columns, T->getAttributeLoc());
5595 if (Result.isNull())
5596 return QualType();
5599 // We might have any sort of matrix type now, but fortunately they
5600 // all have the same location layout.
5601 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);
5602 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5603 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5604 NewTL.setAttrRowOperand(rows);
5605 NewTL.setAttrColumnOperand(columns);
5606 return Result;
5609 template <typename Derived>
5610 QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
5611 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
5612 const DependentAddressSpaceType *T = TL.getTypePtr();
5614 QualType pointeeType = getDerived().TransformType(T->getPointeeType());
5616 if (pointeeType.isNull())
5617 return QualType();
5619 // Address spaces are constant expressions.
5620 EnterExpressionEvaluationContext Unevaluated(
5621 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5623 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
5624 AddrSpace = SemaRef.ActOnConstantExpression(AddrSpace);
5625 if (AddrSpace.isInvalid())
5626 return QualType();
5628 QualType Result = TL.getType();
5629 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
5630 AddrSpace.get() != T->getAddrSpaceExpr()) {
5631 Result = getDerived().RebuildDependentAddressSpaceType(
5632 pointeeType, AddrSpace.get(), T->getAttributeLoc());
5633 if (Result.isNull())
5634 return QualType();
5637 // Result might be dependent or not.
5638 if (isa<DependentAddressSpaceType>(Result)) {
5639 DependentAddressSpaceTypeLoc NewTL =
5640 TLB.push<DependentAddressSpaceTypeLoc>(Result);
5642 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5643 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
5644 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5646 } else {
5647 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(
5648 Result, getDerived().getBaseLocation());
5649 TransformType(TLB, DI->getTypeLoc());
5652 return Result;
5655 template <typename Derived>
5656 QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
5657 VectorTypeLoc TL) {
5658 const VectorType *T = TL.getTypePtr();
5659 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5660 if (ElementType.isNull())
5661 return QualType();
5663 QualType Result = TL.getType();
5664 if (getDerived().AlwaysRebuild() ||
5665 ElementType != T->getElementType()) {
5666 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
5667 T->getVectorKind());
5668 if (Result.isNull())
5669 return QualType();
5672 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5673 NewTL.setNameLoc(TL.getNameLoc());
5675 return Result;
5678 template<typename Derived>
5679 QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
5680 ExtVectorTypeLoc TL) {
5681 const VectorType *T = TL.getTypePtr();
5682 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5683 if (ElementType.isNull())
5684 return QualType();
5686 QualType Result = TL.getType();
5687 if (getDerived().AlwaysRebuild() ||
5688 ElementType != T->getElementType()) {
5689 Result = getDerived().RebuildExtVectorType(ElementType,
5690 T->getNumElements(),
5691 /*FIXME*/ SourceLocation());
5692 if (Result.isNull())
5693 return QualType();
5696 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5697 NewTL.setNameLoc(TL.getNameLoc());
5699 return Result;
5702 template <typename Derived>
5703 ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
5704 ParmVarDecl *OldParm, int indexAdjustment,
5705 std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
5706 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
5707 TypeSourceInfo *NewDI = nullptr;
5709 if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
5710 // If we're substituting into a pack expansion type and we know the
5711 // length we want to expand to, just substitute for the pattern.
5712 TypeLoc OldTL = OldDI->getTypeLoc();
5713 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
5715 TypeLocBuilder TLB;
5716 TypeLoc NewTL = OldDI->getTypeLoc();
5717 TLB.reserve(NewTL.getFullDataSize());
5719 QualType Result = getDerived().TransformType(TLB,
5720 OldExpansionTL.getPatternLoc());
5721 if (Result.isNull())
5722 return nullptr;
5724 Result = RebuildPackExpansionType(Result,
5725 OldExpansionTL.getPatternLoc().getSourceRange(),
5726 OldExpansionTL.getEllipsisLoc(),
5727 NumExpansions);
5728 if (Result.isNull())
5729 return nullptr;
5731 PackExpansionTypeLoc NewExpansionTL
5732 = TLB.push<PackExpansionTypeLoc>(Result);
5733 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
5734 NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result);
5735 } else
5736 NewDI = getDerived().TransformType(OldDI);
5737 if (!NewDI)
5738 return nullptr;
5740 if (NewDI == OldDI && indexAdjustment == 0)
5741 return OldParm;
5743 ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context,
5744 OldParm->getDeclContext(),
5745 OldParm->getInnerLocStart(),
5746 OldParm->getLocation(),
5747 OldParm->getIdentifier(),
5748 NewDI->getType(),
5749 NewDI,
5750 OldParm->getStorageClass(),
5751 /* DefArg */ nullptr);
5752 newParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
5753 OldParm->getFunctionScopeIndex() + indexAdjustment);
5754 transformedLocalDecl(OldParm, {newParm});
5755 return newParm;
5758 template <typename Derived>
5759 bool TreeTransform<Derived>::TransformFunctionTypeParams(
5760 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
5761 const QualType *ParamTypes,
5762 const FunctionProtoType::ExtParameterInfo *ParamInfos,
5763 SmallVectorImpl<QualType> &OutParamTypes,
5764 SmallVectorImpl<ParmVarDecl *> *PVars,
5765 Sema::ExtParameterInfoBuilder &PInfos,
5766 unsigned *LastParamTransformed) {
5767 int indexAdjustment = 0;
5769 unsigned NumParams = Params.size();
5770 for (unsigned i = 0; i != NumParams; ++i) {
5771 if (LastParamTransformed)
5772 *LastParamTransformed = i;
5773 if (ParmVarDecl *OldParm = Params[i]) {
5774 assert(OldParm->getFunctionScopeIndex() == i);
5776 std::optional<unsigned> NumExpansions;
5777 ParmVarDecl *NewParm = nullptr;
5778 if (OldParm->isParameterPack()) {
5779 // We have a function parameter pack that may need to be expanded.
5780 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5782 // Find the parameter packs that could be expanded.
5783 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
5784 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
5785 TypeLoc Pattern = ExpansionTL.getPatternLoc();
5786 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
5788 // Determine whether we should expand the parameter packs.
5789 bool ShouldExpand = false;
5790 bool RetainExpansion = false;
5791 std::optional<unsigned> OrigNumExpansions;
5792 if (Unexpanded.size() > 0) {
5793 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
5794 NumExpansions = OrigNumExpansions;
5795 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
5796 Pattern.getSourceRange(),
5797 Unexpanded,
5798 ShouldExpand,
5799 RetainExpansion,
5800 NumExpansions)) {
5801 return true;
5803 } else {
5804 #ifndef NDEBUG
5805 const AutoType *AT =
5806 Pattern.getType().getTypePtr()->getContainedAutoType();
5807 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
5808 "Could not find parameter packs or undeduced auto type!");
5809 #endif
5812 if (ShouldExpand) {
5813 // Expand the function parameter pack into multiple, separate
5814 // parameters.
5815 getDerived().ExpandingFunctionParameterPack(OldParm);
5816 for (unsigned I = 0; I != *NumExpansions; ++I) {
5817 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
5818 ParmVarDecl *NewParm
5819 = getDerived().TransformFunctionTypeParam(OldParm,
5820 indexAdjustment++,
5821 OrigNumExpansions,
5822 /*ExpectParameterPack=*/false);
5823 if (!NewParm)
5824 return true;
5826 if (ParamInfos)
5827 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5828 OutParamTypes.push_back(NewParm->getType());
5829 if (PVars)
5830 PVars->push_back(NewParm);
5833 // If we're supposed to retain a pack expansion, do so by temporarily
5834 // forgetting the partially-substituted parameter pack.
5835 if (RetainExpansion) {
5836 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5837 ParmVarDecl *NewParm
5838 = getDerived().TransformFunctionTypeParam(OldParm,
5839 indexAdjustment++,
5840 OrigNumExpansions,
5841 /*ExpectParameterPack=*/false);
5842 if (!NewParm)
5843 return true;
5845 if (ParamInfos)
5846 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5847 OutParamTypes.push_back(NewParm->getType());
5848 if (PVars)
5849 PVars->push_back(NewParm);
5852 // The next parameter should have the same adjustment as the
5853 // last thing we pushed, but we post-incremented indexAdjustment
5854 // on every push. Also, if we push nothing, the adjustment should
5855 // go down by one.
5856 indexAdjustment--;
5858 // We're done with the pack expansion.
5859 continue;
5862 // We'll substitute the parameter now without expanding the pack
5863 // expansion.
5864 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
5865 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
5866 indexAdjustment,
5867 NumExpansions,
5868 /*ExpectParameterPack=*/true);
5869 assert(NewParm->isParameterPack() &&
5870 "Parameter pack no longer a parameter pack after "
5871 "transformation.");
5872 } else {
5873 NewParm = getDerived().TransformFunctionTypeParam(
5874 OldParm, indexAdjustment, std::nullopt,
5875 /*ExpectParameterPack=*/false);
5878 if (!NewParm)
5879 return true;
5881 if (ParamInfos)
5882 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5883 OutParamTypes.push_back(NewParm->getType());
5884 if (PVars)
5885 PVars->push_back(NewParm);
5886 continue;
5889 // Deal with the possibility that we don't have a parameter
5890 // declaration for this parameter.
5891 assert(ParamTypes);
5892 QualType OldType = ParamTypes[i];
5893 bool IsPackExpansion = false;
5894 std::optional<unsigned> NumExpansions;
5895 QualType NewType;
5896 if (const PackExpansionType *Expansion
5897 = dyn_cast<PackExpansionType>(OldType)) {
5898 // We have a function parameter pack that may need to be expanded.
5899 QualType Pattern = Expansion->getPattern();
5900 NumExpansions = Expansion->getNumExpansions();
5901 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5902 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5904 // Determine whether we should expand the parameter packs.
5905 bool ShouldExpand = false;
5906 bool RetainExpansion = false;
5907 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
5908 Unexpanded,
5909 ShouldExpand,
5910 RetainExpansion,
5911 NumExpansions)) {
5912 return true;
5915 if (ShouldExpand) {
5916 // Expand the function parameter pack into multiple, separate
5917 // parameters.
5918 for (unsigned I = 0; I != *NumExpansions; ++I) {
5919 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
5920 QualType NewType = getDerived().TransformType(Pattern);
5921 if (NewType.isNull())
5922 return true;
5924 if (NewType->containsUnexpandedParameterPack()) {
5925 NewType = getSema().getASTContext().getPackExpansionType(
5926 NewType, std::nullopt);
5928 if (NewType.isNull())
5929 return true;
5932 if (ParamInfos)
5933 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5934 OutParamTypes.push_back(NewType);
5935 if (PVars)
5936 PVars->push_back(nullptr);
5939 // We're done with the pack expansion.
5940 continue;
5943 // If we're supposed to retain a pack expansion, do so by temporarily
5944 // forgetting the partially-substituted parameter pack.
5945 if (RetainExpansion) {
5946 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5947 QualType NewType = getDerived().TransformType(Pattern);
5948 if (NewType.isNull())
5949 return true;
5951 if (ParamInfos)
5952 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5953 OutParamTypes.push_back(NewType);
5954 if (PVars)
5955 PVars->push_back(nullptr);
5958 // We'll substitute the parameter now without expanding the pack
5959 // expansion.
5960 OldType = Expansion->getPattern();
5961 IsPackExpansion = true;
5962 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
5963 NewType = getDerived().TransformType(OldType);
5964 } else {
5965 NewType = getDerived().TransformType(OldType);
5968 if (NewType.isNull())
5969 return true;
5971 if (IsPackExpansion)
5972 NewType = getSema().Context.getPackExpansionType(NewType,
5973 NumExpansions);
5975 if (ParamInfos)
5976 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
5977 OutParamTypes.push_back(NewType);
5978 if (PVars)
5979 PVars->push_back(nullptr);
5982 #ifndef NDEBUG
5983 if (PVars) {
5984 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
5985 if (ParmVarDecl *parm = (*PVars)[i])
5986 assert(parm->getFunctionScopeIndex() == i);
5988 #endif
5990 return false;
5993 template<typename Derived>
5994 QualType
5995 TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
5996 FunctionProtoTypeLoc TL) {
5997 SmallVector<QualType, 4> ExceptionStorage;
5998 TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
5999 return getDerived().TransformFunctionProtoType(
6000 TLB, TL, nullptr, Qualifiers(),
6001 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6002 return This->getDerived().TransformExceptionSpec(
6003 TL.getBeginLoc(), ESI, ExceptionStorage, Changed);
6007 template<typename Derived> template<typename Fn>
6008 QualType TreeTransform<Derived>::TransformFunctionProtoType(
6009 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6010 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6012 // Transform the parameters and return type.
6014 // We are required to instantiate the params and return type in source order.
6015 // When the function has a trailing return type, we instantiate the
6016 // parameters before the return type, since the return type can then refer
6017 // to the parameters themselves (via decltype, sizeof, etc.).
6019 SmallVector<QualType, 4> ParamTypes;
6020 SmallVector<ParmVarDecl*, 4> ParamDecls;
6021 Sema::ExtParameterInfoBuilder ExtParamInfos;
6022 const FunctionProtoType *T = TL.getTypePtr();
6024 QualType ResultType;
6026 if (T->hasTrailingReturn()) {
6027 if (getDerived().TransformFunctionTypeParams(
6028 TL.getBeginLoc(), TL.getParams(),
6029 TL.getTypePtr()->param_type_begin(),
6030 T->getExtParameterInfosOrNull(),
6031 ParamTypes, &ParamDecls, ExtParamInfos))
6032 return QualType();
6035 // C++11 [expr.prim.general]p3:
6036 // If a declaration declares a member function or member function
6037 // template of a class X, the expression this is a prvalue of type
6038 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6039 // and the end of the function-definition, member-declarator, or
6040 // declarator.
6041 Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals);
6043 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6044 if (ResultType.isNull())
6045 return QualType();
6048 else {
6049 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6050 if (ResultType.isNull())
6051 return QualType();
6053 if (getDerived().TransformFunctionTypeParams(
6054 TL.getBeginLoc(), TL.getParams(),
6055 TL.getTypePtr()->param_type_begin(),
6056 T->getExtParameterInfosOrNull(),
6057 ParamTypes, &ParamDecls, ExtParamInfos))
6058 return QualType();
6061 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6063 bool EPIChanged = false;
6064 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6065 return QualType();
6067 // Handle extended parameter information.
6068 if (auto NewExtParamInfos =
6069 ExtParamInfos.getPointerOrNull(ParamTypes.size())) {
6070 if (!EPI.ExtParameterInfos ||
6071 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6072 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6073 EPIChanged = true;
6075 EPI.ExtParameterInfos = NewExtParamInfos;
6076 } else if (EPI.ExtParameterInfos) {
6077 EPIChanged = true;
6078 EPI.ExtParameterInfos = nullptr;
6081 QualType Result = TL.getType();
6082 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6083 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6084 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6085 if (Result.isNull())
6086 return QualType();
6089 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
6090 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6091 NewTL.setLParenLoc(TL.getLParenLoc());
6092 NewTL.setRParenLoc(TL.getRParenLoc());
6093 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6094 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6095 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6096 NewTL.setParam(i, ParamDecls[i]);
6098 return Result;
6101 template<typename Derived>
6102 bool TreeTransform<Derived>::TransformExceptionSpec(
6103 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6104 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6105 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6107 // Instantiate a dynamic noexcept expression, if any.
6108 if (isComputedNoexcept(ESI.Type)) {
6109 EnterExpressionEvaluationContext Unevaluated(
6110 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6111 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6112 if (NoexceptExpr.isInvalid())
6113 return true;
6115 ExceptionSpecificationType EST = ESI.Type;
6116 NoexceptExpr =
6117 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6118 if (NoexceptExpr.isInvalid())
6119 return true;
6121 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6122 Changed = true;
6123 ESI.NoexceptExpr = NoexceptExpr.get();
6124 ESI.Type = EST;
6127 if (ESI.Type != EST_Dynamic)
6128 return false;
6130 // Instantiate a dynamic exception specification's type.
6131 for (QualType T : ESI.Exceptions) {
6132 if (const PackExpansionType *PackExpansion =
6133 T->getAs<PackExpansionType>()) {
6134 Changed = true;
6136 // We have a pack expansion. Instantiate it.
6137 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6138 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
6139 Unexpanded);
6140 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6142 // Determine whether the set of unexpanded parameter packs can and
6143 // should
6144 // be expanded.
6145 bool Expand = false;
6146 bool RetainExpansion = false;
6147 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
6148 // FIXME: Track the location of the ellipsis (and track source location
6149 // information for the types in the exception specification in general).
6150 if (getDerived().TryExpandParameterPacks(
6151 Loc, SourceRange(), Unexpanded, Expand,
6152 RetainExpansion, NumExpansions))
6153 return true;
6155 if (!Expand) {
6156 // We can't expand this pack expansion into separate arguments yet;
6157 // just substitute into the pattern and create a new pack expansion
6158 // type.
6159 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6160 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6161 if (U.isNull())
6162 return true;
6164 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
6165 Exceptions.push_back(U);
6166 continue;
6169 // Substitute into the pack expansion pattern for each slice of the
6170 // pack.
6171 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6172 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
6174 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6175 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6176 return true;
6178 Exceptions.push_back(U);
6180 } else {
6181 QualType U = getDerived().TransformType(T);
6182 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6183 return true;
6184 if (T != U)
6185 Changed = true;
6187 Exceptions.push_back(U);
6191 ESI.Exceptions = Exceptions;
6192 if (ESI.Exceptions.empty())
6193 ESI.Type = EST_DynamicNone;
6194 return false;
6197 template<typename Derived>
6198 QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6199 TypeLocBuilder &TLB,
6200 FunctionNoProtoTypeLoc TL) {
6201 const FunctionNoProtoType *T = TL.getTypePtr();
6202 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6203 if (ResultType.isNull())
6204 return QualType();
6206 QualType Result = TL.getType();
6207 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6208 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6210 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
6211 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6212 NewTL.setLParenLoc(TL.getLParenLoc());
6213 NewTL.setRParenLoc(TL.getRParenLoc());
6214 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6216 return Result;
6219 template <typename Derived>
6220 QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6221 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6222 const UnresolvedUsingType *T = TL.getTypePtr();
6223 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6224 if (!D)
6225 return QualType();
6227 QualType Result = TL.getType();
6228 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6229 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6230 if (Result.isNull())
6231 return QualType();
6234 // We might get an arbitrary type spec type back. We should at
6235 // least always get a type spec type, though.
6236 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result);
6237 NewTL.setNameLoc(TL.getNameLoc());
6239 return Result;
6242 template <typename Derived>
6243 QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6244 UsingTypeLoc TL) {
6245 const UsingType *T = TL.getTypePtr();
6247 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6248 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6249 if (!Found)
6250 return QualType();
6252 QualType Underlying = getDerived().TransformType(T->desugar());
6253 if (Underlying.isNull())
6254 return QualType();
6256 QualType Result = TL.getType();
6257 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6258 Underlying != T->getUnderlyingType()) {
6259 Result = getDerived().RebuildUsingType(Found, Underlying);
6260 if (Result.isNull())
6261 return QualType();
6264 TLB.pushTypeSpec(Result).setNameLoc(TL.getNameLoc());
6265 return Result;
6268 template<typename Derived>
6269 QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6270 TypedefTypeLoc TL) {
6271 const TypedefType *T = TL.getTypePtr();
6272 TypedefNameDecl *Typedef
6273 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6274 T->getDecl()));
6275 if (!Typedef)
6276 return QualType();
6278 QualType Result = TL.getType();
6279 if (getDerived().AlwaysRebuild() ||
6280 Typedef != T->getDecl()) {
6281 Result = getDerived().RebuildTypedefType(Typedef);
6282 if (Result.isNull())
6283 return QualType();
6286 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
6287 NewTL.setNameLoc(TL.getNameLoc());
6289 return Result;
6292 template<typename Derived>
6293 QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6294 TypeOfExprTypeLoc TL) {
6295 // typeof expressions are not potentially evaluated contexts
6296 EnterExpressionEvaluationContext Unevaluated(
6297 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6298 Sema::ReuseLambdaContextDecl);
6300 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6301 if (E.isInvalid())
6302 return QualType();
6304 E = SemaRef.HandleExprEvaluationContextForTypeof(E.get());
6305 if (E.isInvalid())
6306 return QualType();
6308 QualType Result = TL.getType();
6309 TypeOfKind Kind = Result->getAs<TypeOfExprType>()->getKind();
6310 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6311 Result =
6312 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6313 if (Result.isNull())
6314 return QualType();
6317 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
6318 NewTL.setTypeofLoc(TL.getTypeofLoc());
6319 NewTL.setLParenLoc(TL.getLParenLoc());
6320 NewTL.setRParenLoc(TL.getRParenLoc());
6322 return Result;
6325 template<typename Derived>
6326 QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6327 TypeOfTypeLoc TL) {
6328 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6329 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6330 if (!New_Under_TI)
6331 return QualType();
6333 QualType Result = TL.getType();
6334 TypeOfKind Kind = Result->getAs<TypeOfType>()->getKind();
6335 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6336 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6337 if (Result.isNull())
6338 return QualType();
6341 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
6342 NewTL.setTypeofLoc(TL.getTypeofLoc());
6343 NewTL.setLParenLoc(TL.getLParenLoc());
6344 NewTL.setRParenLoc(TL.getRParenLoc());
6345 NewTL.setUnmodifiedTInfo(New_Under_TI);
6347 return Result;
6350 template<typename Derived>
6351 QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6352 DecltypeTypeLoc TL) {
6353 const DecltypeType *T = TL.getTypePtr();
6355 // decltype expressions are not potentially evaluated contexts
6356 EnterExpressionEvaluationContext Unevaluated(
6357 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
6358 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
6360 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6361 if (E.isInvalid())
6362 return QualType();
6364 E = getSema().ActOnDecltypeExpression(E.get());
6365 if (E.isInvalid())
6366 return QualType();
6368 QualType Result = TL.getType();
6369 if (getDerived().AlwaysRebuild() ||
6370 E.get() != T->getUnderlyingExpr()) {
6371 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6372 if (Result.isNull())
6373 return QualType();
6375 else E.get();
6377 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
6378 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6379 NewTL.setRParenLoc(TL.getRParenLoc());
6380 return Result;
6383 template<typename Derived>
6384 QualType TreeTransform<Derived>::TransformUnaryTransformType(
6385 TypeLocBuilder &TLB,
6386 UnaryTransformTypeLoc TL) {
6387 QualType Result = TL.getType();
6388 if (Result->isDependentType()) {
6389 const UnaryTransformType *T = TL.getTypePtr();
6390 QualType NewBase =
6391 getDerived().TransformType(TL.getUnderlyingTInfo())->getType();
6392 Result = getDerived().RebuildUnaryTransformType(NewBase,
6393 T->getUTTKind(),
6394 TL.getKWLoc());
6395 if (Result.isNull())
6396 return QualType();
6399 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
6400 NewTL.setKWLoc(TL.getKWLoc());
6401 NewTL.setParensRange(TL.getParensRange());
6402 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6403 return Result;
6406 template<typename Derived>
6407 QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6408 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6409 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6411 CXXScopeSpec SS;
6412 TemplateName TemplateName = getDerived().TransformTemplateName(
6413 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6414 if (TemplateName.isNull())
6415 return QualType();
6417 QualType OldDeduced = T->getDeducedType();
6418 QualType NewDeduced;
6419 if (!OldDeduced.isNull()) {
6420 NewDeduced = getDerived().TransformType(OldDeduced);
6421 if (NewDeduced.isNull())
6422 return QualType();
6425 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
6426 TemplateName, NewDeduced);
6427 if (Result.isNull())
6428 return QualType();
6430 DeducedTemplateSpecializationTypeLoc NewTL =
6431 TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
6432 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6434 return Result;
6437 template<typename Derived>
6438 QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
6439 RecordTypeLoc TL) {
6440 const RecordType *T = TL.getTypePtr();
6441 RecordDecl *Record
6442 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6443 T->getDecl()));
6444 if (!Record)
6445 return QualType();
6447 QualType Result = TL.getType();
6448 if (getDerived().AlwaysRebuild() ||
6449 Record != T->getDecl()) {
6450 Result = getDerived().RebuildRecordType(Record);
6451 if (Result.isNull())
6452 return QualType();
6455 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
6456 NewTL.setNameLoc(TL.getNameLoc());
6458 return Result;
6461 template<typename Derived>
6462 QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
6463 EnumTypeLoc TL) {
6464 const EnumType *T = TL.getTypePtr();
6465 EnumDecl *Enum
6466 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6467 T->getDecl()));
6468 if (!Enum)
6469 return QualType();
6471 QualType Result = TL.getType();
6472 if (getDerived().AlwaysRebuild() ||
6473 Enum != T->getDecl()) {
6474 Result = getDerived().RebuildEnumType(Enum);
6475 if (Result.isNull())
6476 return QualType();
6479 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
6480 NewTL.setNameLoc(TL.getNameLoc());
6482 return Result;
6485 template<typename Derived>
6486 QualType TreeTransform<Derived>::TransformInjectedClassNameType(
6487 TypeLocBuilder &TLB,
6488 InjectedClassNameTypeLoc TL) {
6489 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
6490 TL.getTypePtr()->getDecl());
6491 if (!D) return QualType();
6493 QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
6494 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
6495 return T;
6498 template<typename Derived>
6499 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6500 TypeLocBuilder &TLB,
6501 TemplateTypeParmTypeLoc TL) {
6502 return getDerived().TransformTemplateTypeParmType(
6503 TLB, TL,
6504 /*SuppressObjCLifetime=*/false);
6507 template <typename Derived>
6508 QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
6509 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
6510 return TransformTypeSpecType(TLB, TL);
6513 template<typename Derived>
6514 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
6515 TypeLocBuilder &TLB,
6516 SubstTemplateTypeParmTypeLoc TL) {
6517 const SubstTemplateTypeParmType *T = TL.getTypePtr();
6519 Decl *NewReplaced =
6520 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
6522 // Substitute into the replacement type, which itself might involve something
6523 // that needs to be transformed. This only tends to occur with default
6524 // template arguments of template template parameters.
6525 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
6526 QualType Replacement = getDerived().TransformType(T->getReplacementType());
6527 if (Replacement.isNull())
6528 return QualType();
6530 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
6531 Replacement, NewReplaced, T->getIndex(), T->getPackIndex());
6533 // Propagate type-source information.
6534 SubstTemplateTypeParmTypeLoc NewTL
6535 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
6536 NewTL.setNameLoc(TL.getNameLoc());
6537 return Result;
6541 template<typename Derived>
6542 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6543 TypeLocBuilder &TLB,
6544 SubstTemplateTypeParmPackTypeLoc TL) {
6545 return getDerived().TransformSubstTemplateTypeParmPackType(
6546 TLB, TL, /*SuppressObjCLifetime=*/false);
6549 template <typename Derived>
6550 QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
6551 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
6552 return TransformTypeSpecType(TLB, TL);
6555 template<typename Derived>
6556 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
6557 TypeLocBuilder &TLB,
6558 TemplateSpecializationTypeLoc TL) {
6559 const TemplateSpecializationType *T = TL.getTypePtr();
6561 // The nested-name-specifier never matters in a TemplateSpecializationType,
6562 // because we can't have a dependent nested-name-specifier anyway.
6563 CXXScopeSpec SS;
6564 TemplateName Template
6565 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
6566 TL.getTemplateNameLoc());
6567 if (Template.isNull())
6568 return QualType();
6570 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
6573 template<typename Derived>
6574 QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
6575 AtomicTypeLoc TL) {
6576 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6577 if (ValueType.isNull())
6578 return QualType();
6580 QualType Result = TL.getType();
6581 if (getDerived().AlwaysRebuild() ||
6582 ValueType != TL.getValueLoc().getType()) {
6583 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
6584 if (Result.isNull())
6585 return QualType();
6588 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
6589 NewTL.setKWLoc(TL.getKWLoc());
6590 NewTL.setLParenLoc(TL.getLParenLoc());
6591 NewTL.setRParenLoc(TL.getRParenLoc());
6593 return Result;
6596 template <typename Derived>
6597 QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
6598 PipeTypeLoc TL) {
6599 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6600 if (ValueType.isNull())
6601 return QualType();
6603 QualType Result = TL.getType();
6604 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
6605 const PipeType *PT = Result->castAs<PipeType>();
6606 bool isReadPipe = PT->isReadOnly();
6607 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
6608 if (Result.isNull())
6609 return QualType();
6612 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);
6613 NewTL.setKWLoc(TL.getKWLoc());
6615 return Result;
6618 template <typename Derived>
6619 QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
6620 BitIntTypeLoc TL) {
6621 const BitIntType *EIT = TL.getTypePtr();
6622 QualType Result = TL.getType();
6624 if (getDerived().AlwaysRebuild()) {
6625 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
6626 EIT->getNumBits(), TL.getNameLoc());
6627 if (Result.isNull())
6628 return QualType();
6631 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6632 NewTL.setNameLoc(TL.getNameLoc());
6633 return Result;
6636 template <typename Derived>
6637 QualType TreeTransform<Derived>::TransformDependentBitIntType(
6638 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
6639 const DependentBitIntType *EIT = TL.getTypePtr();
6641 EnterExpressionEvaluationContext Unevaluated(
6642 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6643 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
6644 BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr);
6646 if (BitsExpr.isInvalid())
6647 return QualType();
6649 QualType Result = TL.getType();
6651 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
6652 Result = getDerived().RebuildDependentBitIntType(
6653 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
6655 if (Result.isNull())
6656 return QualType();
6659 if (isa<DependentBitIntType>(Result)) {
6660 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);
6661 NewTL.setNameLoc(TL.getNameLoc());
6662 } else {
6663 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6664 NewTL.setNameLoc(TL.getNameLoc());
6666 return Result;
6669 /// Simple iterator that traverses the template arguments in a
6670 /// container that provides a \c getArgLoc() member function.
6672 /// This iterator is intended to be used with the iterator form of
6673 /// \c TreeTransform<Derived>::TransformTemplateArguments().
6674 template<typename ArgLocContainer>
6675 class TemplateArgumentLocContainerIterator {
6676 ArgLocContainer *Container;
6677 unsigned Index;
6679 public:
6680 typedef TemplateArgumentLoc value_type;
6681 typedef TemplateArgumentLoc reference;
6682 typedef int difference_type;
6683 typedef std::input_iterator_tag iterator_category;
6685 class pointer {
6686 TemplateArgumentLoc Arg;
6688 public:
6689 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
6691 const TemplateArgumentLoc *operator->() const {
6692 return &Arg;
6697 TemplateArgumentLocContainerIterator() {}
6699 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
6700 unsigned Index)
6701 : Container(&Container), Index(Index) { }
6703 TemplateArgumentLocContainerIterator &operator++() {
6704 ++Index;
6705 return *this;
6708 TemplateArgumentLocContainerIterator operator++(int) {
6709 TemplateArgumentLocContainerIterator Old(*this);
6710 ++(*this);
6711 return Old;
6714 TemplateArgumentLoc operator*() const {
6715 return Container->getArgLoc(Index);
6718 pointer operator->() const {
6719 return pointer(Container->getArgLoc(Index));
6722 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
6723 const TemplateArgumentLocContainerIterator &Y) {
6724 return X.Container == Y.Container && X.Index == Y.Index;
6727 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
6728 const TemplateArgumentLocContainerIterator &Y) {
6729 return !(X == Y);
6733 template<typename Derived>
6734 QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
6735 AutoTypeLoc TL) {
6736 const AutoType *T = TL.getTypePtr();
6737 QualType OldDeduced = T->getDeducedType();
6738 QualType NewDeduced;
6739 if (!OldDeduced.isNull()) {
6740 NewDeduced = getDerived().TransformType(OldDeduced);
6741 if (NewDeduced.isNull())
6742 return QualType();
6745 ConceptDecl *NewCD = nullptr;
6746 TemplateArgumentListInfo NewTemplateArgs;
6747 NestedNameSpecifierLoc NewNestedNameSpec;
6748 if (T->isConstrained()) {
6749 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
6750 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
6752 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
6753 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
6754 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
6755 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
6756 ArgIterator(TL,
6757 TL.getNumArgs()),
6758 NewTemplateArgs))
6759 return QualType();
6761 if (TL.getNestedNameSpecifierLoc()) {
6762 NewNestedNameSpec
6763 = getDerived().TransformNestedNameSpecifierLoc(
6764 TL.getNestedNameSpecifierLoc());
6765 if (!NewNestedNameSpec)
6766 return QualType();
6770 QualType Result = TL.getType();
6771 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
6772 T->isDependentType() || T->isConstrained()) {
6773 // FIXME: Maybe don't rebuild if all template arguments are the same.
6774 llvm::SmallVector<TemplateArgument, 4> NewArgList;
6775 NewArgList.reserve(NewTemplateArgs.size());
6776 for (const auto &ArgLoc : NewTemplateArgs.arguments())
6777 NewArgList.push_back(ArgLoc.getArgument());
6778 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
6779 NewArgList);
6780 if (Result.isNull())
6781 return QualType();
6784 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
6785 NewTL.setNameLoc(TL.getNameLoc());
6786 NewTL.setNestedNameSpecifierLoc(NewNestedNameSpec);
6787 NewTL.setTemplateKWLoc(TL.getTemplateKWLoc());
6788 NewTL.setConceptNameLoc(TL.getConceptNameLoc());
6789 NewTL.setFoundDecl(TL.getFoundDecl());
6790 NewTL.setLAngleLoc(TL.getLAngleLoc());
6791 NewTL.setRAngleLoc(TL.getRAngleLoc());
6792 NewTL.setRParenLoc(TL.getRParenLoc());
6793 for (unsigned I = 0; I < NewTL.getNumArgs(); ++I)
6794 NewTL.setArgLocInfo(I, NewTemplateArgs.arguments()[I].getLocInfo());
6796 return Result;
6799 template <typename Derived>
6800 QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
6801 TypeLocBuilder &TLB,
6802 TemplateSpecializationTypeLoc TL,
6803 TemplateName Template) {
6804 TemplateArgumentListInfo NewTemplateArgs;
6805 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
6806 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
6807 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
6808 ArgIterator;
6809 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
6810 ArgIterator(TL, TL.getNumArgs()),
6811 NewTemplateArgs))
6812 return QualType();
6814 // FIXME: maybe don't rebuild if all the template arguments are the same.
6816 QualType Result =
6817 getDerived().RebuildTemplateSpecializationType(Template,
6818 TL.getTemplateNameLoc(),
6819 NewTemplateArgs);
6821 if (!Result.isNull()) {
6822 // Specializations of template template parameters are represented as
6823 // TemplateSpecializationTypes, and substitution of type alias templates
6824 // within a dependent context can transform them into
6825 // DependentTemplateSpecializationTypes.
6826 if (isa<DependentTemplateSpecializationType>(Result)) {
6827 DependentTemplateSpecializationTypeLoc NewTL
6828 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
6829 NewTL.setElaboratedKeywordLoc(SourceLocation());
6830 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
6831 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6832 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6833 NewTL.setLAngleLoc(TL.getLAngleLoc());
6834 NewTL.setRAngleLoc(TL.getRAngleLoc());
6835 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6836 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6837 return Result;
6840 TemplateSpecializationTypeLoc NewTL
6841 = TLB.push<TemplateSpecializationTypeLoc>(Result);
6842 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6843 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6844 NewTL.setLAngleLoc(TL.getLAngleLoc());
6845 NewTL.setRAngleLoc(TL.getRAngleLoc());
6846 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6847 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6850 return Result;
6853 template <typename Derived>
6854 QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
6855 TypeLocBuilder &TLB,
6856 DependentTemplateSpecializationTypeLoc TL,
6857 TemplateName Template,
6858 CXXScopeSpec &SS) {
6859 TemplateArgumentListInfo NewTemplateArgs;
6860 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
6861 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
6862 typedef TemplateArgumentLocContainerIterator<
6863 DependentTemplateSpecializationTypeLoc> ArgIterator;
6864 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
6865 ArgIterator(TL, TL.getNumArgs()),
6866 NewTemplateArgs))
6867 return QualType();
6869 // FIXME: maybe don't rebuild if all the template arguments are the same.
6871 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
6872 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
6873 TL.getTypePtr()->getKeyword(), DTN->getQualifier(),
6874 DTN->getIdentifier(), NewTemplateArgs.arguments());
6876 DependentTemplateSpecializationTypeLoc NewTL
6877 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
6878 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
6879 NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
6880 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6881 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6882 NewTL.setLAngleLoc(TL.getLAngleLoc());
6883 NewTL.setRAngleLoc(TL.getRAngleLoc());
6884 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6885 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6886 return Result;
6889 QualType Result
6890 = getDerived().RebuildTemplateSpecializationType(Template,
6891 TL.getTemplateNameLoc(),
6892 NewTemplateArgs);
6894 if (!Result.isNull()) {
6895 /// FIXME: Wrap this in an elaborated-type-specifier?
6896 TemplateSpecializationTypeLoc NewTL
6897 = TLB.push<TemplateSpecializationTypeLoc>(Result);
6898 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
6899 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6900 NewTL.setLAngleLoc(TL.getLAngleLoc());
6901 NewTL.setRAngleLoc(TL.getRAngleLoc());
6902 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
6903 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
6906 return Result;
6909 template<typename Derived>
6910 QualType
6911 TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
6912 ElaboratedTypeLoc TL) {
6913 const ElaboratedType *T = TL.getTypePtr();
6915 NestedNameSpecifierLoc QualifierLoc;
6916 // NOTE: the qualifier in an ElaboratedType is optional.
6917 if (TL.getQualifierLoc()) {
6918 QualifierLoc
6919 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
6920 if (!QualifierLoc)
6921 return QualType();
6924 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
6925 if (NamedT.isNull())
6926 return QualType();
6928 // C++0x [dcl.type.elab]p2:
6929 // If the identifier resolves to a typedef-name or the simple-template-id
6930 // resolves to an alias template specialization, the
6931 // elaborated-type-specifier is ill-formed.
6932 if (T->getKeyword() != ETK_None && T->getKeyword() != ETK_Typename) {
6933 if (const TemplateSpecializationType *TST =
6934 NamedT->getAs<TemplateSpecializationType>()) {
6935 TemplateName Template = TST->getTemplateName();
6936 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
6937 Template.getAsTemplateDecl())) {
6938 SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
6939 diag::err_tag_reference_non_tag)
6940 << TAT << Sema::NTK_TypeAliasTemplate
6941 << ElaboratedType::getTagTypeKindForKeyword(T->getKeyword());
6942 SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
6947 QualType Result = TL.getType();
6948 if (getDerived().AlwaysRebuild() ||
6949 QualifierLoc != TL.getQualifierLoc() ||
6950 NamedT != T->getNamedType()) {
6951 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
6952 T->getKeyword(),
6953 QualifierLoc, NamedT);
6954 if (Result.isNull())
6955 return QualType();
6958 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
6959 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
6960 NewTL.setQualifierLoc(QualifierLoc);
6961 return Result;
6964 template<typename Derived>
6965 QualType TreeTransform<Derived>::TransformAttributedType(
6966 TypeLocBuilder &TLB,
6967 AttributedTypeLoc TL) {
6968 const AttributedType *oldType = TL.getTypePtr();
6969 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
6970 if (modifiedType.isNull())
6971 return QualType();
6973 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
6974 const Attr *oldAttr = TL.getAttr();
6975 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
6976 if (oldAttr && !newAttr)
6977 return QualType();
6979 QualType result = TL.getType();
6981 // FIXME: dependent operand expressions?
6982 if (getDerived().AlwaysRebuild() ||
6983 modifiedType != oldType->getModifiedType()) {
6984 // TODO: this is really lame; we should really be rebuilding the
6985 // equivalent type from first principles.
6986 QualType equivalentType
6987 = getDerived().TransformType(oldType->getEquivalentType());
6988 if (equivalentType.isNull())
6989 return QualType();
6991 // Check whether we can add nullability; it is only represented as
6992 // type sugar, and therefore cannot be diagnosed in any other way.
6993 if (auto nullability = oldType->getImmediateNullability()) {
6994 if (!modifiedType->canHaveNullability()) {
6995 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
6996 : TL.getModifiedLoc().getBeginLoc()),
6997 diag::err_nullability_nonpointer)
6998 << DiagNullabilityKind(*nullability, false) << modifiedType;
6999 return QualType();
7003 result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
7004 modifiedType,
7005 equivalentType);
7008 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
7009 newTL.setAttr(newAttr);
7010 return result;
7013 template <typename Derived>
7014 QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7015 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7016 // The BTFTagAttributedType is available for C only.
7017 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7020 template<typename Derived>
7021 QualType
7022 TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7023 ParenTypeLoc TL) {
7024 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7025 if (Inner.isNull())
7026 return QualType();
7028 QualType Result = TL.getType();
7029 if (getDerived().AlwaysRebuild() ||
7030 Inner != TL.getInnerLoc().getType()) {
7031 Result = getDerived().RebuildParenType(Inner);
7032 if (Result.isNull())
7033 return QualType();
7036 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
7037 NewTL.setLParenLoc(TL.getLParenLoc());
7038 NewTL.setRParenLoc(TL.getRParenLoc());
7039 return Result;
7042 template <typename Derived>
7043 QualType
7044 TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7045 MacroQualifiedTypeLoc TL) {
7046 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7047 if (Inner.isNull())
7048 return QualType();
7050 QualType Result = TL.getType();
7051 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7052 Result =
7053 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7054 if (Result.isNull())
7055 return QualType();
7058 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
7059 NewTL.setExpansionLoc(TL.getExpansionLoc());
7060 return Result;
7063 template<typename Derived>
7064 QualType TreeTransform<Derived>::TransformDependentNameType(
7065 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7066 return TransformDependentNameType(TLB, TL, false);
7069 template<typename Derived>
7070 QualType TreeTransform<Derived>::TransformDependentNameType(
7071 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7072 const DependentNameType *T = TL.getTypePtr();
7074 NestedNameSpecifierLoc QualifierLoc
7075 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7076 if (!QualifierLoc)
7077 return QualType();
7079 QualType Result
7080 = getDerived().RebuildDependentNameType(T->getKeyword(),
7081 TL.getElaboratedKeywordLoc(),
7082 QualifierLoc,
7083 T->getIdentifier(),
7084 TL.getNameLoc(),
7085 DeducedTSTContext);
7086 if (Result.isNull())
7087 return QualType();
7089 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7090 QualType NamedT = ElabT->getNamedType();
7091 TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
7093 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7094 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7095 NewTL.setQualifierLoc(QualifierLoc);
7096 } else {
7097 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
7098 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7099 NewTL.setQualifierLoc(QualifierLoc);
7100 NewTL.setNameLoc(TL.getNameLoc());
7102 return Result;
7105 template<typename Derived>
7106 QualType TreeTransform<Derived>::
7107 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7108 DependentTemplateSpecializationTypeLoc TL) {
7109 NestedNameSpecifierLoc QualifierLoc;
7110 if (TL.getQualifierLoc()) {
7111 QualifierLoc
7112 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7113 if (!QualifierLoc)
7114 return QualType();
7117 return getDerived()
7118 .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
7121 template<typename Derived>
7122 QualType TreeTransform<Derived>::
7123 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7124 DependentTemplateSpecializationTypeLoc TL,
7125 NestedNameSpecifierLoc QualifierLoc) {
7126 const DependentTemplateSpecializationType *T = TL.getTypePtr();
7128 TemplateArgumentListInfo NewTemplateArgs;
7129 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7130 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7132 typedef TemplateArgumentLocContainerIterator<
7133 DependentTemplateSpecializationTypeLoc> ArgIterator;
7134 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7135 ArgIterator(TL, TL.getNumArgs()),
7136 NewTemplateArgs))
7137 return QualType();
7139 QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
7140 T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(),
7141 T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs,
7142 /*AllowInjectedClassName*/ false);
7143 if (Result.isNull())
7144 return QualType();
7146 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
7147 QualType NamedT = ElabT->getNamedType();
7149 // Copy information relevant to the template specialization.
7150 TemplateSpecializationTypeLoc NamedTL
7151 = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
7152 NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7153 NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7154 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7155 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7156 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7157 NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7159 // Copy information relevant to the elaborated type.
7160 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7161 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7162 NewTL.setQualifierLoc(QualifierLoc);
7163 } else if (isa<DependentTemplateSpecializationType>(Result)) {
7164 DependentTemplateSpecializationTypeLoc SpecTL
7165 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7166 SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7167 SpecTL.setQualifierLoc(QualifierLoc);
7168 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7169 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7170 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7171 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7172 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7173 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7174 } else {
7175 TemplateSpecializationTypeLoc SpecTL
7176 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7177 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7178 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7179 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7180 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7181 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7182 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7184 return Result;
7187 template<typename Derived>
7188 QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7189 PackExpansionTypeLoc TL) {
7190 QualType Pattern
7191 = getDerived().TransformType(TLB, TL.getPatternLoc());
7192 if (Pattern.isNull())
7193 return QualType();
7195 QualType Result = TL.getType();
7196 if (getDerived().AlwaysRebuild() ||
7197 Pattern != TL.getPatternLoc().getType()) {
7198 Result = getDerived().RebuildPackExpansionType(Pattern,
7199 TL.getPatternLoc().getSourceRange(),
7200 TL.getEllipsisLoc(),
7201 TL.getTypePtr()->getNumExpansions());
7202 if (Result.isNull())
7203 return QualType();
7206 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
7207 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7208 return Result;
7211 template<typename Derived>
7212 QualType
7213 TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7214 ObjCInterfaceTypeLoc TL) {
7215 // ObjCInterfaceType is never dependent.
7216 TLB.pushFullCopy(TL);
7217 return TL.getType();
7220 template<typename Derived>
7221 QualType
7222 TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7223 ObjCTypeParamTypeLoc TL) {
7224 const ObjCTypeParamType *T = TL.getTypePtr();
7225 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7226 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7227 if (!OTP)
7228 return QualType();
7230 QualType Result = TL.getType();
7231 if (getDerived().AlwaysRebuild() ||
7232 OTP != T->getDecl()) {
7233 Result = getDerived().RebuildObjCTypeParamType(
7234 OTP, TL.getProtocolLAngleLoc(),
7235 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7236 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7237 if (Result.isNull())
7238 return QualType();
7241 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
7242 if (TL.getNumProtocols()) {
7243 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7244 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7245 NewTL.setProtocolLoc(i, TL.getProtocolLoc(i));
7246 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7248 return Result;
7251 template<typename Derived>
7252 QualType
7253 TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7254 ObjCObjectTypeLoc TL) {
7255 // Transform base type.
7256 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7257 if (BaseType.isNull())
7258 return QualType();
7260 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7262 // Transform type arguments.
7263 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7264 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7265 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7266 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7267 QualType TypeArg = TypeArgInfo->getType();
7268 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7269 AnyChanged = true;
7271 // We have a pack expansion. Instantiate it.
7272 const auto *PackExpansion = PackExpansionLoc.getType()
7273 ->castAs<PackExpansionType>();
7274 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7275 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
7276 Unexpanded);
7277 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7279 // Determine whether the set of unexpanded parameter packs can
7280 // and should be expanded.
7281 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7282 bool Expand = false;
7283 bool RetainExpansion = false;
7284 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
7285 if (getDerived().TryExpandParameterPacks(
7286 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7287 Unexpanded, Expand, RetainExpansion, NumExpansions))
7288 return QualType();
7290 if (!Expand) {
7291 // We can't expand this pack expansion into separate arguments yet;
7292 // just substitute into the pattern and create a new pack expansion
7293 // type.
7294 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
7296 TypeLocBuilder TypeArgBuilder;
7297 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7298 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7299 PatternLoc);
7300 if (NewPatternType.isNull())
7301 return QualType();
7303 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7304 NewPatternType, NumExpansions);
7305 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);
7306 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7307 NewTypeArgInfos.push_back(
7308 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewExpansionType));
7309 continue;
7312 // Substitute into the pack expansion pattern for each slice of the
7313 // pack.
7314 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
7315 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
7317 TypeLocBuilder TypeArgBuilder;
7318 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7320 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
7321 PatternLoc);
7322 if (NewTypeArg.isNull())
7323 return QualType();
7325 NewTypeArgInfos.push_back(
7326 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7329 continue;
7332 TypeLocBuilder TypeArgBuilder;
7333 TypeArgBuilder.reserve(TypeArgLoc.getFullDataSize());
7334 QualType NewTypeArg =
7335 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
7336 if (NewTypeArg.isNull())
7337 return QualType();
7339 // If nothing changed, just keep the old TypeSourceInfo.
7340 if (NewTypeArg == TypeArg) {
7341 NewTypeArgInfos.push_back(TypeArgInfo);
7342 continue;
7345 NewTypeArgInfos.push_back(
7346 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7347 AnyChanged = true;
7350 QualType Result = TL.getType();
7351 if (getDerived().AlwaysRebuild() || AnyChanged) {
7352 // Rebuild the type.
7353 Result = getDerived().RebuildObjCObjectType(
7354 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
7355 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
7356 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7357 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7359 if (Result.isNull())
7360 return QualType();
7363 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);
7364 NewT.setHasBaseTypeAsWritten(true);
7365 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
7366 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
7367 NewT.setTypeArgTInfo(i, NewTypeArgInfos[i]);
7368 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
7369 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7370 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7371 NewT.setProtocolLoc(i, TL.getProtocolLoc(i));
7372 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7373 return Result;
7376 template<typename Derived>
7377 QualType
7378 TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
7379 ObjCObjectPointerTypeLoc TL) {
7380 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
7381 if (PointeeType.isNull())
7382 return QualType();
7384 QualType Result = TL.getType();
7385 if (getDerived().AlwaysRebuild() ||
7386 PointeeType != TL.getPointeeLoc().getType()) {
7387 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
7388 TL.getStarLoc());
7389 if (Result.isNull())
7390 return QualType();
7393 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
7394 NewT.setStarLoc(TL.getStarLoc());
7395 return Result;
7398 //===----------------------------------------------------------------------===//
7399 // Statement transformation
7400 //===----------------------------------------------------------------------===//
7401 template<typename Derived>
7402 StmtResult
7403 TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
7404 return S;
7407 template<typename Derived>
7408 StmtResult
7409 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
7410 return getDerived().TransformCompoundStmt(S, false);
7413 template<typename Derived>
7414 StmtResult
7415 TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
7416 bool IsStmtExpr) {
7417 Sema::CompoundScopeRAII CompoundScope(getSema());
7419 const Stmt *ExprResult = S->getStmtExprResult();
7420 bool SubStmtInvalid = false;
7421 bool SubStmtChanged = false;
7422 SmallVector<Stmt*, 8> Statements;
7423 for (auto *B : S->body()) {
7424 StmtResult Result = getDerived().TransformStmt(
7425 B, IsStmtExpr && B == ExprResult ? SDK_StmtExprResult : SDK_Discarded);
7427 if (Result.isInvalid()) {
7428 // Immediately fail if this was a DeclStmt, since it's very
7429 // likely that this will cause problems for future statements.
7430 if (isa<DeclStmt>(B))
7431 return StmtError();
7433 // Otherwise, just keep processing substatements and fail later.
7434 SubStmtInvalid = true;
7435 continue;
7438 SubStmtChanged = SubStmtChanged || Result.get() != B;
7439 Statements.push_back(Result.getAs<Stmt>());
7442 if (SubStmtInvalid)
7443 return StmtError();
7445 if (!getDerived().AlwaysRebuild() &&
7446 !SubStmtChanged)
7447 return S;
7449 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
7450 Statements,
7451 S->getRBracLoc(),
7452 IsStmtExpr);
7455 template<typename Derived>
7456 StmtResult
7457 TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
7458 ExprResult LHS, RHS;
7460 EnterExpressionEvaluationContext Unevaluated(
7461 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7463 // Transform the left-hand case value.
7464 LHS = getDerived().TransformExpr(S->getLHS());
7465 LHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), LHS);
7466 if (LHS.isInvalid())
7467 return StmtError();
7469 // Transform the right-hand case value (for the GNU case-range extension).
7470 RHS = getDerived().TransformExpr(S->getRHS());
7471 RHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), RHS);
7472 if (RHS.isInvalid())
7473 return StmtError();
7476 // Build the case statement.
7477 // Case statements are always rebuilt so that they will attached to their
7478 // transformed switch statement.
7479 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
7480 LHS.get(),
7481 S->getEllipsisLoc(),
7482 RHS.get(),
7483 S->getColonLoc());
7484 if (Case.isInvalid())
7485 return StmtError();
7487 // Transform the statement following the case
7488 StmtResult SubStmt =
7489 getDerived().TransformStmt(S->getSubStmt());
7490 if (SubStmt.isInvalid())
7491 return StmtError();
7493 // Attach the body to the case statement
7494 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
7497 template <typename Derived>
7498 StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
7499 // Transform the statement following the default case
7500 StmtResult SubStmt =
7501 getDerived().TransformStmt(S->getSubStmt());
7502 if (SubStmt.isInvalid())
7503 return StmtError();
7505 // Default statements are always rebuilt
7506 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
7507 SubStmt.get());
7510 template<typename Derived>
7511 StmtResult
7512 TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
7513 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7514 if (SubStmt.isInvalid())
7515 return StmtError();
7517 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
7518 S->getDecl());
7519 if (!LD)
7520 return StmtError();
7522 // If we're transforming "in-place" (we're not creating new local
7523 // declarations), assume we're replacing the old label statement
7524 // and clear out the reference to it.
7525 if (LD == S->getDecl())
7526 S->getDecl()->setStmt(nullptr);
7528 // FIXME: Pass the real colon location in.
7529 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
7530 cast<LabelDecl>(LD), SourceLocation(),
7531 SubStmt.get());
7534 template <typename Derived>
7535 const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
7536 if (!R)
7537 return R;
7539 switch (R->getKind()) {
7540 // Transform attributes with a pragma spelling by calling TransformXXXAttr.
7541 #define ATTR(X)
7542 #define PRAGMA_SPELLING_ATTR(X) \
7543 case attr::X: \
7544 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
7545 #include "clang/Basic/AttrList.inc"
7546 default:
7547 return R;
7551 template <typename Derived>
7552 StmtResult
7553 TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
7554 StmtDiscardKind SDK) {
7555 bool AttrsChanged = false;
7556 SmallVector<const Attr *, 1> Attrs;
7558 // Visit attributes and keep track if any are transformed.
7559 for (const auto *I : S->getAttrs()) {
7560 const Attr *R = getDerived().TransformAttr(I);
7561 AttrsChanged |= (I != R);
7562 if (R)
7563 Attrs.push_back(R);
7566 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7567 if (SubStmt.isInvalid())
7568 return StmtError();
7570 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
7571 return S;
7573 // If transforming the attributes failed for all of the attributes in the
7574 // statement, don't make an AttributedStmt without attributes.
7575 if (Attrs.empty())
7576 return SubStmt;
7578 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
7579 SubStmt.get());
7582 template<typename Derived>
7583 StmtResult
7584 TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
7585 // Transform the initialization statement
7586 StmtResult Init = getDerived().TransformStmt(S->getInit());
7587 if (Init.isInvalid())
7588 return StmtError();
7590 Sema::ConditionResult Cond;
7591 if (!S->isConsteval()) {
7592 // Transform the condition
7593 Cond = getDerived().TransformCondition(
7594 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
7595 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
7596 : Sema::ConditionKind::Boolean);
7597 if (Cond.isInvalid())
7598 return StmtError();
7601 // If this is a constexpr if, determine which arm we should instantiate.
7602 std::optional<bool> ConstexprConditionValue;
7603 if (S->isConstexpr())
7604 ConstexprConditionValue = Cond.getKnownValue();
7606 // Transform the "then" branch.
7607 StmtResult Then;
7608 if (!ConstexprConditionValue || *ConstexprConditionValue) {
7609 Then = getDerived().TransformStmt(S->getThen());
7610 if (Then.isInvalid())
7611 return StmtError();
7612 } else {
7613 Then = new (getSema().Context) NullStmt(S->getThen()->getBeginLoc());
7616 // Transform the "else" branch.
7617 StmtResult Else;
7618 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
7619 Else = getDerived().TransformStmt(S->getElse());
7620 if (Else.isInvalid())
7621 return StmtError();
7624 if (!getDerived().AlwaysRebuild() &&
7625 Init.get() == S->getInit() &&
7626 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7627 Then.get() == S->getThen() &&
7628 Else.get() == S->getElse())
7629 return S;
7631 return getDerived().RebuildIfStmt(
7632 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
7633 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
7636 template<typename Derived>
7637 StmtResult
7638 TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
7639 // Transform the initialization statement
7640 StmtResult Init = getDerived().TransformStmt(S->getInit());
7641 if (Init.isInvalid())
7642 return StmtError();
7644 // Transform the condition.
7645 Sema::ConditionResult Cond = getDerived().TransformCondition(
7646 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
7647 Sema::ConditionKind::Switch);
7648 if (Cond.isInvalid())
7649 return StmtError();
7651 // Rebuild the switch statement.
7652 StmtResult Switch =
7653 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
7654 Init.get(), Cond, S->getRParenLoc());
7655 if (Switch.isInvalid())
7656 return StmtError();
7658 // Transform the body of the switch statement.
7659 StmtResult Body = getDerived().TransformStmt(S->getBody());
7660 if (Body.isInvalid())
7661 return StmtError();
7663 // Complete the switch statement.
7664 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
7665 Body.get());
7668 template<typename Derived>
7669 StmtResult
7670 TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
7671 // Transform the condition
7672 Sema::ConditionResult Cond = getDerived().TransformCondition(
7673 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
7674 Sema::ConditionKind::Boolean);
7675 if (Cond.isInvalid())
7676 return StmtError();
7678 // Transform the body
7679 StmtResult Body = getDerived().TransformStmt(S->getBody());
7680 if (Body.isInvalid())
7681 return StmtError();
7683 if (!getDerived().AlwaysRebuild() &&
7684 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7685 Body.get() == S->getBody())
7686 return Owned(S);
7688 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
7689 Cond, S->getRParenLoc(), Body.get());
7692 template<typename Derived>
7693 StmtResult
7694 TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
7695 // Transform the body
7696 StmtResult Body = getDerived().TransformStmt(S->getBody());
7697 if (Body.isInvalid())
7698 return StmtError();
7700 // Transform the condition
7701 ExprResult Cond = getDerived().TransformExpr(S->getCond());
7702 if (Cond.isInvalid())
7703 return StmtError();
7705 if (!getDerived().AlwaysRebuild() &&
7706 Cond.get() == S->getCond() &&
7707 Body.get() == S->getBody())
7708 return S;
7710 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
7711 /*FIXME:*/S->getWhileLoc(), Cond.get(),
7712 S->getRParenLoc());
7715 template<typename Derived>
7716 StmtResult
7717 TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
7718 if (getSema().getLangOpts().OpenMP)
7719 getSema().startOpenMPLoop();
7721 // Transform the initialization statement
7722 StmtResult Init = getDerived().TransformStmt(S->getInit());
7723 if (Init.isInvalid())
7724 return StmtError();
7726 // In OpenMP loop region loop control variable must be captured and be
7727 // private. Perform analysis of first part (if any).
7728 if (getSema().getLangOpts().OpenMP && Init.isUsable())
7729 getSema().ActOnOpenMPLoopInitialization(S->getForLoc(), Init.get());
7731 // Transform the condition
7732 Sema::ConditionResult Cond = getDerived().TransformCondition(
7733 S->getForLoc(), S->getConditionVariable(), S->getCond(),
7734 Sema::ConditionKind::Boolean);
7735 if (Cond.isInvalid())
7736 return StmtError();
7738 // Transform the increment
7739 ExprResult Inc = getDerived().TransformExpr(S->getInc());
7740 if (Inc.isInvalid())
7741 return StmtError();
7743 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
7744 if (S->getInc() && !FullInc.get())
7745 return StmtError();
7747 // Transform the body
7748 StmtResult Body = getDerived().TransformStmt(S->getBody());
7749 if (Body.isInvalid())
7750 return StmtError();
7752 if (!getDerived().AlwaysRebuild() &&
7753 Init.get() == S->getInit() &&
7754 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
7755 Inc.get() == S->getInc() &&
7756 Body.get() == S->getBody())
7757 return S;
7759 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
7760 Init.get(), Cond, FullInc,
7761 S->getRParenLoc(), Body.get());
7764 template<typename Derived>
7765 StmtResult
7766 TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
7767 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
7768 S->getLabel());
7769 if (!LD)
7770 return StmtError();
7772 // Goto statements must always be rebuilt, to resolve the label.
7773 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
7774 cast<LabelDecl>(LD));
7777 template<typename Derived>
7778 StmtResult
7779 TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
7780 ExprResult Target = getDerived().TransformExpr(S->getTarget());
7781 if (Target.isInvalid())
7782 return StmtError();
7783 Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());
7785 if (!getDerived().AlwaysRebuild() &&
7786 Target.get() == S->getTarget())
7787 return S;
7789 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
7790 Target.get());
7793 template<typename Derived>
7794 StmtResult
7795 TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
7796 return S;
7799 template<typename Derived>
7800 StmtResult
7801 TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
7802 return S;
7805 template<typename Derived>
7806 StmtResult
7807 TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
7808 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
7809 /*NotCopyInit*/false);
7810 if (Result.isInvalid())
7811 return StmtError();
7813 // FIXME: We always rebuild the return statement because there is no way
7814 // to tell whether the return type of the function has changed.
7815 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
7818 template<typename Derived>
7819 StmtResult
7820 TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
7821 bool DeclChanged = false;
7822 SmallVector<Decl *, 4> Decls;
7823 for (auto *D : S->decls()) {
7824 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
7825 if (!Transformed)
7826 return StmtError();
7828 if (Transformed != D)
7829 DeclChanged = true;
7831 Decls.push_back(Transformed);
7834 if (!getDerived().AlwaysRebuild() && !DeclChanged)
7835 return S;
7837 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
7840 template<typename Derived>
7841 StmtResult
7842 TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
7844 SmallVector<Expr*, 8> Constraints;
7845 SmallVector<Expr*, 8> Exprs;
7846 SmallVector<IdentifierInfo *, 4> Names;
7848 ExprResult AsmString;
7849 SmallVector<Expr*, 8> Clobbers;
7851 bool ExprsChanged = false;
7853 // Go through the outputs.
7854 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
7855 Names.push_back(S->getOutputIdentifier(I));
7857 // No need to transform the constraint literal.
7858 Constraints.push_back(S->getOutputConstraintLiteral(I));
7860 // Transform the output expr.
7861 Expr *OutputExpr = S->getOutputExpr(I);
7862 ExprResult Result = getDerived().TransformExpr(OutputExpr);
7863 if (Result.isInvalid())
7864 return StmtError();
7866 ExprsChanged |= Result.get() != OutputExpr;
7868 Exprs.push_back(Result.get());
7871 // Go through the inputs.
7872 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
7873 Names.push_back(S->getInputIdentifier(I));
7875 // No need to transform the constraint literal.
7876 Constraints.push_back(S->getInputConstraintLiteral(I));
7878 // Transform the input expr.
7879 Expr *InputExpr = S->getInputExpr(I);
7880 ExprResult Result = getDerived().TransformExpr(InputExpr);
7881 if (Result.isInvalid())
7882 return StmtError();
7884 ExprsChanged |= Result.get() != InputExpr;
7886 Exprs.push_back(Result.get());
7889 // Go through the Labels.
7890 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
7891 Names.push_back(S->getLabelIdentifier(I));
7893 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(I));
7894 if (Result.isInvalid())
7895 return StmtError();
7896 ExprsChanged |= Result.get() != S->getLabelExpr(I);
7897 Exprs.push_back(Result.get());
7899 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
7900 return S;
7902 // Go through the clobbers.
7903 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
7904 Clobbers.push_back(S->getClobberStringLiteral(I));
7906 // No need to transform the asm string literal.
7907 AsmString = S->getAsmString();
7908 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
7909 S->isVolatile(), S->getNumOutputs(),
7910 S->getNumInputs(), Names.data(),
7911 Constraints, Exprs, AsmString.get(),
7912 Clobbers, S->getNumLabels(),
7913 S->getRParenLoc());
7916 template<typename Derived>
7917 StmtResult
7918 TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
7919 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
7921 bool HadError = false, HadChange = false;
7923 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
7924 SmallVector<Expr*, 8> TransformedExprs;
7925 TransformedExprs.reserve(SrcExprs.size());
7926 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
7927 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
7928 if (!Result.isUsable()) {
7929 HadError = true;
7930 } else {
7931 HadChange |= (Result.get() != SrcExprs[i]);
7932 TransformedExprs.push_back(Result.get());
7936 if (HadError) return StmtError();
7937 if (!HadChange && !getDerived().AlwaysRebuild())
7938 return Owned(S);
7940 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
7941 AsmToks, S->getAsmString(),
7942 S->getNumOutputs(), S->getNumInputs(),
7943 S->getAllConstraints(), S->getClobbers(),
7944 TransformedExprs, S->getEndLoc());
7947 // C++ Coroutines TS
7949 template<typename Derived>
7950 StmtResult
7951 TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
7952 auto *ScopeInfo = SemaRef.getCurFunction();
7953 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
7954 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
7955 ScopeInfo->NeedsCoroutineSuspends &&
7956 ScopeInfo->CoroutineSuspends.first == nullptr &&
7957 ScopeInfo->CoroutineSuspends.second == nullptr &&
7958 "expected clean scope info");
7960 // Set that we have (possibly-invalid) suspend points before we do anything
7961 // that may fail.
7962 ScopeInfo->setNeedsCoroutineSuspends(false);
7964 // We re-build the coroutine promise object (and the coroutine parameters its
7965 // type and constructor depend on) based on the types used in our current
7966 // function. We must do so, and set it on the current FunctionScopeInfo,
7967 // before attempting to transform the other parts of the coroutine body
7968 // statement, such as the implicit suspend statements (because those
7969 // statements reference the FunctionScopeInfo::CoroutinePromise).
7970 if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation()))
7971 return StmtError();
7972 auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());
7973 if (!Promise)
7974 return StmtError();
7975 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
7976 ScopeInfo->CoroutinePromise = Promise;
7978 // Transform the implicit coroutine statements constructed using dependent
7979 // types during the previous parse: initial and final suspensions, the return
7980 // object, and others. We also transform the coroutine function's body.
7981 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
7982 if (InitSuspend.isInvalid())
7983 return StmtError();
7984 StmtResult FinalSuspend =
7985 getDerived().TransformStmt(S->getFinalSuspendStmt());
7986 if (FinalSuspend.isInvalid() ||
7987 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get()))
7988 return StmtError();
7989 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
7990 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
7992 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
7993 if (BodyRes.isInvalid())
7994 return StmtError();
7996 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
7997 if (Builder.isInvalid())
7998 return StmtError();
8000 Expr *ReturnObject = S->getReturnValueInit();
8001 assert(ReturnObject && "the return object is expected to be valid");
8002 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8003 /*NoCopyInit*/ false);
8004 if (Res.isInvalid())
8005 return StmtError();
8006 Builder.ReturnValue = Res.get();
8008 // If during the previous parse the coroutine still had a dependent promise
8009 // statement, we may need to build some implicit coroutine statements
8010 // (such as exception and fallthrough handlers) for the first time.
8011 if (S->hasDependentPromiseType()) {
8012 // We can only build these statements, however, if the current promise type
8013 // is not dependent.
8014 if (!Promise->getType()->isDependentType()) {
8015 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8016 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8017 "these nodes should not have been built yet");
8018 if (!Builder.buildDependentStatements())
8019 return StmtError();
8021 } else {
8022 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8023 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8024 if (Res.isInvalid())
8025 return StmtError();
8026 Builder.OnFallthrough = Res.get();
8029 if (auto *OnException = S->getExceptionHandler()) {
8030 StmtResult Res = getDerived().TransformStmt(OnException);
8031 if (Res.isInvalid())
8032 return StmtError();
8033 Builder.OnException = Res.get();
8036 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8037 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8038 if (Res.isInvalid())
8039 return StmtError();
8040 Builder.ReturnStmtOnAllocFailure = Res.get();
8043 // Transform any additional statements we may have already built
8044 assert(S->getAllocate() && S->getDeallocate() &&
8045 "allocation and deallocation calls must already be built");
8046 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8047 if (AllocRes.isInvalid())
8048 return StmtError();
8049 Builder.Allocate = AllocRes.get();
8051 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8052 if (DeallocRes.isInvalid())
8053 return StmtError();
8054 Builder.Deallocate = DeallocRes.get();
8056 if (auto *ReturnStmt = S->getReturnStmt()) {
8057 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8058 if (Res.isInvalid())
8059 return StmtError();
8060 Builder.ReturnStmt = Res.get();
8064 return getDerived().RebuildCoroutineBodyStmt(Builder);
8067 template<typename Derived>
8068 StmtResult
8069 TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8070 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8071 /*NotCopyInit*/false);
8072 if (Result.isInvalid())
8073 return StmtError();
8075 // Always rebuild; we don't know if this needs to be injected into a new
8076 // context or if the promise type has changed.
8077 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8078 S->isImplicit());
8081 template <typename Derived>
8082 ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8083 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8084 /*NotCopyInit*/ false);
8085 if (Operand.isInvalid())
8086 return ExprError();
8088 // Rebuild the common-expr from the operand rather than transforming it
8089 // separately.
8091 // FIXME: getCurScope() should not be used during template instantiation.
8092 // We should pick up the set of unqualified lookup results for operator
8093 // co_await during the initial parse.
8094 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8095 getSema().getCurScope(), E->getKeywordLoc());
8097 // Always rebuild; we don't know if this needs to be injected into a new
8098 // context or if the promise type has changed.
8099 return getDerived().RebuildCoawaitExpr(
8100 E->getKeywordLoc(), Operand.get(),
8101 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());
8104 template <typename Derived>
8105 ExprResult
8106 TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8107 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8108 /*NotCopyInit*/ false);
8109 if (OperandResult.isInvalid())
8110 return ExprError();
8112 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8113 E->getOperatorCoawaitLookup());
8115 if (LookupResult.isInvalid())
8116 return ExprError();
8118 // Always rebuild; we don't know if this needs to be injected into a new
8119 // context or if the promise type has changed.
8120 return getDerived().RebuildDependentCoawaitExpr(
8121 E->getKeywordLoc(), OperandResult.get(),
8122 cast<UnresolvedLookupExpr>(LookupResult.get()));
8125 template<typename Derived>
8126 ExprResult
8127 TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8128 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8129 /*NotCopyInit*/false);
8130 if (Result.isInvalid())
8131 return ExprError();
8133 // Always rebuild; we don't know if this needs to be injected into a new
8134 // context or if the promise type has changed.
8135 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8138 // Objective-C Statements.
8140 template<typename Derived>
8141 StmtResult
8142 TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8143 // Transform the body of the @try.
8144 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8145 if (TryBody.isInvalid())
8146 return StmtError();
8148 // Transform the @catch statements (if present).
8149 bool AnyCatchChanged = false;
8150 SmallVector<Stmt*, 8> CatchStmts;
8151 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8152 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8153 if (Catch.isInvalid())
8154 return StmtError();
8155 if (Catch.get() != S->getCatchStmt(I))
8156 AnyCatchChanged = true;
8157 CatchStmts.push_back(Catch.get());
8160 // Transform the @finally statement (if present).
8161 StmtResult Finally;
8162 if (S->getFinallyStmt()) {
8163 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8164 if (Finally.isInvalid())
8165 return StmtError();
8168 // If nothing changed, just retain this statement.
8169 if (!getDerived().AlwaysRebuild() &&
8170 TryBody.get() == S->getTryBody() &&
8171 !AnyCatchChanged &&
8172 Finally.get() == S->getFinallyStmt())
8173 return S;
8175 // Build a new statement.
8176 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8177 CatchStmts, Finally.get());
8180 template<typename Derived>
8181 StmtResult
8182 TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8183 // Transform the @catch parameter, if there is one.
8184 VarDecl *Var = nullptr;
8185 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8186 TypeSourceInfo *TSInfo = nullptr;
8187 if (FromVar->getTypeSourceInfo()) {
8188 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8189 if (!TSInfo)
8190 return StmtError();
8193 QualType T;
8194 if (TSInfo)
8195 T = TSInfo->getType();
8196 else {
8197 T = getDerived().TransformType(FromVar->getType());
8198 if (T.isNull())
8199 return StmtError();
8202 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8203 if (!Var)
8204 return StmtError();
8207 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8208 if (Body.isInvalid())
8209 return StmtError();
8211 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
8212 S->getRParenLoc(),
8213 Var, Body.get());
8216 template<typename Derived>
8217 StmtResult
8218 TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
8219 // Transform the body.
8220 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
8221 if (Body.isInvalid())
8222 return StmtError();
8224 // If nothing changed, just retain this statement.
8225 if (!getDerived().AlwaysRebuild() &&
8226 Body.get() == S->getFinallyBody())
8227 return S;
8229 // Build a new statement.
8230 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
8231 Body.get());
8234 template<typename Derived>
8235 StmtResult
8236 TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
8237 ExprResult Operand;
8238 if (S->getThrowExpr()) {
8239 Operand = getDerived().TransformExpr(S->getThrowExpr());
8240 if (Operand.isInvalid())
8241 return StmtError();
8244 if (!getDerived().AlwaysRebuild() &&
8245 Operand.get() == S->getThrowExpr())
8246 return S;
8248 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
8251 template<typename Derived>
8252 StmtResult
8253 TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
8254 ObjCAtSynchronizedStmt *S) {
8255 // Transform the object we are locking.
8256 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
8257 if (Object.isInvalid())
8258 return StmtError();
8259 Object =
8260 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
8261 Object.get());
8262 if (Object.isInvalid())
8263 return StmtError();
8265 // Transform the body.
8266 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
8267 if (Body.isInvalid())
8268 return StmtError();
8270 // If nothing change, just retain the current statement.
8271 if (!getDerived().AlwaysRebuild() &&
8272 Object.get() == S->getSynchExpr() &&
8273 Body.get() == S->getSynchBody())
8274 return S;
8276 // Build a new statement.
8277 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
8278 Object.get(), Body.get());
8281 template<typename Derived>
8282 StmtResult
8283 TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
8284 ObjCAutoreleasePoolStmt *S) {
8285 // Transform the body.
8286 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
8287 if (Body.isInvalid())
8288 return StmtError();
8290 // If nothing changed, just retain this statement.
8291 if (!getDerived().AlwaysRebuild() &&
8292 Body.get() == S->getSubStmt())
8293 return S;
8295 // Build a new statement.
8296 return getDerived().RebuildObjCAutoreleasePoolStmt(
8297 S->getAtLoc(), Body.get());
8300 template<typename Derived>
8301 StmtResult
8302 TreeTransform<Derived>::TransformObjCForCollectionStmt(
8303 ObjCForCollectionStmt *S) {
8304 // Transform the element statement.
8305 StmtResult Element =
8306 getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded);
8307 if (Element.isInvalid())
8308 return StmtError();
8310 // Transform the collection expression.
8311 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
8312 if (Collection.isInvalid())
8313 return StmtError();
8315 // Transform the body.
8316 StmtResult Body = getDerived().TransformStmt(S->getBody());
8317 if (Body.isInvalid())
8318 return StmtError();
8320 // If nothing changed, just retain this statement.
8321 if (!getDerived().AlwaysRebuild() &&
8322 Element.get() == S->getElement() &&
8323 Collection.get() == S->getCollection() &&
8324 Body.get() == S->getBody())
8325 return S;
8327 // Build a new statement.
8328 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
8329 Element.get(),
8330 Collection.get(),
8331 S->getRParenLoc(),
8332 Body.get());
8335 template <typename Derived>
8336 StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
8337 // Transform the exception declaration, if any.
8338 VarDecl *Var = nullptr;
8339 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
8340 TypeSourceInfo *T =
8341 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
8342 if (!T)
8343 return StmtError();
8345 Var = getDerived().RebuildExceptionDecl(
8346 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
8347 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
8348 if (!Var || Var->isInvalidDecl())
8349 return StmtError();
8352 // Transform the actual exception handler.
8353 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
8354 if (Handler.isInvalid())
8355 return StmtError();
8357 if (!getDerived().AlwaysRebuild() && !Var &&
8358 Handler.get() == S->getHandlerBlock())
8359 return S;
8361 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
8364 template <typename Derived>
8365 StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
8366 // Transform the try block itself.
8367 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8368 if (TryBlock.isInvalid())
8369 return StmtError();
8371 // Transform the handlers.
8372 bool HandlerChanged = false;
8373 SmallVector<Stmt *, 8> Handlers;
8374 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
8375 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I));
8376 if (Handler.isInvalid())
8377 return StmtError();
8379 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
8380 Handlers.push_back(Handler.getAs<Stmt>());
8383 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8384 !HandlerChanged)
8385 return S;
8387 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
8388 Handlers);
8391 template<typename Derived>
8392 StmtResult
8393 TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
8394 StmtResult Init =
8395 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
8396 if (Init.isInvalid())
8397 return StmtError();
8399 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
8400 if (Range.isInvalid())
8401 return StmtError();
8403 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
8404 if (Begin.isInvalid())
8405 return StmtError();
8406 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
8407 if (End.isInvalid())
8408 return StmtError();
8410 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8411 if (Cond.isInvalid())
8412 return StmtError();
8413 if (Cond.get())
8414 Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());
8415 if (Cond.isInvalid())
8416 return StmtError();
8417 if (Cond.get())
8418 Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());
8420 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8421 if (Inc.isInvalid())
8422 return StmtError();
8423 if (Inc.get())
8424 Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());
8426 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
8427 if (LoopVar.isInvalid())
8428 return StmtError();
8430 StmtResult NewStmt = S;
8431 if (getDerived().AlwaysRebuild() ||
8432 Init.get() != S->getInit() ||
8433 Range.get() != S->getRangeStmt() ||
8434 Begin.get() != S->getBeginStmt() ||
8435 End.get() != S->getEndStmt() ||
8436 Cond.get() != S->getCond() ||
8437 Inc.get() != S->getInc() ||
8438 LoopVar.get() != S->getLoopVarStmt()) {
8439 NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
8440 S->getCoawaitLoc(), Init.get(),
8441 S->getColonLoc(), Range.get(),
8442 Begin.get(), End.get(),
8443 Cond.get(),
8444 Inc.get(), LoopVar.get(),
8445 S->getRParenLoc());
8446 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
8447 // Might not have attached any initializer to the loop variable.
8448 getSema().ActOnInitializerError(
8449 cast<DeclStmt>(LoopVar.get())->getSingleDecl());
8450 return StmtError();
8454 StmtResult Body = getDerived().TransformStmt(S->getBody());
8455 if (Body.isInvalid())
8456 return StmtError();
8458 // Body has changed but we didn't rebuild the for-range statement. Rebuild
8459 // it now so we have a new statement to attach the body to.
8460 if (Body.get() != S->getBody() && NewStmt.get() == S) {
8461 NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
8462 S->getCoawaitLoc(), Init.get(),
8463 S->getColonLoc(), Range.get(),
8464 Begin.get(), End.get(),
8465 Cond.get(),
8466 Inc.get(), LoopVar.get(),
8467 S->getRParenLoc());
8468 if (NewStmt.isInvalid())
8469 return StmtError();
8472 if (NewStmt.get() == S)
8473 return S;
8475 return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
8478 template<typename Derived>
8479 StmtResult
8480 TreeTransform<Derived>::TransformMSDependentExistsStmt(
8481 MSDependentExistsStmt *S) {
8482 // Transform the nested-name-specifier, if any.
8483 NestedNameSpecifierLoc QualifierLoc;
8484 if (S->getQualifierLoc()) {
8485 QualifierLoc
8486 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
8487 if (!QualifierLoc)
8488 return StmtError();
8491 // Transform the declaration name.
8492 DeclarationNameInfo NameInfo = S->getNameInfo();
8493 if (NameInfo.getName()) {
8494 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
8495 if (!NameInfo.getName())
8496 return StmtError();
8499 // Check whether anything changed.
8500 if (!getDerived().AlwaysRebuild() &&
8501 QualifierLoc == S->getQualifierLoc() &&
8502 NameInfo.getName() == S->getNameInfo().getName())
8503 return S;
8505 // Determine whether this name exists, if we can.
8506 CXXScopeSpec SS;
8507 SS.Adopt(QualifierLoc);
8508 bool Dependent = false;
8509 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
8510 case Sema::IER_Exists:
8511 if (S->isIfExists())
8512 break;
8514 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8516 case Sema::IER_DoesNotExist:
8517 if (S->isIfNotExists())
8518 break;
8520 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8522 case Sema::IER_Dependent:
8523 Dependent = true;
8524 break;
8526 case Sema::IER_Error:
8527 return StmtError();
8530 // We need to continue with the instantiation, so do so now.
8531 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
8532 if (SubStmt.isInvalid())
8533 return StmtError();
8535 // If we have resolved the name, just transform to the substatement.
8536 if (!Dependent)
8537 return SubStmt;
8539 // The name is still dependent, so build a dependent expression again.
8540 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
8541 S->isIfExists(),
8542 QualifierLoc,
8543 NameInfo,
8544 SubStmt.get());
8547 template<typename Derived>
8548 ExprResult
8549 TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
8550 NestedNameSpecifierLoc QualifierLoc;
8551 if (E->getQualifierLoc()) {
8552 QualifierLoc
8553 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
8554 if (!QualifierLoc)
8555 return ExprError();
8558 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
8559 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
8560 if (!PD)
8561 return ExprError();
8563 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
8564 if (Base.isInvalid())
8565 return ExprError();
8567 return new (SemaRef.getASTContext())
8568 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
8569 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
8570 QualifierLoc, E->getMemberLoc());
8573 template <typename Derived>
8574 ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
8575 MSPropertySubscriptExpr *E) {
8576 auto BaseRes = getDerived().TransformExpr(E->getBase());
8577 if (BaseRes.isInvalid())
8578 return ExprError();
8579 auto IdxRes = getDerived().TransformExpr(E->getIdx());
8580 if (IdxRes.isInvalid())
8581 return ExprError();
8583 if (!getDerived().AlwaysRebuild() &&
8584 BaseRes.get() == E->getBase() &&
8585 IdxRes.get() == E->getIdx())
8586 return E;
8588 return getDerived().RebuildArraySubscriptExpr(
8589 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
8592 template <typename Derived>
8593 StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
8594 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8595 if (TryBlock.isInvalid())
8596 return StmtError();
8598 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
8599 if (Handler.isInvalid())
8600 return StmtError();
8602 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8603 Handler.get() == S->getHandler())
8604 return S;
8606 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
8607 TryBlock.get(), Handler.get());
8610 template <typename Derived>
8611 StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
8612 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
8613 if (Block.isInvalid())
8614 return StmtError();
8616 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
8619 template <typename Derived>
8620 StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
8621 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
8622 if (FilterExpr.isInvalid())
8623 return StmtError();
8625 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
8626 if (Block.isInvalid())
8627 return StmtError();
8629 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
8630 Block.get());
8633 template <typename Derived>
8634 StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
8635 if (isa<SEHFinallyStmt>(Handler))
8636 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
8637 else
8638 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
8641 template<typename Derived>
8642 StmtResult
8643 TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
8644 return S;
8647 //===----------------------------------------------------------------------===//
8648 // OpenMP directive transformation
8649 //===----------------------------------------------------------------------===//
8651 template <typename Derived>
8652 StmtResult
8653 TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
8654 // OMPCanonicalLoops are eliminated during transformation, since they will be
8655 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
8656 // after transformation.
8657 return getDerived().TransformStmt(L->getLoopStmt());
8660 template <typename Derived>
8661 StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
8662 OMPExecutableDirective *D) {
8664 // Transform the clauses
8665 llvm::SmallVector<OMPClause *, 16> TClauses;
8666 ArrayRef<OMPClause *> Clauses = D->clauses();
8667 TClauses.reserve(Clauses.size());
8668 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
8669 I != E; ++I) {
8670 if (*I) {
8671 getDerived().getSema().StartOpenMPClause((*I)->getClauseKind());
8672 OMPClause *Clause = getDerived().TransformOMPClause(*I);
8673 getDerived().getSema().EndOpenMPClause();
8674 if (Clause)
8675 TClauses.push_back(Clause);
8676 } else {
8677 TClauses.push_back(nullptr);
8680 StmtResult AssociatedStmt;
8681 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
8682 getDerived().getSema().ActOnOpenMPRegionStart(D->getDirectiveKind(),
8683 /*CurScope=*/nullptr);
8684 StmtResult Body;
8686 Sema::CompoundScopeRAII CompoundScope(getSema());
8687 Stmt *CS;
8688 if (D->getDirectiveKind() == OMPD_atomic ||
8689 D->getDirectiveKind() == OMPD_critical ||
8690 D->getDirectiveKind() == OMPD_section ||
8691 D->getDirectiveKind() == OMPD_master)
8692 CS = D->getAssociatedStmt();
8693 else
8694 CS = D->getRawStmt();
8695 Body = getDerived().TransformStmt(CS);
8696 if (Body.isUsable() && isOpenMPLoopDirective(D->getDirectiveKind()) &&
8697 getSema().getLangOpts().OpenMPIRBuilder)
8698 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
8700 AssociatedStmt =
8701 getDerived().getSema().ActOnOpenMPRegionEnd(Body, TClauses);
8702 if (AssociatedStmt.isInvalid()) {
8703 return StmtError();
8706 if (TClauses.size() != Clauses.size()) {
8707 return StmtError();
8710 // Transform directive name for 'omp critical' directive.
8711 DeclarationNameInfo DirName;
8712 if (D->getDirectiveKind() == OMPD_critical) {
8713 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
8714 DirName = getDerived().TransformDeclarationNameInfo(DirName);
8716 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
8717 if (D->getDirectiveKind() == OMPD_cancellation_point) {
8718 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();
8719 } else if (D->getDirectiveKind() == OMPD_cancel) {
8720 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();
8723 return getDerived().RebuildOMPExecutableDirective(
8724 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
8725 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
8728 template <typename Derived>
8729 StmtResult
8730 TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
8731 // TODO: Fix This
8732 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)
8733 << getOpenMPDirectiveName(D->getDirectiveKind());
8734 return StmtError();
8737 template <typename Derived>
8738 StmtResult
8739 TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
8740 DeclarationNameInfo DirName;
8741 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr,
8742 D->getBeginLoc());
8743 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8744 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8745 return Res;
8748 template <typename Derived>
8749 StmtResult
8750 TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
8751 DeclarationNameInfo DirName;
8752 getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr,
8753 D->getBeginLoc());
8754 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8755 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8756 return Res;
8759 template <typename Derived>
8760 StmtResult
8761 TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
8762 DeclarationNameInfo DirName;
8763 getDerived().getSema().StartOpenMPDSABlock(D->getDirectiveKind(), DirName,
8764 nullptr, D->getBeginLoc());
8765 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8766 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8767 return Res;
8770 template <typename Derived>
8771 StmtResult
8772 TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
8773 DeclarationNameInfo DirName;
8774 getDerived().getSema().StartOpenMPDSABlock(D->getDirectiveKind(), DirName,
8775 nullptr, D->getBeginLoc());
8776 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8777 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8778 return Res;
8781 template <typename Derived>
8782 StmtResult
8783 TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
8784 DeclarationNameInfo DirName;
8785 getDerived().getSema().StartOpenMPDSABlock(OMPD_for, DirName, nullptr,
8786 D->getBeginLoc());
8787 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8788 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8789 return Res;
8792 template <typename Derived>
8793 StmtResult
8794 TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
8795 DeclarationNameInfo DirName;
8796 getDerived().getSema().StartOpenMPDSABlock(OMPD_for_simd, DirName, nullptr,
8797 D->getBeginLoc());
8798 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8799 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8800 return Res;
8803 template <typename Derived>
8804 StmtResult
8805 TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
8806 DeclarationNameInfo DirName;
8807 getDerived().getSema().StartOpenMPDSABlock(OMPD_sections, DirName, nullptr,
8808 D->getBeginLoc());
8809 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8810 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8811 return Res;
8814 template <typename Derived>
8815 StmtResult
8816 TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
8817 DeclarationNameInfo DirName;
8818 getDerived().getSema().StartOpenMPDSABlock(OMPD_section, DirName, nullptr,
8819 D->getBeginLoc());
8820 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8821 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8822 return Res;
8825 template <typename Derived>
8826 StmtResult
8827 TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
8828 DeclarationNameInfo DirName;
8829 getDerived().getSema().StartOpenMPDSABlock(OMPD_single, DirName, nullptr,
8830 D->getBeginLoc());
8831 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8832 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8833 return Res;
8836 template <typename Derived>
8837 StmtResult
8838 TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
8839 DeclarationNameInfo DirName;
8840 getDerived().getSema().StartOpenMPDSABlock(OMPD_master, DirName, nullptr,
8841 D->getBeginLoc());
8842 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8843 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8844 return Res;
8847 template <typename Derived>
8848 StmtResult
8849 TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
8850 getDerived().getSema().StartOpenMPDSABlock(
8851 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
8852 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8853 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8854 return Res;
8857 template <typename Derived>
8858 StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
8859 OMPParallelForDirective *D) {
8860 DeclarationNameInfo DirName;
8861 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for, DirName,
8862 nullptr, D->getBeginLoc());
8863 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8864 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8865 return Res;
8868 template <typename Derived>
8869 StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
8870 OMPParallelForSimdDirective *D) {
8871 DeclarationNameInfo DirName;
8872 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for_simd, DirName,
8873 nullptr, D->getBeginLoc());
8874 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8875 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8876 return Res;
8879 template <typename Derived>
8880 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
8881 OMPParallelMasterDirective *D) {
8882 DeclarationNameInfo DirName;
8883 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_master, DirName,
8884 nullptr, D->getBeginLoc());
8885 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8886 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8887 return Res;
8890 template <typename Derived>
8891 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
8892 OMPParallelMaskedDirective *D) {
8893 DeclarationNameInfo DirName;
8894 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_masked, DirName,
8895 nullptr, D->getBeginLoc());
8896 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8897 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8898 return Res;
8901 template <typename Derived>
8902 StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
8903 OMPParallelSectionsDirective *D) {
8904 DeclarationNameInfo DirName;
8905 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_sections, DirName,
8906 nullptr, D->getBeginLoc());
8907 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8908 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8909 return Res;
8912 template <typename Derived>
8913 StmtResult
8914 TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
8915 DeclarationNameInfo DirName;
8916 getDerived().getSema().StartOpenMPDSABlock(OMPD_task, DirName, nullptr,
8917 D->getBeginLoc());
8918 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8919 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8920 return Res;
8923 template <typename Derived>
8924 StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
8925 OMPTaskyieldDirective *D) {
8926 DeclarationNameInfo DirName;
8927 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskyield, DirName, nullptr,
8928 D->getBeginLoc());
8929 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8930 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8931 return Res;
8934 template <typename Derived>
8935 StmtResult
8936 TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
8937 DeclarationNameInfo DirName;
8938 getDerived().getSema().StartOpenMPDSABlock(OMPD_barrier, DirName, nullptr,
8939 D->getBeginLoc());
8940 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8941 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8942 return Res;
8945 template <typename Derived>
8946 StmtResult
8947 TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
8948 DeclarationNameInfo DirName;
8949 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskwait, DirName, nullptr,
8950 D->getBeginLoc());
8951 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8952 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8953 return Res;
8956 template <typename Derived>
8957 StmtResult
8958 TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
8959 DeclarationNameInfo DirName;
8960 getDerived().getSema().StartOpenMPDSABlock(OMPD_error, DirName, nullptr,
8961 D->getBeginLoc());
8962 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8963 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8964 return Res;
8967 template <typename Derived>
8968 StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
8969 OMPTaskgroupDirective *D) {
8970 DeclarationNameInfo DirName;
8971 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskgroup, DirName, nullptr,
8972 D->getBeginLoc());
8973 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8974 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8975 return Res;
8978 template <typename Derived>
8979 StmtResult
8980 TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
8981 DeclarationNameInfo DirName;
8982 getDerived().getSema().StartOpenMPDSABlock(OMPD_flush, DirName, nullptr,
8983 D->getBeginLoc());
8984 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8985 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8986 return Res;
8989 template <typename Derived>
8990 StmtResult
8991 TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
8992 DeclarationNameInfo DirName;
8993 getDerived().getSema().StartOpenMPDSABlock(OMPD_depobj, DirName, nullptr,
8994 D->getBeginLoc());
8995 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
8996 getDerived().getSema().EndOpenMPDSABlock(Res.get());
8997 return Res;
9000 template <typename Derived>
9001 StmtResult
9002 TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9003 DeclarationNameInfo DirName;
9004 getDerived().getSema().StartOpenMPDSABlock(OMPD_scan, DirName, nullptr,
9005 D->getBeginLoc());
9006 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9007 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9008 return Res;
9011 template <typename Derived>
9012 StmtResult
9013 TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9014 DeclarationNameInfo DirName;
9015 getDerived().getSema().StartOpenMPDSABlock(OMPD_ordered, DirName, nullptr,
9016 D->getBeginLoc());
9017 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9018 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9019 return Res;
9022 template <typename Derived>
9023 StmtResult
9024 TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9025 DeclarationNameInfo DirName;
9026 getDerived().getSema().StartOpenMPDSABlock(OMPD_atomic, DirName, nullptr,
9027 D->getBeginLoc());
9028 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9029 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9030 return Res;
9033 template <typename Derived>
9034 StmtResult
9035 TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9036 DeclarationNameInfo DirName;
9037 getDerived().getSema().StartOpenMPDSABlock(OMPD_target, DirName, nullptr,
9038 D->getBeginLoc());
9039 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9040 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9041 return Res;
9044 template <typename Derived>
9045 StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9046 OMPTargetDataDirective *D) {
9047 DeclarationNameInfo DirName;
9048 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_data, DirName, nullptr,
9049 D->getBeginLoc());
9050 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9051 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9052 return Res;
9055 template <typename Derived>
9056 StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9057 OMPTargetEnterDataDirective *D) {
9058 DeclarationNameInfo DirName;
9059 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_enter_data, DirName,
9060 nullptr, D->getBeginLoc());
9061 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9062 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9063 return Res;
9066 template <typename Derived>
9067 StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9068 OMPTargetExitDataDirective *D) {
9069 DeclarationNameInfo DirName;
9070 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_exit_data, DirName,
9071 nullptr, D->getBeginLoc());
9072 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9073 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9074 return Res;
9077 template <typename Derived>
9078 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
9079 OMPTargetParallelDirective *D) {
9080 DeclarationNameInfo DirName;
9081 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel, DirName,
9082 nullptr, D->getBeginLoc());
9083 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9084 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9085 return Res;
9088 template <typename Derived>
9089 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
9090 OMPTargetParallelForDirective *D) {
9091 DeclarationNameInfo DirName;
9092 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_for, DirName,
9093 nullptr, D->getBeginLoc());
9094 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9095 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9096 return Res;
9099 template <typename Derived>
9100 StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
9101 OMPTargetUpdateDirective *D) {
9102 DeclarationNameInfo DirName;
9103 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_update, DirName,
9104 nullptr, D->getBeginLoc());
9105 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9106 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9107 return Res;
9110 template <typename Derived>
9111 StmtResult
9112 TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
9113 DeclarationNameInfo DirName;
9114 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams, DirName, nullptr,
9115 D->getBeginLoc());
9116 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9117 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9118 return Res;
9121 template <typename Derived>
9122 StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
9123 OMPCancellationPointDirective *D) {
9124 DeclarationNameInfo DirName;
9125 getDerived().getSema().StartOpenMPDSABlock(OMPD_cancellation_point, DirName,
9126 nullptr, D->getBeginLoc());
9127 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9128 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9129 return Res;
9132 template <typename Derived>
9133 StmtResult
9134 TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
9135 DeclarationNameInfo DirName;
9136 getDerived().getSema().StartOpenMPDSABlock(OMPD_cancel, DirName, nullptr,
9137 D->getBeginLoc());
9138 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9139 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9140 return Res;
9143 template <typename Derived>
9144 StmtResult
9145 TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
9146 DeclarationNameInfo DirName;
9147 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop, DirName, nullptr,
9148 D->getBeginLoc());
9149 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9150 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9151 return Res;
9154 template <typename Derived>
9155 StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
9156 OMPTaskLoopSimdDirective *D) {
9157 DeclarationNameInfo DirName;
9158 getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop_simd, DirName,
9159 nullptr, D->getBeginLoc());
9160 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9161 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9162 return Res;
9165 template <typename Derived>
9166 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
9167 OMPMasterTaskLoopDirective *D) {
9168 DeclarationNameInfo DirName;
9169 getDerived().getSema().StartOpenMPDSABlock(OMPD_master_taskloop, DirName,
9170 nullptr, D->getBeginLoc());
9171 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9172 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9173 return Res;
9176 template <typename Derived>
9177 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
9178 OMPMaskedTaskLoopDirective *D) {
9179 DeclarationNameInfo DirName;
9180 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked_taskloop, DirName,
9181 nullptr, D->getBeginLoc());
9182 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9183 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9184 return Res;
9187 template <typename Derived>
9188 StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
9189 OMPMasterTaskLoopSimdDirective *D) {
9190 DeclarationNameInfo DirName;
9191 getDerived().getSema().StartOpenMPDSABlock(OMPD_master_taskloop_simd, DirName,
9192 nullptr, D->getBeginLoc());
9193 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9194 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9195 return Res;
9198 template <typename Derived>
9199 StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
9200 OMPMaskedTaskLoopSimdDirective *D) {
9201 DeclarationNameInfo DirName;
9202 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked_taskloop_simd, DirName,
9203 nullptr, D->getBeginLoc());
9204 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9205 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9206 return Res;
9209 template <typename Derived>
9210 StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
9211 OMPParallelMasterTaskLoopDirective *D) {
9212 DeclarationNameInfo DirName;
9213 getDerived().getSema().StartOpenMPDSABlock(
9214 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
9215 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9216 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9217 return Res;
9220 template <typename Derived>
9221 StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
9222 OMPParallelMaskedTaskLoopDirective *D) {
9223 DeclarationNameInfo DirName;
9224 getDerived().getSema().StartOpenMPDSABlock(
9225 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9226 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9227 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9228 return Res;
9231 template <typename Derived>
9232 StmtResult
9233 TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
9234 OMPParallelMasterTaskLoopSimdDirective *D) {
9235 DeclarationNameInfo DirName;
9236 getDerived().getSema().StartOpenMPDSABlock(
9237 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9238 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9239 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9240 return Res;
9243 template <typename Derived>
9244 StmtResult
9245 TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
9246 OMPParallelMaskedTaskLoopSimdDirective *D) {
9247 DeclarationNameInfo DirName;
9248 getDerived().getSema().StartOpenMPDSABlock(
9249 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9250 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9251 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9252 return Res;
9255 template <typename Derived>
9256 StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
9257 OMPDistributeDirective *D) {
9258 DeclarationNameInfo DirName;
9259 getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute, DirName, nullptr,
9260 D->getBeginLoc());
9261 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9262 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9263 return Res;
9266 template <typename Derived>
9267 StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
9268 OMPDistributeParallelForDirective *D) {
9269 DeclarationNameInfo DirName;
9270 getDerived().getSema().StartOpenMPDSABlock(
9271 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9272 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9273 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9274 return Res;
9277 template <typename Derived>
9278 StmtResult
9279 TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
9280 OMPDistributeParallelForSimdDirective *D) {
9281 DeclarationNameInfo DirName;
9282 getDerived().getSema().StartOpenMPDSABlock(
9283 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9284 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9285 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9286 return Res;
9289 template <typename Derived>
9290 StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
9291 OMPDistributeSimdDirective *D) {
9292 DeclarationNameInfo DirName;
9293 getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute_simd, DirName,
9294 nullptr, D->getBeginLoc());
9295 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9296 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9297 return Res;
9300 template <typename Derived>
9301 StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
9302 OMPTargetParallelForSimdDirective *D) {
9303 DeclarationNameInfo DirName;
9304 getDerived().getSema().StartOpenMPDSABlock(
9305 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9306 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9307 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9308 return Res;
9311 template <typename Derived>
9312 StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
9313 OMPTargetSimdDirective *D) {
9314 DeclarationNameInfo DirName;
9315 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_simd, DirName, nullptr,
9316 D->getBeginLoc());
9317 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9318 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9319 return Res;
9322 template <typename Derived>
9323 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
9324 OMPTeamsDistributeDirective *D) {
9325 DeclarationNameInfo DirName;
9326 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams_distribute, DirName,
9327 nullptr, D->getBeginLoc());
9328 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9329 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9330 return Res;
9333 template <typename Derived>
9334 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
9335 OMPTeamsDistributeSimdDirective *D) {
9336 DeclarationNameInfo DirName;
9337 getDerived().getSema().StartOpenMPDSABlock(
9338 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9339 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9340 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9341 return Res;
9344 template <typename Derived>
9345 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
9346 OMPTeamsDistributeParallelForSimdDirective *D) {
9347 DeclarationNameInfo DirName;
9348 getDerived().getSema().StartOpenMPDSABlock(
9349 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
9350 D->getBeginLoc());
9351 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9352 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9353 return Res;
9356 template <typename Derived>
9357 StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
9358 OMPTeamsDistributeParallelForDirective *D) {
9359 DeclarationNameInfo DirName;
9360 getDerived().getSema().StartOpenMPDSABlock(
9361 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9362 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9363 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9364 return Res;
9367 template <typename Derived>
9368 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
9369 OMPTargetTeamsDirective *D) {
9370 DeclarationNameInfo DirName;
9371 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams, DirName,
9372 nullptr, D->getBeginLoc());
9373 auto Res = getDerived().TransformOMPExecutableDirective(D);
9374 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9375 return Res;
9378 template <typename Derived>
9379 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
9380 OMPTargetTeamsDistributeDirective *D) {
9381 DeclarationNameInfo DirName;
9382 getDerived().getSema().StartOpenMPDSABlock(
9383 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
9384 auto Res = getDerived().TransformOMPExecutableDirective(D);
9385 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9386 return Res;
9389 template <typename Derived>
9390 StmtResult
9391 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
9392 OMPTargetTeamsDistributeParallelForDirective *D) {
9393 DeclarationNameInfo DirName;
9394 getDerived().getSema().StartOpenMPDSABlock(
9395 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
9396 D->getBeginLoc());
9397 auto Res = getDerived().TransformOMPExecutableDirective(D);
9398 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9399 return Res;
9402 template <typename Derived>
9403 StmtResult TreeTransform<Derived>::
9404 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
9405 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
9406 DeclarationNameInfo DirName;
9407 getDerived().getSema().StartOpenMPDSABlock(
9408 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
9409 D->getBeginLoc());
9410 auto Res = getDerived().TransformOMPExecutableDirective(D);
9411 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9412 return Res;
9415 template <typename Derived>
9416 StmtResult
9417 TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
9418 OMPTargetTeamsDistributeSimdDirective *D) {
9419 DeclarationNameInfo DirName;
9420 getDerived().getSema().StartOpenMPDSABlock(
9421 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9422 auto Res = getDerived().TransformOMPExecutableDirective(D);
9423 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9424 return Res;
9427 template <typename Derived>
9428 StmtResult
9429 TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
9430 DeclarationNameInfo DirName;
9431 getDerived().getSema().StartOpenMPDSABlock(OMPD_interop, DirName, nullptr,
9432 D->getBeginLoc());
9433 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9434 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9435 return Res;
9438 template <typename Derived>
9439 StmtResult
9440 TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
9441 DeclarationNameInfo DirName;
9442 getDerived().getSema().StartOpenMPDSABlock(OMPD_dispatch, DirName, nullptr,
9443 D->getBeginLoc());
9444 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9445 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9446 return Res;
9449 template <typename Derived>
9450 StmtResult
9451 TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
9452 DeclarationNameInfo DirName;
9453 getDerived().getSema().StartOpenMPDSABlock(OMPD_masked, DirName, nullptr,
9454 D->getBeginLoc());
9455 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9456 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9457 return Res;
9460 template <typename Derived>
9461 StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
9462 OMPGenericLoopDirective *D) {
9463 DeclarationNameInfo DirName;
9464 getDerived().getSema().StartOpenMPDSABlock(OMPD_loop, DirName, nullptr,
9465 D->getBeginLoc());
9466 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9467 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9468 return Res;
9471 template <typename Derived>
9472 StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
9473 OMPTeamsGenericLoopDirective *D) {
9474 DeclarationNameInfo DirName;
9475 getDerived().getSema().StartOpenMPDSABlock(OMPD_teams_loop, DirName, nullptr,
9476 D->getBeginLoc());
9477 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9478 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9479 return Res;
9482 template <typename Derived>
9483 StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
9484 OMPTargetTeamsGenericLoopDirective *D) {
9485 DeclarationNameInfo DirName;
9486 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams_loop, DirName,
9487 nullptr, D->getBeginLoc());
9488 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9489 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9490 return Res;
9493 template <typename Derived>
9494 StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
9495 OMPParallelGenericLoopDirective *D) {
9496 DeclarationNameInfo DirName;
9497 getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_loop, DirName,
9498 nullptr, D->getBeginLoc());
9499 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9500 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9501 return Res;
9504 template <typename Derived>
9505 StmtResult
9506 TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
9507 OMPTargetParallelGenericLoopDirective *D) {
9508 DeclarationNameInfo DirName;
9509 getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_loop, DirName,
9510 nullptr, D->getBeginLoc());
9511 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9512 getDerived().getSema().EndOpenMPDSABlock(Res.get());
9513 return Res;
9516 //===----------------------------------------------------------------------===//
9517 // OpenMP clause transformation
9518 //===----------------------------------------------------------------------===//
9519 template <typename Derived>
9520 OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
9521 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9522 if (Cond.isInvalid())
9523 return nullptr;
9524 return getDerived().RebuildOMPIfClause(
9525 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
9526 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
9529 template <typename Derived>
9530 OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
9531 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9532 if (Cond.isInvalid())
9533 return nullptr;
9534 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
9535 C->getLParenLoc(), C->getEndLoc());
9538 template <typename Derived>
9539 OMPClause *
9540 TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
9541 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
9542 if (NumThreads.isInvalid())
9543 return nullptr;
9544 return getDerived().RebuildOMPNumThreadsClause(
9545 NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9548 template <typename Derived>
9549 OMPClause *
9550 TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
9551 ExprResult E = getDerived().TransformExpr(C->getSafelen());
9552 if (E.isInvalid())
9553 return nullptr;
9554 return getDerived().RebuildOMPSafelenClause(
9555 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9558 template <typename Derived>
9559 OMPClause *
9560 TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
9561 ExprResult E = getDerived().TransformExpr(C->getAllocator());
9562 if (E.isInvalid())
9563 return nullptr;
9564 return getDerived().RebuildOMPAllocatorClause(
9565 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9568 template <typename Derived>
9569 OMPClause *
9570 TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
9571 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
9572 if (E.isInvalid())
9573 return nullptr;
9574 return getDerived().RebuildOMPSimdlenClause(
9575 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9578 template <typename Derived>
9579 OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
9580 SmallVector<Expr *, 4> TransformedSizes;
9581 TransformedSizes.reserve(C->getNumSizes());
9582 bool Changed = false;
9583 for (Expr *E : C->getSizesRefs()) {
9584 if (!E) {
9585 TransformedSizes.push_back(nullptr);
9586 continue;
9589 ExprResult T = getDerived().TransformExpr(E);
9590 if (T.isInvalid())
9591 return nullptr;
9592 if (E != T.get())
9593 Changed = true;
9594 TransformedSizes.push_back(T.get());
9597 if (!Changed && !getDerived().AlwaysRebuild())
9598 return C;
9599 return RebuildOMPSizesClause(TransformedSizes, C->getBeginLoc(),
9600 C->getLParenLoc(), C->getEndLoc());
9603 template <typename Derived>
9604 OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
9605 if (!getDerived().AlwaysRebuild())
9606 return C;
9607 return RebuildOMPFullClause(C->getBeginLoc(), C->getEndLoc());
9610 template <typename Derived>
9611 OMPClause *
9612 TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
9613 ExprResult T = getDerived().TransformExpr(C->getFactor());
9614 if (T.isInvalid())
9615 return nullptr;
9616 Expr *Factor = T.get();
9617 bool Changed = Factor != C->getFactor();
9619 if (!Changed && !getDerived().AlwaysRebuild())
9620 return C;
9621 return RebuildOMPPartialClause(Factor, C->getBeginLoc(), C->getLParenLoc(),
9622 C->getEndLoc());
9625 template <typename Derived>
9626 OMPClause *
9627 TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
9628 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
9629 if (E.isInvalid())
9630 return nullptr;
9631 return getDerived().RebuildOMPCollapseClause(
9632 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9635 template <typename Derived>
9636 OMPClause *
9637 TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
9638 return getDerived().RebuildOMPDefaultClause(
9639 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
9640 C->getLParenLoc(), C->getEndLoc());
9643 template <typename Derived>
9644 OMPClause *
9645 TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
9646 return getDerived().RebuildOMPProcBindClause(
9647 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
9648 C->getLParenLoc(), C->getEndLoc());
9651 template <typename Derived>
9652 OMPClause *
9653 TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
9654 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
9655 if (E.isInvalid())
9656 return nullptr;
9657 return getDerived().RebuildOMPScheduleClause(
9658 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
9659 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
9660 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
9661 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
9664 template <typename Derived>
9665 OMPClause *
9666 TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
9667 ExprResult E;
9668 if (auto *Num = C->getNumForLoops()) {
9669 E = getDerived().TransformExpr(Num);
9670 if (E.isInvalid())
9671 return nullptr;
9673 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
9674 C->getLParenLoc(), E.get());
9677 template <typename Derived>
9678 OMPClause *
9679 TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
9680 ExprResult E;
9681 if (Expr *Evt = C->getEventHandler()) {
9682 E = getDerived().TransformExpr(Evt);
9683 if (E.isInvalid())
9684 return nullptr;
9686 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
9687 C->getLParenLoc(), C->getEndLoc());
9690 template <typename Derived>
9691 OMPClause *
9692 TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
9693 // No need to rebuild this clause, no template-dependent parameters.
9694 return C;
9697 template <typename Derived>
9698 OMPClause *
9699 TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
9700 // No need to rebuild this clause, no template-dependent parameters.
9701 return C;
9704 template <typename Derived>
9705 OMPClause *
9706 TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
9707 // No need to rebuild this clause, no template-dependent parameters.
9708 return C;
9711 template <typename Derived>
9712 OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
9713 // No need to rebuild this clause, no template-dependent parameters.
9714 return C;
9717 template <typename Derived>
9718 OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
9719 // No need to rebuild this clause, no template-dependent parameters.
9720 return C;
9723 template <typename Derived>
9724 OMPClause *
9725 TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
9726 // No need to rebuild this clause, no template-dependent parameters.
9727 return C;
9730 template <typename Derived>
9731 OMPClause *
9732 TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
9733 // No need to rebuild this clause, no template-dependent parameters.
9734 return C;
9737 template <typename Derived>
9738 OMPClause *
9739 TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
9740 // No need to rebuild this clause, no template-dependent parameters.
9741 return C;
9744 template <typename Derived>
9745 OMPClause *
9746 TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
9747 // No need to rebuild this clause, no template-dependent parameters.
9748 return C;
9751 template <typename Derived>
9752 OMPClause *
9753 TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
9754 // No need to rebuild this clause, no template-dependent parameters.
9755 return C;
9758 template <typename Derived>
9759 OMPClause *
9760 TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
9761 // No need to rebuild this clause, no template-dependent parameters.
9762 return C;
9765 template <typename Derived>
9766 OMPClause *
9767 TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
9768 // No need to rebuild this clause, no template-dependent parameters.
9769 return C;
9772 template <typename Derived>
9773 OMPClause *
9774 TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
9775 // No need to rebuild this clause, no template-dependent parameters.
9776 return C;
9779 template <typename Derived>
9780 OMPClause *
9781 TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
9782 // No need to rebuild this clause, no template-dependent parameters.
9783 return C;
9786 template <typename Derived>
9787 OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
9788 // No need to rebuild this clause, no template-dependent parameters.
9789 return C;
9792 template <typename Derived>
9793 OMPClause *
9794 TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
9795 // No need to rebuild this clause, no template-dependent parameters.
9796 return C;
9799 template <typename Derived>
9800 OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
9801 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
9802 if (IVR.isInvalid())
9803 return nullptr;
9805 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
9806 InteropInfo.PreferTypes.reserve(C->varlist_size() - 1);
9807 for (Expr *E : llvm::drop_begin(C->varlists())) {
9808 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
9809 if (ER.isInvalid())
9810 return nullptr;
9811 InteropInfo.PreferTypes.push_back(ER.get());
9813 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
9814 C->getBeginLoc(), C->getLParenLoc(),
9815 C->getVarLoc(), C->getEndLoc());
9818 template <typename Derived>
9819 OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
9820 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
9821 if (ER.isInvalid())
9822 return nullptr;
9823 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
9824 C->getLParenLoc(), C->getVarLoc(),
9825 C->getEndLoc());
9828 template <typename Derived>
9829 OMPClause *
9830 TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
9831 ExprResult ER;
9832 if (Expr *IV = C->getInteropVar()) {
9833 ER = getDerived().TransformExpr(IV);
9834 if (ER.isInvalid())
9835 return nullptr;
9837 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
9838 C->getLParenLoc(), C->getVarLoc(),
9839 C->getEndLoc());
9842 template <typename Derived>
9843 OMPClause *
9844 TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
9845 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9846 if (Cond.isInvalid())
9847 return nullptr;
9848 return getDerived().RebuildOMPNovariantsClause(
9849 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9852 template <typename Derived>
9853 OMPClause *
9854 TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
9855 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9856 if (Cond.isInvalid())
9857 return nullptr;
9858 return getDerived().RebuildOMPNocontextClause(
9859 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9862 template <typename Derived>
9863 OMPClause *
9864 TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
9865 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
9866 if (ThreadID.isInvalid())
9867 return nullptr;
9868 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
9869 C->getLParenLoc(), C->getEndLoc());
9872 template <typename Derived>
9873 OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
9874 ExprResult E = getDerived().TransformExpr(C->getAlignment());
9875 if (E.isInvalid())
9876 return nullptr;
9877 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
9878 C->getLParenLoc(), C->getEndLoc());
9881 template <typename Derived>
9882 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
9883 OMPUnifiedAddressClause *C) {
9884 llvm_unreachable("unified_address clause cannot appear in dependent context");
9887 template <typename Derived>
9888 OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
9889 OMPUnifiedSharedMemoryClause *C) {
9890 llvm_unreachable(
9891 "unified_shared_memory clause cannot appear in dependent context");
9894 template <typename Derived>
9895 OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
9896 OMPReverseOffloadClause *C) {
9897 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
9900 template <typename Derived>
9901 OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
9902 OMPDynamicAllocatorsClause *C) {
9903 llvm_unreachable(
9904 "dynamic_allocators clause cannot appear in dependent context");
9907 template <typename Derived>
9908 OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
9909 OMPAtomicDefaultMemOrderClause *C) {
9910 llvm_unreachable(
9911 "atomic_default_mem_order clause cannot appear in dependent context");
9914 template <typename Derived>
9915 OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
9916 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
9917 C->getBeginLoc(), C->getLParenLoc(),
9918 C->getEndLoc());
9921 template <typename Derived>
9922 OMPClause *
9923 TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
9924 return getDerived().RebuildOMPSeverityClause(
9925 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
9926 C->getLParenLoc(), C->getEndLoc());
9929 template <typename Derived>
9930 OMPClause *
9931 TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
9932 ExprResult E = getDerived().TransformExpr(C->getMessageString());
9933 if (E.isInvalid())
9934 return nullptr;
9935 return getDerived().RebuildOMPMessageClause(
9936 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
9937 C->getEndLoc());
9940 template <typename Derived>
9941 OMPClause *
9942 TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
9943 llvm::SmallVector<Expr *, 16> Vars;
9944 Vars.reserve(C->varlist_size());
9945 for (auto *VE : C->varlists()) {
9946 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
9947 if (EVar.isInvalid())
9948 return nullptr;
9949 Vars.push_back(EVar.get());
9951 return getDerived().RebuildOMPPrivateClause(
9952 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9955 template <typename Derived>
9956 OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
9957 OMPFirstprivateClause *C) {
9958 llvm::SmallVector<Expr *, 16> Vars;
9959 Vars.reserve(C->varlist_size());
9960 for (auto *VE : C->varlists()) {
9961 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
9962 if (EVar.isInvalid())
9963 return nullptr;
9964 Vars.push_back(EVar.get());
9966 return getDerived().RebuildOMPFirstprivateClause(
9967 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9970 template <typename Derived>
9971 OMPClause *
9972 TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
9973 llvm::SmallVector<Expr *, 16> Vars;
9974 Vars.reserve(C->varlist_size());
9975 for (auto *VE : C->varlists()) {
9976 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
9977 if (EVar.isInvalid())
9978 return nullptr;
9979 Vars.push_back(EVar.get());
9981 return getDerived().RebuildOMPLastprivateClause(
9982 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
9983 C->getLParenLoc(), C->getEndLoc());
9986 template <typename Derived>
9987 OMPClause *
9988 TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
9989 llvm::SmallVector<Expr *, 16> Vars;
9990 Vars.reserve(C->varlist_size());
9991 for (auto *VE : C->varlists()) {
9992 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
9993 if (EVar.isInvalid())
9994 return nullptr;
9995 Vars.push_back(EVar.get());
9997 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
9998 C->getLParenLoc(), C->getEndLoc());
10001 template <typename Derived>
10002 OMPClause *
10003 TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
10004 llvm::SmallVector<Expr *, 16> Vars;
10005 Vars.reserve(C->varlist_size());
10006 for (auto *VE : C->varlists()) {
10007 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10008 if (EVar.isInvalid())
10009 return nullptr;
10010 Vars.push_back(EVar.get());
10012 CXXScopeSpec ReductionIdScopeSpec;
10013 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10015 DeclarationNameInfo NameInfo = C->getNameInfo();
10016 if (NameInfo.getName()) {
10017 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10018 if (!NameInfo.getName())
10019 return nullptr;
10021 // Build a list of all UDR decls with the same names ranged by the Scopes.
10022 // The Scope boundary is a duplication of the previous decl.
10023 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10024 for (auto *E : C->reduction_ops()) {
10025 // Transform all the decls.
10026 if (E) {
10027 auto *ULE = cast<UnresolvedLookupExpr>(E);
10028 UnresolvedSet<8> Decls;
10029 for (auto *D : ULE->decls()) {
10030 NamedDecl *InstD =
10031 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10032 Decls.addDecl(InstD, InstD->getAccess());
10034 UnresolvedReductions.push_back(
10035 UnresolvedLookupExpr::Create(
10036 SemaRef.Context, /*NamingClass=*/nullptr,
10037 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context),
10038 NameInfo, /*ADL=*/true, ULE->isOverloaded(),
10039 Decls.begin(), Decls.end()));
10040 } else
10041 UnresolvedReductions.push_back(nullptr);
10043 return getDerived().RebuildOMPReductionClause(
10044 Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(),
10045 C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
10046 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10049 template <typename Derived>
10050 OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
10051 OMPTaskReductionClause *C) {
10052 llvm::SmallVector<Expr *, 16> Vars;
10053 Vars.reserve(C->varlist_size());
10054 for (auto *VE : C->varlists()) {
10055 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10056 if (EVar.isInvalid())
10057 return nullptr;
10058 Vars.push_back(EVar.get());
10060 CXXScopeSpec ReductionIdScopeSpec;
10061 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10063 DeclarationNameInfo NameInfo = C->getNameInfo();
10064 if (NameInfo.getName()) {
10065 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10066 if (!NameInfo.getName())
10067 return nullptr;
10069 // Build a list of all UDR decls with the same names ranged by the Scopes.
10070 // The Scope boundary is a duplication of the previous decl.
10071 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10072 for (auto *E : C->reduction_ops()) {
10073 // Transform all the decls.
10074 if (E) {
10075 auto *ULE = cast<UnresolvedLookupExpr>(E);
10076 UnresolvedSet<8> Decls;
10077 for (auto *D : ULE->decls()) {
10078 NamedDecl *InstD =
10079 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10080 Decls.addDecl(InstD, InstD->getAccess());
10082 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10083 SemaRef.Context, /*NamingClass=*/nullptr,
10084 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10085 /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end()));
10086 } else
10087 UnresolvedReductions.push_back(nullptr);
10089 return getDerived().RebuildOMPTaskReductionClause(
10090 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10091 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10094 template <typename Derived>
10095 OMPClause *
10096 TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
10097 llvm::SmallVector<Expr *, 16> Vars;
10098 Vars.reserve(C->varlist_size());
10099 for (auto *VE : C->varlists()) {
10100 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10101 if (EVar.isInvalid())
10102 return nullptr;
10103 Vars.push_back(EVar.get());
10105 CXXScopeSpec ReductionIdScopeSpec;
10106 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10108 DeclarationNameInfo NameInfo = C->getNameInfo();
10109 if (NameInfo.getName()) {
10110 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10111 if (!NameInfo.getName())
10112 return nullptr;
10114 // Build a list of all UDR decls with the same names ranged by the Scopes.
10115 // The Scope boundary is a duplication of the previous decl.
10116 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10117 for (auto *E : C->reduction_ops()) {
10118 // Transform all the decls.
10119 if (E) {
10120 auto *ULE = cast<UnresolvedLookupExpr>(E);
10121 UnresolvedSet<8> Decls;
10122 for (auto *D : ULE->decls()) {
10123 NamedDecl *InstD =
10124 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10125 Decls.addDecl(InstD, InstD->getAccess());
10127 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10128 SemaRef.Context, /*NamingClass=*/nullptr,
10129 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10130 /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end()));
10131 } else
10132 UnresolvedReductions.push_back(nullptr);
10134 return getDerived().RebuildOMPInReductionClause(
10135 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10136 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10139 template <typename Derived>
10140 OMPClause *
10141 TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
10142 llvm::SmallVector<Expr *, 16> Vars;
10143 Vars.reserve(C->varlist_size());
10144 for (auto *VE : C->varlists()) {
10145 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10146 if (EVar.isInvalid())
10147 return nullptr;
10148 Vars.push_back(EVar.get());
10150 ExprResult Step = getDerived().TransformExpr(C->getStep());
10151 if (Step.isInvalid())
10152 return nullptr;
10153 return getDerived().RebuildOMPLinearClause(
10154 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
10155 C->getModifierLoc(), C->getColonLoc(), C->getEndLoc());
10158 template <typename Derived>
10159 OMPClause *
10160 TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
10161 llvm::SmallVector<Expr *, 16> Vars;
10162 Vars.reserve(C->varlist_size());
10163 for (auto *VE : C->varlists()) {
10164 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10165 if (EVar.isInvalid())
10166 return nullptr;
10167 Vars.push_back(EVar.get());
10169 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
10170 if (Alignment.isInvalid())
10171 return nullptr;
10172 return getDerived().RebuildOMPAlignedClause(
10173 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
10174 C->getColonLoc(), C->getEndLoc());
10177 template <typename Derived>
10178 OMPClause *
10179 TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
10180 llvm::SmallVector<Expr *, 16> Vars;
10181 Vars.reserve(C->varlist_size());
10182 for (auto *VE : C->varlists()) {
10183 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10184 if (EVar.isInvalid())
10185 return nullptr;
10186 Vars.push_back(EVar.get());
10188 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
10189 C->getLParenLoc(), C->getEndLoc());
10192 template <typename Derived>
10193 OMPClause *
10194 TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
10195 llvm::SmallVector<Expr *, 16> Vars;
10196 Vars.reserve(C->varlist_size());
10197 for (auto *VE : C->varlists()) {
10198 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10199 if (EVar.isInvalid())
10200 return nullptr;
10201 Vars.push_back(EVar.get());
10203 return getDerived().RebuildOMPCopyprivateClause(
10204 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10207 template <typename Derived>
10208 OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
10209 llvm::SmallVector<Expr *, 16> Vars;
10210 Vars.reserve(C->varlist_size());
10211 for (auto *VE : C->varlists()) {
10212 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10213 if (EVar.isInvalid())
10214 return nullptr;
10215 Vars.push_back(EVar.get());
10217 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
10218 C->getLParenLoc(), C->getEndLoc());
10221 template <typename Derived>
10222 OMPClause *
10223 TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
10224 ExprResult E = getDerived().TransformExpr(C->getDepobj());
10225 if (E.isInvalid())
10226 return nullptr;
10227 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
10228 C->getLParenLoc(), C->getEndLoc());
10231 template <typename Derived>
10232 OMPClause *
10233 TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
10234 llvm::SmallVector<Expr *, 16> Vars;
10235 Expr *DepModifier = C->getModifier();
10236 if (DepModifier) {
10237 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
10238 if (DepModRes.isInvalid())
10239 return nullptr;
10240 DepModifier = DepModRes.get();
10242 Vars.reserve(C->varlist_size());
10243 for (auto *VE : C->varlists()) {
10244 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10245 if (EVar.isInvalid())
10246 return nullptr;
10247 Vars.push_back(EVar.get());
10249 return getDerived().RebuildOMPDependClause(
10250 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
10251 C->getOmpAllMemoryLoc()},
10252 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10255 template <typename Derived>
10256 OMPClause *
10257 TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
10258 ExprResult E = getDerived().TransformExpr(C->getDevice());
10259 if (E.isInvalid())
10260 return nullptr;
10261 return getDerived().RebuildOMPDeviceClause(
10262 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10263 C->getModifierLoc(), C->getEndLoc());
10266 template <typename Derived, class T>
10267 bool transformOMPMappableExprListClause(
10268 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
10269 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
10270 DeclarationNameInfo &MapperIdInfo,
10271 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
10272 // Transform expressions in the list.
10273 Vars.reserve(C->varlist_size());
10274 for (auto *VE : C->varlists()) {
10275 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
10276 if (EVar.isInvalid())
10277 return true;
10278 Vars.push_back(EVar.get());
10280 // Transform mapper scope specifier and identifier.
10281 NestedNameSpecifierLoc QualifierLoc;
10282 if (C->getMapperQualifierLoc()) {
10283 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
10284 C->getMapperQualifierLoc());
10285 if (!QualifierLoc)
10286 return true;
10288 MapperIdScopeSpec.Adopt(QualifierLoc);
10289 MapperIdInfo = C->getMapperIdInfo();
10290 if (MapperIdInfo.getName()) {
10291 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
10292 if (!MapperIdInfo.getName())
10293 return true;
10295 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
10296 // the previous user-defined mapper lookup in dependent environment.
10297 for (auto *E : C->mapperlists()) {
10298 // Transform all the decls.
10299 if (E) {
10300 auto *ULE = cast<UnresolvedLookupExpr>(E);
10301 UnresolvedSet<8> Decls;
10302 for (auto *D : ULE->decls()) {
10303 NamedDecl *InstD =
10304 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
10305 Decls.addDecl(InstD, InstD->getAccess());
10307 UnresolvedMappers.push_back(UnresolvedLookupExpr::Create(
10308 TT.getSema().Context, /*NamingClass=*/nullptr,
10309 MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
10310 MapperIdInfo, /*ADL=*/true, ULE->isOverloaded(), Decls.begin(),
10311 Decls.end()));
10312 } else {
10313 UnresolvedMappers.push_back(nullptr);
10316 return false;
10319 template <typename Derived>
10320 OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
10321 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10322 llvm::SmallVector<Expr *, 16> Vars;
10323 Expr *IteratorModifier = C->getIteratorModifier();
10324 if (IteratorModifier) {
10325 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
10326 if (MapModRes.isInvalid())
10327 return nullptr;
10328 IteratorModifier = MapModRes.get();
10330 CXXScopeSpec MapperIdScopeSpec;
10331 DeclarationNameInfo MapperIdInfo;
10332 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10333 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
10334 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10335 return nullptr;
10336 return getDerived().RebuildOMPMapClause(
10337 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
10338 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
10339 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10342 template <typename Derived>
10343 OMPClause *
10344 TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
10345 Expr *Allocator = C->getAllocator();
10346 if (Allocator) {
10347 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
10348 if (AllocatorRes.isInvalid())
10349 return nullptr;
10350 Allocator = AllocatorRes.get();
10352 llvm::SmallVector<Expr *, 16> Vars;
10353 Vars.reserve(C->varlist_size());
10354 for (auto *VE : C->varlists()) {
10355 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10356 if (EVar.isInvalid())
10357 return nullptr;
10358 Vars.push_back(EVar.get());
10360 return getDerived().RebuildOMPAllocateClause(
10361 Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10362 C->getEndLoc());
10365 template <typename Derived>
10366 OMPClause *
10367 TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
10368 ExprResult E = getDerived().TransformExpr(C->getNumTeams());
10369 if (E.isInvalid())
10370 return nullptr;
10371 return getDerived().RebuildOMPNumTeamsClause(
10372 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10375 template <typename Derived>
10376 OMPClause *
10377 TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
10378 ExprResult E = getDerived().TransformExpr(C->getThreadLimit());
10379 if (E.isInvalid())
10380 return nullptr;
10381 return getDerived().RebuildOMPThreadLimitClause(
10382 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10385 template <typename Derived>
10386 OMPClause *
10387 TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
10388 ExprResult E = getDerived().TransformExpr(C->getPriority());
10389 if (E.isInvalid())
10390 return nullptr;
10391 return getDerived().RebuildOMPPriorityClause(
10392 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10395 template <typename Derived>
10396 OMPClause *
10397 TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
10398 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
10399 if (E.isInvalid())
10400 return nullptr;
10401 return getDerived().RebuildOMPGrainsizeClause(
10402 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10403 C->getModifierLoc(), C->getEndLoc());
10406 template <typename Derived>
10407 OMPClause *
10408 TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
10409 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
10410 if (E.isInvalid())
10411 return nullptr;
10412 return getDerived().RebuildOMPNumTasksClause(
10413 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10414 C->getModifierLoc(), C->getEndLoc());
10417 template <typename Derived>
10418 OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
10419 ExprResult E = getDerived().TransformExpr(C->getHint());
10420 if (E.isInvalid())
10421 return nullptr;
10422 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
10423 C->getLParenLoc(), C->getEndLoc());
10426 template <typename Derived>
10427 OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
10428 OMPDistScheduleClause *C) {
10429 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10430 if (E.isInvalid())
10431 return nullptr;
10432 return getDerived().RebuildOMPDistScheduleClause(
10433 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10434 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10437 template <typename Derived>
10438 OMPClause *
10439 TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
10440 // Rebuild Defaultmap Clause since we need to invoke the checking of
10441 // defaultmap(none:variable-category) after template initialization.
10442 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
10443 C->getDefaultmapKind(),
10444 C->getBeginLoc(),
10445 C->getLParenLoc(),
10446 C->getDefaultmapModifierLoc(),
10447 C->getDefaultmapKindLoc(),
10448 C->getEndLoc());
10451 template <typename Derived>
10452 OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
10453 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10454 llvm::SmallVector<Expr *, 16> Vars;
10455 CXXScopeSpec MapperIdScopeSpec;
10456 DeclarationNameInfo MapperIdInfo;
10457 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10458 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
10459 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10460 return nullptr;
10461 return getDerived().RebuildOMPToClause(
10462 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10463 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10466 template <typename Derived>
10467 OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
10468 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10469 llvm::SmallVector<Expr *, 16> Vars;
10470 CXXScopeSpec MapperIdScopeSpec;
10471 DeclarationNameInfo MapperIdInfo;
10472 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10473 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
10474 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10475 return nullptr;
10476 return getDerived().RebuildOMPFromClause(
10477 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10478 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10481 template <typename Derived>
10482 OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
10483 OMPUseDevicePtrClause *C) {
10484 llvm::SmallVector<Expr *, 16> Vars;
10485 Vars.reserve(C->varlist_size());
10486 for (auto *VE : C->varlists()) {
10487 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10488 if (EVar.isInvalid())
10489 return nullptr;
10490 Vars.push_back(EVar.get());
10492 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10493 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
10496 template <typename Derived>
10497 OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
10498 OMPUseDeviceAddrClause *C) {
10499 llvm::SmallVector<Expr *, 16> Vars;
10500 Vars.reserve(C->varlist_size());
10501 for (auto *VE : C->varlists()) {
10502 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10503 if (EVar.isInvalid())
10504 return nullptr;
10505 Vars.push_back(EVar.get());
10507 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10508 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
10511 template <typename Derived>
10512 OMPClause *
10513 TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
10514 llvm::SmallVector<Expr *, 16> Vars;
10515 Vars.reserve(C->varlist_size());
10516 for (auto *VE : C->varlists()) {
10517 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10518 if (EVar.isInvalid())
10519 return nullptr;
10520 Vars.push_back(EVar.get());
10522 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10523 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
10526 template <typename Derived>
10527 OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
10528 OMPHasDeviceAddrClause *C) {
10529 llvm::SmallVector<Expr *, 16> Vars;
10530 Vars.reserve(C->varlist_size());
10531 for (auto *VE : C->varlists()) {
10532 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10533 if (EVar.isInvalid())
10534 return nullptr;
10535 Vars.push_back(EVar.get());
10537 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10538 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
10541 template <typename Derived>
10542 OMPClause *
10543 TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
10544 llvm::SmallVector<Expr *, 16> Vars;
10545 Vars.reserve(C->varlist_size());
10546 for (auto *VE : C->varlists()) {
10547 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10548 if (EVar.isInvalid())
10549 return nullptr;
10550 Vars.push_back(EVar.get());
10552 return getDerived().RebuildOMPNontemporalClause(
10553 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10556 template <typename Derived>
10557 OMPClause *
10558 TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
10559 llvm::SmallVector<Expr *, 16> Vars;
10560 Vars.reserve(C->varlist_size());
10561 for (auto *VE : C->varlists()) {
10562 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10563 if (EVar.isInvalid())
10564 return nullptr;
10565 Vars.push_back(EVar.get());
10567 return getDerived().RebuildOMPInclusiveClause(
10568 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10571 template <typename Derived>
10572 OMPClause *
10573 TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
10574 llvm::SmallVector<Expr *, 16> Vars;
10575 Vars.reserve(C->varlist_size());
10576 for (auto *VE : C->varlists()) {
10577 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10578 if (EVar.isInvalid())
10579 return nullptr;
10580 Vars.push_back(EVar.get());
10582 return getDerived().RebuildOMPExclusiveClause(
10583 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10586 template <typename Derived>
10587 OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
10588 OMPUsesAllocatorsClause *C) {
10589 SmallVector<Sema::UsesAllocatorsData, 16> Data;
10590 Data.reserve(C->getNumberOfAllocators());
10591 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
10592 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
10593 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
10594 if (Allocator.isInvalid())
10595 continue;
10596 ExprResult AllocatorTraits;
10597 if (Expr *AT = D.AllocatorTraits) {
10598 AllocatorTraits = getDerived().TransformExpr(AT);
10599 if (AllocatorTraits.isInvalid())
10600 continue;
10602 Sema::UsesAllocatorsData &NewD = Data.emplace_back();
10603 NewD.Allocator = Allocator.get();
10604 NewD.AllocatorTraits = AllocatorTraits.get();
10605 NewD.LParenLoc = D.LParenLoc;
10606 NewD.RParenLoc = D.RParenLoc;
10608 return getDerived().RebuildOMPUsesAllocatorsClause(
10609 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10612 template <typename Derived>
10613 OMPClause *
10614 TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
10615 SmallVector<Expr *, 4> Locators;
10616 Locators.reserve(C->varlist_size());
10617 ExprResult ModifierRes;
10618 if (Expr *Modifier = C->getModifier()) {
10619 ModifierRes = getDerived().TransformExpr(Modifier);
10620 if (ModifierRes.isInvalid())
10621 return nullptr;
10623 for (Expr *E : C->varlists()) {
10624 ExprResult Locator = getDerived().TransformExpr(E);
10625 if (Locator.isInvalid())
10626 continue;
10627 Locators.push_back(Locator.get());
10629 return getDerived().RebuildOMPAffinityClause(
10630 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
10631 ModifierRes.get(), Locators);
10634 template <typename Derived>
10635 OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
10636 return getDerived().RebuildOMPOrderClause(
10637 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
10638 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
10641 template <typename Derived>
10642 OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
10643 return getDerived().RebuildOMPBindClause(
10644 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
10645 C->getLParenLoc(), C->getEndLoc());
10648 template <typename Derived>
10649 OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
10650 OMPXDynCGroupMemClause *C) {
10651 ExprResult Size = getDerived().TransformExpr(C->getSize());
10652 if (Size.isInvalid())
10653 return nullptr;
10654 return getDerived().RebuildOMPXDynCGroupMemClause(
10655 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10658 //===----------------------------------------------------------------------===//
10659 // Expression transformation
10660 //===----------------------------------------------------------------------===//
10661 template<typename Derived>
10662 ExprResult
10663 TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
10664 return TransformExpr(E->getSubExpr());
10667 template <typename Derived>
10668 ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
10669 SYCLUniqueStableNameExpr *E) {
10670 if (!E->isTypeDependent())
10671 return E;
10673 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
10675 if (!NewT)
10676 return ExprError();
10678 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
10679 return E;
10681 return getDerived().RebuildSYCLUniqueStableNameExpr(
10682 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
10685 template<typename Derived>
10686 ExprResult
10687 TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
10688 if (!E->isTypeDependent())
10689 return E;
10691 return getDerived().RebuildPredefinedExpr(E->getLocation(),
10692 E->getIdentKind());
10695 template<typename Derived>
10696 ExprResult
10697 TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
10698 NestedNameSpecifierLoc QualifierLoc;
10699 if (E->getQualifierLoc()) {
10700 QualifierLoc
10701 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
10702 if (!QualifierLoc)
10703 return ExprError();
10706 ValueDecl *ND
10707 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
10708 E->getDecl()));
10709 if (!ND)
10710 return ExprError();
10712 NamedDecl *Found = ND;
10713 if (E->getFoundDecl() != E->getDecl()) {
10714 Found = cast_or_null<NamedDecl>(
10715 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
10716 if (!Found)
10717 return ExprError();
10720 DeclarationNameInfo NameInfo = E->getNameInfo();
10721 if (NameInfo.getName()) {
10722 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10723 if (!NameInfo.getName())
10724 return ExprError();
10727 if (!getDerived().AlwaysRebuild() &&
10728 QualifierLoc == E->getQualifierLoc() &&
10729 ND == E->getDecl() &&
10730 Found == E->getFoundDecl() &&
10731 NameInfo.getName() == E->getDecl()->getDeclName() &&
10732 !E->hasExplicitTemplateArgs()) {
10734 // Mark it referenced in the new context regardless.
10735 // FIXME: this is a bit instantiation-specific.
10736 SemaRef.MarkDeclRefReferenced(E);
10738 return E;
10741 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
10742 if (E->hasExplicitTemplateArgs()) {
10743 TemplateArgs = &TransArgs;
10744 TransArgs.setLAngleLoc(E->getLAngleLoc());
10745 TransArgs.setRAngleLoc(E->getRAngleLoc());
10746 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
10747 E->getNumTemplateArgs(),
10748 TransArgs))
10749 return ExprError();
10752 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
10753 Found, TemplateArgs);
10756 template<typename Derived>
10757 ExprResult
10758 TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
10759 return E;
10762 template <typename Derived>
10763 ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
10764 FixedPointLiteral *E) {
10765 return E;
10768 template<typename Derived>
10769 ExprResult
10770 TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
10771 return E;
10774 template<typename Derived>
10775 ExprResult
10776 TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
10777 return E;
10780 template<typename Derived>
10781 ExprResult
10782 TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
10783 return E;
10786 template<typename Derived>
10787 ExprResult
10788 TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
10789 return E;
10792 template<typename Derived>
10793 ExprResult
10794 TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
10795 return getDerived().TransformCallExpr(E);
10798 template<typename Derived>
10799 ExprResult
10800 TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
10801 ExprResult ControllingExpr =
10802 getDerived().TransformExpr(E->getControllingExpr());
10803 if (ControllingExpr.isInvalid())
10804 return ExprError();
10806 SmallVector<Expr *, 4> AssocExprs;
10807 SmallVector<TypeSourceInfo *, 4> AssocTypes;
10808 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
10809 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
10810 if (TSI) {
10811 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
10812 if (!AssocType)
10813 return ExprError();
10814 AssocTypes.push_back(AssocType);
10815 } else {
10816 AssocTypes.push_back(nullptr);
10819 ExprResult AssocExpr =
10820 getDerived().TransformExpr(Assoc.getAssociationExpr());
10821 if (AssocExpr.isInvalid())
10822 return ExprError();
10823 AssocExprs.push_back(AssocExpr.get());
10826 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
10827 E->getDefaultLoc(),
10828 E->getRParenLoc(),
10829 ControllingExpr.get(),
10830 AssocTypes,
10831 AssocExprs);
10834 template<typename Derived>
10835 ExprResult
10836 TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
10837 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
10838 if (SubExpr.isInvalid())
10839 return ExprError();
10841 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
10842 return E;
10844 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
10845 E->getRParen());
10848 /// The operand of a unary address-of operator has special rules: it's
10849 /// allowed to refer to a non-static member of a class even if there's no 'this'
10850 /// object available.
10851 template<typename Derived>
10852 ExprResult
10853 TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
10854 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
10855 return getDerived().TransformDependentScopeDeclRefExpr(DRE, true, nullptr);
10856 else
10857 return getDerived().TransformExpr(E);
10860 template<typename Derived>
10861 ExprResult
10862 TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
10863 ExprResult SubExpr;
10864 if (E->getOpcode() == UO_AddrOf)
10865 SubExpr = TransformAddressOfOperand(E->getSubExpr());
10866 else
10867 SubExpr = TransformExpr(E->getSubExpr());
10868 if (SubExpr.isInvalid())
10869 return ExprError();
10871 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
10872 return E;
10874 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
10875 E->getOpcode(),
10876 SubExpr.get());
10879 template<typename Derived>
10880 ExprResult
10881 TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
10882 // Transform the type.
10883 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
10884 if (!Type)
10885 return ExprError();
10887 // Transform all of the components into components similar to what the
10888 // parser uses.
10889 // FIXME: It would be slightly more efficient in the non-dependent case to
10890 // just map FieldDecls, rather than requiring the rebuilder to look for
10891 // the fields again. However, __builtin_offsetof is rare enough in
10892 // template code that we don't care.
10893 bool ExprChanged = false;
10894 typedef Sema::OffsetOfComponent Component;
10895 SmallVector<Component, 4> Components;
10896 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
10897 const OffsetOfNode &ON = E->getComponent(I);
10898 Component Comp;
10899 Comp.isBrackets = true;
10900 Comp.LocStart = ON.getSourceRange().getBegin();
10901 Comp.LocEnd = ON.getSourceRange().getEnd();
10902 switch (ON.getKind()) {
10903 case OffsetOfNode::Array: {
10904 Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
10905 ExprResult Index = getDerived().TransformExpr(FromIndex);
10906 if (Index.isInvalid())
10907 return ExprError();
10909 ExprChanged = ExprChanged || Index.get() != FromIndex;
10910 Comp.isBrackets = true;
10911 Comp.U.E = Index.get();
10912 break;
10915 case OffsetOfNode::Field:
10916 case OffsetOfNode::Identifier:
10917 Comp.isBrackets = false;
10918 Comp.U.IdentInfo = ON.getFieldName();
10919 if (!Comp.U.IdentInfo)
10920 continue;
10922 break;
10924 case OffsetOfNode::Base:
10925 // Will be recomputed during the rebuild.
10926 continue;
10929 Components.push_back(Comp);
10932 // If nothing changed, retain the existing expression.
10933 if (!getDerived().AlwaysRebuild() &&
10934 Type == E->getTypeSourceInfo() &&
10935 !ExprChanged)
10936 return E;
10938 // Build a new offsetof expression.
10939 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
10940 Components, E->getRParenLoc());
10943 template<typename Derived>
10944 ExprResult
10945 TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
10946 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
10947 "opaque value expression requires transformation");
10948 return E;
10951 template<typename Derived>
10952 ExprResult
10953 TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
10954 return E;
10957 template <typename Derived>
10958 ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
10959 llvm::SmallVector<Expr *, 8> Children;
10960 bool Changed = false;
10961 for (Expr *C : E->subExpressions()) {
10962 ExprResult NewC = getDerived().TransformExpr(C);
10963 if (NewC.isInvalid())
10964 return ExprError();
10965 Children.push_back(NewC.get());
10967 Changed |= NewC.get() != C;
10969 if (!getDerived().AlwaysRebuild() && !Changed)
10970 return E;
10971 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
10972 Children, E->getType());
10975 template<typename Derived>
10976 ExprResult
10977 TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
10978 // Rebuild the syntactic form. The original syntactic form has
10979 // opaque-value expressions in it, so strip those away and rebuild
10980 // the result. This is a really awful way of doing this, but the
10981 // better solution (rebuilding the semantic expressions and
10982 // rebinding OVEs as necessary) doesn't work; we'd need
10983 // TreeTransform to not strip away implicit conversions.
10984 Expr *newSyntacticForm = SemaRef.recreateSyntacticForm(E);
10985 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
10986 if (result.isInvalid()) return ExprError();
10988 // If that gives us a pseudo-object result back, the pseudo-object
10989 // expression must have been an lvalue-to-rvalue conversion which we
10990 // should reapply.
10991 if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
10992 result = SemaRef.checkPseudoObjectRValue(result.get());
10994 return result;
10997 template<typename Derived>
10998 ExprResult
10999 TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
11000 UnaryExprOrTypeTraitExpr *E) {
11001 if (E->isArgumentType()) {
11002 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
11004 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
11005 if (!NewT)
11006 return ExprError();
11008 if (!getDerived().AlwaysRebuild() && OldT == NewT)
11009 return E;
11011 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
11012 E->getKind(),
11013 E->getSourceRange());
11016 // C++0x [expr.sizeof]p1:
11017 // The operand is either an expression, which is an unevaluated operand
11018 // [...]
11019 EnterExpressionEvaluationContext Unevaluated(
11020 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
11021 Sema::ReuseLambdaContextDecl);
11023 // Try to recover if we have something like sizeof(T::X) where X is a type.
11024 // Notably, there must be *exactly* one set of parens if X is a type.
11025 TypeSourceInfo *RecoveryTSI = nullptr;
11026 ExprResult SubExpr;
11027 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
11028 if (auto *DRE =
11029 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
11030 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
11031 PE, DRE, false, &RecoveryTSI);
11032 else
11033 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
11035 if (RecoveryTSI) {
11036 return getDerived().RebuildUnaryExprOrTypeTrait(
11037 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
11038 } else if (SubExpr.isInvalid())
11039 return ExprError();
11041 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
11042 return E;
11044 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
11045 E->getOperatorLoc(),
11046 E->getKind(),
11047 E->getSourceRange());
11050 template<typename Derived>
11051 ExprResult
11052 TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
11053 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11054 if (LHS.isInvalid())
11055 return ExprError();
11057 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11058 if (RHS.isInvalid())
11059 return ExprError();
11062 if (!getDerived().AlwaysRebuild() &&
11063 LHS.get() == E->getLHS() &&
11064 RHS.get() == E->getRHS())
11065 return E;
11067 return getDerived().RebuildArraySubscriptExpr(
11068 LHS.get(),
11069 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
11072 template <typename Derived>
11073 ExprResult
11074 TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
11075 ExprResult Base = getDerived().TransformExpr(E->getBase());
11076 if (Base.isInvalid())
11077 return ExprError();
11079 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
11080 if (RowIdx.isInvalid())
11081 return ExprError();
11083 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
11084 if (ColumnIdx.isInvalid())
11085 return ExprError();
11087 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
11088 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
11089 return E;
11091 return getDerived().RebuildMatrixSubscriptExpr(
11092 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
11095 template <typename Derived>
11096 ExprResult
11097 TreeTransform<Derived>::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) {
11098 ExprResult Base = getDerived().TransformExpr(E->getBase());
11099 if (Base.isInvalid())
11100 return ExprError();
11102 ExprResult LowerBound;
11103 if (E->getLowerBound()) {
11104 LowerBound = getDerived().TransformExpr(E->getLowerBound());
11105 if (LowerBound.isInvalid())
11106 return ExprError();
11109 ExprResult Length;
11110 if (E->getLength()) {
11111 Length = getDerived().TransformExpr(E->getLength());
11112 if (Length.isInvalid())
11113 return ExprError();
11116 ExprResult Stride;
11117 if (Expr *Str = E->getStride()) {
11118 Stride = getDerived().TransformExpr(Str);
11119 if (Stride.isInvalid())
11120 return ExprError();
11123 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
11124 LowerBound.get() == E->getLowerBound() && Length.get() == E->getLength())
11125 return E;
11127 return getDerived().RebuildOMPArraySectionExpr(
11128 Base.get(), E->getBase()->getEndLoc(), LowerBound.get(),
11129 E->getColonLocFirst(), E->getColonLocSecond(), Length.get(), Stride.get(),
11130 E->getRBracketLoc());
11133 template <typename Derived>
11134 ExprResult
11135 TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
11136 ExprResult Base = getDerived().TransformExpr(E->getBase());
11137 if (Base.isInvalid())
11138 return ExprError();
11140 SmallVector<Expr *, 4> Dims;
11141 bool ErrorFound = false;
11142 for (Expr *Dim : E->getDimensions()) {
11143 ExprResult DimRes = getDerived().TransformExpr(Dim);
11144 if (DimRes.isInvalid()) {
11145 ErrorFound = true;
11146 continue;
11148 Dims.push_back(DimRes.get());
11151 if (ErrorFound)
11152 return ExprError();
11153 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
11154 E->getRParenLoc(), Dims,
11155 E->getBracketsRanges());
11158 template <typename Derived>
11159 ExprResult
11160 TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
11161 unsigned NumIterators = E->numOfIterators();
11162 SmallVector<Sema::OMPIteratorData, 4> Data(NumIterators);
11164 bool ErrorFound = false;
11165 bool NeedToRebuild = getDerived().AlwaysRebuild();
11166 for (unsigned I = 0; I < NumIterators; ++I) {
11167 auto *D = cast<VarDecl>(E->getIteratorDecl(I));
11168 Data[I].DeclIdent = D->getIdentifier();
11169 Data[I].DeclIdentLoc = D->getLocation();
11170 if (D->getLocation() == D->getBeginLoc()) {
11171 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
11172 "Implicit type must be int.");
11173 } else {
11174 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
11175 QualType DeclTy = getDerived().TransformType(D->getType());
11176 Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI);
11178 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
11179 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
11180 ExprResult End = getDerived().TransformExpr(Range.End);
11181 ExprResult Step = getDerived().TransformExpr(Range.Step);
11182 ErrorFound = ErrorFound ||
11183 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
11184 !Data[I].Type.get().isNull())) ||
11185 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
11186 if (ErrorFound)
11187 continue;
11188 Data[I].Range.Begin = Begin.get();
11189 Data[I].Range.End = End.get();
11190 Data[I].Range.Step = Step.get();
11191 Data[I].AssignLoc = E->getAssignLoc(I);
11192 Data[I].ColonLoc = E->getColonLoc(I);
11193 Data[I].SecColonLoc = E->getSecondColonLoc(I);
11194 NeedToRebuild =
11195 NeedToRebuild ||
11196 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
11197 D->getType().getTypePtrOrNull()) ||
11198 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
11199 Range.Step != Data[I].Range.Step;
11201 if (ErrorFound)
11202 return ExprError();
11203 if (!NeedToRebuild)
11204 return E;
11206 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
11207 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
11208 if (!Res.isUsable())
11209 return Res;
11210 auto *IE = cast<OMPIteratorExpr>(Res.get());
11211 for (unsigned I = 0; I < NumIterators; ++I)
11212 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
11213 IE->getIteratorDecl(I));
11214 return Res;
11217 template<typename Derived>
11218 ExprResult
11219 TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
11220 // Transform the callee.
11221 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
11222 if (Callee.isInvalid())
11223 return ExprError();
11225 // Transform arguments.
11226 bool ArgChanged = false;
11227 SmallVector<Expr*, 8> Args;
11228 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
11229 &ArgChanged))
11230 return ExprError();
11232 if (!getDerived().AlwaysRebuild() &&
11233 Callee.get() == E->getCallee() &&
11234 !ArgChanged)
11235 return SemaRef.MaybeBindToTemporary(E);
11237 // FIXME: Wrong source location information for the '('.
11238 SourceLocation FakeLParenLoc
11239 = ((Expr *)Callee.get())->getSourceRange().getBegin();
11241 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11242 if (E->hasStoredFPFeatures()) {
11243 FPOptionsOverride NewOverrides = E->getFPFeatures();
11244 getSema().CurFPFeatures =
11245 NewOverrides.applyOverrides(getSema().getLangOpts());
11246 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11249 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
11250 Args,
11251 E->getRParenLoc());
11254 template<typename Derived>
11255 ExprResult
11256 TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
11257 ExprResult Base = getDerived().TransformExpr(E->getBase());
11258 if (Base.isInvalid())
11259 return ExprError();
11261 NestedNameSpecifierLoc QualifierLoc;
11262 if (E->hasQualifier()) {
11263 QualifierLoc
11264 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
11266 if (!QualifierLoc)
11267 return ExprError();
11269 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
11271 ValueDecl *Member
11272 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
11273 E->getMemberDecl()));
11274 if (!Member)
11275 return ExprError();
11277 NamedDecl *FoundDecl = E->getFoundDecl();
11278 if (FoundDecl == E->getMemberDecl()) {
11279 FoundDecl = Member;
11280 } else {
11281 FoundDecl = cast_or_null<NamedDecl>(
11282 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
11283 if (!FoundDecl)
11284 return ExprError();
11287 if (!getDerived().AlwaysRebuild() &&
11288 Base.get() == E->getBase() &&
11289 QualifierLoc == E->getQualifierLoc() &&
11290 Member == E->getMemberDecl() &&
11291 FoundDecl == E->getFoundDecl() &&
11292 !E->hasExplicitTemplateArgs()) {
11294 // Skip for member expression of (this->f), rebuilt thisi->f is needed
11295 // for Openmp where the field need to be privatizized in the case.
11296 if (!(isa<CXXThisExpr>(E->getBase()) &&
11297 getSema().isOpenMPRebuildMemberExpr(cast<ValueDecl>(Member)))) {
11298 // Mark it referenced in the new context regardless.
11299 // FIXME: this is a bit instantiation-specific.
11300 SemaRef.MarkMemberReferenced(E);
11301 return E;
11305 TemplateArgumentListInfo TransArgs;
11306 if (E->hasExplicitTemplateArgs()) {
11307 TransArgs.setLAngleLoc(E->getLAngleLoc());
11308 TransArgs.setRAngleLoc(E->getRAngleLoc());
11309 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
11310 E->getNumTemplateArgs(),
11311 TransArgs))
11312 return ExprError();
11315 // FIXME: Bogus source location for the operator
11316 SourceLocation FakeOperatorLoc =
11317 SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
11319 // FIXME: to do this check properly, we will need to preserve the
11320 // first-qualifier-in-scope here, just in case we had a dependent
11321 // base (and therefore couldn't do the check) and a
11322 // nested-name-qualifier (and therefore could do the lookup).
11323 NamedDecl *FirstQualifierInScope = nullptr;
11324 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
11325 if (MemberNameInfo.getName()) {
11326 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
11327 if (!MemberNameInfo.getName())
11328 return ExprError();
11331 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
11332 E->isArrow(),
11333 QualifierLoc,
11334 TemplateKWLoc,
11335 MemberNameInfo,
11336 Member,
11337 FoundDecl,
11338 (E->hasExplicitTemplateArgs()
11339 ? &TransArgs : nullptr),
11340 FirstQualifierInScope);
11343 template<typename Derived>
11344 ExprResult
11345 TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
11346 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11347 if (LHS.isInvalid())
11348 return ExprError();
11350 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11351 if (RHS.isInvalid())
11352 return ExprError();
11354 if (!getDerived().AlwaysRebuild() &&
11355 LHS.get() == E->getLHS() &&
11356 RHS.get() == E->getRHS())
11357 return E;
11359 if (E->isCompoundAssignmentOp())
11360 // FPFeatures has already been established from trailing storage
11361 return getDerived().RebuildBinaryOperator(
11362 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
11363 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11364 FPOptionsOverride NewOverrides(E->getFPFeatures());
11365 getSema().CurFPFeatures =
11366 NewOverrides.applyOverrides(getSema().getLangOpts());
11367 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11368 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
11369 LHS.get(), RHS.get());
11372 template <typename Derived>
11373 ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
11374 CXXRewrittenBinaryOperator *E) {
11375 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
11377 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
11378 if (LHS.isInvalid())
11379 return ExprError();
11381 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
11382 if (RHS.isInvalid())
11383 return ExprError();
11385 // Extract the already-resolved callee declarations so that we can restrict
11386 // ourselves to using them as the unqualified lookup results when rebuilding.
11387 UnresolvedSet<2> UnqualLookups;
11388 bool ChangedAnyLookups = false;
11389 Expr *PossibleBinOps[] = {E->getSemanticForm(),
11390 const_cast<Expr *>(Decomp.InnerBinOp)};
11391 for (Expr *PossibleBinOp : PossibleBinOps) {
11392 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());
11393 if (!Op)
11394 continue;
11395 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());
11396 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))
11397 continue;
11399 // Transform the callee in case we built a call to a local extern
11400 // declaration.
11401 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
11402 E->getOperatorLoc(), Callee->getFoundDecl()));
11403 if (!Found)
11404 return ExprError();
11405 if (Found != Callee->getFoundDecl())
11406 ChangedAnyLookups = true;
11407 UnqualLookups.addDecl(Found);
11410 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
11411 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
11412 // Mark all functions used in the rewrite as referenced. Note that when
11413 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
11414 // function calls, and/or there might be a user-defined conversion sequence
11415 // applied to the operands of the <.
11416 // FIXME: this is a bit instantiation-specific.
11417 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
11418 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);
11419 return E;
11422 return getDerived().RebuildCXXRewrittenBinaryOperator(
11423 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
11426 template<typename Derived>
11427 ExprResult
11428 TreeTransform<Derived>::TransformCompoundAssignOperator(
11429 CompoundAssignOperator *E) {
11430 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11431 FPOptionsOverride NewOverrides(E->getFPFeatures());
11432 getSema().CurFPFeatures =
11433 NewOverrides.applyOverrides(getSema().getLangOpts());
11434 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11435 return getDerived().TransformBinaryOperator(E);
11438 template<typename Derived>
11439 ExprResult TreeTransform<Derived>::
11440 TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
11441 // Just rebuild the common and RHS expressions and see whether we
11442 // get any changes.
11444 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
11445 if (commonExpr.isInvalid())
11446 return ExprError();
11448 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
11449 if (rhs.isInvalid())
11450 return ExprError();
11452 if (!getDerived().AlwaysRebuild() &&
11453 commonExpr.get() == e->getCommon() &&
11454 rhs.get() == e->getFalseExpr())
11455 return e;
11457 return getDerived().RebuildConditionalOperator(commonExpr.get(),
11458 e->getQuestionLoc(),
11459 nullptr,
11460 e->getColonLoc(),
11461 rhs.get());
11464 template<typename Derived>
11465 ExprResult
11466 TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
11467 ExprResult Cond = getDerived().TransformExpr(E->getCond());
11468 if (Cond.isInvalid())
11469 return ExprError();
11471 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11472 if (LHS.isInvalid())
11473 return ExprError();
11475 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11476 if (RHS.isInvalid())
11477 return ExprError();
11479 if (!getDerived().AlwaysRebuild() &&
11480 Cond.get() == E->getCond() &&
11481 LHS.get() == E->getLHS() &&
11482 RHS.get() == E->getRHS())
11483 return E;
11485 return getDerived().RebuildConditionalOperator(Cond.get(),
11486 E->getQuestionLoc(),
11487 LHS.get(),
11488 E->getColonLoc(),
11489 RHS.get());
11492 template<typename Derived>
11493 ExprResult
11494 TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
11495 // Implicit casts are eliminated during transformation, since they
11496 // will be recomputed by semantic analysis after transformation.
11497 return getDerived().TransformExpr(E->getSubExprAsWritten());
11500 template<typename Derived>
11501 ExprResult
11502 TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
11503 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
11504 if (!Type)
11505 return ExprError();
11507 ExprResult SubExpr
11508 = getDerived().TransformExpr(E->getSubExprAsWritten());
11509 if (SubExpr.isInvalid())
11510 return ExprError();
11512 if (!getDerived().AlwaysRebuild() &&
11513 Type == E->getTypeInfoAsWritten() &&
11514 SubExpr.get() == E->getSubExpr())
11515 return E;
11517 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
11518 Type,
11519 E->getRParenLoc(),
11520 SubExpr.get());
11523 template<typename Derived>
11524 ExprResult
11525 TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
11526 TypeSourceInfo *OldT = E->getTypeSourceInfo();
11527 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
11528 if (!NewT)
11529 return ExprError();
11531 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
11532 if (Init.isInvalid())
11533 return ExprError();
11535 if (!getDerived().AlwaysRebuild() &&
11536 OldT == NewT &&
11537 Init.get() == E->getInitializer())
11538 return SemaRef.MaybeBindToTemporary(E);
11540 // Note: the expression type doesn't necessarily match the
11541 // type-as-written, but that's okay, because it should always be
11542 // derivable from the initializer.
11544 return getDerived().RebuildCompoundLiteralExpr(
11545 E->getLParenLoc(), NewT,
11546 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
11549 template<typename Derived>
11550 ExprResult
11551 TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
11552 ExprResult Base = getDerived().TransformExpr(E->getBase());
11553 if (Base.isInvalid())
11554 return ExprError();
11556 if (!getDerived().AlwaysRebuild() &&
11557 Base.get() == E->getBase())
11558 return E;
11560 // FIXME: Bad source location
11561 SourceLocation FakeOperatorLoc =
11562 SemaRef.getLocForEndOfToken(E->getBase()->getEndLoc());
11563 return getDerived().RebuildExtVectorElementExpr(
11564 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
11565 E->getAccessor());
11568 template<typename Derived>
11569 ExprResult
11570 TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
11571 if (InitListExpr *Syntactic = E->getSyntacticForm())
11572 E = Syntactic;
11574 bool InitChanged = false;
11576 EnterExpressionEvaluationContext Context(
11577 getSema(), EnterExpressionEvaluationContext::InitList);
11579 SmallVector<Expr*, 4> Inits;
11580 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
11581 Inits, &InitChanged))
11582 return ExprError();
11584 if (!getDerived().AlwaysRebuild() && !InitChanged) {
11585 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
11586 // in some cases. We can't reuse it in general, because the syntactic and
11587 // semantic forms are linked, and we can't know that semantic form will
11588 // match even if the syntactic form does.
11591 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
11592 E->getRBraceLoc());
11595 template<typename Derived>
11596 ExprResult
11597 TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
11598 Designation Desig;
11600 // transform the initializer value
11601 ExprResult Init = getDerived().TransformExpr(E->getInit());
11602 if (Init.isInvalid())
11603 return ExprError();
11605 // transform the designators.
11606 SmallVector<Expr*, 4> ArrayExprs;
11607 bool ExprChanged = false;
11608 for (const Designator &D : E->designators()) {
11609 if (D.isFieldDesignator()) {
11610 Desig.AddDesignator(Designator::CreateFieldDesignator(
11611 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
11612 if (D.getField()) {
11613 FieldDecl *Field = cast_or_null<FieldDecl>(
11614 getDerived().TransformDecl(D.getFieldLoc(), D.getField()));
11615 if (Field != D.getField())
11616 // Rebuild the expression when the transformed FieldDecl is
11617 // different to the already assigned FieldDecl.
11618 ExprChanged = true;
11619 } else {
11620 // Ensure that the designator expression is rebuilt when there isn't
11621 // a resolved FieldDecl in the designator as we don't want to assign
11622 // a FieldDecl to a pattern designator that will be instantiated again.
11623 ExprChanged = true;
11625 continue;
11628 if (D.isArrayDesignator()) {
11629 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
11630 if (Index.isInvalid())
11631 return ExprError();
11633 Desig.AddDesignator(
11634 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
11636 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
11637 ArrayExprs.push_back(Index.get());
11638 continue;
11641 assert(D.isArrayRangeDesignator() && "New kind of designator?");
11642 ExprResult Start
11643 = getDerived().TransformExpr(E->getArrayRangeStart(D));
11644 if (Start.isInvalid())
11645 return ExprError();
11647 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
11648 if (End.isInvalid())
11649 return ExprError();
11651 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
11652 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
11654 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
11655 End.get() != E->getArrayRangeEnd(D);
11657 ArrayExprs.push_back(Start.get());
11658 ArrayExprs.push_back(End.get());
11661 if (!getDerived().AlwaysRebuild() &&
11662 Init.get() == E->getInit() &&
11663 !ExprChanged)
11664 return E;
11666 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
11667 E->getEqualOrColonLoc(),
11668 E->usesGNUSyntax(), Init.get());
11671 // Seems that if TransformInitListExpr() only works on the syntactic form of an
11672 // InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
11673 template<typename Derived>
11674 ExprResult
11675 TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
11676 DesignatedInitUpdateExpr *E) {
11677 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
11678 "initializer");
11679 return ExprError();
11682 template<typename Derived>
11683 ExprResult
11684 TreeTransform<Derived>::TransformNoInitExpr(
11685 NoInitExpr *E) {
11686 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
11687 return ExprError();
11690 template<typename Derived>
11691 ExprResult
11692 TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
11693 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
11694 return ExprError();
11697 template<typename Derived>
11698 ExprResult
11699 TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
11700 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
11701 return ExprError();
11704 template<typename Derived>
11705 ExprResult
11706 TreeTransform<Derived>::TransformImplicitValueInitExpr(
11707 ImplicitValueInitExpr *E) {
11708 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
11710 // FIXME: Will we ever have proper type location here? Will we actually
11711 // need to transform the type?
11712 QualType T = getDerived().TransformType(E->getType());
11713 if (T.isNull())
11714 return ExprError();
11716 if (!getDerived().AlwaysRebuild() &&
11717 T == E->getType())
11718 return E;
11720 return getDerived().RebuildImplicitValueInitExpr(T);
11723 template<typename Derived>
11724 ExprResult
11725 TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
11726 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
11727 if (!TInfo)
11728 return ExprError();
11730 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
11731 if (SubExpr.isInvalid())
11732 return ExprError();
11734 if (!getDerived().AlwaysRebuild() &&
11735 TInfo == E->getWrittenTypeInfo() &&
11736 SubExpr.get() == E->getSubExpr())
11737 return E;
11739 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
11740 TInfo, E->getRParenLoc());
11743 template<typename Derived>
11744 ExprResult
11745 TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
11746 bool ArgumentChanged = false;
11747 SmallVector<Expr*, 4> Inits;
11748 if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits,
11749 &ArgumentChanged))
11750 return ExprError();
11752 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
11753 Inits,
11754 E->getRParenLoc());
11757 /// Transform an address-of-label expression.
11759 /// By default, the transformation of an address-of-label expression always
11760 /// rebuilds the expression, so that the label identifier can be resolved to
11761 /// the corresponding label statement by semantic analysis.
11762 template<typename Derived>
11763 ExprResult
11764 TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
11765 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
11766 E->getLabel());
11767 if (!LD)
11768 return ExprError();
11770 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
11771 cast<LabelDecl>(LD));
11774 template<typename Derived>
11775 ExprResult
11776 TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
11777 SemaRef.ActOnStartStmtExpr();
11778 StmtResult SubStmt
11779 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
11780 if (SubStmt.isInvalid()) {
11781 SemaRef.ActOnStmtExprError();
11782 return ExprError();
11785 unsigned OldDepth = E->getTemplateDepth();
11786 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
11788 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
11789 SubStmt.get() == E->getSubStmt()) {
11790 // Calling this an 'error' is unintuitive, but it does the right thing.
11791 SemaRef.ActOnStmtExprError();
11792 return SemaRef.MaybeBindToTemporary(E);
11795 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
11796 E->getRParenLoc(), NewDepth);
11799 template<typename Derived>
11800 ExprResult
11801 TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
11802 ExprResult Cond = getDerived().TransformExpr(E->getCond());
11803 if (Cond.isInvalid())
11804 return ExprError();
11806 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11807 if (LHS.isInvalid())
11808 return ExprError();
11810 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11811 if (RHS.isInvalid())
11812 return ExprError();
11814 if (!getDerived().AlwaysRebuild() &&
11815 Cond.get() == E->getCond() &&
11816 LHS.get() == E->getLHS() &&
11817 RHS.get() == E->getRHS())
11818 return E;
11820 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
11821 Cond.get(), LHS.get(), RHS.get(),
11822 E->getRParenLoc());
11825 template<typename Derived>
11826 ExprResult
11827 TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
11828 return E;
11831 template<typename Derived>
11832 ExprResult
11833 TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
11834 switch (E->getOperator()) {
11835 case OO_New:
11836 case OO_Delete:
11837 case OO_Array_New:
11838 case OO_Array_Delete:
11839 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
11841 case OO_Subscript:
11842 case OO_Call: {
11843 // This is a call to an object's operator().
11844 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
11846 // Transform the object itself.
11847 ExprResult Object = getDerived().TransformExpr(E->getArg(0));
11848 if (Object.isInvalid())
11849 return ExprError();
11851 // FIXME: Poor location information
11852 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
11853 static_cast<Expr *>(Object.get())->getEndLoc());
11855 // Transform the call arguments.
11856 SmallVector<Expr*, 8> Args;
11857 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
11858 Args))
11859 return ExprError();
11861 if (E->getOperator() == OO_Subscript)
11862 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
11863 Args, E->getEndLoc());
11865 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
11866 E->getEndLoc());
11869 #define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
11870 case OO_##Name: \
11871 break;
11873 #define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
11874 #include "clang/Basic/OperatorKinds.def"
11876 case OO_Conditional:
11877 llvm_unreachable("conditional operator is not actually overloadable");
11879 case OO_None:
11880 case NUM_OVERLOADED_OPERATORS:
11881 llvm_unreachable("not an overloaded operator?");
11884 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
11885 if (Callee.isInvalid())
11886 return ExprError();
11888 ExprResult First;
11889 if (E->getOperator() == OO_Amp)
11890 First = getDerived().TransformAddressOfOperand(E->getArg(0));
11891 else
11892 First = getDerived().TransformExpr(E->getArg(0));
11893 if (First.isInvalid())
11894 return ExprError();
11896 ExprResult Second;
11897 if (E->getNumArgs() == 2) {
11898 Second = getDerived().TransformExpr(E->getArg(1));
11899 if (Second.isInvalid())
11900 return ExprError();
11903 if (!getDerived().AlwaysRebuild() &&
11904 Callee.get() == E->getCallee() &&
11905 First.get() == E->getArg(0) &&
11906 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
11907 return SemaRef.MaybeBindToTemporary(E);
11909 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
11910 FPOptionsOverride NewOverrides(E->getFPFeatures());
11911 getSema().CurFPFeatures =
11912 NewOverrides.applyOverrides(getSema().getLangOpts());
11913 getSema().FpPragmaStack.CurrentValue = NewOverrides;
11915 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
11916 E->getOperatorLoc(),
11917 Callee.get(),
11918 First.get(),
11919 Second.get());
11922 template<typename Derived>
11923 ExprResult
11924 TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
11925 return getDerived().TransformCallExpr(E);
11928 template <typename Derived>
11929 ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
11930 bool NeedRebuildFunc = E->getIdentKind() == SourceLocExpr::Function &&
11931 getSema().CurContext != E->getParentContext();
11933 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
11934 return E;
11936 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
11937 E->getBeginLoc(), E->getEndLoc(),
11938 getSema().CurContext);
11941 template<typename Derived>
11942 ExprResult
11943 TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
11944 // Transform the callee.
11945 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
11946 if (Callee.isInvalid())
11947 return ExprError();
11949 // Transform exec config.
11950 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
11951 if (EC.isInvalid())
11952 return ExprError();
11954 // Transform arguments.
11955 bool ArgChanged = false;
11956 SmallVector<Expr*, 8> Args;
11957 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
11958 &ArgChanged))
11959 return ExprError();
11961 if (!getDerived().AlwaysRebuild() &&
11962 Callee.get() == E->getCallee() &&
11963 !ArgChanged)
11964 return SemaRef.MaybeBindToTemporary(E);
11966 // FIXME: Wrong source location information for the '('.
11967 SourceLocation FakeLParenLoc
11968 = ((Expr *)Callee.get())->getSourceRange().getBegin();
11969 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
11970 Args,
11971 E->getRParenLoc(), EC.get());
11974 template<typename Derived>
11975 ExprResult
11976 TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
11977 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
11978 if (!Type)
11979 return ExprError();
11981 ExprResult SubExpr
11982 = getDerived().TransformExpr(E->getSubExprAsWritten());
11983 if (SubExpr.isInvalid())
11984 return ExprError();
11986 if (!getDerived().AlwaysRebuild() &&
11987 Type == E->getTypeInfoAsWritten() &&
11988 SubExpr.get() == E->getSubExpr())
11989 return E;
11990 return getDerived().RebuildCXXNamedCastExpr(
11991 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
11992 Type, E->getAngleBrackets().getEnd(),
11993 // FIXME. this should be '(' location
11994 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
11997 template<typename Derived>
11998 ExprResult
11999 TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
12000 TypeSourceInfo *TSI =
12001 getDerived().TransformType(BCE->getTypeInfoAsWritten());
12002 if (!TSI)
12003 return ExprError();
12005 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
12006 if (Sub.isInvalid())
12007 return ExprError();
12009 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
12010 Sub.get(), BCE->getEndLoc());
12013 template<typename Derived>
12014 ExprResult
12015 TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
12016 return getDerived().TransformCXXNamedCastExpr(E);
12019 template<typename Derived>
12020 ExprResult
12021 TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
12022 return getDerived().TransformCXXNamedCastExpr(E);
12025 template<typename Derived>
12026 ExprResult
12027 TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
12028 CXXReinterpretCastExpr *E) {
12029 return getDerived().TransformCXXNamedCastExpr(E);
12032 template<typename Derived>
12033 ExprResult
12034 TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
12035 return getDerived().TransformCXXNamedCastExpr(E);
12038 template<typename Derived>
12039 ExprResult
12040 TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
12041 return getDerived().TransformCXXNamedCastExpr(E);
12044 template<typename Derived>
12045 ExprResult
12046 TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
12047 CXXFunctionalCastExpr *E) {
12048 TypeSourceInfo *Type =
12049 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
12050 if (!Type)
12051 return ExprError();
12053 ExprResult SubExpr
12054 = getDerived().TransformExpr(E->getSubExprAsWritten());
12055 if (SubExpr.isInvalid())
12056 return ExprError();
12058 if (!getDerived().AlwaysRebuild() &&
12059 Type == E->getTypeInfoAsWritten() &&
12060 SubExpr.get() == E->getSubExpr())
12061 return E;
12063 return getDerived().RebuildCXXFunctionalCastExpr(Type,
12064 E->getLParenLoc(),
12065 SubExpr.get(),
12066 E->getRParenLoc(),
12067 E->isListInitialization());
12070 template<typename Derived>
12071 ExprResult
12072 TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
12073 if (E->isTypeOperand()) {
12074 TypeSourceInfo *TInfo
12075 = getDerived().TransformType(E->getTypeOperandSourceInfo());
12076 if (!TInfo)
12077 return ExprError();
12079 if (!getDerived().AlwaysRebuild() &&
12080 TInfo == E->getTypeOperandSourceInfo())
12081 return E;
12083 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
12084 TInfo, E->getEndLoc());
12087 // Typeid's operand is an unevaluated context, unless it's a polymorphic
12088 // type. We must not unilaterally enter unevaluated context here, as then
12089 // semantic processing can re-transform an already transformed operand.
12090 Expr *Op = E->getExprOperand();
12091 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
12092 if (E->isGLValue())
12093 if (auto *RecordT = Op->getType()->getAs<RecordType>())
12094 if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
12095 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
12097 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
12098 Sema::ReuseLambdaContextDecl);
12100 ExprResult SubExpr = getDerived().TransformExpr(Op);
12101 if (SubExpr.isInvalid())
12102 return ExprError();
12104 if (!getDerived().AlwaysRebuild() &&
12105 SubExpr.get() == E->getExprOperand())
12106 return E;
12108 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
12109 SubExpr.get(), E->getEndLoc());
12112 template<typename Derived>
12113 ExprResult
12114 TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
12115 if (E->isTypeOperand()) {
12116 TypeSourceInfo *TInfo
12117 = getDerived().TransformType(E->getTypeOperandSourceInfo());
12118 if (!TInfo)
12119 return ExprError();
12121 if (!getDerived().AlwaysRebuild() &&
12122 TInfo == E->getTypeOperandSourceInfo())
12123 return E;
12125 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
12126 TInfo, E->getEndLoc());
12129 EnterExpressionEvaluationContext Unevaluated(
12130 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
12132 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
12133 if (SubExpr.isInvalid())
12134 return ExprError();
12136 if (!getDerived().AlwaysRebuild() &&
12137 SubExpr.get() == E->getExprOperand())
12138 return E;
12140 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
12141 SubExpr.get(), E->getEndLoc());
12144 template<typename Derived>
12145 ExprResult
12146 TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
12147 return E;
12150 template<typename Derived>
12151 ExprResult
12152 TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
12153 CXXNullPtrLiteralExpr *E) {
12154 return E;
12157 template<typename Derived>
12158 ExprResult
12159 TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
12160 QualType T = getSema().getCurrentThisType();
12162 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
12163 // Mark it referenced in the new context regardless.
12164 // FIXME: this is a bit instantiation-specific.
12165 getSema().MarkThisReferenced(E);
12166 return E;
12169 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
12172 template<typename Derived>
12173 ExprResult
12174 TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
12175 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12176 if (SubExpr.isInvalid())
12177 return ExprError();
12179 if (!getDerived().AlwaysRebuild() &&
12180 SubExpr.get() == E->getSubExpr())
12181 return E;
12183 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
12184 E->isThrownVariableInScope());
12187 template<typename Derived>
12188 ExprResult
12189 TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
12190 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
12191 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
12192 if (!Param)
12193 return ExprError();
12195 ExprResult InitRes;
12196 if (E->hasRewrittenInit()) {
12197 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
12198 if (InitRes.isInvalid())
12199 return ExprError();
12202 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
12203 E->getUsedContext() == SemaRef.CurContext &&
12204 InitRes.get() == E->getRewrittenExpr())
12205 return E;
12207 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
12208 InitRes.get());
12211 template<typename Derived>
12212 ExprResult
12213 TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
12214 FieldDecl *Field = cast_or_null<FieldDecl>(
12215 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
12216 if (!Field)
12217 return ExprError();
12219 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
12220 E->getUsedContext() == SemaRef.CurContext)
12221 return E;
12223 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
12226 template<typename Derived>
12227 ExprResult
12228 TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
12229 CXXScalarValueInitExpr *E) {
12230 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
12231 if (!T)
12232 return ExprError();
12234 if (!getDerived().AlwaysRebuild() &&
12235 T == E->getTypeSourceInfo())
12236 return E;
12238 return getDerived().RebuildCXXScalarValueInitExpr(T,
12239 /*FIXME:*/T->getTypeLoc().getEndLoc(),
12240 E->getRParenLoc());
12243 template<typename Derived>
12244 ExprResult
12245 TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
12246 // Transform the type that we're allocating
12247 TypeSourceInfo *AllocTypeInfo =
12248 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
12249 if (!AllocTypeInfo)
12250 return ExprError();
12252 // Transform the size of the array we're allocating (if any).
12253 std::optional<Expr *> ArraySize;
12254 if (E->isArray()) {
12255 ExprResult NewArraySize;
12256 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
12257 NewArraySize = getDerived().TransformExpr(*OldArraySize);
12258 if (NewArraySize.isInvalid())
12259 return ExprError();
12261 ArraySize = NewArraySize.get();
12264 // Transform the placement arguments (if any).
12265 bool ArgumentChanged = false;
12266 SmallVector<Expr*, 8> PlacementArgs;
12267 if (getDerived().TransformExprs(E->getPlacementArgs(),
12268 E->getNumPlacementArgs(), true,
12269 PlacementArgs, &ArgumentChanged))
12270 return ExprError();
12272 // Transform the initializer (if any).
12273 Expr *OldInit = E->getInitializer();
12274 ExprResult NewInit;
12275 if (OldInit)
12276 NewInit = getDerived().TransformInitializer(OldInit, true);
12277 if (NewInit.isInvalid())
12278 return ExprError();
12280 // Transform new operator and delete operator.
12281 FunctionDecl *OperatorNew = nullptr;
12282 if (E->getOperatorNew()) {
12283 OperatorNew = cast_or_null<FunctionDecl>(
12284 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
12285 if (!OperatorNew)
12286 return ExprError();
12289 FunctionDecl *OperatorDelete = nullptr;
12290 if (E->getOperatorDelete()) {
12291 OperatorDelete = cast_or_null<FunctionDecl>(
12292 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
12293 if (!OperatorDelete)
12294 return ExprError();
12297 if (!getDerived().AlwaysRebuild() &&
12298 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
12299 ArraySize == E->getArraySize() &&
12300 NewInit.get() == OldInit &&
12301 OperatorNew == E->getOperatorNew() &&
12302 OperatorDelete == E->getOperatorDelete() &&
12303 !ArgumentChanged) {
12304 // Mark any declarations we need as referenced.
12305 // FIXME: instantiation-specific.
12306 if (OperatorNew)
12307 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorNew);
12308 if (OperatorDelete)
12309 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
12311 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
12312 QualType ElementType
12313 = SemaRef.Context.getBaseElementType(E->getAllocatedType());
12314 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
12315 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
12316 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
12317 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor);
12322 return E;
12325 QualType AllocType = AllocTypeInfo->getType();
12326 if (!ArraySize) {
12327 // If no array size was specified, but the new expression was
12328 // instantiated with an array type (e.g., "new T" where T is
12329 // instantiated with "int[4]"), extract the outer bound from the
12330 // array type as our array size. We do this with constant and
12331 // dependently-sized array types.
12332 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);
12333 if (!ArrayT) {
12334 // Do nothing
12335 } else if (const ConstantArrayType *ConsArrayT
12336 = dyn_cast<ConstantArrayType>(ArrayT)) {
12337 ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),
12338 SemaRef.Context.getSizeType(),
12339 /*FIXME:*/ E->getBeginLoc());
12340 AllocType = ConsArrayT->getElementType();
12341 } else if (const DependentSizedArrayType *DepArrayT
12342 = dyn_cast<DependentSizedArrayType>(ArrayT)) {
12343 if (DepArrayT->getSizeExpr()) {
12344 ArraySize = DepArrayT->getSizeExpr();
12345 AllocType = DepArrayT->getElementType();
12350 return getDerived().RebuildCXXNewExpr(
12351 E->getBeginLoc(), E->isGlobalNew(),
12352 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
12353 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
12354 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
12357 template<typename Derived>
12358 ExprResult
12359 TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
12360 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
12361 if (Operand.isInvalid())
12362 return ExprError();
12364 // Transform the delete operator, if known.
12365 FunctionDecl *OperatorDelete = nullptr;
12366 if (E->getOperatorDelete()) {
12367 OperatorDelete = cast_or_null<FunctionDecl>(
12368 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
12369 if (!OperatorDelete)
12370 return ExprError();
12373 if (!getDerived().AlwaysRebuild() &&
12374 Operand.get() == E->getArgument() &&
12375 OperatorDelete == E->getOperatorDelete()) {
12376 // Mark any declarations we need as referenced.
12377 // FIXME: instantiation-specific.
12378 if (OperatorDelete)
12379 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
12381 if (!E->getArgument()->isTypeDependent()) {
12382 QualType Destroyed = SemaRef.Context.getBaseElementType(
12383 E->getDestroyedType());
12384 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
12385 CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
12386 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
12387 SemaRef.LookupDestructor(Record));
12391 return E;
12394 return getDerived().RebuildCXXDeleteExpr(
12395 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
12398 template<typename Derived>
12399 ExprResult
12400 TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
12401 CXXPseudoDestructorExpr *E) {
12402 ExprResult Base = getDerived().TransformExpr(E->getBase());
12403 if (Base.isInvalid())
12404 return ExprError();
12406 ParsedType ObjectTypePtr;
12407 bool MayBePseudoDestructor = false;
12408 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
12409 E->getOperatorLoc(),
12410 E->isArrow()? tok::arrow : tok::period,
12411 ObjectTypePtr,
12412 MayBePseudoDestructor);
12413 if (Base.isInvalid())
12414 return ExprError();
12416 QualType ObjectType = ObjectTypePtr.get();
12417 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
12418 if (QualifierLoc) {
12419 QualifierLoc
12420 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
12421 if (!QualifierLoc)
12422 return ExprError();
12424 CXXScopeSpec SS;
12425 SS.Adopt(QualifierLoc);
12427 PseudoDestructorTypeStorage Destroyed;
12428 if (E->getDestroyedTypeInfo()) {
12429 TypeSourceInfo *DestroyedTypeInfo
12430 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
12431 ObjectType, nullptr, SS);
12432 if (!DestroyedTypeInfo)
12433 return ExprError();
12434 Destroyed = DestroyedTypeInfo;
12435 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
12436 // We aren't likely to be able to resolve the identifier down to a type
12437 // now anyway, so just retain the identifier.
12438 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
12439 E->getDestroyedTypeLoc());
12440 } else {
12441 // Look for a destructor known with the given name.
12442 ParsedType T = SemaRef.getDestructorName(E->getTildeLoc(),
12443 *E->getDestroyedTypeIdentifier(),
12444 E->getDestroyedTypeLoc(),
12445 /*Scope=*/nullptr,
12446 SS, ObjectTypePtr,
12447 false);
12448 if (!T)
12449 return ExprError();
12451 Destroyed
12452 = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),
12453 E->getDestroyedTypeLoc());
12456 TypeSourceInfo *ScopeTypeInfo = nullptr;
12457 if (E->getScopeTypeInfo()) {
12458 CXXScopeSpec EmptySS;
12459 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
12460 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
12461 if (!ScopeTypeInfo)
12462 return ExprError();
12465 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
12466 E->getOperatorLoc(),
12467 E->isArrow(),
12469 ScopeTypeInfo,
12470 E->getColonColonLoc(),
12471 E->getTildeLoc(),
12472 Destroyed);
12475 template <typename Derived>
12476 bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
12477 bool RequiresADL,
12478 LookupResult &R) {
12479 // Transform all the decls.
12480 bool AllEmptyPacks = true;
12481 for (auto *OldD : Old->decls()) {
12482 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
12483 if (!InstD) {
12484 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
12485 // This can happen because of dependent hiding.
12486 if (isa<UsingShadowDecl>(OldD))
12487 continue;
12488 else {
12489 R.clear();
12490 return true;
12494 // Expand using pack declarations.
12495 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
12496 ArrayRef<NamedDecl*> Decls = SingleDecl;
12497 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
12498 Decls = UPD->expansions();
12500 // Expand using declarations.
12501 for (auto *D : Decls) {
12502 if (auto *UD = dyn_cast<UsingDecl>(D)) {
12503 for (auto *SD : UD->shadows())
12504 R.addDecl(SD);
12505 } else {
12506 R.addDecl(D);
12510 AllEmptyPacks &= Decls.empty();
12513 // C++ [temp.res]/8.4.2:
12514 // The program is ill-formed, no diagnostic required, if [...] lookup for
12515 // a name in the template definition found a using-declaration, but the
12516 // lookup in the corresponding scope in the instantiation odoes not find
12517 // any declarations because the using-declaration was a pack expansion and
12518 // the corresponding pack is empty
12519 if (AllEmptyPacks && !RequiresADL) {
12520 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
12521 << isa<UnresolvedMemberExpr>(Old) << Old->getName();
12522 return true;
12525 // Resolve a kind, but don't do any further analysis. If it's
12526 // ambiguous, the callee needs to deal with it.
12527 R.resolveKind();
12528 return false;
12531 template<typename Derived>
12532 ExprResult
12533 TreeTransform<Derived>::TransformUnresolvedLookupExpr(
12534 UnresolvedLookupExpr *Old) {
12535 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
12536 Sema::LookupOrdinaryName);
12538 // Transform the declaration set.
12539 if (TransformOverloadExprDecls(Old, Old->requiresADL(), R))
12540 return ExprError();
12542 // Rebuild the nested-name qualifier, if present.
12543 CXXScopeSpec SS;
12544 if (Old->getQualifierLoc()) {
12545 NestedNameSpecifierLoc QualifierLoc
12546 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
12547 if (!QualifierLoc)
12548 return ExprError();
12550 SS.Adopt(QualifierLoc);
12553 if (Old->getNamingClass()) {
12554 CXXRecordDecl *NamingClass
12555 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
12556 Old->getNameLoc(),
12557 Old->getNamingClass()));
12558 if (!NamingClass) {
12559 R.clear();
12560 return ExprError();
12563 R.setNamingClass(NamingClass);
12566 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
12568 // If we have neither explicit template arguments, nor the template keyword,
12569 // it's a normal declaration name or member reference.
12570 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) {
12571 NamedDecl *D = R.getAsSingle<NamedDecl>();
12572 // In a C++11 unevaluated context, an UnresolvedLookupExpr might refer to an
12573 // instance member. In other contexts, BuildPossibleImplicitMemberExpr will
12574 // give a good diagnostic.
12575 if (D && D->isCXXInstanceMember()) {
12576 return SemaRef.BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, R,
12577 /*TemplateArgs=*/nullptr,
12578 /*Scope=*/nullptr);
12581 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
12584 // If we have template arguments, rebuild them, then rebuild the
12585 // templateid expression.
12586 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
12587 if (Old->hasExplicitTemplateArgs() &&
12588 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
12589 Old->getNumTemplateArgs(),
12590 TransArgs)) {
12591 R.clear();
12592 return ExprError();
12595 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
12596 Old->requiresADL(), &TransArgs);
12599 template<typename Derived>
12600 ExprResult
12601 TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
12602 bool ArgChanged = false;
12603 SmallVector<TypeSourceInfo *, 4> Args;
12604 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
12605 TypeSourceInfo *From = E->getArg(I);
12606 TypeLoc FromTL = From->getTypeLoc();
12607 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
12608 TypeLocBuilder TLB;
12609 TLB.reserve(FromTL.getFullDataSize());
12610 QualType To = getDerived().TransformType(TLB, FromTL);
12611 if (To.isNull())
12612 return ExprError();
12614 if (To == From->getType())
12615 Args.push_back(From);
12616 else {
12617 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12618 ArgChanged = true;
12620 continue;
12623 ArgChanged = true;
12625 // We have a pack expansion. Instantiate it.
12626 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
12627 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
12628 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
12629 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
12631 // Determine whether the set of unexpanded parameter packs can and should
12632 // be expanded.
12633 bool Expand = true;
12634 bool RetainExpansion = false;
12635 std::optional<unsigned> OrigNumExpansions =
12636 ExpansionTL.getTypePtr()->getNumExpansions();
12637 std::optional<unsigned> NumExpansions = OrigNumExpansions;
12638 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
12639 PatternTL.getSourceRange(),
12640 Unexpanded,
12641 Expand, RetainExpansion,
12642 NumExpansions))
12643 return ExprError();
12645 if (!Expand) {
12646 // The transform has determined that we should perform a simple
12647 // transformation on the pack expansion, producing another pack
12648 // expansion.
12649 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
12651 TypeLocBuilder TLB;
12652 TLB.reserve(From->getTypeLoc().getFullDataSize());
12654 QualType To = getDerived().TransformType(TLB, PatternTL);
12655 if (To.isNull())
12656 return ExprError();
12658 To = getDerived().RebuildPackExpansionType(To,
12659 PatternTL.getSourceRange(),
12660 ExpansionTL.getEllipsisLoc(),
12661 NumExpansions);
12662 if (To.isNull())
12663 return ExprError();
12665 PackExpansionTypeLoc ToExpansionTL
12666 = TLB.push<PackExpansionTypeLoc>(To);
12667 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
12668 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12669 continue;
12672 // Expand the pack expansion by substituting for each argument in the
12673 // pack(s).
12674 for (unsigned I = 0; I != *NumExpansions; ++I) {
12675 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
12676 TypeLocBuilder TLB;
12677 TLB.reserve(PatternTL.getFullDataSize());
12678 QualType To = getDerived().TransformType(TLB, PatternTL);
12679 if (To.isNull())
12680 return ExprError();
12682 if (To->containsUnexpandedParameterPack()) {
12683 To = getDerived().RebuildPackExpansionType(To,
12684 PatternTL.getSourceRange(),
12685 ExpansionTL.getEllipsisLoc(),
12686 NumExpansions);
12687 if (To.isNull())
12688 return ExprError();
12690 PackExpansionTypeLoc ToExpansionTL
12691 = TLB.push<PackExpansionTypeLoc>(To);
12692 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
12695 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12698 if (!RetainExpansion)
12699 continue;
12701 // If we're supposed to retain a pack expansion, do so by temporarily
12702 // forgetting the partially-substituted parameter pack.
12703 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
12705 TypeLocBuilder TLB;
12706 TLB.reserve(From->getTypeLoc().getFullDataSize());
12708 QualType To = getDerived().TransformType(TLB, PatternTL);
12709 if (To.isNull())
12710 return ExprError();
12712 To = getDerived().RebuildPackExpansionType(To,
12713 PatternTL.getSourceRange(),
12714 ExpansionTL.getEllipsisLoc(),
12715 NumExpansions);
12716 if (To.isNull())
12717 return ExprError();
12719 PackExpansionTypeLoc ToExpansionTL
12720 = TLB.push<PackExpansionTypeLoc>(To);
12721 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
12722 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
12725 if (!getDerived().AlwaysRebuild() && !ArgChanged)
12726 return E;
12728 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
12729 E->getEndLoc());
12732 template<typename Derived>
12733 ExprResult
12734 TreeTransform<Derived>::TransformConceptSpecializationExpr(
12735 ConceptSpecializationExpr *E) {
12736 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
12737 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
12738 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
12739 Old->NumTemplateArgs, TransArgs))
12740 return ExprError();
12742 return getDerived().RebuildConceptSpecializationExpr(
12743 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
12744 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
12745 &TransArgs);
12748 template<typename Derived>
12749 ExprResult
12750 TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
12751 SmallVector<ParmVarDecl*, 4> TransParams;
12752 SmallVector<QualType, 4> TransParamTypes;
12753 Sema::ExtParameterInfoBuilder ExtParamInfos;
12755 // C++2a [expr.prim.req]p2
12756 // Expressions appearing within a requirement-body are unevaluated operands.
12757 EnterExpressionEvaluationContext Ctx(
12758 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
12759 Sema::ReuseLambdaContextDecl);
12761 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
12762 getSema().Context, getSema().CurContext,
12763 E->getBody()->getBeginLoc());
12765 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
12767 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
12768 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
12769 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
12771 for (ParmVarDecl *Param : TransParams)
12772 if (Param)
12773 Param->setDeclContext(Body);
12775 // On failure to transform, TransformRequiresTypeParams returns an expression
12776 // in the event that the transformation of the type params failed in some way.
12777 // It is expected that this will result in a 'not satisfied' Requires clause
12778 // when instantiating.
12779 if (!TypeParamResult.isUnset())
12780 return TypeParamResult;
12782 SmallVector<concepts::Requirement *, 4> TransReqs;
12783 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
12784 TransReqs))
12785 return ExprError();
12787 for (concepts::Requirement *Req : TransReqs) {
12788 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
12789 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
12790 ER->getReturnTypeRequirement()
12791 .getTypeConstraintTemplateParameterList()->getParam(0)
12792 ->setDeclContext(Body);
12797 return getDerived().RebuildRequiresExpr(E->getRequiresKWLoc(), Body,
12798 TransParams, TransReqs,
12799 E->getRBraceLoc());
12802 template<typename Derived>
12803 bool TreeTransform<Derived>::TransformRequiresExprRequirements(
12804 ArrayRef<concepts::Requirement *> Reqs,
12805 SmallVectorImpl<concepts::Requirement *> &Transformed) {
12806 for (concepts::Requirement *Req : Reqs) {
12807 concepts::Requirement *TransReq = nullptr;
12808 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
12809 TransReq = getDerived().TransformTypeRequirement(TypeReq);
12810 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
12811 TransReq = getDerived().TransformExprRequirement(ExprReq);
12812 else
12813 TransReq = getDerived().TransformNestedRequirement(
12814 cast<concepts::NestedRequirement>(Req));
12815 if (!TransReq)
12816 return true;
12817 Transformed.push_back(TransReq);
12819 return false;
12822 template<typename Derived>
12823 concepts::TypeRequirement *
12824 TreeTransform<Derived>::TransformTypeRequirement(
12825 concepts::TypeRequirement *Req) {
12826 if (Req->isSubstitutionFailure()) {
12827 if (getDerived().AlwaysRebuild())
12828 return getDerived().RebuildTypeRequirement(
12829 Req->getSubstitutionDiagnostic());
12830 return Req;
12832 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
12833 if (!TransType)
12834 return nullptr;
12835 return getDerived().RebuildTypeRequirement(TransType);
12838 template<typename Derived>
12839 concepts::ExprRequirement *
12840 TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
12841 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
12842 if (Req->isExprSubstitutionFailure())
12843 TransExpr = Req->getExprSubstitutionDiagnostic();
12844 else {
12845 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
12846 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
12847 TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
12848 if (TransExprRes.isInvalid())
12849 return nullptr;
12850 TransExpr = TransExprRes.get();
12853 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
12854 const auto &RetReq = Req->getReturnTypeRequirement();
12855 if (RetReq.isEmpty())
12856 TransRetReq.emplace();
12857 else if (RetReq.isSubstitutionFailure())
12858 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
12859 else if (RetReq.isTypeConstraint()) {
12860 TemplateParameterList *OrigTPL =
12861 RetReq.getTypeConstraintTemplateParameterList();
12862 TemplateParameterList *TPL =
12863 getDerived().TransformTemplateParameterList(OrigTPL);
12864 if (!TPL)
12865 return nullptr;
12866 TransRetReq.emplace(TPL);
12868 assert(TransRetReq && "All code paths leading here must set TransRetReq");
12869 if (Expr *E = TransExpr.dyn_cast<Expr *>())
12870 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
12871 Req->getNoexceptLoc(),
12872 std::move(*TransRetReq));
12873 return getDerived().RebuildExprRequirement(
12874 TransExpr.get<concepts::Requirement::SubstitutionDiagnostic *>(),
12875 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
12878 template<typename Derived>
12879 concepts::NestedRequirement *
12880 TreeTransform<Derived>::TransformNestedRequirement(
12881 concepts::NestedRequirement *Req) {
12882 if (Req->hasInvalidConstraint()) {
12883 if (getDerived().AlwaysRebuild())
12884 return getDerived().RebuildNestedRequirement(
12885 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
12886 return Req;
12888 ExprResult TransConstraint =
12889 getDerived().TransformExpr(Req->getConstraintExpr());
12890 if (TransConstraint.isInvalid())
12891 return nullptr;
12892 return getDerived().RebuildNestedRequirement(TransConstraint.get());
12895 template<typename Derived>
12896 ExprResult
12897 TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
12898 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
12899 if (!T)
12900 return ExprError();
12902 if (!getDerived().AlwaysRebuild() &&
12903 T == E->getQueriedTypeSourceInfo())
12904 return E;
12906 ExprResult SubExpr;
12908 EnterExpressionEvaluationContext Unevaluated(
12909 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
12910 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
12911 if (SubExpr.isInvalid())
12912 return ExprError();
12914 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
12915 return E;
12918 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
12919 SubExpr.get(), E->getEndLoc());
12922 template<typename Derived>
12923 ExprResult
12924 TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
12925 ExprResult SubExpr;
12927 EnterExpressionEvaluationContext Unevaluated(
12928 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
12929 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
12930 if (SubExpr.isInvalid())
12931 return ExprError();
12933 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
12934 return E;
12937 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
12938 SubExpr.get(), E->getEndLoc());
12941 template <typename Derived>
12942 ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
12943 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
12944 TypeSourceInfo **RecoveryTSI) {
12945 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
12946 DRE, AddrTaken, RecoveryTSI);
12948 // Propagate both errors and recovered types, which return ExprEmpty.
12949 if (!NewDRE.isUsable())
12950 return NewDRE;
12952 // We got an expr, wrap it up in parens.
12953 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
12954 return PE;
12955 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
12956 PE->getRParen());
12959 template <typename Derived>
12960 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
12961 DependentScopeDeclRefExpr *E) {
12962 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
12963 nullptr);
12966 template <typename Derived>
12967 ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
12968 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
12969 TypeSourceInfo **RecoveryTSI) {
12970 assert(E->getQualifierLoc());
12971 NestedNameSpecifierLoc QualifierLoc =
12972 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
12973 if (!QualifierLoc)
12974 return ExprError();
12975 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
12977 // TODO: If this is a conversion-function-id, verify that the
12978 // destination type name (if present) resolves the same way after
12979 // instantiation as it did in the local scope.
12981 DeclarationNameInfo NameInfo =
12982 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
12983 if (!NameInfo.getName())
12984 return ExprError();
12986 if (!E->hasExplicitTemplateArgs()) {
12987 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
12988 // Note: it is sufficient to compare the Name component of NameInfo:
12989 // if name has not changed, DNLoc has not changed either.
12990 NameInfo.getName() == E->getDeclName())
12991 return E;
12993 return getDerived().RebuildDependentScopeDeclRefExpr(
12994 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
12995 IsAddressOfOperand, RecoveryTSI);
12998 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
12999 if (getDerived().TransformTemplateArguments(
13000 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
13001 return ExprError();
13003 return getDerived().RebuildDependentScopeDeclRefExpr(
13004 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
13005 RecoveryTSI);
13008 template<typename Derived>
13009 ExprResult
13010 TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
13011 // CXXConstructExprs other than for list-initialization and
13012 // CXXTemporaryObjectExpr are always implicit, so when we have
13013 // a 1-argument construction we just transform that argument.
13014 if (getDerived().AllowSkippingCXXConstructExpr() &&
13015 ((E->getNumArgs() == 1 ||
13016 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) &&
13017 (!getDerived().DropCallArgument(E->getArg(0))) &&
13018 !E->isListInitialization()))
13019 return getDerived().TransformInitializer(E->getArg(0),
13020 /*DirectInit*/ false);
13022 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
13024 QualType T = getDerived().TransformType(E->getType());
13025 if (T.isNull())
13026 return ExprError();
13028 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13029 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13030 if (!Constructor)
13031 return ExprError();
13033 bool ArgumentChanged = false;
13034 SmallVector<Expr*, 8> Args;
13036 EnterExpressionEvaluationContext Context(
13037 getSema(), EnterExpressionEvaluationContext::InitList,
13038 E->isListInitialization());
13039 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13040 &ArgumentChanged))
13041 return ExprError();
13044 if (!getDerived().AlwaysRebuild() &&
13045 T == E->getType() &&
13046 Constructor == E->getConstructor() &&
13047 !ArgumentChanged) {
13048 // Mark the constructor as referenced.
13049 // FIXME: Instantiation-specific
13050 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13051 return E;
13054 return getDerived().RebuildCXXConstructExpr(
13055 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
13056 E->hadMultipleCandidates(), E->isListInitialization(),
13057 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
13058 E->getConstructionKind(), E->getParenOrBraceRange());
13061 template<typename Derived>
13062 ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
13063 CXXInheritedCtorInitExpr *E) {
13064 QualType T = getDerived().TransformType(E->getType());
13065 if (T.isNull())
13066 return ExprError();
13068 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13069 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13070 if (!Constructor)
13071 return ExprError();
13073 if (!getDerived().AlwaysRebuild() &&
13074 T == E->getType() &&
13075 Constructor == E->getConstructor()) {
13076 // Mark the constructor as referenced.
13077 // FIXME: Instantiation-specific
13078 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13079 return E;
13082 return getDerived().RebuildCXXInheritedCtorInitExpr(
13083 T, E->getLocation(), Constructor,
13084 E->constructsVBase(), E->inheritedFromVBase());
13087 /// Transform a C++ temporary-binding expression.
13089 /// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
13090 /// transform the subexpression and return that.
13091 template<typename Derived>
13092 ExprResult
13093 TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
13094 if (auto *Dtor = E->getTemporary()->getDestructor())
13095 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
13096 const_cast<CXXDestructorDecl *>(Dtor));
13097 return getDerived().TransformExpr(E->getSubExpr());
13100 /// Transform a C++ expression that contains cleanups that should
13101 /// be run after the expression is evaluated.
13103 /// Since ExprWithCleanups nodes are implicitly generated, we
13104 /// just transform the subexpression and return that.
13105 template<typename Derived>
13106 ExprResult
13107 TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
13108 return getDerived().TransformExpr(E->getSubExpr());
13111 template<typename Derived>
13112 ExprResult
13113 TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
13114 CXXTemporaryObjectExpr *E) {
13115 TypeSourceInfo *T =
13116 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
13117 if (!T)
13118 return ExprError();
13120 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13121 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13122 if (!Constructor)
13123 return ExprError();
13125 bool ArgumentChanged = false;
13126 SmallVector<Expr*, 8> Args;
13127 Args.reserve(E->getNumArgs());
13129 EnterExpressionEvaluationContext Context(
13130 getSema(), EnterExpressionEvaluationContext::InitList,
13131 E->isListInitialization());
13132 if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13133 &ArgumentChanged))
13134 return ExprError();
13137 if (!getDerived().AlwaysRebuild() &&
13138 T == E->getTypeSourceInfo() &&
13139 Constructor == E->getConstructor() &&
13140 !ArgumentChanged) {
13141 // FIXME: Instantiation-specific
13142 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
13143 return SemaRef.MaybeBindToTemporary(E);
13146 // FIXME: We should just pass E->isListInitialization(), but we're not
13147 // prepared to handle list-initialization without a child InitListExpr.
13148 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
13149 return getDerived().RebuildCXXTemporaryObjectExpr(
13150 T, LParenLoc, Args, E->getEndLoc(),
13151 /*ListInitialization=*/LParenLoc.isInvalid());
13154 template<typename Derived>
13155 ExprResult
13156 TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
13157 // Transform any init-capture expressions before entering the scope of the
13158 // lambda body, because they are not semantically within that scope.
13159 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
13160 struct TransformedInitCapture {
13161 // The location of the ... if the result is retaining a pack expansion.
13162 SourceLocation EllipsisLoc;
13163 // Zero or more expansions of the init-capture.
13164 SmallVector<InitCaptureInfoTy, 4> Expansions;
13166 SmallVector<TransformedInitCapture, 4> InitCaptures;
13167 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
13168 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13169 CEnd = E->capture_end();
13170 C != CEnd; ++C) {
13171 if (!E->isInitCapture(C))
13172 continue;
13174 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
13175 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
13177 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
13178 std::optional<unsigned> NumExpansions) {
13179 ExprResult NewExprInitResult = getDerived().TransformInitializer(
13180 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
13182 if (NewExprInitResult.isInvalid()) {
13183 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
13184 return;
13186 Expr *NewExprInit = NewExprInitResult.get();
13188 QualType NewInitCaptureType =
13189 getSema().buildLambdaInitCaptureInitialization(
13190 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
13191 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
13192 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=
13193 VarDecl::CInit,
13194 NewExprInit);
13195 Result.Expansions.push_back(
13196 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
13199 // If this is an init-capture pack, consider expanding the pack now.
13200 if (OldVD->isParameterPack()) {
13201 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
13202 ->getTypeLoc()
13203 .castAs<PackExpansionTypeLoc>();
13204 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
13205 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
13207 // Determine whether the set of unexpanded parameter packs can and should
13208 // be expanded.
13209 bool Expand = true;
13210 bool RetainExpansion = false;
13211 std::optional<unsigned> OrigNumExpansions =
13212 ExpansionTL.getTypePtr()->getNumExpansions();
13213 std::optional<unsigned> NumExpansions = OrigNumExpansions;
13214 if (getDerived().TryExpandParameterPacks(
13215 ExpansionTL.getEllipsisLoc(),
13216 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
13217 RetainExpansion, NumExpansions))
13218 return ExprError();
13219 if (Expand) {
13220 for (unsigned I = 0; I != *NumExpansions; ++I) {
13221 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
13222 SubstInitCapture(SourceLocation(), std::nullopt);
13225 if (!Expand || RetainExpansion) {
13226 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
13227 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
13228 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
13230 } else {
13231 SubstInitCapture(SourceLocation(), std::nullopt);
13235 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
13236 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
13238 // Transform the template parameters, and add them to the current
13239 // instantiation scope. The null case is handled correctly.
13240 auto TPL = getDerived().TransformTemplateParameterList(
13241 E->getTemplateParameterList());
13242 LSI->GLTemplateParameterList = TPL;
13244 // Transform the type of the original lambda's call operator.
13245 // The transformation MUST be done in the CurrentInstantiationScope since
13246 // it introduces a mapping of the original to the newly created
13247 // transformed parameters.
13248 TypeSourceInfo *NewCallOpTSI = nullptr;
13250 TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo();
13251 FunctionProtoTypeLoc OldCallOpFPTL =
13252 OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
13254 TypeLocBuilder NewCallOpTLBuilder;
13255 SmallVector<QualType, 4> ExceptionStorage;
13256 TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
13257 QualType NewCallOpType = TransformFunctionProtoType(
13258 NewCallOpTLBuilder, OldCallOpFPTL, nullptr, Qualifiers(),
13259 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
13260 return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI,
13261 ExceptionStorage, Changed);
13263 if (NewCallOpType.isNull())
13264 return ExprError();
13265 NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context,
13266 NewCallOpType);
13269 // Create the local class that will describe the lambda.
13271 // FIXME: DependencyKind below is wrong when substituting inside a templated
13272 // context that isn't a DeclContext (such as a variable template), or when
13273 // substituting an unevaluated lambda inside of a function's parameter's type
13274 // - as parameter types are not instantiated from within a function's DC. We
13275 // use evaluation contexts to distinguish the function parameter case.
13276 CXXRecordDecl::LambdaDependencyKind DependencyKind =
13277 CXXRecordDecl::LDK_Unknown;
13278 if ((getSema().isUnevaluatedContext() ||
13279 getSema().isConstantEvaluatedContext()) &&
13280 (getSema().CurContext->isFileContext() ||
13281 !getSema().CurContext->getParent()->isDependentContext()))
13282 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
13284 CXXRecordDecl *OldClass = E->getLambdaClass();
13285 CXXRecordDecl *Class =
13286 getSema().createLambdaClosureType(E->getIntroducerRange(), NewCallOpTSI,
13287 DependencyKind, E->getCaptureDefault());
13289 getDerived().transformedLocalDecl(OldClass, {Class});
13291 std::optional<std::tuple<bool, unsigned, unsigned, Decl *>> Mangling;
13292 if (getDerived().ReplacingOriginal())
13293 Mangling = std::make_tuple(OldClass->hasKnownLambdaInternalLinkage(),
13294 OldClass->getLambdaManglingNumber(),
13295 OldClass->getDeviceLambdaManglingNumber(),
13296 OldClass->getLambdaContextDecl());
13298 // Build the call operator.
13299 CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition(
13300 Class, E->getIntroducerRange(), NewCallOpTSI,
13301 E->getCallOperator()->getEndLoc(),
13302 NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
13303 E->getCallOperator()->getConstexprKind(),
13304 E->getCallOperator()->getStorageClass(),
13305 E->getCallOperator()->getTrailingRequiresClause());
13307 LSI->CallOperator = NewCallOperator;
13309 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
13310 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
13312 // Number the lambda for linkage purposes if necessary.
13313 getSema().handleLambdaNumbering(Class, NewCallOperator, Mangling);
13315 // Introduce the context of the call operator.
13316 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
13317 /*NewThisContext*/false);
13319 // Enter the scope of the lambda.
13320 getSema().buildLambdaScope(LSI, NewCallOperator,
13321 E->getIntroducerRange(),
13322 E->getCaptureDefault(),
13323 E->getCaptureDefaultLoc(),
13324 E->hasExplicitParameters(),
13325 E->hasExplicitResultType(),
13326 E->isMutable());
13328 bool Invalid = false;
13330 // Transform captures.
13331 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13332 CEnd = E->capture_end();
13333 C != CEnd; ++C) {
13334 // When we hit the first implicit capture, tell Sema that we've finished
13335 // the list of explicit captures.
13336 if (C->isImplicit())
13337 break;
13339 // Capturing 'this' is trivial.
13340 if (C->capturesThis()) {
13341 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
13342 /*BuildAndDiagnose*/ true, nullptr,
13343 C->getCaptureKind() == LCK_StarThis);
13344 continue;
13346 // Captured expression will be recaptured during captured variables
13347 // rebuilding.
13348 if (C->capturesVLAType())
13349 continue;
13351 // Rebuild init-captures, including the implied field declaration.
13352 if (E->isInitCapture(C)) {
13353 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
13355 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
13356 llvm::SmallVector<Decl*, 4> NewVDs;
13358 for (InitCaptureInfoTy &Info : NewC.Expansions) {
13359 ExprResult Init = Info.first;
13360 QualType InitQualType = Info.second;
13361 if (Init.isInvalid() || InitQualType.isNull()) {
13362 Invalid = true;
13363 break;
13365 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
13366 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
13367 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get());
13368 if (!NewVD) {
13369 Invalid = true;
13370 break;
13372 NewVDs.push_back(NewVD);
13373 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
13376 if (Invalid)
13377 break;
13379 getDerived().transformedLocalDecl(OldVD, NewVDs);
13380 continue;
13383 assert(C->capturesVariable() && "unexpected kind of lambda capture");
13385 // Determine the capture kind for Sema.
13386 Sema::TryCaptureKind Kind
13387 = C->isImplicit()? Sema::TryCapture_Implicit
13388 : C->getCaptureKind() == LCK_ByCopy
13389 ? Sema::TryCapture_ExplicitByVal
13390 : Sema::TryCapture_ExplicitByRef;
13391 SourceLocation EllipsisLoc;
13392 if (C->isPackExpansion()) {
13393 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
13394 bool ShouldExpand = false;
13395 bool RetainExpansion = false;
13396 std::optional<unsigned> NumExpansions;
13397 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
13398 C->getLocation(),
13399 Unexpanded,
13400 ShouldExpand, RetainExpansion,
13401 NumExpansions)) {
13402 Invalid = true;
13403 continue;
13406 if (ShouldExpand) {
13407 // The transform has determined that we should perform an expansion;
13408 // transform and capture each of the arguments.
13409 // expansion of the pattern. Do so.
13410 auto *Pack = cast<VarDecl>(C->getCapturedVar());
13411 for (unsigned I = 0; I != *NumExpansions; ++I) {
13412 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
13413 VarDecl *CapturedVar
13414 = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
13415 Pack));
13416 if (!CapturedVar) {
13417 Invalid = true;
13418 continue;
13421 // Capture the transformed variable.
13422 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
13425 // FIXME: Retain a pack expansion if RetainExpansion is true.
13427 continue;
13430 EllipsisLoc = C->getEllipsisLoc();
13433 // Transform the captured variable.
13434 auto *CapturedVar = cast_or_null<ValueDecl>(
13435 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
13436 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
13437 Invalid = true;
13438 continue;
13441 // Capture the transformed variable.
13442 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
13443 EllipsisLoc);
13445 getSema().finishLambdaExplicitCaptures(LSI);
13447 // FIXME: Sema's lambda-building mechanism expects us to push an expression
13448 // evaluation context even if we're not transforming the function body.
13449 getSema().PushExpressionEvaluationContext(
13450 Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
13452 // Instantiate the body of the lambda expression.
13453 StmtResult Body =
13454 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
13456 // ActOnLambda* will pop the function scope for us.
13457 FuncScopeCleanup.disable();
13459 if (Body.isInvalid()) {
13460 SavedContext.pop();
13461 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
13462 /*IsInstantiation=*/true);
13463 return ExprError();
13466 // Copy the LSI before ActOnFinishFunctionBody removes it.
13467 // FIXME: This is dumb. Store the lambda information somewhere that outlives
13468 // the call operator.
13469 auto LSICopy = *LSI;
13470 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
13471 /*IsInstantiation*/ true);
13472 SavedContext.pop();
13474 return getSema().BuildLambdaExpr(E->getBeginLoc(), Body.get()->getEndLoc(),
13475 &LSICopy);
13478 template<typename Derived>
13479 StmtResult
13480 TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
13481 return TransformStmt(S);
13484 template<typename Derived>
13485 StmtResult
13486 TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
13487 // Transform captures.
13488 for (LambdaExpr::capture_iterator C = E->capture_begin(),
13489 CEnd = E->capture_end();
13490 C != CEnd; ++C) {
13491 // When we hit the first implicit capture, tell Sema that we've finished
13492 // the list of explicit captures.
13493 if (!C->isImplicit())
13494 continue;
13496 // Capturing 'this' is trivial.
13497 if (C->capturesThis()) {
13498 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
13499 /*BuildAndDiagnose*/ true, nullptr,
13500 C->getCaptureKind() == LCK_StarThis);
13501 continue;
13503 // Captured expression will be recaptured during captured variables
13504 // rebuilding.
13505 if (C->capturesVLAType())
13506 continue;
13508 assert(C->capturesVariable() && "unexpected kind of lambda capture");
13509 assert(!E->isInitCapture(C) && "implicit init-capture?");
13511 // Transform the captured variable.
13512 VarDecl *CapturedVar = cast_or_null<VarDecl>(
13513 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
13514 if (!CapturedVar || CapturedVar->isInvalidDecl())
13515 return StmtError();
13517 // Capture the transformed variable.
13518 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
13521 return S;
13524 template<typename Derived>
13525 ExprResult
13526 TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
13527 CXXUnresolvedConstructExpr *E) {
13528 TypeSourceInfo *T =
13529 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
13530 if (!T)
13531 return ExprError();
13533 bool ArgumentChanged = false;
13534 SmallVector<Expr*, 8> Args;
13535 Args.reserve(E->getNumArgs());
13537 EnterExpressionEvaluationContext Context(
13538 getSema(), EnterExpressionEvaluationContext::InitList,
13539 E->isListInitialization());
13540 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
13541 &ArgumentChanged))
13542 return ExprError();
13545 if (!getDerived().AlwaysRebuild() &&
13546 T == E->getTypeSourceInfo() &&
13547 !ArgumentChanged)
13548 return E;
13550 // FIXME: we're faking the locations of the commas
13551 return getDerived().RebuildCXXUnresolvedConstructExpr(
13552 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
13555 template<typename Derived>
13556 ExprResult
13557 TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
13558 CXXDependentScopeMemberExpr *E) {
13559 // Transform the base of the expression.
13560 ExprResult Base((Expr*) nullptr);
13561 Expr *OldBase;
13562 QualType BaseType;
13563 QualType ObjectType;
13564 if (!E->isImplicitAccess()) {
13565 OldBase = E->getBase();
13566 Base = getDerived().TransformExpr(OldBase);
13567 if (Base.isInvalid())
13568 return ExprError();
13570 // Start the member reference and compute the object's type.
13571 ParsedType ObjectTy;
13572 bool MayBePseudoDestructor = false;
13573 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
13574 E->getOperatorLoc(),
13575 E->isArrow()? tok::arrow : tok::period,
13576 ObjectTy,
13577 MayBePseudoDestructor);
13578 if (Base.isInvalid())
13579 return ExprError();
13581 ObjectType = ObjectTy.get();
13582 BaseType = ((Expr*) Base.get())->getType();
13583 } else {
13584 OldBase = nullptr;
13585 BaseType = getDerived().TransformType(E->getBaseType());
13586 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
13589 // Transform the first part of the nested-name-specifier that qualifies
13590 // the member name.
13591 NamedDecl *FirstQualifierInScope
13592 = getDerived().TransformFirstQualifierInScope(
13593 E->getFirstQualifierFoundInScope(),
13594 E->getQualifierLoc().getBeginLoc());
13596 NestedNameSpecifierLoc QualifierLoc;
13597 if (E->getQualifier()) {
13598 QualifierLoc
13599 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
13600 ObjectType,
13601 FirstQualifierInScope);
13602 if (!QualifierLoc)
13603 return ExprError();
13606 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13608 // TODO: If this is a conversion-function-id, verify that the
13609 // destination type name (if present) resolves the same way after
13610 // instantiation as it did in the local scope.
13612 DeclarationNameInfo NameInfo
13613 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
13614 if (!NameInfo.getName())
13615 return ExprError();
13617 if (!E->hasExplicitTemplateArgs()) {
13618 // This is a reference to a member without an explicitly-specified
13619 // template argument list. Optimize for this common case.
13620 if (!getDerived().AlwaysRebuild() &&
13621 Base.get() == OldBase &&
13622 BaseType == E->getBaseType() &&
13623 QualifierLoc == E->getQualifierLoc() &&
13624 NameInfo.getName() == E->getMember() &&
13625 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
13626 return E;
13628 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
13629 BaseType,
13630 E->isArrow(),
13631 E->getOperatorLoc(),
13632 QualifierLoc,
13633 TemplateKWLoc,
13634 FirstQualifierInScope,
13635 NameInfo,
13636 /*TemplateArgs*/nullptr);
13639 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
13640 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13641 E->getNumTemplateArgs(),
13642 TransArgs))
13643 return ExprError();
13645 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
13646 BaseType,
13647 E->isArrow(),
13648 E->getOperatorLoc(),
13649 QualifierLoc,
13650 TemplateKWLoc,
13651 FirstQualifierInScope,
13652 NameInfo,
13653 &TransArgs);
13656 template <typename Derived>
13657 ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
13658 UnresolvedMemberExpr *Old) {
13659 // Transform the base of the expression.
13660 ExprResult Base((Expr *)nullptr);
13661 QualType BaseType;
13662 if (!Old->isImplicitAccess()) {
13663 Base = getDerived().TransformExpr(Old->getBase());
13664 if (Base.isInvalid())
13665 return ExprError();
13666 Base =
13667 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
13668 if (Base.isInvalid())
13669 return ExprError();
13670 BaseType = Base.get()->getType();
13671 } else {
13672 BaseType = getDerived().TransformType(Old->getBaseType());
13675 NestedNameSpecifierLoc QualifierLoc;
13676 if (Old->getQualifierLoc()) {
13677 QualifierLoc =
13678 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
13679 if (!QualifierLoc)
13680 return ExprError();
13683 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
13685 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
13687 // Transform the declaration set.
13688 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ false, R))
13689 return ExprError();
13691 // Determine the naming class.
13692 if (Old->getNamingClass()) {
13693 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
13694 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
13695 if (!NamingClass)
13696 return ExprError();
13698 R.setNamingClass(NamingClass);
13701 TemplateArgumentListInfo TransArgs;
13702 if (Old->hasExplicitTemplateArgs()) {
13703 TransArgs.setLAngleLoc(Old->getLAngleLoc());
13704 TransArgs.setRAngleLoc(Old->getRAngleLoc());
13705 if (getDerived().TransformTemplateArguments(
13706 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
13707 return ExprError();
13710 // FIXME: to do this check properly, we will need to preserve the
13711 // first-qualifier-in-scope here, just in case we had a dependent
13712 // base (and therefore couldn't do the check) and a
13713 // nested-name-qualifier (and therefore could do the lookup).
13714 NamedDecl *FirstQualifierInScope = nullptr;
13716 return getDerived().RebuildUnresolvedMemberExpr(
13717 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
13718 TemplateKWLoc, FirstQualifierInScope, R,
13719 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
13722 template<typename Derived>
13723 ExprResult
13724 TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
13725 EnterExpressionEvaluationContext Unevaluated(
13726 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
13727 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
13728 if (SubExpr.isInvalid())
13729 return ExprError();
13731 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
13732 return E;
13734 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
13737 template<typename Derived>
13738 ExprResult
13739 TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
13740 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
13741 if (Pattern.isInvalid())
13742 return ExprError();
13744 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
13745 return E;
13747 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
13748 E->getNumExpansions());
13751 template<typename Derived>
13752 ExprResult
13753 TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
13754 // If E is not value-dependent, then nothing will change when we transform it.
13755 // Note: This is an instantiation-centric view.
13756 if (!E->isValueDependent())
13757 return E;
13759 EnterExpressionEvaluationContext Unevaluated(
13760 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
13762 ArrayRef<TemplateArgument> PackArgs;
13763 TemplateArgument ArgStorage;
13765 // Find the argument list to transform.
13766 if (E->isPartiallySubstituted()) {
13767 PackArgs = E->getPartialArguments();
13768 } else if (E->isValueDependent()) {
13769 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
13770 bool ShouldExpand = false;
13771 bool RetainExpansion = false;
13772 std::optional<unsigned> NumExpansions;
13773 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
13774 Unexpanded,
13775 ShouldExpand, RetainExpansion,
13776 NumExpansions))
13777 return ExprError();
13779 // If we need to expand the pack, build a template argument from it and
13780 // expand that.
13781 if (ShouldExpand) {
13782 auto *Pack = E->getPack();
13783 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) {
13784 ArgStorage = getSema().Context.getPackExpansionType(
13785 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
13786 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {
13787 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
13788 } else {
13789 auto *VD = cast<ValueDecl>(Pack);
13790 ExprResult DRE = getSema().BuildDeclRefExpr(
13791 VD, VD->getType().getNonLValueExprType(getSema().Context),
13792 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
13793 E->getPackLoc());
13794 if (DRE.isInvalid())
13795 return ExprError();
13796 ArgStorage = new (getSema().Context)
13797 PackExpansionExpr(getSema().Context.DependentTy, DRE.get(),
13798 E->getPackLoc(), std::nullopt);
13800 PackArgs = ArgStorage;
13804 // If we're not expanding the pack, just transform the decl.
13805 if (!PackArgs.size()) {
13806 auto *Pack = cast_or_null<NamedDecl>(
13807 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
13808 if (!Pack)
13809 return ExprError();
13810 return getDerived().RebuildSizeOfPackExpr(
13811 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
13812 std::nullopt, std::nullopt);
13815 // Try to compute the result without performing a partial substitution.
13816 std::optional<unsigned> Result = 0;
13817 for (const TemplateArgument &Arg : PackArgs) {
13818 if (!Arg.isPackExpansion()) {
13819 Result = *Result + 1;
13820 continue;
13823 TemplateArgumentLoc ArgLoc;
13824 InventTemplateArgumentLoc(Arg, ArgLoc);
13826 // Find the pattern of the pack expansion.
13827 SourceLocation Ellipsis;
13828 std::optional<unsigned> OrigNumExpansions;
13829 TemplateArgumentLoc Pattern =
13830 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
13831 OrigNumExpansions);
13833 // Substitute under the pack expansion. Do not expand the pack (yet).
13834 TemplateArgumentLoc OutPattern;
13835 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
13836 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
13837 /*Uneval*/ true))
13838 return true;
13840 // See if we can determine the number of arguments from the result.
13841 std::optional<unsigned> NumExpansions =
13842 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
13843 if (!NumExpansions) {
13844 // No: we must be in an alias template expansion, and we're going to need
13845 // to actually expand the packs.
13846 Result = std::nullopt;
13847 break;
13850 Result = *Result + *NumExpansions;
13853 // Common case: we could determine the number of expansions without
13854 // substituting.
13855 if (Result)
13856 return getDerived().RebuildSizeOfPackExpr(
13857 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
13858 *Result, std::nullopt);
13860 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
13861 E->getPackLoc());
13863 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
13864 typedef TemplateArgumentLocInventIterator<
13865 Derived, const TemplateArgument*> PackLocIterator;
13866 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
13867 PackLocIterator(*this, PackArgs.end()),
13868 TransformedPackArgs, /*Uneval*/true))
13869 return ExprError();
13872 // Check whether we managed to fully-expand the pack.
13873 // FIXME: Is it possible for us to do so and not hit the early exit path?
13874 SmallVector<TemplateArgument, 8> Args;
13875 bool PartialSubstitution = false;
13876 for (auto &Loc : TransformedPackArgs.arguments()) {
13877 Args.push_back(Loc.getArgument());
13878 if (Loc.getArgument().isPackExpansion())
13879 PartialSubstitution = true;
13882 if (PartialSubstitution)
13883 return getDerived().RebuildSizeOfPackExpr(
13884 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
13885 std::nullopt, Args);
13887 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
13888 E->getPackLoc(), E->getRParenLoc(),
13889 Args.size(), std::nullopt);
13892 template<typename Derived>
13893 ExprResult
13894 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
13895 SubstNonTypeTemplateParmPackExpr *E) {
13896 // Default behavior is to do nothing with this transformation.
13897 return E;
13900 template<typename Derived>
13901 ExprResult
13902 TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
13903 SubstNonTypeTemplateParmExpr *E) {
13904 // Default behavior is to do nothing with this transformation.
13905 return E;
13908 template<typename Derived>
13909 ExprResult
13910 TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
13911 // Default behavior is to do nothing with this transformation.
13912 return E;
13915 template<typename Derived>
13916 ExprResult
13917 TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
13918 MaterializeTemporaryExpr *E) {
13919 return getDerived().TransformExpr(E->getSubExpr());
13922 template<typename Derived>
13923 ExprResult
13924 TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
13925 UnresolvedLookupExpr *Callee = nullptr;
13926 if (Expr *OldCallee = E->getCallee()) {
13927 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
13928 if (CalleeResult.isInvalid())
13929 return ExprError();
13930 Callee = cast<UnresolvedLookupExpr>(CalleeResult.get());
13933 Expr *Pattern = E->getPattern();
13935 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
13936 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
13937 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
13939 // Determine whether the set of unexpanded parameter packs can and should
13940 // be expanded.
13941 bool Expand = true;
13942 bool RetainExpansion = false;
13943 std::optional<unsigned> OrigNumExpansions = E->getNumExpansions(),
13944 NumExpansions = OrigNumExpansions;
13945 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
13946 Pattern->getSourceRange(),
13947 Unexpanded,
13948 Expand, RetainExpansion,
13949 NumExpansions))
13950 return true;
13952 if (!Expand) {
13953 // Do not expand any packs here, just transform and rebuild a fold
13954 // expression.
13955 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
13957 ExprResult LHS =
13958 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
13959 if (LHS.isInvalid())
13960 return true;
13962 ExprResult RHS =
13963 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
13964 if (RHS.isInvalid())
13965 return true;
13967 if (!getDerived().AlwaysRebuild() &&
13968 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
13969 return E;
13971 return getDerived().RebuildCXXFoldExpr(
13972 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
13973 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
13976 // Formally a fold expression expands to nested parenthesized expressions.
13977 // Enforce this limit to avoid creating trees so deep we can't safely traverse
13978 // them.
13979 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) {
13980 SemaRef.Diag(E->getEllipsisLoc(),
13981 clang::diag::err_fold_expression_limit_exceeded)
13982 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
13983 << E->getSourceRange();
13984 SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);
13985 return ExprError();
13988 // The transform has determined that we should perform an elementwise
13989 // expansion of the pattern. Do so.
13990 ExprResult Result = getDerived().TransformExpr(E->getInit());
13991 if (Result.isInvalid())
13992 return true;
13993 bool LeftFold = E->isLeftFold();
13995 // If we're retaining an expansion for a right fold, it is the innermost
13996 // component and takes the init (if any).
13997 if (!LeftFold && RetainExpansion) {
13998 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14000 ExprResult Out = getDerived().TransformExpr(Pattern);
14001 if (Out.isInvalid())
14002 return true;
14004 Result = getDerived().RebuildCXXFoldExpr(
14005 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
14006 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
14007 if (Result.isInvalid())
14008 return true;
14011 for (unsigned I = 0; I != *NumExpansions; ++I) {
14012 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(
14013 getSema(), LeftFold ? I : *NumExpansions - I - 1);
14014 ExprResult Out = getDerived().TransformExpr(Pattern);
14015 if (Out.isInvalid())
14016 return true;
14018 if (Out.get()->containsUnexpandedParameterPack()) {
14019 // We still have a pack; retain a pack expansion for this slice.
14020 Result = getDerived().RebuildCXXFoldExpr(
14021 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
14022 E->getOperator(), E->getEllipsisLoc(),
14023 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
14024 OrigNumExpansions);
14025 } else if (Result.isUsable()) {
14026 // We've got down to a single element; build a binary operator.
14027 Expr *LHS = LeftFold ? Result.get() : Out.get();
14028 Expr *RHS = LeftFold ? Out.get() : Result.get();
14029 if (Callee)
14030 Result = getDerived().RebuildCXXOperatorCallExpr(
14031 BinaryOperator::getOverloadedOperator(E->getOperator()),
14032 E->getEllipsisLoc(), Callee, LHS, RHS);
14033 else
14034 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
14035 E->getOperator(), LHS, RHS);
14036 } else
14037 Result = Out;
14039 if (Result.isInvalid())
14040 return true;
14043 // If we're retaining an expansion for a left fold, it is the outermost
14044 // component and takes the complete expansion so far as its init (if any).
14045 if (LeftFold && RetainExpansion) {
14046 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14048 ExprResult Out = getDerived().TransformExpr(Pattern);
14049 if (Out.isInvalid())
14050 return true;
14052 Result = getDerived().RebuildCXXFoldExpr(
14053 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
14054 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
14055 if (Result.isInvalid())
14056 return true;
14059 // If we had no init and an empty pack, and we're not retaining an expansion,
14060 // then produce a fallback value or error.
14061 if (Result.isUnset())
14062 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
14063 E->getOperator());
14065 return Result;
14068 template <typename Derived>
14069 ExprResult
14070 TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
14071 SmallVector<Expr *, 4> TransformedInits;
14072 ArrayRef<Expr *> InitExprs = E->getInitExprs();
14073 if (TransformExprs(InitExprs.data(), InitExprs.size(), true,
14074 TransformedInits))
14075 return ExprError();
14077 return getDerived().RebuildCXXParenListInitExpr(
14078 TransformedInits, E->getType(), E->getUserSpecifiedInitExprs().size(),
14079 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
14082 template<typename Derived>
14083 ExprResult
14084 TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
14085 CXXStdInitializerListExpr *E) {
14086 return getDerived().TransformExpr(E->getSubExpr());
14089 template<typename Derived>
14090 ExprResult
14091 TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
14092 return SemaRef.MaybeBindToTemporary(E);
14095 template<typename Derived>
14096 ExprResult
14097 TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
14098 return E;
14101 template<typename Derived>
14102 ExprResult
14103 TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
14104 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14105 if (SubExpr.isInvalid())
14106 return ExprError();
14108 if (!getDerived().AlwaysRebuild() &&
14109 SubExpr.get() == E->getSubExpr())
14110 return E;
14112 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
14115 template<typename Derived>
14116 ExprResult
14117 TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
14118 // Transform each of the elements.
14119 SmallVector<Expr *, 8> Elements;
14120 bool ArgChanged = false;
14121 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
14122 /*IsCall=*/false, Elements, &ArgChanged))
14123 return ExprError();
14125 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14126 return SemaRef.MaybeBindToTemporary(E);
14128 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
14129 Elements.data(),
14130 Elements.size());
14133 template<typename Derived>
14134 ExprResult
14135 TreeTransform<Derived>::TransformObjCDictionaryLiteral(
14136 ObjCDictionaryLiteral *E) {
14137 // Transform each of the elements.
14138 SmallVector<ObjCDictionaryElement, 8> Elements;
14139 bool ArgChanged = false;
14140 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
14141 ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);
14143 if (OrigElement.isPackExpansion()) {
14144 // This key/value element is a pack expansion.
14145 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14146 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
14147 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
14148 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
14150 // Determine whether the set of unexpanded parameter packs can
14151 // and should be expanded.
14152 bool Expand = true;
14153 bool RetainExpansion = false;
14154 std::optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
14155 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14156 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
14157 OrigElement.Value->getEndLoc());
14158 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
14159 PatternRange, Unexpanded, Expand,
14160 RetainExpansion, NumExpansions))
14161 return ExprError();
14163 if (!Expand) {
14164 // The transform has determined that we should perform a simple
14165 // transformation on the pack expansion, producing another pack
14166 // expansion.
14167 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14168 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14169 if (Key.isInvalid())
14170 return ExprError();
14172 if (Key.get() != OrigElement.Key)
14173 ArgChanged = true;
14175 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
14176 if (Value.isInvalid())
14177 return ExprError();
14179 if (Value.get() != OrigElement.Value)
14180 ArgChanged = true;
14182 ObjCDictionaryElement Expansion = {
14183 Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions
14185 Elements.push_back(Expansion);
14186 continue;
14189 // Record right away that the argument was changed. This needs
14190 // to happen even if the array expands to nothing.
14191 ArgChanged = true;
14193 // The transform has determined that we should perform an elementwise
14194 // expansion of the pattern. Do so.
14195 for (unsigned I = 0; I != *NumExpansions; ++I) {
14196 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14197 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14198 if (Key.isInvalid())
14199 return ExprError();
14201 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
14202 if (Value.isInvalid())
14203 return ExprError();
14205 ObjCDictionaryElement Element = {
14206 Key.get(), Value.get(), SourceLocation(), NumExpansions
14209 // If any unexpanded parameter packs remain, we still have a
14210 // pack expansion.
14211 // FIXME: Can this really happen?
14212 if (Key.get()->containsUnexpandedParameterPack() ||
14213 Value.get()->containsUnexpandedParameterPack())
14214 Element.EllipsisLoc = OrigElement.EllipsisLoc;
14216 Elements.push_back(Element);
14219 // FIXME: Retain a pack expansion if RetainExpansion is true.
14221 // We've finished with this pack expansion.
14222 continue;
14225 // Transform and check key.
14226 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
14227 if (Key.isInvalid())
14228 return ExprError();
14230 if (Key.get() != OrigElement.Key)
14231 ArgChanged = true;
14233 // Transform and check value.
14234 ExprResult Value
14235 = getDerived().TransformExpr(OrigElement.Value);
14236 if (Value.isInvalid())
14237 return ExprError();
14239 if (Value.get() != OrigElement.Value)
14240 ArgChanged = true;
14242 ObjCDictionaryElement Element = {Key.get(), Value.get(), SourceLocation(),
14243 std::nullopt};
14244 Elements.push_back(Element);
14247 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14248 return SemaRef.MaybeBindToTemporary(E);
14250 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
14251 Elements);
14254 template<typename Derived>
14255 ExprResult
14256 TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
14257 TypeSourceInfo *EncodedTypeInfo
14258 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
14259 if (!EncodedTypeInfo)
14260 return ExprError();
14262 if (!getDerived().AlwaysRebuild() &&
14263 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
14264 return E;
14266 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
14267 EncodedTypeInfo,
14268 E->getRParenLoc());
14271 template<typename Derived>
14272 ExprResult TreeTransform<Derived>::
14273 TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
14274 // This is a kind of implicit conversion, and it needs to get dropped
14275 // and recomputed for the same general reasons that ImplicitCastExprs
14276 // do, as well a more specific one: this expression is only valid when
14277 // it appears *immediately* as an argument expression.
14278 return getDerived().TransformExpr(E->getSubExpr());
14281 template<typename Derived>
14282 ExprResult TreeTransform<Derived>::
14283 TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
14284 TypeSourceInfo *TSInfo
14285 = getDerived().TransformType(E->getTypeInfoAsWritten());
14286 if (!TSInfo)
14287 return ExprError();
14289 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
14290 if (Result.isInvalid())
14291 return ExprError();
14293 if (!getDerived().AlwaysRebuild() &&
14294 TSInfo == E->getTypeInfoAsWritten() &&
14295 Result.get() == E->getSubExpr())
14296 return E;
14298 return SemaRef.BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(),
14299 E->getBridgeKeywordLoc(), TSInfo,
14300 Result.get());
14303 template <typename Derived>
14304 ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
14305 ObjCAvailabilityCheckExpr *E) {
14306 return E;
14309 template<typename Derived>
14310 ExprResult
14311 TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
14312 // Transform arguments.
14313 bool ArgChanged = false;
14314 SmallVector<Expr*, 8> Args;
14315 Args.reserve(E->getNumArgs());
14316 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
14317 &ArgChanged))
14318 return ExprError();
14320 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
14321 // Class message: transform the receiver type.
14322 TypeSourceInfo *ReceiverTypeInfo
14323 = getDerived().TransformType(E->getClassReceiverTypeInfo());
14324 if (!ReceiverTypeInfo)
14325 return ExprError();
14327 // If nothing changed, just retain the existing message send.
14328 if (!getDerived().AlwaysRebuild() &&
14329 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
14330 return SemaRef.MaybeBindToTemporary(E);
14332 // Build a new class message send.
14333 SmallVector<SourceLocation, 16> SelLocs;
14334 E->getSelectorLocs(SelLocs);
14335 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
14336 E->getSelector(),
14337 SelLocs,
14338 E->getMethodDecl(),
14339 E->getLeftLoc(),
14340 Args,
14341 E->getRightLoc());
14343 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
14344 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
14345 if (!E->getMethodDecl())
14346 return ExprError();
14348 // Build a new class message send to 'super'.
14349 SmallVector<SourceLocation, 16> SelLocs;
14350 E->getSelectorLocs(SelLocs);
14351 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
14352 E->getSelector(),
14353 SelLocs,
14354 E->getReceiverType(),
14355 E->getMethodDecl(),
14356 E->getLeftLoc(),
14357 Args,
14358 E->getRightLoc());
14361 // Instance message: transform the receiver
14362 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
14363 "Only class and instance messages may be instantiated");
14364 ExprResult Receiver
14365 = getDerived().TransformExpr(E->getInstanceReceiver());
14366 if (Receiver.isInvalid())
14367 return ExprError();
14369 // If nothing changed, just retain the existing message send.
14370 if (!getDerived().AlwaysRebuild() &&
14371 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
14372 return SemaRef.MaybeBindToTemporary(E);
14374 // Build a new instance message send.
14375 SmallVector<SourceLocation, 16> SelLocs;
14376 E->getSelectorLocs(SelLocs);
14377 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
14378 E->getSelector(),
14379 SelLocs,
14380 E->getMethodDecl(),
14381 E->getLeftLoc(),
14382 Args,
14383 E->getRightLoc());
14386 template<typename Derived>
14387 ExprResult
14388 TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
14389 return E;
14392 template<typename Derived>
14393 ExprResult
14394 TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
14395 return E;
14398 template<typename Derived>
14399 ExprResult
14400 TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
14401 // Transform the base expression.
14402 ExprResult Base = getDerived().TransformExpr(E->getBase());
14403 if (Base.isInvalid())
14404 return ExprError();
14406 // We don't need to transform the ivar; it will never change.
14408 // If nothing changed, just retain the existing expression.
14409 if (!getDerived().AlwaysRebuild() &&
14410 Base.get() == E->getBase())
14411 return E;
14413 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
14414 E->getLocation(),
14415 E->isArrow(), E->isFreeIvar());
14418 template<typename Derived>
14419 ExprResult
14420 TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
14421 // 'super' and types never change. Property never changes. Just
14422 // retain the existing expression.
14423 if (!E->isObjectReceiver())
14424 return E;
14426 // Transform the base expression.
14427 ExprResult Base = getDerived().TransformExpr(E->getBase());
14428 if (Base.isInvalid())
14429 return ExprError();
14431 // We don't need to transform the property; it will never change.
14433 // If nothing changed, just retain the existing expression.
14434 if (!getDerived().AlwaysRebuild() &&
14435 Base.get() == E->getBase())
14436 return E;
14438 if (E->isExplicitProperty())
14439 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
14440 E->getExplicitProperty(),
14441 E->getLocation());
14443 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
14444 SemaRef.Context.PseudoObjectTy,
14445 E->getImplicitPropertyGetter(),
14446 E->getImplicitPropertySetter(),
14447 E->getLocation());
14450 template<typename Derived>
14451 ExprResult
14452 TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
14453 // Transform the base expression.
14454 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
14455 if (Base.isInvalid())
14456 return ExprError();
14458 // Transform the key expression.
14459 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
14460 if (Key.isInvalid())
14461 return ExprError();
14463 // If nothing changed, just retain the existing expression.
14464 if (!getDerived().AlwaysRebuild() &&
14465 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
14466 return E;
14468 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
14469 Base.get(), Key.get(),
14470 E->getAtIndexMethodDecl(),
14471 E->setAtIndexMethodDecl());
14474 template<typename Derived>
14475 ExprResult
14476 TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
14477 // Transform the base expression.
14478 ExprResult Base = getDerived().TransformExpr(E->getBase());
14479 if (Base.isInvalid())
14480 return ExprError();
14482 // If nothing changed, just retain the existing expression.
14483 if (!getDerived().AlwaysRebuild() &&
14484 Base.get() == E->getBase())
14485 return E;
14487 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
14488 E->getOpLoc(),
14489 E->isArrow());
14492 template<typename Derived>
14493 ExprResult
14494 TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
14495 bool ArgumentChanged = false;
14496 SmallVector<Expr*, 8> SubExprs;
14497 SubExprs.reserve(E->getNumSubExprs());
14498 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
14499 SubExprs, &ArgumentChanged))
14500 return ExprError();
14502 if (!getDerived().AlwaysRebuild() &&
14503 !ArgumentChanged)
14504 return E;
14506 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
14507 SubExprs,
14508 E->getRParenLoc());
14511 template<typename Derived>
14512 ExprResult
14513 TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
14514 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
14515 if (SrcExpr.isInvalid())
14516 return ExprError();
14518 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
14519 if (!Type)
14520 return ExprError();
14522 if (!getDerived().AlwaysRebuild() &&
14523 Type == E->getTypeSourceInfo() &&
14524 SrcExpr.get() == E->getSrcExpr())
14525 return E;
14527 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
14528 SrcExpr.get(), Type,
14529 E->getRParenLoc());
14532 template<typename Derived>
14533 ExprResult
14534 TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
14535 BlockDecl *oldBlock = E->getBlockDecl();
14537 SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr);
14538 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
14540 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
14541 blockScope->TheDecl->setBlockMissingReturnType(
14542 oldBlock->blockMissingReturnType());
14544 SmallVector<ParmVarDecl*, 4> params;
14545 SmallVector<QualType, 4> paramTypes;
14547 const FunctionProtoType *exprFunctionType = E->getFunctionType();
14549 // Parameter substitution.
14550 Sema::ExtParameterInfoBuilder extParamInfos;
14551 if (getDerived().TransformFunctionTypeParams(
14552 E->getCaretLocation(), oldBlock->parameters(), nullptr,
14553 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
14554 extParamInfos)) {
14555 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
14556 return ExprError();
14559 QualType exprResultType =
14560 getDerived().TransformType(exprFunctionType->getReturnType());
14562 auto epi = exprFunctionType->getExtProtoInfo();
14563 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size());
14565 QualType functionType =
14566 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
14567 blockScope->FunctionType = functionType;
14569 // Set the parameters on the block decl.
14570 if (!params.empty())
14571 blockScope->TheDecl->setParams(params);
14573 if (!oldBlock->blockMissingReturnType()) {
14574 blockScope->HasImplicitReturnType = false;
14575 blockScope->ReturnType = exprResultType;
14578 // Transform the body
14579 StmtResult body = getDerived().TransformStmt(E->getBody());
14580 if (body.isInvalid()) {
14581 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
14582 return ExprError();
14585 #ifndef NDEBUG
14586 // In builds with assertions, make sure that we captured everything we
14587 // captured before.
14588 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
14589 for (const auto &I : oldBlock->captures()) {
14590 VarDecl *oldCapture = I.getVariable();
14592 // Ignore parameter packs.
14593 if (oldCapture->isParameterPack())
14594 continue;
14596 VarDecl *newCapture =
14597 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
14598 oldCapture));
14599 assert(blockScope->CaptureMap.count(newCapture));
14601 assert(oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured());
14603 #endif
14605 return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(),
14606 /*Scope=*/nullptr);
14609 template<typename Derived>
14610 ExprResult
14611 TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
14612 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
14613 if (SrcExpr.isInvalid())
14614 return ExprError();
14616 QualType Type = getDerived().TransformType(E->getType());
14618 return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(),
14619 E->getRParenLoc());
14622 template<typename Derived>
14623 ExprResult
14624 TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
14625 bool ArgumentChanged = false;
14626 SmallVector<Expr*, 8> SubExprs;
14627 SubExprs.reserve(E->getNumSubExprs());
14628 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
14629 SubExprs, &ArgumentChanged))
14630 return ExprError();
14632 if (!getDerived().AlwaysRebuild() &&
14633 !ArgumentChanged)
14634 return E;
14636 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
14637 E->getOp(), E->getRParenLoc());
14640 //===----------------------------------------------------------------------===//
14641 // Type reconstruction
14642 //===----------------------------------------------------------------------===//
14644 template<typename Derived>
14645 QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
14646 SourceLocation Star) {
14647 return SemaRef.BuildPointerType(PointeeType, Star,
14648 getDerived().getBaseEntity());
14651 template<typename Derived>
14652 QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
14653 SourceLocation Star) {
14654 return SemaRef.BuildBlockPointerType(PointeeType, Star,
14655 getDerived().getBaseEntity());
14658 template<typename Derived>
14659 QualType
14660 TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
14661 bool WrittenAsLValue,
14662 SourceLocation Sigil) {
14663 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue,
14664 Sigil, getDerived().getBaseEntity());
14667 template<typename Derived>
14668 QualType
14669 TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
14670 QualType ClassType,
14671 SourceLocation Sigil) {
14672 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil,
14673 getDerived().getBaseEntity());
14676 template<typename Derived>
14677 QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
14678 const ObjCTypeParamDecl *Decl,
14679 SourceLocation ProtocolLAngleLoc,
14680 ArrayRef<ObjCProtocolDecl *> Protocols,
14681 ArrayRef<SourceLocation> ProtocolLocs,
14682 SourceLocation ProtocolRAngleLoc) {
14683 return SemaRef.BuildObjCTypeParamType(Decl,
14684 ProtocolLAngleLoc, Protocols,
14685 ProtocolLocs, ProtocolRAngleLoc,
14686 /*FailOnError=*/true);
14689 template<typename Derived>
14690 QualType TreeTransform<Derived>::RebuildObjCObjectType(
14691 QualType BaseType,
14692 SourceLocation Loc,
14693 SourceLocation TypeArgsLAngleLoc,
14694 ArrayRef<TypeSourceInfo *> TypeArgs,
14695 SourceLocation TypeArgsRAngleLoc,
14696 SourceLocation ProtocolLAngleLoc,
14697 ArrayRef<ObjCProtocolDecl *> Protocols,
14698 ArrayRef<SourceLocation> ProtocolLocs,
14699 SourceLocation ProtocolRAngleLoc) {
14700 return SemaRef.BuildObjCObjectType(BaseType, Loc, TypeArgsLAngleLoc, TypeArgs,
14701 TypeArgsRAngleLoc, ProtocolLAngleLoc,
14702 Protocols, ProtocolLocs, ProtocolRAngleLoc,
14703 /*FailOnError=*/true,
14704 /*Rebuilding=*/true);
14707 template<typename Derived>
14708 QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
14709 QualType PointeeType,
14710 SourceLocation Star) {
14711 return SemaRef.Context.getObjCObjectPointerType(PointeeType);
14714 template<typename Derived>
14715 QualType
14716 TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
14717 ArrayType::ArraySizeModifier SizeMod,
14718 const llvm::APInt *Size,
14719 Expr *SizeExpr,
14720 unsigned IndexTypeQuals,
14721 SourceRange BracketsRange) {
14722 if (SizeExpr || !Size)
14723 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
14724 IndexTypeQuals, BracketsRange,
14725 getDerived().getBaseEntity());
14727 QualType Types[] = {
14728 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
14729 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
14730 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
14732 QualType SizeType;
14733 for (const auto &T : Types)
14734 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
14735 SizeType = T;
14736 break;
14739 // Note that we can return a VariableArrayType here in the case where
14740 // the element type was a dependent VariableArrayType.
14741 IntegerLiteral *ArraySize
14742 = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType,
14743 /*FIXME*/BracketsRange.getBegin());
14744 return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize,
14745 IndexTypeQuals, BracketsRange,
14746 getDerived().getBaseEntity());
14749 template<typename Derived>
14750 QualType
14751 TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
14752 ArrayType::ArraySizeModifier SizeMod,
14753 const llvm::APInt &Size,
14754 Expr *SizeExpr,
14755 unsigned IndexTypeQuals,
14756 SourceRange BracketsRange) {
14757 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
14758 IndexTypeQuals, BracketsRange);
14761 template<typename Derived>
14762 QualType
14763 TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
14764 ArrayType::ArraySizeModifier SizeMod,
14765 unsigned IndexTypeQuals,
14766 SourceRange BracketsRange) {
14767 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
14768 IndexTypeQuals, BracketsRange);
14771 template<typename Derived>
14772 QualType
14773 TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
14774 ArrayType::ArraySizeModifier SizeMod,
14775 Expr *SizeExpr,
14776 unsigned IndexTypeQuals,
14777 SourceRange BracketsRange) {
14778 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
14779 SizeExpr,
14780 IndexTypeQuals, BracketsRange);
14783 template<typename Derived>
14784 QualType
14785 TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
14786 ArrayType::ArraySizeModifier SizeMod,
14787 Expr *SizeExpr,
14788 unsigned IndexTypeQuals,
14789 SourceRange BracketsRange) {
14790 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
14791 SizeExpr,
14792 IndexTypeQuals, BracketsRange);
14795 template <typename Derived>
14796 QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
14797 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
14798 return SemaRef.BuildAddressSpaceAttr(PointeeType, AddrSpaceExpr,
14799 AttributeLoc);
14802 template <typename Derived>
14803 QualType
14804 TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
14805 unsigned NumElements,
14806 VectorType::VectorKind VecKind) {
14807 // FIXME: semantic checking!
14808 return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);
14811 template <typename Derived>
14812 QualType TreeTransform<Derived>::RebuildDependentVectorType(
14813 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
14814 VectorType::VectorKind VecKind) {
14815 return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc);
14818 template<typename Derived>
14819 QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
14820 unsigned NumElements,
14821 SourceLocation AttributeLoc) {
14822 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
14823 NumElements, true);
14824 IntegerLiteral *VectorSize
14825 = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
14826 AttributeLoc);
14827 return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
14830 template<typename Derived>
14831 QualType
14832 TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
14833 Expr *SizeExpr,
14834 SourceLocation AttributeLoc) {
14835 return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
14838 template <typename Derived>
14839 QualType TreeTransform<Derived>::RebuildConstantMatrixType(
14840 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
14841 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
14842 NumColumns);
14845 template <typename Derived>
14846 QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
14847 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
14848 SourceLocation AttributeLoc) {
14849 return SemaRef.BuildMatrixType(ElementType, RowExpr, ColumnExpr,
14850 AttributeLoc);
14853 template<typename Derived>
14854 QualType TreeTransform<Derived>::RebuildFunctionProtoType(
14855 QualType T,
14856 MutableArrayRef<QualType> ParamTypes,
14857 const FunctionProtoType::ExtProtoInfo &EPI) {
14858 return SemaRef.BuildFunctionType(T, ParamTypes,
14859 getDerived().getBaseLocation(),
14860 getDerived().getBaseEntity(),
14861 EPI);
14864 template<typename Derived>
14865 QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
14866 return SemaRef.Context.getFunctionNoProtoType(T);
14869 template<typename Derived>
14870 QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
14871 Decl *D) {
14872 assert(D && "no decl found");
14873 if (D->isInvalidDecl()) return QualType();
14875 // FIXME: Doesn't account for ObjCInterfaceDecl!
14876 if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
14877 // A valid resolved using typename pack expansion decl can have multiple
14878 // UsingDecls, but they must each have exactly one type, and it must be
14879 // the same type in every case. But we must have at least one expansion!
14880 if (UPD->expansions().empty()) {
14881 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
14882 << UPD->isCXXClassMember() << UPD;
14883 return QualType();
14886 // We might still have some unresolved types. Try to pick a resolved type
14887 // if we can. The final instantiation will check that the remaining
14888 // unresolved types instantiate to the type we pick.
14889 QualType FallbackT;
14890 QualType T;
14891 for (auto *E : UPD->expansions()) {
14892 QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
14893 if (ThisT.isNull())
14894 continue;
14895 else if (ThisT->getAs<UnresolvedUsingType>())
14896 FallbackT = ThisT;
14897 else if (T.isNull())
14898 T = ThisT;
14899 else
14900 assert(getSema().Context.hasSameType(ThisT, T) &&
14901 "mismatched resolved types in using pack expansion");
14903 return T.isNull() ? FallbackT : T;
14904 } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
14905 assert(Using->hasTypename() &&
14906 "UnresolvedUsingTypenameDecl transformed to non-typename using");
14908 // A valid resolved using typename decl points to exactly one type decl.
14909 assert(++Using->shadow_begin() == Using->shadow_end());
14911 UsingShadowDecl *Shadow = *Using->shadow_begin();
14912 if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), Loc))
14913 return QualType();
14914 return SemaRef.Context.getUsingType(
14915 Shadow, SemaRef.Context.getTypeDeclType(
14916 cast<TypeDecl>(Shadow->getTargetDecl())));
14917 } else {
14918 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
14919 "UnresolvedUsingTypenameDecl transformed to non-using decl");
14920 return SemaRef.Context.getTypeDeclType(
14921 cast<UnresolvedUsingTypenameDecl>(D));
14925 template <typename Derived>
14926 QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
14927 TypeOfKind Kind) {
14928 return SemaRef.BuildTypeofExprType(E, Kind);
14931 template<typename Derived>
14932 QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
14933 TypeOfKind Kind) {
14934 return SemaRef.Context.getTypeOfType(Underlying, Kind);
14937 template <typename Derived>
14938 QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
14939 return SemaRef.BuildDecltypeType(E);
14942 template<typename Derived>
14943 QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
14944 UnaryTransformType::UTTKind UKind,
14945 SourceLocation Loc) {
14946 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
14949 template<typename Derived>
14950 QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
14951 TemplateName Template,
14952 SourceLocation TemplateNameLoc,
14953 TemplateArgumentListInfo &TemplateArgs) {
14954 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
14957 template<typename Derived>
14958 QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
14959 SourceLocation KWLoc) {
14960 return SemaRef.BuildAtomicType(ValueType, KWLoc);
14963 template<typename Derived>
14964 QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
14965 SourceLocation KWLoc,
14966 bool isReadPipe) {
14967 return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc)
14968 : SemaRef.BuildWritePipeType(ValueType, KWLoc);
14971 template <typename Derived>
14972 QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
14973 unsigned NumBits,
14974 SourceLocation Loc) {
14975 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
14976 NumBits, true);
14977 IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,
14978 SemaRef.Context.IntTy, Loc);
14979 return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc);
14982 template <typename Derived>
14983 QualType TreeTransform<Derived>::RebuildDependentBitIntType(
14984 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
14985 return SemaRef.BuildBitIntType(IsUnsigned, NumBitsExpr, Loc);
14988 template<typename Derived>
14989 TemplateName
14990 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
14991 bool TemplateKW,
14992 TemplateDecl *Template) {
14993 return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW,
14994 TemplateName(Template));
14997 template<typename Derived>
14998 TemplateName
14999 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15000 SourceLocation TemplateKWLoc,
15001 const IdentifierInfo &Name,
15002 SourceLocation NameLoc,
15003 QualType ObjectType,
15004 NamedDecl *FirstQualifierInScope,
15005 bool AllowInjectedClassName) {
15006 UnqualifiedId TemplateName;
15007 TemplateName.setIdentifier(&Name, NameLoc);
15008 Sema::TemplateTy Template;
15009 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
15010 TemplateName, ParsedType::make(ObjectType),
15011 /*EnteringContext=*/false, Template,
15012 AllowInjectedClassName);
15013 return Template.get();
15016 template<typename Derived>
15017 TemplateName
15018 TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
15019 SourceLocation TemplateKWLoc,
15020 OverloadedOperatorKind Operator,
15021 SourceLocation NameLoc,
15022 QualType ObjectType,
15023 bool AllowInjectedClassName) {
15024 UnqualifiedId Name;
15025 // FIXME: Bogus location information.
15026 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
15027 Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);
15028 Sema::TemplateTy Template;
15029 getSema().ActOnTemplateName(
15030 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(ObjectType),
15031 /*EnteringContext=*/false, Template, AllowInjectedClassName);
15032 return Template.get();
15035 template<typename Derived>
15036 ExprResult
15037 TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
15038 SourceLocation OpLoc,
15039 Expr *OrigCallee,
15040 Expr *First,
15041 Expr *Second) {
15042 Expr *Callee = OrigCallee->IgnoreParenCasts();
15043 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
15045 if (First->getObjectKind() == OK_ObjCProperty) {
15046 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
15047 if (BinaryOperator::isAssignmentOp(Opc))
15048 return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc, Opc,
15049 First, Second);
15050 ExprResult Result = SemaRef.CheckPlaceholderExpr(First);
15051 if (Result.isInvalid())
15052 return ExprError();
15053 First = Result.get();
15056 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
15057 ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
15058 if (Result.isInvalid())
15059 return ExprError();
15060 Second = Result.get();
15063 // Determine whether this should be a builtin operation.
15064 if (Op == OO_Subscript) {
15065 if (!First->getType()->isOverloadableType() &&
15066 !Second->getType()->isOverloadableType())
15067 return getSema().CreateBuiltinArraySubscriptExpr(
15068 First, Callee->getBeginLoc(), Second, OpLoc);
15069 } else if (Op == OO_Arrow) {
15070 // It is possible that the type refers to a RecoveryExpr created earlier
15071 // in the tree transformation.
15072 if (First->getType()->isDependentType())
15073 return ExprError();
15074 // -> is never a builtin operation.
15075 return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);
15076 } else if (Second == nullptr || isPostIncDec) {
15077 if (!First->getType()->isOverloadableType() ||
15078 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
15079 // The argument is not of overloadable type, or this is an expression
15080 // of the form &Class::member, so try to create a built-in unary
15081 // operation.
15082 UnaryOperatorKind Opc
15083 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
15085 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
15087 } else {
15088 if (!First->getType()->isOverloadableType() &&
15089 !Second->getType()->isOverloadableType()) {
15090 // Neither of the arguments is an overloadable type, so try to
15091 // create a built-in binary operation.
15092 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
15093 ExprResult Result
15094 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
15095 if (Result.isInvalid())
15096 return ExprError();
15098 return Result;
15102 // Compute the transformed set of functions (and function templates) to be
15103 // used during overload resolution.
15104 UnresolvedSet<16> Functions;
15105 bool RequiresADL;
15107 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
15108 Functions.append(ULE->decls_begin(), ULE->decls_end());
15109 // If the overload could not be resolved in the template definition
15110 // (because we had a dependent argument), ADL is performed as part of
15111 // template instantiation.
15112 RequiresADL = ULE->requiresADL();
15113 } else {
15114 // If we've resolved this to a particular non-member function, just call
15115 // that function. If we resolved it to a member function,
15116 // CreateOverloaded* will find that function for us.
15117 NamedDecl *ND = cast<DeclRefExpr>(Callee)->getDecl();
15118 if (!isa<CXXMethodDecl>(ND))
15119 Functions.addDecl(ND);
15120 RequiresADL = false;
15123 // Add any functions found via argument-dependent lookup.
15124 Expr *Args[2] = { First, Second };
15125 unsigned NumArgs = 1 + (Second != nullptr);
15127 // Create the overloaded operator invocation for unary operators.
15128 if (NumArgs == 1 || isPostIncDec) {
15129 UnaryOperatorKind Opc
15130 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
15131 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First,
15132 RequiresADL);
15135 if (Op == OO_Subscript) {
15136 SourceLocation LBrace;
15137 SourceLocation RBrace;
15139 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee)) {
15140 DeclarationNameLoc NameLoc = DRE->getNameInfo().getInfo();
15141 LBrace = NameLoc.getCXXOperatorNameBeginLoc();
15142 RBrace = NameLoc.getCXXOperatorNameEndLoc();
15143 } else {
15144 LBrace = Callee->getBeginLoc();
15145 RBrace = OpLoc;
15148 return SemaRef.CreateOverloadedArraySubscriptExpr(LBrace, RBrace,
15149 First, Second);
15152 // Create the overloaded operator invocation for binary operators.
15153 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
15154 ExprResult Result = SemaRef.CreateOverloadedBinOp(
15155 OpLoc, Opc, Functions, Args[0], Args[1], RequiresADL);
15156 if (Result.isInvalid())
15157 return ExprError();
15159 return Result;
15162 template<typename Derived>
15163 ExprResult
15164 TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
15165 SourceLocation OperatorLoc,
15166 bool isArrow,
15167 CXXScopeSpec &SS,
15168 TypeSourceInfo *ScopeType,
15169 SourceLocation CCLoc,
15170 SourceLocation TildeLoc,
15171 PseudoDestructorTypeStorage Destroyed) {
15172 QualType BaseType = Base->getType();
15173 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
15174 (!isArrow && !BaseType->getAs<RecordType>()) ||
15175 (isArrow && BaseType->getAs<PointerType>() &&
15176 !BaseType->castAs<PointerType>()->getPointeeType()
15177 ->template getAs<RecordType>())){
15178 // This pseudo-destructor expression is still a pseudo-destructor.
15179 return SemaRef.BuildPseudoDestructorExpr(
15180 Base, OperatorLoc, isArrow ? tok::arrow : tok::period, SS, ScopeType,
15181 CCLoc, TildeLoc, Destroyed);
15184 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
15185 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
15186 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
15187 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
15188 NameInfo.setNamedTypeInfo(DestroyedType);
15190 // The scope type is now known to be a valid nested name specifier
15191 // component. Tack it on to the end of the nested name specifier.
15192 if (ScopeType) {
15193 if (!ScopeType->getType()->getAs<TagType>()) {
15194 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
15195 diag::err_expected_class_or_namespace)
15196 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
15197 return ExprError();
15199 SS.Extend(SemaRef.Context, SourceLocation(), ScopeType->getTypeLoc(),
15200 CCLoc);
15203 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
15204 return getSema().BuildMemberReferenceExpr(Base, BaseType,
15205 OperatorLoc, isArrow,
15206 SS, TemplateKWLoc,
15207 /*FIXME: FirstQualifier*/ nullptr,
15208 NameInfo,
15209 /*TemplateArgs*/ nullptr,
15210 /*S*/nullptr);
15213 template<typename Derived>
15214 StmtResult
15215 TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
15216 SourceLocation Loc = S->getBeginLoc();
15217 CapturedDecl *CD = S->getCapturedDecl();
15218 unsigned NumParams = CD->getNumParams();
15219 unsigned ContextParamPos = CD->getContextParamPosition();
15220 SmallVector<Sema::CapturedParamNameType, 4> Params;
15221 for (unsigned I = 0; I < NumParams; ++I) {
15222 if (I != ContextParamPos) {
15223 Params.push_back(
15224 std::make_pair(
15225 CD->getParam(I)->getName(),
15226 getDerived().TransformType(CD->getParam(I)->getType())));
15227 } else {
15228 Params.push_back(std::make_pair(StringRef(), QualType()));
15231 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
15232 S->getCapturedRegionKind(), Params);
15233 StmtResult Body;
15235 Sema::CompoundScopeRAII CompoundScope(getSema());
15236 Body = getDerived().TransformStmt(S->getCapturedStmt());
15239 if (Body.isInvalid()) {
15240 getSema().ActOnCapturedRegionError();
15241 return StmtError();
15244 return getSema().ActOnCapturedRegionEnd(Body.get());
15247 } // end namespace clang
15249 #endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H