clang 20.0.0git
TreeTransform.h
Go to the documentation of this file.
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.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
14#define LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
15
17#include "TypeLocBuilder.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclObjC.h"
21#include "clang/AST/Expr.h"
22#include "clang/AST/ExprCXX.h"
24#include "clang/AST/ExprObjC.h"
27#include "clang/AST/Stmt.h"
28#include "clang/AST/StmtCXX.h"
29#include "clang/AST/StmtObjC.h"
36#include "clang/Sema/Lookup.h"
42#include "clang/Sema/SemaObjC.h"
46#include "clang/Sema/SemaSYCL.h"
47#include "llvm/ADT/ArrayRef.h"
48#include "llvm/Support/ErrorHandling.h"
49#include <algorithm>
50#include <optional>
51
52using namespace llvm::omp;
53
54namespace clang {
55using namespace sema;
56
57/// A semantic tree transformation that allows one to transform one
58/// abstract syntax tree into another.
59///
60/// A new tree transformation is defined by creating a new subclass \c X of
61/// \c TreeTransform<X> and then overriding certain operations to provide
62/// behavior specific to that transformation. For example, template
63/// instantiation is implemented as a tree transformation where the
64/// transformation of TemplateTypeParmType nodes involves substituting the
65/// template arguments for their corresponding template parameters; a similar
66/// transformation is performed for non-type template parameters and
67/// template template parameters.
68///
69/// This tree-transformation template uses static polymorphism to allow
70/// subclasses to customize any of its operations. Thus, a subclass can
71/// override any of the transformation or rebuild operators by providing an
72/// operation with the same signature as the default implementation. The
73/// overriding function should not be virtual.
74///
75/// Semantic tree transformations are split into two stages, either of which
76/// can be replaced by a subclass. The "transform" step transforms an AST node
77/// or the parts of an AST node using the various transformation functions,
78/// then passes the pieces on to the "rebuild" step, which constructs a new AST
79/// node of the appropriate kind from the pieces. The default transformation
80/// routines recursively transform the operands to composite AST nodes (e.g.,
81/// the pointee type of a PointerType node) and, if any of those operand nodes
82/// were changed by the transformation, invokes the rebuild operation to create
83/// a new AST node.
84///
85/// Subclasses can customize the transformation at various levels. The
86/// most coarse-grained transformations involve replacing TransformType(),
87/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
88/// TransformTemplateName(), or TransformTemplateArgument() with entirely
89/// new implementations.
90///
91/// For more fine-grained transformations, subclasses can replace any of the
92/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
93/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
94/// replacing TransformTemplateTypeParmType() allows template instantiation
95/// to substitute template arguments for their corresponding template
96/// parameters. Additionally, subclasses can override the \c RebuildXXX
97/// functions to control how AST nodes are rebuilt when their operands change.
98/// By default, \c TreeTransform will invoke semantic analysis to rebuild
99/// AST nodes. However, certain other tree transformations (e.g, cloning) may
100/// be able to use more efficient rebuild steps.
101///
102/// There are a handful of other functions that can be overridden, allowing one
103/// to avoid traversing nodes that don't need any transformation
104/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
105/// operands have not changed (\c AlwaysRebuild()), and customize the
106/// default locations and entity names used for type-checking
107/// (\c getBaseLocation(), \c getBaseEntity()).
108template<typename Derived>
110 /// Private RAII object that helps us forget and then re-remember
111 /// the template argument corresponding to a partially-substituted parameter
112 /// pack.
113 class ForgetPartiallySubstitutedPackRAII {
114 Derived &Self;
116
117 public:
118 ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) {
119 Old = Self.ForgetPartiallySubstitutedPack();
120 }
121
122 ~ForgetPartiallySubstitutedPackRAII() {
123 Self.RememberPartiallySubstitutedPack(Old);
124 }
125 };
126
127protected:
129
130 /// The set of local declarations that have been transformed, for
131 /// cases where we are forced to build new declarations within the transformer
132 /// rather than in the subclass (e.g., lambda closure types).
133 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
134
135public:
136 /// Initializes a new tree transformer.
138
139 /// Retrieves a reference to the derived class.
140 Derived &getDerived() { return static_cast<Derived&>(*this); }
141
142 /// Retrieves a reference to the derived class.
143 const Derived &getDerived() const {
144 return static_cast<const Derived&>(*this);
145 }
146
147 static inline ExprResult Owned(Expr *E) { return E; }
148 static inline StmtResult Owned(Stmt *S) { return S; }
149
150 /// Retrieves a reference to the semantic analysis object used for
151 /// this tree transform.
152 Sema &getSema() const { return SemaRef; }
153
154 /// Whether the transformation should always rebuild AST nodes, even
155 /// if none of the children have changed.
156 ///
157 /// Subclasses may override this function to specify when the transformation
158 /// should rebuild all AST nodes.
159 ///
160 /// We must always rebuild all AST nodes when performing variadic template
161 /// pack expansion, in order to avoid violating the AST invariant that each
162 /// statement node appears at most once in its containing declaration.
164
165 /// Whether the transformation is forming an expression or statement that
166 /// replaces the original. In this case, we'll reuse mangling numbers from
167 /// existing lambdas.
168 bool ReplacingOriginal() { return false; }
169
170 /// Wether CXXConstructExpr can be skipped when they are implicit.
171 /// They will be reconstructed when used if needed.
172 /// This is useful when the user that cause rebuilding of the
173 /// CXXConstructExpr is outside of the expression at which the TreeTransform
174 /// started.
175 bool AllowSkippingCXXConstructExpr() { return true; }
176
177 /// Returns the location of the entity being transformed, if that
178 /// information was not available elsewhere in the AST.
179 ///
180 /// By default, returns no source-location information. Subclasses can
181 /// provide an alternative implementation that provides better location
182 /// information.
184
185 /// Returns the name of the entity being transformed, if that
186 /// information was not available elsewhere in the AST.
187 ///
188 /// By default, returns an empty name. Subclasses can provide an alternative
189 /// implementation with a more precise name.
191
192 /// Sets the "base" location and entity when that
193 /// information is known based on another transformation.
194 ///
195 /// By default, the source location and entity are ignored. Subclasses can
196 /// override this function to provide a customized implementation.
198
199 /// RAII object that temporarily sets the base location and entity
200 /// used for reporting diagnostics in types.
202 TreeTransform &Self;
203 SourceLocation OldLocation;
204 DeclarationName OldEntity;
205
206 public:
208 DeclarationName Entity) : Self(Self) {
209 OldLocation = Self.getDerived().getBaseLocation();
210 OldEntity = Self.getDerived().getBaseEntity();
211
212 if (Location.isValid())
213 Self.getDerived().setBase(Location, Entity);
214 }
215
217 Self.getDerived().setBase(OldLocation, OldEntity);
218 }
219 };
220
221 /// Determine whether the given type \p T has already been
222 /// transformed.
223 ///
224 /// Subclasses can provide an alternative implementation of this routine
225 /// to short-circuit evaluation when it is known that a given type will
226 /// not change. For example, template instantiation need not traverse
227 /// non-dependent types.
229 return T.isNull();
230 }
231
232 /// Transform a template parameter depth level.
233 ///
234 /// During a transformation that transforms template parameters, this maps
235 /// an old template parameter depth to a new depth.
236 unsigned TransformTemplateDepth(unsigned Depth) {
237 return Depth;
238 }
239
240 /// Determine whether the given call argument should be dropped, e.g.,
241 /// because it is a default argument.
242 ///
243 /// Subclasses can provide an alternative implementation of this routine to
244 /// determine which kinds of call arguments get dropped. By default,
245 /// CXXDefaultArgument nodes are dropped (prior to transformation).
247 return E->isDefaultArgument();
248 }
249
250 /// Determine whether we should expand a pack expansion with the
251 /// given set of parameter packs into separate arguments by repeatedly
252 /// transforming the pattern.
253 ///
254 /// By default, the transformer never tries to expand pack expansions.
255 /// Subclasses can override this routine to provide different behavior.
256 ///
257 /// \param EllipsisLoc The location of the ellipsis that identifies the
258 /// pack expansion.
259 ///
260 /// \param PatternRange The source range that covers the entire pattern of
261 /// the pack expansion.
262 ///
263 /// \param Unexpanded The set of unexpanded parameter packs within the
264 /// pattern.
265 ///
266 /// \param ShouldExpand Will be set to \c true if the transformer should
267 /// expand the corresponding pack expansions into separate arguments. When
268 /// set, \c NumExpansions must also be set.
269 ///
270 /// \param RetainExpansion Whether the caller should add an unexpanded
271 /// pack expansion after all of the expanded arguments. This is used
272 /// when extending explicitly-specified template argument packs per
273 /// C++0x [temp.arg.explicit]p9.
274 ///
275 /// \param NumExpansions The number of separate arguments that will be in
276 /// the expanded form of the corresponding pack expansion. This is both an
277 /// input and an output parameter, which can be set by the caller if the
278 /// number of expansions is known a priori (e.g., due to a prior substitution)
279 /// and will be set by the callee when the number of expansions is known.
280 /// The callee must set this value when \c ShouldExpand is \c true; it may
281 /// set this value in other cases.
282 ///
283 /// \returns true if an error occurred (e.g., because the parameter packs
284 /// are to be instantiated with arguments of different lengths), false
285 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
286 /// must be set.
288 SourceRange PatternRange,
290 bool &ShouldExpand, bool &RetainExpansion,
291 std::optional<unsigned> &NumExpansions) {
292 ShouldExpand = false;
293 return false;
294 }
295
296 /// "Forget" about the partially-substituted pack template argument,
297 /// when performing an instantiation that must preserve the parameter pack
298 /// use.
299 ///
300 /// This routine is meant to be overridden by the template instantiator.
302 return TemplateArgument();
303 }
304
305 /// "Remember" the partially-substituted pack template argument
306 /// after performing an instantiation that must preserve the parameter pack
307 /// use.
308 ///
309 /// This routine is meant to be overridden by the template instantiator.
311
312 /// Note to the derived class when a function parameter pack is
313 /// being expanded.
315
316 /// Transforms the given type into another type.
317 ///
318 /// By default, this routine transforms a type by creating a
319 /// TypeSourceInfo for it and delegating to the appropriate
320 /// function. This is expensive, but we don't mind, because
321 /// this method is deprecated anyway; all users should be
322 /// switched to storing TypeSourceInfos.
323 ///
324 /// \returns the transformed type.
326
327 /// Transforms the given type-with-location into a new
328 /// type-with-location.
329 ///
330 /// By default, this routine transforms a type by delegating to the
331 /// appropriate TransformXXXType to build a new type. Subclasses
332 /// may override this function (to take over all type
333 /// transformations) or some set of the TransformXXXType functions
334 /// to alter the transformation.
336
337 /// Transform the given type-with-location into a new
338 /// type, collecting location information in the given builder
339 /// as necessary.
340 ///
342
343 /// Transform a type that is permitted to produce a
344 /// DeducedTemplateSpecializationType.
345 ///
346 /// This is used in the (relatively rare) contexts where it is acceptable
347 /// for transformation to produce a class template type with deduced
348 /// template arguments.
349 /// @{
352 /// @}
353
354 /// The reason why the value of a statement is not discarded, if any.
359 };
360
361 /// Transform the given statement.
362 ///
363 /// By default, this routine transforms a statement by delegating to the
364 /// appropriate TransformXXXStmt function to transform a specific kind of
365 /// statement or the TransformExpr() function to transform an expression.
366 /// Subclasses may override this function to transform statements using some
367 /// other mechanism.
368 ///
369 /// \returns the transformed statement.
371
372 /// Transform the given statement.
373 ///
374 /// By default, this routine transforms a statement by delegating to the
375 /// appropriate TransformOMPXXXClause function to transform a specific kind
376 /// of clause. Subclasses may override this function to transform statements
377 /// using some other mechanism.
378 ///
379 /// \returns the transformed OpenMP clause.
381
382 /// Transform the given attribute.
383 ///
384 /// By default, this routine transforms a statement by delegating to the
385 /// appropriate TransformXXXAttr function to transform a specific kind
386 /// of attribute. Subclasses may override this function to transform
387 /// attributed statements/types using some other mechanism.
388 ///
389 /// \returns the transformed attribute
390 const Attr *TransformAttr(const Attr *S);
391
392 // Transform the given statement attribute.
393 //
394 // Delegates to the appropriate TransformXXXAttr function to transform a
395 // specific kind of statement attribute. Unlike the non-statement taking
396 // version of this, this implements all attributes, not just pragmas.
397 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
398 const Attr *A);
399
400 // Transform the specified attribute.
401 //
402 // Subclasses should override the transformation of attributes with a pragma
403 // spelling to transform expressions stored within the attribute.
404 //
405 // \returns the transformed attribute.
406#define ATTR(X) \
407 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
408#include "clang/Basic/AttrList.inc"
409
410 // Transform the specified attribute.
411 //
412 // Subclasses should override the transformation of attributes to do
413 // transformation and checking of statement attributes. By default, this
414 // delegates to the non-statement taking version.
415 //
416 // \returns the transformed attribute.
417#define ATTR(X) \
418 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
419 const X##Attr *A) { \
420 return getDerived().Transform##X##Attr(A); \
421 }
422#include "clang/Basic/AttrList.inc"
423
424 /// Transform the given expression.
425 ///
426 /// By default, this routine transforms an expression by delegating to the
427 /// appropriate TransformXXXExpr function to build a new expression.
428 /// Subclasses may override this function to transform expressions using some
429 /// other mechanism.
430 ///
431 /// \returns the transformed expression.
433
434 /// Transform the given initializer.
435 ///
436 /// By default, this routine transforms an initializer by stripping off the
437 /// semantic nodes added by initialization, then passing the result to
438 /// TransformExpr or TransformExprs.
439 ///
440 /// \returns the transformed initializer.
442
443 /// Transform the given list of expressions.
444 ///
445 /// This routine transforms a list of expressions by invoking
446 /// \c TransformExpr() for each subexpression. However, it also provides
447 /// support for variadic templates by expanding any pack expansions (if the
448 /// derived class permits such expansion) along the way. When pack expansions
449 /// are present, the number of outputs may not equal the number of inputs.
450 ///
451 /// \param Inputs The set of expressions to be transformed.
452 ///
453 /// \param NumInputs The number of expressions in \c Inputs.
454 ///
455 /// \param IsCall If \c true, then this transform is being performed on
456 /// function-call arguments, and any arguments that should be dropped, will
457 /// be.
458 ///
459 /// \param Outputs The transformed input expressions will be added to this
460 /// vector.
461 ///
462 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
463 /// due to transformation.
464 ///
465 /// \returns true if an error occurred, false otherwise.
466 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
468 bool *ArgChanged = nullptr);
469
470 /// Transform the given declaration, which is referenced from a type
471 /// or expression.
472 ///
473 /// By default, acts as the identity function on declarations, unless the
474 /// transformer has had to transform the declaration itself. Subclasses
475 /// may override this function to provide alternate behavior.
477 llvm::DenseMap<Decl *, Decl *>::iterator Known
478 = TransformedLocalDecls.find(D);
479 if (Known != TransformedLocalDecls.end())
480 return Known->second;
481
482 return D;
483 }
484
485 /// Transform the specified condition.
486 ///
487 /// By default, this transforms the variable and expression and rebuilds
488 /// the condition.
490 Expr *Expr,
492
493 /// Transform the attributes associated with the given declaration and
494 /// place them on the new declaration.
495 ///
496 /// By default, this operation does nothing. Subclasses may override this
497 /// behavior to transform attributes.
498 void transformAttrs(Decl *Old, Decl *New) { }
499
500 /// Note that a local declaration has been transformed by this
501 /// transformer.
502 ///
503 /// Local declarations are typically transformed via a call to
504 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
505 /// the transformer itself has to transform the declarations. This routine
506 /// can be overridden by a subclass that keeps track of such mappings.
508 assert(New.size() == 1 &&
509 "must override transformedLocalDecl if performing pack expansion");
510 TransformedLocalDecls[Old] = New.front();
511 }
512
513 /// Transform the definition of the given declaration.
514 ///
515 /// By default, invokes TransformDecl() to transform the declaration.
516 /// Subclasses may override this function to provide alternate behavior.
518 return getDerived().TransformDecl(Loc, D);
519 }
520
521 /// Transform the given declaration, which was the first part of a
522 /// nested-name-specifier in a member access expression.
523 ///
524 /// This specific declaration transformation only applies to the first
525 /// identifier in a nested-name-specifier of a member access expression, e.g.,
526 /// the \c T in \c x->T::member
527 ///
528 /// By default, invokes TransformDecl() to transform the declaration.
529 /// Subclasses may override this function to provide alternate behavior.
531 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
532 }
533
534 /// Transform the set of declarations in an OverloadExpr.
535 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
536 LookupResult &R);
537
538 /// Transform the given nested-name-specifier with source-location
539 /// information.
540 ///
541 /// By default, transforms all of the types and declarations within the
542 /// nested-name-specifier. Subclasses may override this function to provide
543 /// alternate behavior.
546 QualType ObjectType = QualType(),
547 NamedDecl *FirstQualifierInScope = nullptr);
548
549 /// Transform the given declaration name.
550 ///
551 /// By default, transforms the types of conversion function, constructor,
552 /// and destructor names and then (if needed) rebuilds the declaration name.
553 /// Identifiers and selectors are returned unmodified. Subclasses may
554 /// override this function to provide alternate behavior.
557
567
568 /// Transform the given template name.
569 ///
570 /// \param SS The nested-name-specifier that qualifies the template
571 /// name. This nested-name-specifier must already have been transformed.
572 ///
573 /// \param Name The template name to transform.
574 ///
575 /// \param NameLoc The source location of the template name.
576 ///
577 /// \param ObjectType If we're translating a template name within a member
578 /// access expression, this is the type of the object whose member template
579 /// is being referenced.
580 ///
581 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
582 /// also refers to a name within the current (lexical) scope, this is the
583 /// declaration it refers to.
584 ///
585 /// By default, transforms the template name by transforming the declarations
586 /// and nested-name-specifiers that occur within the template name.
587 /// Subclasses may override this function to provide alternate behavior.
590 SourceLocation NameLoc,
591 QualType ObjectType = QualType(),
592 NamedDecl *FirstQualifierInScope = nullptr,
593 bool AllowInjectedClassName = false);
594
595 /// Transform the given template argument.
596 ///
597 /// By default, this operation transforms the type, expression, or
598 /// declaration stored within the template argument and constructs a
599 /// new template argument from the transformed result. Subclasses may
600 /// override this function to provide alternate behavior.
601 ///
602 /// Returns true if there was an error.
604 TemplateArgumentLoc &Output,
605 bool Uneval = false);
606
607 /// Transform the given set of template arguments.
608 ///
609 /// By default, this operation transforms all of the template arguments
610 /// in the input set using \c TransformTemplateArgument(), and appends
611 /// the transformed arguments to the output list.
612 ///
613 /// Note that this overload of \c TransformTemplateArguments() is merely
614 /// a convenience function. Subclasses that wish to override this behavior
615 /// should override the iterator-based member template version.
616 ///
617 /// \param Inputs The set of template arguments to be transformed.
618 ///
619 /// \param NumInputs The number of template arguments in \p Inputs.
620 ///
621 /// \param Outputs The set of transformed template arguments output by this
622 /// routine.
623 ///
624 /// Returns true if an error occurred.
626 unsigned NumInputs,
628 bool Uneval = false) {
629 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
630 Uneval);
631 }
632
633 /// Transform the given set of template arguments.
634 ///
635 /// By default, this operation transforms all of the template arguments
636 /// in the input set using \c TransformTemplateArgument(), and appends
637 /// the transformed arguments to the output list.
638 ///
639 /// \param First An iterator to the first template argument.
640 ///
641 /// \param Last An iterator one step past the last template argument.
642 ///
643 /// \param Outputs The set of transformed template arguments output by this
644 /// routine.
645 ///
646 /// Returns true if an error occurred.
647 template<typename InputIterator>
649 InputIterator Last,
651 bool Uneval = false);
652
653 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
655 TemplateArgumentLoc &ArgLoc);
656
657 /// Fakes up a TypeSourceInfo for a type.
661 }
662
663#define ABSTRACT_TYPELOC(CLASS, PARENT)
664#define TYPELOC(CLASS, PARENT) \
665 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
666#include "clang/AST/TypeLocNodes.def"
667
670 bool SuppressObjCLifetime);
674 bool SuppressObjCLifetime);
675
676 template<typename Fn>
679 CXXRecordDecl *ThisContext,
680 Qualifiers ThisTypeQuals,
682
683 template <typename Fn>
685 Fn TransformModifiedType);
686
689 SmallVectorImpl<QualType> &Exceptions,
690 bool &Changed);
691
693
697 TemplateName Template);
698
702 TemplateName Template,
703 CXXScopeSpec &SS);
704
707 NestedNameSpecifierLoc QualifierLoc);
708
709 /// Transforms the parameters of a function type into the
710 /// given vectors.
711 ///
712 /// The result vectors should be kept in sync; null entries in the
713 /// variables vector are acceptable.
714 ///
715 /// LastParamTransformed, if non-null, will be set to the index of the last
716 /// parameter on which transfromation was started. In the event of an error,
717 /// this will contain the parameter which failed to instantiate.
718 ///
719 /// Return true on error.
722 const QualType *ParamTypes,
723 const FunctionProtoType::ExtParameterInfo *ParamInfos,
725 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
726
729 const QualType *ParamTypes,
730 const FunctionProtoType::ExtParameterInfo *ParamInfos,
733 return getDerived().TransformFunctionTypeParams(
734 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
735 }
736
737 /// Transforms the parameters of a requires expresison into the given vectors.
738 ///
739 /// The result vectors should be kept in sync; null entries in the
740 /// variables vector are acceptable.
741 ///
742 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
743 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
744 /// which are cases where transformation shouldn't continue.
746 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
752 KWLoc, Params, /*ParamTypes=*/nullptr,
753 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
754 return ExprError();
755
756 return ExprResult{};
757 }
758
759 /// Transforms a single function-type parameter. Return null
760 /// on error.
761 ///
762 /// \param indexAdjustment - A number to add to the parameter's
763 /// scope index; can be negative
765 int indexAdjustment,
766 std::optional<unsigned> NumExpansions,
767 bool ExpectParameterPack);
768
769 /// Transform the body of a lambda-expression.
771 /// Alternative implementation of TransformLambdaBody that skips transforming
772 /// the body.
774
777 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
779 }
780
782
785
788 return TPL;
789 }
790
792
794 bool IsAddressOfOperand,
795 TypeSourceInfo **RecoveryTSI);
796
798 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
799 TypeSourceInfo **RecoveryTSI);
800
802 bool IsAddressOfOperand);
803
805
807
808// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
809// amount of stack usage with clang.
810#define STMT(Node, Parent) \
811 LLVM_ATTRIBUTE_NOINLINE \
812 StmtResult Transform##Node(Node *S);
813#define VALUESTMT(Node, Parent) \
814 LLVM_ATTRIBUTE_NOINLINE \
815 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
816#define EXPR(Node, Parent) \
817 LLVM_ATTRIBUTE_NOINLINE \
818 ExprResult Transform##Node(Node *E);
819#define ABSTRACT_STMT(Stmt)
820#include "clang/AST/StmtNodes.inc"
821
822#define GEN_CLANG_CLAUSE_CLASS
823#define CLAUSE_CLASS(Enum, Str, Class) \
824 LLVM_ATTRIBUTE_NOINLINE \
825 OMPClause *Transform##Class(Class *S);
826#include "llvm/Frontend/OpenMP/OMP.inc"
827
828 /// Build a new qualified type given its unqualified type and type location.
829 ///
830 /// By default, this routine adds type qualifiers only to types that can
831 /// have qualifiers, and silently suppresses those qualifiers that are not
832 /// permitted. Subclasses may override this routine to provide different
833 /// behavior.
835
836 /// Build a new pointer type given its pointee type.
837 ///
838 /// By default, performs semantic analysis when building the pointer type.
839 /// Subclasses may override this routine to provide different behavior.
841
842 /// Build a new block pointer type given its pointee type.
843 ///
844 /// By default, performs semantic analysis when building the block pointer
845 /// type. Subclasses may override this routine to provide different behavior.
847
848 /// Build a new reference type given the type it references.
849 ///
850 /// By default, performs semantic analysis when building the
851 /// reference type. Subclasses may override this routine to provide
852 /// different behavior.
853 ///
854 /// \param LValue whether the type was written with an lvalue sigil
855 /// or an rvalue sigil.
857 bool LValue,
858 SourceLocation Sigil);
859
860 /// Build a new member pointer type given the pointee type and the
861 /// class type it refers into.
862 ///
863 /// By default, performs semantic analysis when building the member pointer
864 /// type. Subclasses may override this routine to provide different behavior.
866 SourceLocation Sigil);
867
869 SourceLocation ProtocolLAngleLoc,
871 ArrayRef<SourceLocation> ProtocolLocs,
872 SourceLocation ProtocolRAngleLoc);
873
874 /// Build an Objective-C object type.
875 ///
876 /// By default, performs semantic analysis when building the object type.
877 /// Subclasses may override this routine to provide different behavior.
880 SourceLocation TypeArgsLAngleLoc,
882 SourceLocation TypeArgsRAngleLoc,
883 SourceLocation ProtocolLAngleLoc,
885 ArrayRef<SourceLocation> ProtocolLocs,
886 SourceLocation ProtocolRAngleLoc);
887
888 /// Build a new Objective-C object pointer type given the pointee type.
889 ///
890 /// By default, directly builds the pointer type, with no additional semantic
891 /// analysis.
894
895 /// Build a new array type given the element type, size
896 /// modifier, size of the array (if known), size expression, and index type
897 /// qualifiers.
898 ///
899 /// By default, performs semantic analysis when building the array type.
900 /// Subclasses may override this routine to provide different behavior.
901 /// Also by default, all of the other Rebuild*Array
903 const llvm::APInt *Size, Expr *SizeExpr,
904 unsigned IndexTypeQuals, SourceRange BracketsRange);
905
906 /// Build a new constant array type given the element type, size
907 /// modifier, (known) size of the array, and index type qualifiers.
908 ///
909 /// By default, performs semantic analysis when building the array type.
910 /// Subclasses may override this routine to provide different behavior.
912 ArraySizeModifier SizeMod,
913 const llvm::APInt &Size, Expr *SizeExpr,
914 unsigned IndexTypeQuals,
915 SourceRange BracketsRange);
916
917 /// Build a new incomplete array type given the element type, size
918 /// modifier, and index type qualifiers.
919 ///
920 /// By default, performs semantic analysis when building the array type.
921 /// Subclasses may override this routine to provide different behavior.
923 ArraySizeModifier SizeMod,
924 unsigned IndexTypeQuals,
925 SourceRange BracketsRange);
926
927 /// Build a new variable-length array type given the element type,
928 /// size modifier, size expression, and index type qualifiers.
929 ///
930 /// By default, performs semantic analysis when building the array type.
931 /// Subclasses may override this routine to provide different behavior.
933 ArraySizeModifier SizeMod, Expr *SizeExpr,
934 unsigned IndexTypeQuals,
935 SourceRange BracketsRange);
936
937 /// Build a new dependent-sized array type given the element type,
938 /// size modifier, size expression, and index type qualifiers.
939 ///
940 /// By default, performs semantic analysis when building the array type.
941 /// Subclasses may override this routine to provide different behavior.
943 ArraySizeModifier SizeMod,
944 Expr *SizeExpr,
945 unsigned IndexTypeQuals,
946 SourceRange BracketsRange);
947
948 /// Build a new vector type given the element type and
949 /// number of elements.
950 ///
951 /// By default, performs semantic analysis when building the vector type.
952 /// Subclasses may override this routine to provide different behavior.
953 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
954 VectorKind VecKind);
955
956 /// Build a new potentially dependently-sized extended vector type
957 /// given the element type and number of elements.
958 ///
959 /// By default, performs semantic analysis when building the vector type.
960 /// Subclasses may override this routine to provide different behavior.
962 SourceLocation AttributeLoc, VectorKind);
963
964 /// Build a new extended vector type given the element type and
965 /// number of elements.
966 ///
967 /// By default, performs semantic analysis when building the vector type.
968 /// Subclasses may override this routine to provide different behavior.
969 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
970 SourceLocation AttributeLoc);
971
972 /// Build a new potentially dependently-sized extended vector type
973 /// given the element type and number of elements.
974 ///
975 /// By default, performs semantic analysis when building the vector type.
976 /// Subclasses may override this routine to provide different behavior.
978 Expr *SizeExpr,
979 SourceLocation AttributeLoc);
980
981 /// Build a new matrix type given the element type and dimensions.
982 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
983 unsigned NumColumns);
984
985 /// Build a new matrix type given the type and dependently-defined
986 /// dimensions.
988 Expr *ColumnExpr,
989 SourceLocation AttributeLoc);
990
991 /// Build a new DependentAddressSpaceType or return the pointee
992 /// type variable with the correct address space (retrieved from
993 /// AddrSpaceExpr) applied to it. The former will be returned in cases
994 /// where the address space remains dependent.
995 ///
996 /// By default, performs semantic analysis when building the type with address
997 /// space applied. Subclasses may override this routine to provide different
998 /// behavior.
1000 Expr *AddrSpaceExpr,
1001 SourceLocation AttributeLoc);
1002
1003 /// Build a new function type.
1004 ///
1005 /// By default, performs semantic analysis when building the function type.
1006 /// Subclasses may override this routine to provide different behavior.
1008 MutableArrayRef<QualType> ParamTypes,
1010
1011 /// Build a new unprototyped function type.
1013
1014 /// Rebuild an unresolved typename type, given the decl that
1015 /// the UnresolvedUsingTypenameDecl was transformed to.
1017
1018 /// Build a new type found via an alias.
1020 return SemaRef.Context.getUsingType(Found, Underlying);
1021 }
1022
1023 /// Build a new typedef type.
1025 return SemaRef.Context.getTypeDeclType(Typedef);
1026 }
1027
1028 /// Build a new MacroDefined type.
1030 const IdentifierInfo *MacroII) {
1031 return SemaRef.Context.getMacroQualifiedType(T, MacroII);
1032 }
1033
1034 /// Build a new class/struct/union type.
1037 }
1038
1039 /// Build a new Enum type.
1042 }
1043
1044 /// Build a new typeof(expr) type.
1045 ///
1046 /// By default, performs semantic analysis when building the typeof type.
1047 /// Subclasses may override this routine to provide different behavior.
1049 TypeOfKind Kind);
1050
1051 /// Build a new typeof(type) type.
1052 ///
1053 /// By default, builds a new TypeOfType with the given underlying type.
1055
1056 /// Build a new unary transform type.
1060
1061 /// Build a new C++11 decltype type.
1062 ///
1063 /// By default, performs semantic analysis when building the decltype type.
1064 /// Subclasses may override this routine to provide different behavior.
1066
1069 SourceLocation EllipsisLoc,
1070 bool FullySubstituted,
1071 ArrayRef<QualType> Expansions = {});
1072
1073 /// Build a new C++11 auto type.
1074 ///
1075 /// By default, builds a new AutoType with the given deduced type.
1077 ConceptDecl *TypeConstraintConcept,
1078 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1079 // Note, IsDependent is always false here: we implicitly convert an 'auto'
1080 // which has been deduced to a dependent type into an undeduced 'auto', so
1081 // that we'll retry deduction after the transformation.
1082 return SemaRef.Context.getAutoType(Deduced, Keyword,
1083 /*IsDependent*/ false, /*IsPack=*/false,
1084 TypeConstraintConcept,
1085 TypeConstraintArgs);
1086 }
1087
1088 /// By default, builds a new DeducedTemplateSpecializationType with the given
1089 /// deduced type.
1091 QualType Deduced) {
1093 Template, Deduced, /*IsDependent*/ false);
1094 }
1095
1096 /// Build a new template specialization type.
1097 ///
1098 /// By default, performs semantic analysis when building the template
1099 /// specialization type. Subclasses may override this routine to provide
1100 /// different behavior.
1102 SourceLocation TemplateLoc,
1104
1105 /// Build a new parenthesized type.
1106 ///
1107 /// By default, builds a new ParenType type from the inner type.
1108 /// Subclasses may override this routine to provide different behavior.
1110 return SemaRef.BuildParenType(InnerType);
1111 }
1112
1113 /// Build a new qualified name type.
1114 ///
1115 /// By default, builds a new ElaboratedType type from the keyword,
1116 /// the nested-name-specifier and the named type.
1117 /// Subclasses may override this routine to provide different behavior.
1119 ElaboratedTypeKeyword Keyword,
1120 NestedNameSpecifierLoc QualifierLoc,
1121 QualType Named) {
1122 return SemaRef.Context.getElaboratedType(Keyword,
1123 QualifierLoc.getNestedNameSpecifier(),
1124 Named);
1125 }
1126
1127 /// Build a new typename type that refers to a template-id.
1128 ///
1129 /// By default, builds a new DependentNameType type from the
1130 /// nested-name-specifier and the given type. Subclasses may override
1131 /// this routine to provide different behavior.
1133 ElaboratedTypeKeyword Keyword,
1134 NestedNameSpecifierLoc QualifierLoc,
1135 SourceLocation TemplateKWLoc,
1136 const IdentifierInfo *Name,
1137 SourceLocation NameLoc,
1139 bool AllowInjectedClassName) {
1140 // Rebuild the template name.
1141 // TODO: avoid TemplateName abstraction
1142 CXXScopeSpec SS;
1143 SS.Adopt(QualifierLoc);
1144 TemplateName InstName = getDerived().RebuildTemplateName(
1145 SS, TemplateKWLoc, *Name, NameLoc, QualType(), nullptr,
1146 AllowInjectedClassName);
1147
1148 if (InstName.isNull())
1149 return QualType();
1150
1151 // If it's still dependent, make a dependent specialization.
1152 if (InstName.getAsDependentTemplateName())
1154 Keyword, QualifierLoc.getNestedNameSpecifier(), Name,
1155 Args.arguments());
1156
1157 // Otherwise, make an elaborated type wrapping a non-dependent
1158 // specialization.
1159 QualType T =
1160 getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
1161 if (T.isNull())
1162 return QualType();
1164 Keyword, QualifierLoc.getNestedNameSpecifier(), T);
1165 }
1166
1167 /// Build a new typename type that refers to an identifier.
1168 ///
1169 /// By default, performs semantic analysis when building the typename type
1170 /// (or elaborated type). Subclasses may override this routine to provide
1171 /// different behavior.
1173 SourceLocation KeywordLoc,
1174 NestedNameSpecifierLoc QualifierLoc,
1175 const IdentifierInfo *Id,
1176 SourceLocation IdLoc,
1177 bool DeducedTSTContext) {
1178 CXXScopeSpec SS;
1179 SS.Adopt(QualifierLoc);
1180
1181 if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
1182 // If the name is still dependent, just build a new dependent name type.
1183 if (!SemaRef.computeDeclContext(SS))
1184 return SemaRef.Context.getDependentNameType(Keyword,
1185 QualifierLoc.getNestedNameSpecifier(),
1186 Id);
1187 }
1188
1189 if (Keyword == ElaboratedTypeKeyword::None ||
1191 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1192 *Id, IdLoc, DeducedTSTContext);
1193 }
1194
1196
1197 // We had a dependent elaborated-type-specifier that has been transformed
1198 // into a non-dependent elaborated-type-specifier. Find the tag we're
1199 // referring to.
1201 DeclContext *DC = SemaRef.computeDeclContext(SS, false);
1202 if (!DC)
1203 return QualType();
1204
1206 return QualType();
1207
1208 TagDecl *Tag = nullptr;
1210 switch (Result.getResultKind()) {
1213 break;
1214
1216 Tag = Result.getAsSingle<TagDecl>();
1217 break;
1218
1221 llvm_unreachable("Tag lookup cannot find non-tags");
1222
1224 // Let the LookupResult structure handle ambiguities.
1225 return QualType();
1226 }
1227
1228 if (!Tag) {
1229 // Check where the name exists but isn't a tag type and use that to emit
1230 // better diagnostics.
1233 switch (Result.getResultKind()) {
1237 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1238 Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind);
1239 SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag)
1240 << SomeDecl << NTK << llvm::to_underlying(Kind);
1241 SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
1242 break;
1243 }
1244 default:
1245 SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
1246 << llvm::to_underlying(Kind) << Id << DC
1247 << QualifierLoc.getSourceRange();
1248 break;
1249 }
1250 return QualType();
1251 }
1252
1253 if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false,
1254 IdLoc, Id)) {
1255 SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
1256 SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
1257 return QualType();
1258 }
1259
1260 // Build the elaborated-type-specifier type.
1262 return SemaRef.Context.getElaboratedType(Keyword,
1263 QualifierLoc.getNestedNameSpecifier(),
1264 T);
1265 }
1266
1267 /// Build a new pack expansion type.
1268 ///
1269 /// By default, builds a new PackExpansionType type from the given pattern.
1270 /// Subclasses may override this routine to provide different behavior.
1272 SourceLocation EllipsisLoc,
1273 std::optional<unsigned> NumExpansions) {
1274 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1275 NumExpansions);
1276 }
1277
1278 /// Build a new atomic type given its value type.
1279 ///
1280 /// By default, performs semantic analysis when building the atomic type.
1281 /// Subclasses may override this routine to provide different behavior.
1283
1284 /// Build a new pipe type given its value type.
1286 bool isReadPipe);
1287
1288 /// Build a bit-precise int given its value type.
1289 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1291
1292 /// Build a dependent bit-precise int given its value type.
1293 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1295
1296 /// Build a new template name given a nested name specifier, a flag
1297 /// indicating whether the "template" keyword was provided, and the template
1298 /// that the template name refers to.
1299 ///
1300 /// By default, builds the new template name directly. Subclasses may override
1301 /// this routine to provide different behavior.
1303 bool TemplateKW,
1304 TemplateDecl *Template);
1305
1306 /// Build a new template name given a nested name specifier and the
1307 /// name that is referred to as a template.
1308 ///
1309 /// By default, performs semantic analysis to determine whether the name can
1310 /// be resolved to a specific template, then builds the appropriate kind of
1311 /// template name. Subclasses may override this routine to provide different
1312 /// behavior.
1314 SourceLocation TemplateKWLoc,
1315 const IdentifierInfo &Name,
1316 SourceLocation NameLoc, QualType ObjectType,
1317 NamedDecl *FirstQualifierInScope,
1318 bool AllowInjectedClassName);
1319
1320 /// Build a new template name given a nested name specifier and the
1321 /// overloaded operator name that is referred to as a template.
1322 ///
1323 /// By default, performs semantic analysis to determine whether the name can
1324 /// be resolved to a specific template, then builds the appropriate kind of
1325 /// template name. Subclasses may override this routine to provide different
1326 /// behavior.
1328 SourceLocation TemplateKWLoc,
1329 OverloadedOperatorKind Operator,
1330 SourceLocation NameLoc, QualType ObjectType,
1331 bool AllowInjectedClassName);
1332
1333 /// Build a new template name given a template template parameter pack
1334 /// and the
1335 ///
1336 /// By default, performs semantic analysis to determine whether the name can
1337 /// be resolved to a specific template, then builds the appropriate kind of
1338 /// template name. Subclasses may override this routine to provide different
1339 /// behavior.
1341 Decl *AssociatedDecl, unsigned Index,
1342 bool Final) {
1344 ArgPack, AssociatedDecl, Index, Final);
1345 }
1346
1347 /// Build a new compound statement.
1348 ///
1349 /// By default, performs semantic analysis to build the new statement.
1350 /// Subclasses may override this routine to provide different behavior.
1352 MultiStmtArg Statements,
1353 SourceLocation RBraceLoc,
1354 bool IsStmtExpr) {
1355 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1356 IsStmtExpr);
1357 }
1358
1359 /// Build a new case statement.
1360 ///
1361 /// By default, performs semantic analysis to build the new statement.
1362 /// Subclasses may override this routine to provide different behavior.
1364 Expr *LHS,
1365 SourceLocation EllipsisLoc,
1366 Expr *RHS,
1367 SourceLocation ColonLoc) {
1368 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1369 ColonLoc);
1370 }
1371
1372 /// Attach the body to a new case statement.
1373 ///
1374 /// By default, performs semantic analysis to build the new statement.
1375 /// Subclasses may override this routine to provide different behavior.
1377 getSema().ActOnCaseStmtBody(S, Body);
1378 return S;
1379 }
1380
1381 /// Build a new default statement.
1382 ///
1383 /// By default, performs semantic analysis to build the new statement.
1384 /// Subclasses may override this routine to provide different behavior.
1386 SourceLocation ColonLoc,
1387 Stmt *SubStmt) {
1388 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1389 /*CurScope=*/nullptr);
1390 }
1391
1392 /// Build a new label statement.
1393 ///
1394 /// By default, performs semantic analysis to build the new statement.
1395 /// Subclasses may override this routine to provide different behavior.
1397 SourceLocation ColonLoc, Stmt *SubStmt) {
1398 return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt);
1399 }
1400
1401 /// Build a new attributed statement.
1402 ///
1403 /// By default, performs semantic analysis to build the new statement.
1404 /// Subclasses may override this routine to provide different behavior.
1407 Stmt *SubStmt) {
1409 return StmtError();
1410 return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt);
1411 }
1412
1413 /// Build a new "if" statement.
1414 ///
1415 /// By default, performs semantic analysis to build the new statement.
1416 /// Subclasses may override this routine to provide different behavior.
1418 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1419 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1420 SourceLocation ElseLoc, Stmt *Else) {
1421 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1422 Then, ElseLoc, Else);
1423 }
1424
1425 /// Start building a new switch statement.
1426 ///
1427 /// By default, performs semantic analysis to build the new statement.
1428 /// Subclasses may override this routine to provide different behavior.
1430 SourceLocation LParenLoc, Stmt *Init,
1432 SourceLocation RParenLoc) {
1433 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1434 RParenLoc);
1435 }
1436
1437 /// Attach the body to the switch statement.
1438 ///
1439 /// By default, performs semantic analysis to build the new statement.
1440 /// Subclasses may override this routine to provide different behavior.
1442 Stmt *Switch, Stmt *Body) {
1443 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1444 }
1445
1446 /// Build a new while statement.
1447 ///
1448 /// By default, performs semantic analysis to build the new statement.
1449 /// Subclasses may override this routine to provide different behavior.
1452 SourceLocation RParenLoc, Stmt *Body) {
1453 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1454 }
1455
1456 /// Build a new do-while statement.
1457 ///
1458 /// By default, performs semantic analysis to build the new statement.
1459 /// Subclasses may override this routine to provide different behavior.
1461 SourceLocation WhileLoc, SourceLocation LParenLoc,
1462 Expr *Cond, SourceLocation RParenLoc) {
1463 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1464 Cond, RParenLoc);
1465 }
1466
1467 /// Build a new for statement.
1468 ///
1469 /// By default, performs semantic analysis to build the new statement.
1470 /// Subclasses may override this routine to provide different behavior.
1473 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1474 Stmt *Body) {
1475 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1476 Inc, RParenLoc, Body);
1477 }
1478
1479 /// Build a new goto statement.
1480 ///
1481 /// By default, performs semantic analysis to build the new statement.
1482 /// Subclasses may override this routine to provide different behavior.
1484 LabelDecl *Label) {
1485 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1486 }
1487
1488 /// Build a new indirect goto statement.
1489 ///
1490 /// By default, performs semantic analysis to build the new statement.
1491 /// Subclasses may override this routine to provide different behavior.
1493 SourceLocation StarLoc,
1494 Expr *Target) {
1495 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1496 }
1497
1498 /// Build a new return statement.
1499 ///
1500 /// By default, performs semantic analysis to build the new statement.
1501 /// Subclasses may override this routine to provide different behavior.
1503 return getSema().BuildReturnStmt(ReturnLoc, Result);
1504 }
1505
1506 /// Build a new declaration statement.
1507 ///
1508 /// By default, performs semantic analysis to build the new statement.
1509 /// Subclasses may override this routine to provide different behavior.
1511 SourceLocation StartLoc, SourceLocation EndLoc) {
1513 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1514 }
1515
1516 /// Build a new inline asm statement.
1517 ///
1518 /// By default, performs semantic analysis to build the new statement.
1519 /// Subclasses may override this routine to provide different behavior.
1521 bool IsVolatile, unsigned NumOutputs,
1522 unsigned NumInputs, IdentifierInfo **Names,
1523 MultiExprArg Constraints, MultiExprArg Exprs,
1524 Expr *AsmString, MultiExprArg Clobbers,
1525 unsigned NumLabels,
1526 SourceLocation RParenLoc) {
1527 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1528 NumInputs, Names, Constraints, Exprs,
1529 AsmString, Clobbers, NumLabels, RParenLoc);
1530 }
1531
1532 /// Build a new MS style inline asm statement.
1533 ///
1534 /// By default, performs semantic analysis to build the new statement.
1535 /// Subclasses may override this routine to provide different behavior.
1537 ArrayRef<Token> AsmToks,
1538 StringRef AsmString,
1539 unsigned NumOutputs, unsigned NumInputs,
1540 ArrayRef<StringRef> Constraints,
1541 ArrayRef<StringRef> Clobbers,
1542 ArrayRef<Expr*> Exprs,
1543 SourceLocation EndLoc) {
1544 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1545 NumOutputs, NumInputs,
1546 Constraints, Clobbers, Exprs, EndLoc);
1547 }
1548
1549 /// Build a new co_return statement.
1550 ///
1551 /// By default, performs semantic analysis to build the new statement.
1552 /// Subclasses may override this routine to provide different behavior.
1554 bool IsImplicit) {
1555 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1556 }
1557
1558 /// Build a new co_await expression.
1559 ///
1560 /// By default, performs semantic analysis to build the new expression.
1561 /// Subclasses may override this routine to provide different behavior.
1563 UnresolvedLookupExpr *OpCoawaitLookup,
1564 bool IsImplicit) {
1565 // This function rebuilds a coawait-expr given its operator.
1566 // For an explicit coawait-expr, the rebuild involves the full set
1567 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1568 // including calling await_transform().
1569 // For an implicit coawait-expr, we need to rebuild the "operator
1570 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1571 // This mirrors how the implicit CoawaitExpr is originally created
1572 // in Sema::ActOnCoroutineBodyStart().
1573 if (IsImplicit) {
1575 CoawaitLoc, Operand, OpCoawaitLookup);
1576 if (Suspend.isInvalid())
1577 return ExprError();
1578 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1579 Suspend.get(), true);
1580 }
1581
1582 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1583 OpCoawaitLookup);
1584 }
1585
1586 /// Build a new co_await expression.
1587 ///
1588 /// By default, performs semantic analysis to build the new expression.
1589 /// Subclasses may override this routine to provide different behavior.
1591 Expr *Result,
1592 UnresolvedLookupExpr *Lookup) {
1593 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1594 }
1595
1596 /// Build a new co_yield expression.
1597 ///
1598 /// By default, performs semantic analysis to build the new expression.
1599 /// Subclasses may override this routine to provide different behavior.
1601 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1602 }
1603
1605 return getSema().BuildCoroutineBodyStmt(Args);
1606 }
1607
1608 /// Build a new Objective-C \@try statement.
1609 ///
1610 /// By default, performs semantic analysis to build the new statement.
1611 /// Subclasses may override this routine to provide different behavior.
1613 Stmt *TryBody,
1614 MultiStmtArg CatchStmts,
1615 Stmt *Finally) {
1616 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1617 Finally);
1618 }
1619
1620 /// Rebuild an Objective-C exception declaration.
1621 ///
1622 /// By default, performs semantic analysis to build the new declaration.
1623 /// Subclasses may override this routine to provide different behavior.
1625 TypeSourceInfo *TInfo, QualType T) {
1627 TInfo, T, ExceptionDecl->getInnerLocStart(),
1628 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1629 }
1630
1631 /// Build a new Objective-C \@catch statement.
1632 ///
1633 /// By default, performs semantic analysis to build the new statement.
1634 /// Subclasses may override this routine to provide different behavior.
1636 SourceLocation RParenLoc,
1637 VarDecl *Var,
1638 Stmt *Body) {
1639 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1640 }
1641
1642 /// Build a new Objective-C \@finally statement.
1643 ///
1644 /// By default, performs semantic analysis to build the new statement.
1645 /// Subclasses may override this routine to provide different behavior.
1647 Stmt *Body) {
1648 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1649 }
1650
1651 /// Build a new Objective-C \@throw statement.
1652 ///
1653 /// By default, performs semantic analysis to build the new statement.
1654 /// Subclasses may override this routine to provide different behavior.
1656 Expr *Operand) {
1657 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1658 }
1659
1660 /// Build a new OpenMP Canonical loop.
1661 ///
1662 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1663 /// OMPCanonicalLoop.
1665 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1666 }
1667
1668 /// Build a new OpenMP executable directive.
1669 ///
1670 /// By default, performs semantic analysis to build the new statement.
1671 /// Subclasses may override this routine to provide different behavior.
1673 DeclarationNameInfo DirName,
1674 OpenMPDirectiveKind CancelRegion,
1675 ArrayRef<OMPClause *> Clauses,
1676 Stmt *AStmt, SourceLocation StartLoc,
1677 SourceLocation EndLoc) {
1678
1680 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1681 }
1682
1683 /// Build a new OpenMP informational directive.
1685 DeclarationNameInfo DirName,
1686 ArrayRef<OMPClause *> Clauses,
1687 Stmt *AStmt,
1688 SourceLocation StartLoc,
1689 SourceLocation EndLoc) {
1690
1692 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1693 }
1694
1695 /// Build a new OpenMP 'if' clause.
1696 ///
1697 /// By default, performs semantic analysis to build the new OpenMP clause.
1698 /// Subclasses may override this routine to provide different behavior.
1700 Expr *Condition, SourceLocation StartLoc,
1701 SourceLocation LParenLoc,
1702 SourceLocation NameModifierLoc,
1703 SourceLocation ColonLoc,
1704 SourceLocation EndLoc) {
1706 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1707 EndLoc);
1708 }
1709
1710 /// Build a new OpenMP 'final' clause.
1711 ///
1712 /// By default, performs semantic analysis to build the new OpenMP clause.
1713 /// Subclasses may override this routine to provide different behavior.
1715 SourceLocation LParenLoc,
1716 SourceLocation EndLoc) {
1717 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1718 LParenLoc, EndLoc);
1719 }
1720
1721 /// Build a new OpenMP 'num_threads' clause.
1722 ///
1723 /// By default, performs semantic analysis to build the new OpenMP clause.
1724 /// Subclasses may override this routine to provide different behavior.
1726 SourceLocation StartLoc,
1727 SourceLocation LParenLoc,
1728 SourceLocation EndLoc) {
1729 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc,
1730 LParenLoc, EndLoc);
1731 }
1732
1733 /// Build a new OpenMP 'safelen' clause.
1734 ///
1735 /// By default, performs semantic analysis to build the new OpenMP clause.
1736 /// Subclasses may override this routine to provide different behavior.
1738 SourceLocation LParenLoc,
1739 SourceLocation EndLoc) {
1740 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1741 EndLoc);
1742 }
1743
1744 /// Build a new OpenMP 'simdlen' clause.
1745 ///
1746 /// By default, performs semantic analysis to build the new OpenMP clause.
1747 /// Subclasses may override this routine to provide different behavior.
1749 SourceLocation LParenLoc,
1750 SourceLocation EndLoc) {
1751 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1752 EndLoc);
1753 }
1754
1756 SourceLocation StartLoc,
1757 SourceLocation LParenLoc,
1758 SourceLocation EndLoc) {
1759 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1760 EndLoc);
1761 }
1762
1763 /// Build a new OpenMP 'full' clause.
1765 SourceLocation EndLoc) {
1766 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1767 }
1768
1769 /// Build a new OpenMP 'partial' clause.
1771 SourceLocation LParenLoc,
1772 SourceLocation EndLoc) {
1773 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1774 LParenLoc, EndLoc);
1775 }
1776
1777 /// Build a new OpenMP 'allocator' clause.
1778 ///
1779 /// By default, performs semantic analysis to build the new OpenMP clause.
1780 /// Subclasses may override this routine to provide different behavior.
1782 SourceLocation LParenLoc,
1783 SourceLocation EndLoc) {
1784 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1785 EndLoc);
1786 }
1787
1788 /// Build a new OpenMP 'collapse' clause.
1789 ///
1790 /// By default, performs semantic analysis to build the new OpenMP clause.
1791 /// Subclasses may override this routine to provide different behavior.
1793 SourceLocation LParenLoc,
1794 SourceLocation EndLoc) {
1795 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1796 LParenLoc, EndLoc);
1797 }
1798
1799 /// Build a new OpenMP 'default' clause.
1800 ///
1801 /// By default, performs semantic analysis to build the new OpenMP clause.
1802 /// Subclasses may override this routine to provide different behavior.
1804 SourceLocation StartLoc,
1805 SourceLocation LParenLoc,
1806 SourceLocation EndLoc) {
1808 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1809 }
1810
1811 /// Build a new OpenMP 'proc_bind' clause.
1812 ///
1813 /// By default, performs semantic analysis to build the new OpenMP clause.
1814 /// Subclasses may override this routine to provide different behavior.
1816 SourceLocation KindKwLoc,
1817 SourceLocation StartLoc,
1818 SourceLocation LParenLoc,
1819 SourceLocation EndLoc) {
1821 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1822 }
1823
1824 /// Build a new OpenMP 'schedule' clause.
1825 ///
1826 /// By default, performs semantic analysis to build the new OpenMP clause.
1827 /// Subclasses may override this routine to provide different behavior.
1830 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1831 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1832 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1834 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1835 CommaLoc, EndLoc);
1836 }
1837
1838 /// Build a new OpenMP 'ordered' clause.
1839 ///
1840 /// By default, performs semantic analysis to build the new OpenMP clause.
1841 /// Subclasses may override this routine to provide different behavior.
1843 SourceLocation EndLoc,
1844 SourceLocation LParenLoc, Expr *Num) {
1845 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1846 LParenLoc, Num);
1847 }
1848
1849 /// Build a new OpenMP 'private' clause.
1850 ///
1851 /// By default, performs semantic analysis to build the new OpenMP clause.
1852 /// Subclasses may override this routine to provide different behavior.
1854 SourceLocation StartLoc,
1855 SourceLocation LParenLoc,
1856 SourceLocation EndLoc) {
1857 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1858 LParenLoc, EndLoc);
1859 }
1860
1861 /// Build a new OpenMP 'firstprivate' clause.
1862 ///
1863 /// By default, performs semantic analysis to build the new OpenMP clause.
1864 /// Subclasses may override this routine to provide different behavior.
1866 SourceLocation StartLoc,
1867 SourceLocation LParenLoc,
1868 SourceLocation EndLoc) {
1869 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1870 LParenLoc, EndLoc);
1871 }
1872
1873 /// Build a new OpenMP 'lastprivate' clause.
1874 ///
1875 /// By default, performs semantic analysis to build the new OpenMP clause.
1876 /// Subclasses may override this routine to provide different behavior.
1879 SourceLocation LPKindLoc,
1880 SourceLocation ColonLoc,
1881 SourceLocation StartLoc,
1882 SourceLocation LParenLoc,
1883 SourceLocation EndLoc) {
1885 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1886 }
1887
1888 /// Build a new OpenMP 'shared' clause.
1889 ///
1890 /// By default, performs semantic analysis to build the new OpenMP clause.
1891 /// Subclasses may override this routine to provide different behavior.
1893 SourceLocation StartLoc,
1894 SourceLocation LParenLoc,
1895 SourceLocation EndLoc) {
1896 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1897 LParenLoc, EndLoc);
1898 }
1899
1900 /// Build a new OpenMP 'reduction' clause.
1901 ///
1902 /// By default, performs semantic analysis to build the new statement.
1903 /// Subclasses may override this routine to provide different behavior.
1906 SourceLocation StartLoc, SourceLocation LParenLoc,
1907 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1908 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1909 const DeclarationNameInfo &ReductionId,
1910 ArrayRef<Expr *> UnresolvedReductions) {
1912 VarList, Modifier, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
1913 ReductionIdScopeSpec, ReductionId, UnresolvedReductions);
1914 }
1915
1916 /// Build a new OpenMP 'task_reduction' clause.
1917 ///
1918 /// By default, performs semantic analysis to build the new statement.
1919 /// Subclasses may override this routine to provide different behavior.
1921 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1922 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1923 CXXScopeSpec &ReductionIdScopeSpec,
1924 const DeclarationNameInfo &ReductionId,
1925 ArrayRef<Expr *> UnresolvedReductions) {
1927 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1928 ReductionId, UnresolvedReductions);
1929 }
1930
1931 /// Build a new OpenMP 'in_reduction' clause.
1932 ///
1933 /// By default, performs semantic analysis to build the new statement.
1934 /// Subclasses may override this routine to provide different behavior.
1935 OMPClause *
1937 SourceLocation LParenLoc, SourceLocation ColonLoc,
1938 SourceLocation EndLoc,
1939 CXXScopeSpec &ReductionIdScopeSpec,
1940 const DeclarationNameInfo &ReductionId,
1941 ArrayRef<Expr *> UnresolvedReductions) {
1943 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1944 ReductionId, UnresolvedReductions);
1945 }
1946
1947 /// Build a new OpenMP 'linear' clause.
1948 ///
1949 /// By default, performs semantic analysis to build the new OpenMP clause.
1950 /// Subclasses may override this routine to provide different behavior.
1952 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1953 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1954 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1955 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
1957 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
1958 StepModifierLoc, EndLoc);
1959 }
1960
1961 /// Build a new OpenMP 'aligned' clause.
1962 ///
1963 /// By default, performs semantic analysis to build the new OpenMP clause.
1964 /// Subclasses may override this routine to provide different behavior.
1966 SourceLocation StartLoc,
1967 SourceLocation LParenLoc,
1968 SourceLocation ColonLoc,
1969 SourceLocation EndLoc) {
1971 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
1972 }
1973
1974 /// Build a new OpenMP 'copyin' clause.
1975 ///
1976 /// By default, performs semantic analysis to build the new OpenMP clause.
1977 /// Subclasses may override this routine to provide different behavior.
1979 SourceLocation StartLoc,
1980 SourceLocation LParenLoc,
1981 SourceLocation EndLoc) {
1982 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
1983 LParenLoc, EndLoc);
1984 }
1985
1986 /// Build a new OpenMP 'copyprivate' clause.
1987 ///
1988 /// By default, performs semantic analysis to build the new OpenMP clause.
1989 /// Subclasses may override this routine to provide different behavior.
1991 SourceLocation StartLoc,
1992 SourceLocation LParenLoc,
1993 SourceLocation EndLoc) {
1994 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
1995 LParenLoc, EndLoc);
1996 }
1997
1998 /// Build a new OpenMP 'flush' pseudo clause.
1999 ///
2000 /// By default, performs semantic analysis to build the new OpenMP clause.
2001 /// Subclasses may override this routine to provide different behavior.
2003 SourceLocation StartLoc,
2004 SourceLocation LParenLoc,
2005 SourceLocation EndLoc) {
2006 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2007 LParenLoc, EndLoc);
2008 }
2009
2010 /// Build a new OpenMP 'depobj' pseudo clause.
2011 ///
2012 /// By default, performs semantic analysis to build the new OpenMP clause.
2013 /// Subclasses may override this routine to provide different behavior.
2015 SourceLocation LParenLoc,
2016 SourceLocation EndLoc) {
2017 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2018 LParenLoc, EndLoc);
2019 }
2020
2021 /// Build a new OpenMP 'depend' pseudo clause.
2022 ///
2023 /// By default, performs semantic analysis to build the new OpenMP clause.
2024 /// Subclasses may override this routine to provide different behavior.
2026 Expr *DepModifier, ArrayRef<Expr *> VarList,
2027 SourceLocation StartLoc,
2028 SourceLocation LParenLoc,
2029 SourceLocation EndLoc) {
2031 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2032 }
2033
2034 /// Build a new OpenMP 'device' clause.
2035 ///
2036 /// By default, performs semantic analysis to build the new statement.
2037 /// Subclasses may override this routine to provide different behavior.
2039 Expr *Device, SourceLocation StartLoc,
2040 SourceLocation LParenLoc,
2041 SourceLocation ModifierLoc,
2042 SourceLocation EndLoc) {
2044 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2045 }
2046
2047 /// Build a new OpenMP 'map' clause.
2048 ///
2049 /// By default, performs semantic analysis to build the new OpenMP clause.
2050 /// Subclasses may override this routine to provide different behavior.
2052 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2053 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2054 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2055 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2056 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2057 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2059 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2060 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2061 ColonLoc, VarList, Locs,
2062 /*NoDiagnose=*/false, UnresolvedMappers);
2063 }
2064
2065 /// Build a new OpenMP 'allocate' clause.
2066 ///
2067 /// By default, performs semantic analysis to build the new OpenMP clause.
2068 /// Subclasses may override this routine to provide different behavior.
2070 SourceLocation StartLoc,
2071 SourceLocation LParenLoc,
2072 SourceLocation ColonLoc,
2073 SourceLocation EndLoc) {
2075 Allocate, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2076 }
2077
2078 /// Build a new OpenMP 'num_teams' clause.
2079 ///
2080 /// By default, performs semantic analysis to build the new statement.
2081 /// Subclasses may override this routine to provide different behavior.
2083 SourceLocation StartLoc,
2084 SourceLocation LParenLoc,
2085 SourceLocation EndLoc) {
2086 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(VarList, StartLoc,
2087 LParenLoc, EndLoc);
2088 }
2089
2090 /// Build a new OpenMP 'thread_limit' clause.
2091 ///
2092 /// By default, performs semantic analysis to build the new statement.
2093 /// Subclasses may override this routine to provide different behavior.
2095 SourceLocation StartLoc,
2096 SourceLocation LParenLoc,
2097 SourceLocation EndLoc) {
2098 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(VarList, StartLoc,
2099 LParenLoc, EndLoc);
2100 }
2101
2102 /// Build a new OpenMP 'priority' clause.
2103 ///
2104 /// By default, performs semantic analysis to build the new statement.
2105 /// Subclasses may override this routine to provide different behavior.
2107 SourceLocation LParenLoc,
2108 SourceLocation EndLoc) {
2109 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2110 LParenLoc, EndLoc);
2111 }
2112
2113 /// Build a new OpenMP 'grainsize' clause.
2114 ///
2115 /// By default, performs semantic analysis to build the new statement.
2116 /// Subclasses may override this routine to provide different behavior.
2118 Expr *Device, SourceLocation StartLoc,
2119 SourceLocation LParenLoc,
2120 SourceLocation ModifierLoc,
2121 SourceLocation EndLoc) {
2123 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2124 }
2125
2126 /// Build a new OpenMP 'num_tasks' clause.
2127 ///
2128 /// By default, performs semantic analysis to build the new statement.
2129 /// Subclasses may override this routine to provide different behavior.
2131 Expr *NumTasks, SourceLocation StartLoc,
2132 SourceLocation LParenLoc,
2133 SourceLocation ModifierLoc,
2134 SourceLocation EndLoc) {
2136 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2137 }
2138
2139 /// Build a new OpenMP 'hint' clause.
2140 ///
2141 /// By default, performs semantic analysis to build the new statement.
2142 /// Subclasses may override this routine to provide different behavior.
2144 SourceLocation LParenLoc,
2145 SourceLocation EndLoc) {
2146 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2147 EndLoc);
2148 }
2149
2150 /// Build a new OpenMP 'detach' clause.
2151 ///
2152 /// By default, performs semantic analysis to build the new statement.
2153 /// Subclasses may override this routine to provide different behavior.
2155 SourceLocation LParenLoc,
2156 SourceLocation EndLoc) {
2157 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2158 EndLoc);
2159 }
2160
2161 /// Build a new OpenMP 'dist_schedule' clause.
2162 ///
2163 /// By default, performs semantic analysis to build the new OpenMP clause.
2164 /// Subclasses may override this routine to provide different behavior.
2165 OMPClause *
2167 Expr *ChunkSize, SourceLocation StartLoc,
2168 SourceLocation LParenLoc, SourceLocation KindLoc,
2169 SourceLocation CommaLoc, SourceLocation EndLoc) {
2171 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2172 }
2173
2174 /// Build a new OpenMP 'to' clause.
2175 ///
2176 /// By default, performs semantic analysis to build the new statement.
2177 /// Subclasses may override this routine to provide different behavior.
2178 OMPClause *
2180 ArrayRef<SourceLocation> MotionModifiersLoc,
2181 CXXScopeSpec &MapperIdScopeSpec,
2182 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2183 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2184 ArrayRef<Expr *> UnresolvedMappers) {
2186 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2187 ColonLoc, VarList, Locs, UnresolvedMappers);
2188 }
2189
2190 /// Build a new OpenMP 'from' clause.
2191 ///
2192 /// By default, performs semantic analysis to build the new statement.
2193 /// Subclasses may override this routine to provide different behavior.
2194 OMPClause *
2196 ArrayRef<SourceLocation> MotionModifiersLoc,
2197 CXXScopeSpec &MapperIdScopeSpec,
2198 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2199 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2200 ArrayRef<Expr *> UnresolvedMappers) {
2202 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2203 ColonLoc, VarList, Locs, UnresolvedMappers);
2204 }
2205
2206 /// Build a new OpenMP 'use_device_ptr' clause.
2207 ///
2208 /// By default, performs semantic analysis to build the new OpenMP clause.
2209 /// Subclasses may override this routine to provide different behavior.
2211 const OMPVarListLocTy &Locs) {
2212 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2213 }
2214
2215 /// Build a new OpenMP 'use_device_addr' clause.
2216 ///
2217 /// By default, performs semantic analysis to build the new OpenMP clause.
2218 /// Subclasses may override this routine to provide different behavior.
2220 const OMPVarListLocTy &Locs) {
2221 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2222 }
2223
2224 /// Build a new OpenMP 'is_device_ptr' clause.
2225 ///
2226 /// By default, performs semantic analysis to build the new OpenMP clause.
2227 /// Subclasses may override this routine to provide different behavior.
2229 const OMPVarListLocTy &Locs) {
2230 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2231 }
2232
2233 /// Build a new OpenMP 'has_device_addr' clause.
2234 ///
2235 /// By default, performs semantic analysis to build the new OpenMP clause.
2236 /// Subclasses may override this routine to provide different behavior.
2238 const OMPVarListLocTy &Locs) {
2239 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2240 }
2241
2242 /// Build a new OpenMP 'defaultmap' clause.
2243 ///
2244 /// By default, performs semantic analysis to build the new OpenMP clause.
2245 /// Subclasses may override this routine to provide different behavior.
2248 SourceLocation StartLoc,
2249 SourceLocation LParenLoc,
2250 SourceLocation MLoc,
2251 SourceLocation KindLoc,
2252 SourceLocation EndLoc) {
2254 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2255 }
2256
2257 /// Build a new OpenMP 'nontemporal' clause.
2258 ///
2259 /// By default, performs semantic analysis to build the new OpenMP clause.
2260 /// Subclasses may override this routine to provide different behavior.
2262 SourceLocation StartLoc,
2263 SourceLocation LParenLoc,
2264 SourceLocation EndLoc) {
2265 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2266 LParenLoc, EndLoc);
2267 }
2268
2269 /// Build a new OpenMP 'inclusive' clause.
2270 ///
2271 /// By default, performs semantic analysis to build the new OpenMP clause.
2272 /// Subclasses may override this routine to provide different behavior.
2274 SourceLocation StartLoc,
2275 SourceLocation LParenLoc,
2276 SourceLocation EndLoc) {
2277 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2278 LParenLoc, EndLoc);
2279 }
2280
2281 /// Build a new OpenMP 'exclusive' clause.
2282 ///
2283 /// By default, performs semantic analysis to build the new OpenMP clause.
2284 /// Subclasses may override this routine to provide different behavior.
2286 SourceLocation StartLoc,
2287 SourceLocation LParenLoc,
2288 SourceLocation EndLoc) {
2289 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2290 LParenLoc, EndLoc);
2291 }
2292
2293 /// Build a new OpenMP 'uses_allocators' clause.
2294 ///
2295 /// By default, performs semantic analysis to build the new OpenMP clause.
2296 /// Subclasses may override this routine to provide different behavior.
2299 SourceLocation LParenLoc, SourceLocation EndLoc) {
2301 StartLoc, LParenLoc, EndLoc, Data);
2302 }
2303
2304 /// Build a new OpenMP 'affinity' clause.
2305 ///
2306 /// By default, performs semantic analysis to build the new OpenMP clause.
2307 /// Subclasses may override this routine to provide different behavior.
2309 SourceLocation LParenLoc,
2310 SourceLocation ColonLoc,
2311 SourceLocation EndLoc, Expr *Modifier,
2312 ArrayRef<Expr *> Locators) {
2314 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2315 }
2316
2317 /// Build a new OpenMP 'order' clause.
2318 ///
2319 /// By default, performs semantic analysis to build the new OpenMP clause.
2320 /// Subclasses may override this routine to provide different behavior.
2322 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2323 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2324 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2326 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2327 }
2328
2329 /// Build a new OpenMP 'init' clause.
2330 ///
2331 /// By default, performs semantic analysis to build the new OpenMP clause.
2332 /// Subclasses may override this routine to provide different behavior.
2334 SourceLocation StartLoc,
2335 SourceLocation LParenLoc,
2336 SourceLocation VarLoc,
2337 SourceLocation EndLoc) {
2339 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2340 }
2341
2342 /// Build a new OpenMP 'use' clause.
2343 ///
2344 /// By default, performs semantic analysis to build the new OpenMP clause.
2345 /// Subclasses may override this routine to provide different behavior.
2347 SourceLocation LParenLoc,
2348 SourceLocation VarLoc, SourceLocation EndLoc) {
2349 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2350 LParenLoc, VarLoc, EndLoc);
2351 }
2352
2353 /// Build a new OpenMP 'destroy' clause.
2354 ///
2355 /// By default, performs semantic analysis to build the new OpenMP clause.
2356 /// Subclasses may override this routine to provide different behavior.
2358 SourceLocation LParenLoc,
2359 SourceLocation VarLoc,
2360 SourceLocation EndLoc) {
2362 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2363 }
2364
2365 /// Build a new OpenMP 'novariants' clause.
2366 ///
2367 /// By default, performs semantic analysis to build the new OpenMP clause.
2368 /// Subclasses may override this routine to provide different behavior.
2370 SourceLocation StartLoc,
2371 SourceLocation LParenLoc,
2372 SourceLocation EndLoc) {
2374 LParenLoc, EndLoc);
2375 }
2376
2377 /// Build a new OpenMP 'nocontext' clause.
2378 ///
2379 /// By default, performs semantic analysis to build the new OpenMP clause.
2380 /// Subclasses may override this routine to provide different behavior.
2382 SourceLocation LParenLoc,
2383 SourceLocation EndLoc) {
2385 LParenLoc, EndLoc);
2386 }
2387
2388 /// Build a new OpenMP 'filter' clause.
2389 ///
2390 /// By default, performs semantic analysis to build the new OpenMP clause.
2391 /// Subclasses may override this routine to provide different behavior.
2393 SourceLocation LParenLoc,
2394 SourceLocation EndLoc) {
2395 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2396 LParenLoc, EndLoc);
2397 }
2398
2399 /// Build a new OpenMP 'bind' clause.
2400 ///
2401 /// By default, performs semantic analysis to build the new OpenMP clause.
2402 /// Subclasses may override this routine to provide different behavior.
2404 SourceLocation KindLoc,
2405 SourceLocation StartLoc,
2406 SourceLocation LParenLoc,
2407 SourceLocation EndLoc) {
2408 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2409 LParenLoc, EndLoc);
2410 }
2411
2412 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2413 ///
2414 /// By default, performs semantic analysis to build the new OpenMP clause.
2415 /// Subclasses may override this routine to provide different behavior.
2417 SourceLocation LParenLoc,
2418 SourceLocation EndLoc) {
2419 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2420 LParenLoc, EndLoc);
2421 }
2422
2423 /// Build a new OpenMP 'ompx_attribute' clause.
2424 ///
2425 /// By default, performs semantic analysis to build the new OpenMP clause.
2426 /// Subclasses may override this routine to provide different behavior.
2428 SourceLocation StartLoc,
2429 SourceLocation LParenLoc,
2430 SourceLocation EndLoc) {
2431 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2432 LParenLoc, EndLoc);
2433 }
2434
2435 /// Build a new OpenMP 'ompx_bare' clause.
2436 ///
2437 /// By default, performs semantic analysis to build the new OpenMP clause.
2438 /// Subclasses may override this routine to provide different behavior.
2440 SourceLocation EndLoc) {
2441 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2442 }
2443
2444 /// Build a new OpenMP 'align' clause.
2445 ///
2446 /// By default, performs semantic analysis to build the new OpenMP clause.
2447 /// Subclasses may override this routine to provide different behavior.
2449 SourceLocation LParenLoc,
2450 SourceLocation EndLoc) {
2451 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2452 EndLoc);
2453 }
2454
2455 /// Build a new OpenMP 'at' clause.
2456 ///
2457 /// By default, performs semantic analysis to build the new OpenMP clause.
2458 /// Subclasses may override this routine to provide different behavior.
2460 SourceLocation StartLoc,
2461 SourceLocation LParenLoc,
2462 SourceLocation EndLoc) {
2463 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2464 LParenLoc, EndLoc);
2465 }
2466
2467 /// Build a new OpenMP 'severity' clause.
2468 ///
2469 /// By default, performs semantic analysis to build the new OpenMP clause.
2470 /// Subclasses may override this routine to provide different behavior.
2472 SourceLocation KwLoc,
2473 SourceLocation StartLoc,
2474 SourceLocation LParenLoc,
2475 SourceLocation EndLoc) {
2476 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2477 LParenLoc, EndLoc);
2478 }
2479
2480 /// Build a new OpenMP 'message' clause.
2481 ///
2482 /// By default, performs semantic analysis to build the new OpenMP clause.
2483 /// Subclasses may override this routine to provide different behavior.
2485 SourceLocation LParenLoc,
2486 SourceLocation EndLoc) {
2487 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2488 EndLoc);
2489 }
2490
2491 /// Build a new OpenMP 'doacross' clause.
2492 ///
2493 /// By default, performs semantic analysis to build the new OpenMP clause.
2494 /// Subclasses may override this routine to provide different behavior.
2495 OMPClause *
2497 SourceLocation DepLoc, SourceLocation ColonLoc,
2498 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2499 SourceLocation LParenLoc, SourceLocation EndLoc) {
2501 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2502 }
2503
2504 /// Build a new OpenMP 'holds' clause.
2506 SourceLocation LParenLoc,
2507 SourceLocation EndLoc) {
2508 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2509 EndLoc);
2510 }
2511
2512 /// Rebuild the operand to an Objective-C \@synchronized statement.
2513 ///
2514 /// By default, performs semantic analysis to build the new statement.
2515 /// Subclasses may override this routine to provide different behavior.
2517 Expr *object) {
2518 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2519 }
2520
2521 /// Build a new Objective-C \@synchronized statement.
2522 ///
2523 /// By default, performs semantic analysis to build the new statement.
2524 /// Subclasses may override this routine to provide different behavior.
2526 Expr *Object, Stmt *Body) {
2527 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2528 }
2529
2530 /// Build a new Objective-C \@autoreleasepool statement.
2531 ///
2532 /// By default, performs semantic analysis to build the new statement.
2533 /// Subclasses may override this routine to provide different behavior.
2535 Stmt *Body) {
2536 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2537 }
2538
2539 /// Build a new Objective-C fast enumeration statement.
2540 ///
2541 /// By default, performs semantic analysis to build the new statement.
2542 /// Subclasses may override this routine to provide different behavior.
2544 Stmt *Element,
2545 Expr *Collection,
2546 SourceLocation RParenLoc,
2547 Stmt *Body) {
2549 ForLoc, Element, Collection, RParenLoc);
2550 if (ForEachStmt.isInvalid())
2551 return StmtError();
2552
2553 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2554 Body);
2555 }
2556
2557 /// Build a new C++ exception declaration.
2558 ///
2559 /// By default, performs semantic analysis to build the new decaration.
2560 /// Subclasses may override this routine to provide different behavior.
2563 SourceLocation StartLoc,
2564 SourceLocation IdLoc,
2565 IdentifierInfo *Id) {
2567 StartLoc, IdLoc, Id);
2568 if (Var)
2569 getSema().CurContext->addDecl(Var);
2570 return Var;
2571 }
2572
2573 /// Build a new C++ catch statement.
2574 ///
2575 /// By default, performs semantic analysis to build the new statement.
2576 /// Subclasses may override this routine to provide different behavior.
2578 VarDecl *ExceptionDecl,
2579 Stmt *Handler) {
2580 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2581 Handler));
2582 }
2583
2584 /// Build a new C++ try statement.
2585 ///
2586 /// By default, performs semantic analysis to build the new statement.
2587 /// Subclasses may override this routine to provide different behavior.
2589 ArrayRef<Stmt *> Handlers) {
2590 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2591 }
2592
2593 /// Build a new C++0x range-based for statement.
2594 ///
2595 /// By default, performs semantic analysis to build the new statement.
2596 /// Subclasses may override this routine to provide different behavior.
2598 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2599 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2600 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2601 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2602 // If we've just learned that the range is actually an Objective-C
2603 // collection, treat this as an Objective-C fast enumeration loop.
2604 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
2605 if (RangeStmt->isSingleDecl()) {
2606 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
2607 if (RangeVar->isInvalidDecl())
2608 return StmtError();
2609
2610 Expr *RangeExpr = RangeVar->getInit();
2611 if (!RangeExpr->isTypeDependent() &&
2612 RangeExpr->getType()->isObjCObjectPointerType()) {
2613 // FIXME: Support init-statements in Objective-C++20 ranged for
2614 // statement.
2615 if (Init) {
2616 return SemaRef.Diag(Init->getBeginLoc(),
2617 diag::err_objc_for_range_init_stmt)
2618 << Init->getSourceRange();
2619 }
2621 ForLoc, LoopVar, RangeExpr, RParenLoc);
2622 }
2623 }
2624 }
2625 }
2626
2628 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2629 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2630 }
2631
2632 /// Build a new C++0x range-based for statement.
2633 ///
2634 /// By default, performs semantic analysis to build the new statement.
2635 /// Subclasses may override this routine to provide different behavior.
2637 bool IsIfExists,
2638 NestedNameSpecifierLoc QualifierLoc,
2639 DeclarationNameInfo NameInfo,
2640 Stmt *Nested) {
2641 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2642 QualifierLoc, NameInfo, Nested);
2643 }
2644
2645 /// Attach body to a C++0x range-based for statement.
2646 ///
2647 /// By default, performs semantic analysis to finish the new statement.
2648 /// Subclasses may override this routine to provide different behavior.
2650 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2651 }
2652
2654 Stmt *TryBlock, Stmt *Handler) {
2655 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2656 }
2657
2659 Stmt *Block) {
2660 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2661 }
2662
2664 return SEHFinallyStmt::Create(getSema().getASTContext(), Loc, Block);
2665 }
2666
2668 SourceLocation LParen,
2669 SourceLocation RParen,
2670 TypeSourceInfo *TSI) {
2671 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2672 TSI);
2673 }
2674
2675 /// Build a new predefined expression.
2676 ///
2677 /// By default, performs semantic analysis to build the new expression.
2678 /// Subclasses may override this routine to provide different behavior.
2680 return getSema().BuildPredefinedExpr(Loc, IK);
2681 }
2682
2683 /// Build a new expression that references a declaration.
2684 ///
2685 /// By default, performs semantic analysis to build the new expression.
2686 /// Subclasses may override this routine to provide different behavior.
2688 LookupResult &R,
2689 bool RequiresADL) {
2690 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2691 }
2692
2693
2694 /// Build a new expression that references a declaration.
2695 ///
2696 /// By default, performs semantic analysis to build the new expression.
2697 /// Subclasses may override this routine to provide different behavior.
2699 ValueDecl *VD,
2700 const DeclarationNameInfo &NameInfo,
2702 TemplateArgumentListInfo *TemplateArgs) {
2703 CXXScopeSpec SS;
2704 SS.Adopt(QualifierLoc);
2705 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2706 TemplateArgs);
2707 }
2708
2709 /// Build a new expression in parentheses.
2710 ///
2711 /// By default, performs semantic analysis to build the new expression.
2712 /// Subclasses may override this routine to provide different behavior.
2714 SourceLocation RParen) {
2715 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2716 }
2717
2718 /// Build a new pseudo-destructor expression.
2719 ///
2720 /// By default, performs semantic analysis to build the new expression.
2721 /// Subclasses may override this routine to provide different behavior.
2723 SourceLocation OperatorLoc,
2724 bool isArrow,
2725 CXXScopeSpec &SS,
2726 TypeSourceInfo *ScopeType,
2727 SourceLocation CCLoc,
2728 SourceLocation TildeLoc,
2729 PseudoDestructorTypeStorage Destroyed);
2730
2731 /// Build a new unary operator expression.
2732 ///
2733 /// By default, performs semantic analysis to build the new expression.
2734 /// Subclasses may override this routine to provide different behavior.
2737 Expr *SubExpr) {
2738 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2739 }
2740
2741 /// Build a new builtin offsetof expression.
2742 ///
2743 /// By default, performs semantic analysis to build the new expression.
2744 /// Subclasses may override this routine to provide different behavior.
2748 SourceLocation RParenLoc) {
2749 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2750 RParenLoc);
2751 }
2752
2753 /// Build a new sizeof, alignof or vec_step expression with a
2754 /// type argument.
2755 ///
2756 /// By default, performs semantic analysis to build the new expression.
2757 /// Subclasses may override this routine to provide different behavior.
2759 SourceLocation OpLoc,
2760 UnaryExprOrTypeTrait ExprKind,
2761 SourceRange R) {
2762 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2763 }
2764
2765 /// Build a new sizeof, alignof or vec step expression with an
2766 /// expression argument.
2767 ///
2768 /// By default, performs semantic analysis to build the new expression.
2769 /// Subclasses may override this routine to provide different behavior.
2771 UnaryExprOrTypeTrait ExprKind,
2772 SourceRange R) {
2774 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2775 if (Result.isInvalid())
2776 return ExprError();
2777
2778 return Result;
2779 }
2780
2781 /// Build a new array subscript expression.
2782 ///
2783 /// By default, performs semantic analysis to build the new expression.
2784 /// Subclasses may override this routine to provide different behavior.
2786 SourceLocation LBracketLoc,
2787 Expr *RHS,
2788 SourceLocation RBracketLoc) {
2789 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2790 LBracketLoc, RHS,
2791 RBracketLoc);
2792 }
2793
2794 /// Build a new matrix subscript expression.
2795 ///
2796 /// By default, performs semantic analysis to build the new expression.
2797 /// Subclasses may override this routine to provide different behavior.
2799 Expr *ColumnIdx,
2800 SourceLocation RBracketLoc) {
2801 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2802 RBracketLoc);
2803 }
2804
2805 /// Build a new array section expression.
2806 ///
2807 /// By default, performs semantic analysis to build the new expression.
2808 /// Subclasses may override this routine to provide different behavior.
2810 SourceLocation LBracketLoc,
2811 Expr *LowerBound,
2812 SourceLocation ColonLocFirst,
2813 SourceLocation ColonLocSecond,
2814 Expr *Length, Expr *Stride,
2815 SourceLocation RBracketLoc) {
2816 if (IsOMPArraySection)
2818 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2819 Stride, RBracketLoc);
2820
2821 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2822 "Stride/second colon not allowed for OpenACC");
2823
2825 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2826 }
2827
2828 /// Build a new array shaping expression.
2829 ///
2830 /// By default, performs semantic analysis to build the new expression.
2831 /// Subclasses may override this routine to provide different behavior.
2833 SourceLocation RParenLoc,
2834 ArrayRef<Expr *> Dims,
2835 ArrayRef<SourceRange> BracketsRanges) {
2837 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2838 }
2839
2840 /// Build a new iterator expression.
2841 ///
2842 /// By default, performs semantic analysis to build the new expression.
2843 /// Subclasses may override this routine to provide different behavior.
2846 SourceLocation RLoc,
2849 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2850 }
2851
2852 /// Build a new call expression.
2853 ///
2854 /// By default, performs semantic analysis to build the new expression.
2855 /// Subclasses may override this routine to provide different behavior.
2857 MultiExprArg Args,
2858 SourceLocation RParenLoc,
2859 Expr *ExecConfig = nullptr) {
2860 return getSema().ActOnCallExpr(
2861 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2862 }
2863
2865 MultiExprArg Args,
2866 SourceLocation RParenLoc) {
2868 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2869 }
2870
2871 /// Build a new member access expression.
2872 ///
2873 /// By default, performs semantic analysis to build the new expression.
2874 /// Subclasses may override this routine to provide different behavior.
2876 bool isArrow,
2877 NestedNameSpecifierLoc QualifierLoc,
2878 SourceLocation TemplateKWLoc,
2879 const DeclarationNameInfo &MemberNameInfo,
2881 NamedDecl *FoundDecl,
2882 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2883 NamedDecl *FirstQualifierInScope) {
2885 isArrow);
2886 if (!Member->getDeclName()) {
2887 // We have a reference to an unnamed field. This is always the
2888 // base of an anonymous struct/union member access, i.e. the
2889 // field is always of record type.
2890 assert(Member->getType()->isRecordType() &&
2891 "unnamed member not of record type?");
2892
2893 BaseResult =
2895 QualifierLoc.getNestedNameSpecifier(),
2896 FoundDecl, Member);
2897 if (BaseResult.isInvalid())
2898 return ExprError();
2899 Base = BaseResult.get();
2900
2901 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
2902 // from the AST, so we need to re-insert them if needed (since
2903 // `BuildFieldRefereneExpr()` doesn't do this).
2904 if (!isArrow && Base->isPRValue()) {
2906 if (BaseResult.isInvalid())
2907 return ExprError();
2908 Base = BaseResult.get();
2909 }
2910
2911 CXXScopeSpec EmptySS;
2913 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
2914 DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()),
2915 MemberNameInfo);
2916 }
2917
2918 CXXScopeSpec SS;
2919 SS.Adopt(QualifierLoc);
2920
2921 Base = BaseResult.get();
2922 if (Base->containsErrors())
2923 return ExprError();
2924
2925 QualType BaseType = Base->getType();
2926
2927 if (isArrow && !BaseType->isPointerType())
2928 return ExprError();
2929
2930 // FIXME: this involves duplicating earlier analysis in a lot of
2931 // cases; we should avoid this when possible.
2932 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2933 R.addDecl(FoundDecl);
2934 R.resolveKind();
2935
2936 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2937 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {
2938 if (auto *ThisClass = cast<CXXThisExpr>(Base)
2939 ->getType()
2940 ->getPointeeType()
2941 ->getAsCXXRecordDecl()) {
2942 auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());
2943 // In unevaluated contexts, an expression supposed to be a member access
2944 // might reference a member in an unrelated class.
2945 if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))
2946 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2947 VK_LValue, Member->getLocation());
2948 }
2949 }
2950
2951 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2952 SS, TemplateKWLoc,
2953 FirstQualifierInScope,
2954 R, ExplicitTemplateArgs,
2955 /*S*/nullptr);
2956 }
2957
2958 /// Build a new binary operator expression.
2959 ///
2960 /// By default, performs semantic analysis to build the new expression.
2961 /// Subclasses may override this routine to provide different behavior.
2964 Expr *LHS, Expr *RHS) {
2965 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS);
2966 }
2967
2968 /// Build a new rewritten operator expression.
2969 ///
2970 /// By default, performs semantic analysis to build the new expression.
2971 /// Subclasses may override this routine to provide different behavior.
2973 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2974 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2975 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2976 RHS, /*RequiresADL*/false);
2977 }
2978
2979 /// Build a new conditional operator expression.
2980 ///
2981 /// By default, performs semantic analysis to build the new expression.
2982 /// Subclasses may override this routine to provide different behavior.
2984 SourceLocation QuestionLoc,
2985 Expr *LHS,
2986 SourceLocation ColonLoc,
2987 Expr *RHS) {
2988 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
2989 LHS, RHS);
2990 }
2991
2992 /// Build a new C-style cast expression.
2993 ///
2994 /// By default, performs semantic analysis to build the new expression.
2995 /// Subclasses may override this routine to provide different behavior.
2997 TypeSourceInfo *TInfo,
2998 SourceLocation RParenLoc,
2999 Expr *SubExpr) {
3000 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3001 SubExpr);
3002 }
3003
3004 /// Build a new compound literal expression.
3005 ///
3006 /// By default, performs semantic analysis to build the new expression.
3007 /// Subclasses may override this routine to provide different behavior.
3009 TypeSourceInfo *TInfo,
3010 SourceLocation RParenLoc,
3011 Expr *Init) {
3012 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3013 Init);
3014 }
3015
3016 /// Build a new extended vector element access expression.
3017 ///
3018 /// By default, performs semantic analysis to build the new expression.
3019 /// Subclasses may override this routine to provide different behavior.
3021 bool IsArrow,
3022 SourceLocation AccessorLoc,
3023 IdentifierInfo &Accessor) {
3024
3025 CXXScopeSpec SS;
3026 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3028 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3029 /*FirstQualifierInScope*/ nullptr, NameInfo,
3030 /* TemplateArgs */ nullptr,
3031 /*S*/ nullptr);
3032 }
3033
3034 /// Build a new initializer list expression.
3035 ///
3036 /// By default, performs semantic analysis to build the new expression.
3037 /// Subclasses may override this routine to provide different behavior.
3039 MultiExprArg Inits,
3040 SourceLocation RBraceLoc) {
3041 return SemaRef.BuildInitList(LBraceLoc, Inits, RBraceLoc);
3042 }
3043
3044 /// Build a new designated initializer expression.
3045 ///
3046 /// By default, performs semantic analysis to build the new expression.
3047 /// Subclasses may override this routine to provide different behavior.
3049 MultiExprArg ArrayExprs,
3050 SourceLocation EqualOrColonLoc,
3051 bool GNUSyntax,
3052 Expr *Init) {
3054 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3055 Init);
3056 if (Result.isInvalid())
3057 return ExprError();
3058
3059 return Result;
3060 }
3061
3062 /// Build a new value-initialized expression.
3063 ///
3064 /// By default, builds the implicit value initialization without performing
3065 /// any semantic analysis. Subclasses may override this routine to provide
3066 /// different behavior.
3068 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3069 }
3070
3071 /// Build a new \c va_arg expression.
3072 ///
3073 /// By default, performs semantic analysis to build the new expression.
3074 /// Subclasses may override this routine to provide different behavior.
3076 Expr *SubExpr, TypeSourceInfo *TInfo,
3077 SourceLocation RParenLoc) {
3078 return getSema().BuildVAArgExpr(BuiltinLoc,
3079 SubExpr, TInfo,
3080 RParenLoc);
3081 }
3082
3083 /// Build a new expression list in parentheses.
3084 ///
3085 /// By default, performs semantic analysis to build the new expression.
3086 /// Subclasses may override this routine to provide different behavior.
3088 MultiExprArg SubExprs,
3089 SourceLocation RParenLoc) {
3090 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3091 }
3092
3093 /// Build a new address-of-label expression.
3094 ///
3095 /// By default, performs semantic analysis, using the name of the label
3096 /// rather than attempting to map the label statement itself.
3097 /// Subclasses may override this routine to provide different behavior.
3099 SourceLocation LabelLoc, LabelDecl *Label) {
3100 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3101 }
3102
3103 /// Build a new GNU statement expression.
3104 ///
3105 /// By default, performs semantic analysis to build the new expression.
3106 /// Subclasses may override this routine to provide different behavior.
3108 SourceLocation RParenLoc, unsigned TemplateDepth) {
3109 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3110 TemplateDepth);
3111 }
3112
3113 /// Build a new __builtin_choose_expr expression.
3114 ///
3115 /// By default, performs semantic analysis to build the new expression.
3116 /// Subclasses may override this routine to provide different behavior.
3118 Expr *Cond, Expr *LHS, Expr *RHS,
3119 SourceLocation RParenLoc) {
3120 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3121 Cond, LHS, RHS,
3122 RParenLoc);
3123 }
3124
3125 /// Build a new generic selection expression with an expression predicate.
3126 ///
3127 /// By default, performs semantic analysis to build the new expression.
3128 /// Subclasses may override this routine to provide different behavior.
3130 SourceLocation DefaultLoc,
3131 SourceLocation RParenLoc,
3132 Expr *ControllingExpr,
3134 ArrayRef<Expr *> Exprs) {
3135 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3136 /*PredicateIsExpr=*/true,
3137 ControllingExpr, Types, Exprs);
3138 }
3139
3140 /// Build a new generic selection expression with a type predicate.
3141 ///
3142 /// By default, performs semantic analysis to build the new expression.
3143 /// Subclasses may override this routine to provide different behavior.
3145 SourceLocation DefaultLoc,
3146 SourceLocation RParenLoc,
3147 TypeSourceInfo *ControllingType,
3149 ArrayRef<Expr *> Exprs) {
3150 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3151 /*PredicateIsExpr=*/false,
3152 ControllingType, Types, Exprs);
3153 }
3154
3155 /// Build a new overloaded operator call expression.
3156 ///
3157 /// By default, performs semantic analysis to build the new expression.
3158 /// The semantic analysis provides the behavior of template instantiation,
3159 /// copying with transformations that turn what looks like an overloaded
3160 /// operator call into a use of a builtin operator, performing
3161 /// argument-dependent lookup, etc. Subclasses may override this routine to
3162 /// provide different behavior.
3164 SourceLocation OpLoc,
3165 SourceLocation CalleeLoc,
3166 bool RequiresADL,
3167 const UnresolvedSetImpl &Functions,
3168 Expr *First, Expr *Second);
3169
3170 /// Build a new C++ "named" cast expression, such as static_cast or
3171 /// reinterpret_cast.
3172 ///
3173 /// By default, this routine dispatches to one of the more-specific routines
3174 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3175 /// Subclasses may override this routine to provide different behavior.
3178 SourceLocation LAngleLoc,
3179 TypeSourceInfo *TInfo,
3180 SourceLocation RAngleLoc,
3181 SourceLocation LParenLoc,
3182 Expr *SubExpr,
3183 SourceLocation RParenLoc) {
3184 switch (Class) {
3185 case Stmt::CXXStaticCastExprClass:
3186 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3187 RAngleLoc, LParenLoc,
3188 SubExpr, RParenLoc);
3189
3190 case Stmt::CXXDynamicCastExprClass:
3191 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3192 RAngleLoc, LParenLoc,
3193 SubExpr, RParenLoc);
3194
3195 case Stmt::CXXReinterpretCastExprClass:
3196 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3197 RAngleLoc, LParenLoc,
3198 SubExpr,
3199 RParenLoc);
3200
3201 case Stmt::CXXConstCastExprClass:
3202 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3203 RAngleLoc, LParenLoc,
3204 SubExpr, RParenLoc);
3205
3206 case Stmt::CXXAddrspaceCastExprClass:
3207 return getDerived().RebuildCXXAddrspaceCastExpr(
3208 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3209
3210 default:
3211 llvm_unreachable("Invalid C++ named cast");
3212 }
3213 }
3214
3215 /// Build a new C++ static_cast expression.
3216 ///
3217 /// By default, performs semantic analysis to build the new expression.
3218 /// Subclasses may override this routine to provide different behavior.
3220 SourceLocation LAngleLoc,
3221 TypeSourceInfo *TInfo,
3222 SourceLocation RAngleLoc,
3223 SourceLocation LParenLoc,
3224 Expr *SubExpr,
3225 SourceLocation RParenLoc) {
3226 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3227 TInfo, SubExpr,
3228 SourceRange(LAngleLoc, RAngleLoc),
3229 SourceRange(LParenLoc, RParenLoc));
3230 }
3231
3232 /// Build a new C++ dynamic_cast expression.
3233 ///
3234 /// By default, performs semantic analysis to build the new expression.
3235 /// Subclasses may override this routine to provide different behavior.
3237 SourceLocation LAngleLoc,
3238 TypeSourceInfo *TInfo,
3239 SourceLocation RAngleLoc,
3240 SourceLocation LParenLoc,
3241 Expr *SubExpr,
3242 SourceLocation RParenLoc) {
3243 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3244 TInfo, SubExpr,
3245 SourceRange(LAngleLoc, RAngleLoc),
3246 SourceRange(LParenLoc, RParenLoc));
3247 }
3248
3249 /// Build a new C++ reinterpret_cast expression.
3250 ///
3251 /// By default, performs semantic analysis to build the new expression.
3252 /// Subclasses may override this routine to provide different behavior.
3254 SourceLocation LAngleLoc,
3255 TypeSourceInfo *TInfo,
3256 SourceLocation RAngleLoc,
3257 SourceLocation LParenLoc,
3258 Expr *SubExpr,
3259 SourceLocation RParenLoc) {
3260 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3261 TInfo, SubExpr,
3262 SourceRange(LAngleLoc, RAngleLoc),
3263 SourceRange(LParenLoc, RParenLoc));
3264 }
3265
3266 /// Build a new C++ const_cast expression.
3267 ///
3268 /// By default, performs semantic analysis to build the new expression.
3269 /// Subclasses may override this routine to provide different behavior.
3271 SourceLocation LAngleLoc,
3272 TypeSourceInfo *TInfo,
3273 SourceLocation RAngleLoc,
3274 SourceLocation LParenLoc,
3275 Expr *SubExpr,
3276 SourceLocation RParenLoc) {
3277 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3278 TInfo, SubExpr,
3279 SourceRange(LAngleLoc, RAngleLoc),
3280 SourceRange(LParenLoc, RParenLoc));
3281 }
3282
3285 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3286 SourceLocation LParenLoc, Expr *SubExpr,
3287 SourceLocation RParenLoc) {
3288 return getSema().BuildCXXNamedCast(
3289 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3290 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3291 }
3292
3293 /// Build a new C++ functional-style cast expression.
3294 ///
3295 /// By default, performs semantic analysis to build the new expression.
3296 /// Subclasses may override this routine to provide different behavior.
3298 SourceLocation LParenLoc,
3299 Expr *Sub,
3300 SourceLocation RParenLoc,
3301 bool ListInitialization) {
3302 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3303 // CXXParenListInitExpr. Pass its expanded arguments so that the
3304 // CXXParenListInitExpr can be rebuilt.
3305 if (auto *PLE = dyn_cast<ParenListExpr>(Sub))
3307 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3308 RParenLoc, ListInitialization);
3309 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3310 MultiExprArg(&Sub, 1), RParenLoc,
3311 ListInitialization);
3312 }
3313
3314 /// Build a new C++ __builtin_bit_cast expression.
3315 ///
3316 /// By default, performs semantic analysis to build the new expression.
3317 /// Subclasses may override this routine to provide different behavior.
3319 TypeSourceInfo *TSI, Expr *Sub,
3320 SourceLocation RParenLoc) {
3321 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3322 }
3323
3324 /// Build a new C++ typeid(type) expression.
3325 ///
3326 /// By default, performs semantic analysis to build the new expression.
3327 /// Subclasses may override this routine to provide different behavior.
3329 SourceLocation TypeidLoc,
3330 TypeSourceInfo *Operand,
3331 SourceLocation RParenLoc) {
3332 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3333 RParenLoc);
3334 }
3335
3336
3337 /// Build a new C++ typeid(expr) expression.
3338 ///
3339 /// By default, performs semantic analysis to build the new expression.
3340 /// Subclasses may override this routine to provide different behavior.
3342 SourceLocation TypeidLoc,
3343 Expr *Operand,
3344 SourceLocation RParenLoc) {
3345 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3346 RParenLoc);
3347 }
3348
3349 /// Build a new C++ __uuidof(type) expression.
3350 ///
3351 /// By default, performs semantic analysis to build the new expression.
3352 /// Subclasses may override this routine to provide different behavior.
3354 TypeSourceInfo *Operand,
3355 SourceLocation RParenLoc) {
3356 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3357 }
3358
3359 /// Build a new C++ __uuidof(expr) expression.
3360 ///
3361 /// By default, performs semantic analysis to build the new expression.
3362 /// Subclasses may override this routine to provide different behavior.
3364 Expr *Operand, SourceLocation RParenLoc) {
3365 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3366 }
3367
3368 /// Build a new C++ "this" expression.
3369 ///
3370 /// By default, performs semantic analysis to build a new "this" expression.
3371 /// Subclasses may override this routine to provide different behavior.
3373 QualType ThisType,
3374 bool isImplicit) {
3375 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3376 return ExprError();
3377 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3378 }
3379
3380 /// Build a new C++ throw expression.
3381 ///
3382 /// By default, performs semantic analysis to build the new expression.
3383 /// Subclasses may override this routine to provide different behavior.
3385 bool IsThrownVariableInScope) {
3386 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3387 }
3388
3389 /// Build a new C++ default-argument expression.
3390 ///
3391 /// By default, builds a new default-argument expression, which does not
3392 /// require any semantic analysis. Subclasses may override this routine to
3393 /// provide different behavior.
3395 Expr *RewrittenExpr) {
3396 return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param,
3397 RewrittenExpr, getSema().CurContext);
3398 }
3399
3400 /// Build a new C++11 default-initialization expression.
3401 ///
3402 /// By default, builds a new default field initialization expression, which
3403 /// does not require any semantic analysis. Subclasses may override this
3404 /// routine to provide different behavior.
3406 FieldDecl *Field) {
3407 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3408 }
3409
3410 /// Build a new C++ zero-initialization expression.
3411 ///
3412 /// By default, performs semantic analysis to build the new expression.
3413 /// Subclasses may override this routine to provide different behavior.
3415 SourceLocation LParenLoc,
3416 SourceLocation RParenLoc) {
3417 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, std::nullopt,
3418 RParenLoc,
3419 /*ListInitialization=*/false);
3420 }
3421
3422 /// Build a new C++ "new" expression.
3423 ///
3424 /// By default, performs semantic analysis to build the new expression.
3425 /// Subclasses may override this routine to provide different behavior.
3427 SourceLocation PlacementLParen,
3428 MultiExprArg PlacementArgs,
3429 SourceLocation PlacementRParen,
3430 SourceRange TypeIdParens, QualType AllocatedType,
3431 TypeSourceInfo *AllocatedTypeInfo,
3432 std::optional<Expr *> ArraySize,
3433 SourceRange DirectInitRange, Expr *Initializer) {
3434 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3435 PlacementLParen,
3436 PlacementArgs,
3437 PlacementRParen,
3438 TypeIdParens,
3439 AllocatedType,
3440 AllocatedTypeInfo,
3441 ArraySize,
3442 DirectInitRange,
3443 Initializer);
3444 }
3445
3446 /// Build a new C++ "delete" expression.
3447 ///
3448 /// By default, performs semantic analysis to build the new expression.
3449 /// Subclasses may override this routine to provide different behavior.
3451 bool IsGlobalDelete,
3452 bool IsArrayForm,
3453 Expr *Operand) {
3454 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3455 Operand);
3456 }
3457
3458 /// Build a new type trait expression.
3459 ///
3460 /// By default, performs semantic analysis to build the new expression.
3461 /// Subclasses may override this routine to provide different behavior.
3463 SourceLocation StartLoc,
3465 SourceLocation RParenLoc) {
3466 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3467 }
3468
3469 /// Build a new array type trait expression.
3470 ///
3471 /// By default, performs semantic analysis to build the new expression.
3472 /// Subclasses may override this routine to provide different behavior.
3474 SourceLocation StartLoc,
3475 TypeSourceInfo *TSInfo,
3476 Expr *DimExpr,
3477 SourceLocation RParenLoc) {
3478 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3479 }
3480
3481 /// Build a new expression trait expression.
3482 ///
3483 /// By default, performs semantic analysis to build the new expression.
3484 /// Subclasses may override this routine to provide different behavior.
3486 SourceLocation StartLoc,
3487 Expr *Queried,
3488 SourceLocation RParenLoc) {
3489 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3490 }
3491
3492 /// Build a new (previously unresolved) declaration reference
3493 /// expression.
3494 ///
3495 /// By default, performs semantic analysis to build the new expression.
3496 /// Subclasses may override this routine to provide different behavior.
3498 NestedNameSpecifierLoc QualifierLoc,
3499 SourceLocation TemplateKWLoc,
3500 const DeclarationNameInfo &NameInfo,
3501 const TemplateArgumentListInfo *TemplateArgs,
3502 bool IsAddressOfOperand,
3503 TypeSourceInfo **RecoveryTSI) {
3504 CXXScopeSpec SS;
3505 SS.Adopt(QualifierLoc);
3506
3507 if (TemplateArgs || TemplateKWLoc.isValid())
3509 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3510
3512 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3513 }
3514
3515 /// Build a new template-id expression.
3516 ///
3517 /// By default, performs semantic analysis to build the new expression.
3518 /// Subclasses may override this routine to provide different behavior.
3520 SourceLocation TemplateKWLoc,
3521 LookupResult &R,
3522 bool RequiresADL,
3523 const TemplateArgumentListInfo *TemplateArgs) {
3524 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3525 TemplateArgs);
3526 }
3527
3528 /// Build a new object-construction expression.
3529 ///
3530 /// By default, performs semantic analysis to build the new expression.
3531 /// Subclasses may override this routine to provide different behavior.
3534 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3535 bool ListInitialization, bool StdInitListInitialization,
3536 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3537 SourceRange ParenRange) {
3538 // Reconstruct the constructor we originally found, which might be
3539 // different if this is a call to an inherited constructor.
3540 CXXConstructorDecl *FoundCtor = Constructor;
3541 if (Constructor->isInheritingConstructor())
3542 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3543
3544 SmallVector<Expr *, 8> ConvertedArgs;
3545 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3546 ConvertedArgs))
3547 return ExprError();
3548
3549 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3550 IsElidable,
3551 ConvertedArgs,
3552 HadMultipleCandidates,
3553 ListInitialization,
3554 StdInitListInitialization,
3555 RequiresZeroInit, ConstructKind,
3556 ParenRange);
3557 }
3558
3559 /// Build a new implicit construction via inherited constructor
3560 /// expression.
3562 CXXConstructorDecl *Constructor,
3563 bool ConstructsVBase,
3564 bool InheritedFromVBase) {
3566 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3567 }
3568
3569 /// Build a new object-construction expression.
3570 ///
3571 /// By default, performs semantic analysis to build the new expression.
3572 /// Subclasses may override this routine to provide different behavior.
3574 SourceLocation LParenOrBraceLoc,
3575 MultiExprArg Args,
3576 SourceLocation RParenOrBraceLoc,
3577 bool ListInitialization) {
3579 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3580 }
3581
3582 /// Build a new object-construction expression.
3583 ///
3584 /// By default, performs semantic analysis to build the new expression.
3585 /// Subclasses may override this routine to provide different behavior.
3587 SourceLocation LParenLoc,
3588 MultiExprArg Args,
3589 SourceLocation RParenLoc,
3590 bool ListInitialization) {
3591 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3592 RParenLoc, ListInitialization);
3593 }
3594
3595 /// Build a new member reference expression.
3596 ///
3597 /// By default, performs semantic analysis to build the new expression.
3598 /// Subclasses may override this routine to provide different behavior.
3600 QualType BaseType,
3601 bool IsArrow,
3602 SourceLocation OperatorLoc,
3603 NestedNameSpecifierLoc QualifierLoc,
3604 SourceLocation TemplateKWLoc,
3605 NamedDecl *FirstQualifierInScope,
3606 const DeclarationNameInfo &MemberNameInfo,
3607 const TemplateArgumentListInfo *TemplateArgs) {
3608 CXXScopeSpec SS;
3609 SS.Adopt(QualifierLoc);
3610
3611 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3612 OperatorLoc, IsArrow,
3613 SS, TemplateKWLoc,
3614 FirstQualifierInScope,
3615 MemberNameInfo,
3616 TemplateArgs, /*S*/nullptr);
3617 }
3618
3619 /// Build a new member reference expression.
3620 ///
3621 /// By default, performs semantic analysis to build the new expression.
3622 /// Subclasses may override this routine to provide different behavior.
3624 SourceLocation OperatorLoc,
3625 bool IsArrow,
3626 NestedNameSpecifierLoc QualifierLoc,
3627 SourceLocation TemplateKWLoc,
3628 NamedDecl *FirstQualifierInScope,
3629 LookupResult &R,
3630 const TemplateArgumentListInfo *TemplateArgs) {
3631 CXXScopeSpec SS;
3632 SS.Adopt(QualifierLoc);
3633
3634 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3635 OperatorLoc, IsArrow,
3636 SS, TemplateKWLoc,
3637 FirstQualifierInScope,
3638 R, TemplateArgs, /*S*/nullptr);
3639 }
3640
3641 /// Build a new noexcept expression.
3642 ///
3643 /// By default, performs semantic analysis to build the new expression.
3644 /// Subclasses may override this routine to provide different behavior.
3646 return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd());
3647 }
3648
3649 /// Build a new expression to compute the length of a parameter pack.
3651 SourceLocation PackLoc,
3652 SourceLocation RParenLoc,
3653 std::optional<unsigned> Length,
3654 ArrayRef<TemplateArgument> PartialArgs) {
3655 return SizeOfPackExpr::Create(SemaRef.Context, OperatorLoc, Pack, PackLoc,
3656 RParenLoc, Length, PartialArgs);
3657 }
3658
3660 SourceLocation RSquareLoc,
3661 Expr *PackIdExpression, Expr *IndexExpr,
3662 ArrayRef<Expr *> ExpandedExprs,
3663 bool EmptyPack = false) {
3664 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3665 IndexExpr, RSquareLoc, ExpandedExprs,
3666 EmptyPack);
3667 }
3668
3669 /// Build a new expression representing a call to a source location
3670 /// builtin.
3671 ///
3672 /// By default, performs semantic analysis to build the new expression.
3673 /// Subclasses may override this routine to provide different behavior.
3675 SourceLocation BuiltinLoc,
3676 SourceLocation RPLoc,
3677 DeclContext *ParentContext) {
3678 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3679 ParentContext);
3680 }
3681
3682 /// Build a new Objective-C boxed expression.
3683 ///
3684 /// By default, performs semantic analysis to build the new expression.
3685 /// Subclasses may override this routine to provide different behavior.
3687 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3688 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3690 CXXScopeSpec SS;
3691 SS.Adopt(NNS);
3692 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3693 ConceptNameInfo,
3694 FoundDecl,
3695 NamedConcept, TALI);
3696 if (Result.isInvalid())
3697 return ExprError();
3698 return Result;
3699 }
3700
3701 /// \brief Build a new requires expression.
3702 ///
3703 /// By default, performs semantic analysis to build the new expression.
3704 /// Subclasses may override this routine to provide different behavior.
3707 SourceLocation LParenLoc,
3708 ArrayRef<ParmVarDecl *> LocalParameters,
3709 SourceLocation RParenLoc,
3711 SourceLocation ClosingBraceLoc) {
3712 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3713 LocalParameters, RParenLoc, Requirements,
3714 ClosingBraceLoc);
3715 }
3716
3720 return SemaRef.BuildTypeRequirement(SubstDiag);
3721 }
3722
3725 }
3726
3729 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3730 SourceLocation NoexceptLoc,
3732 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
3733 std::move(Ret));
3734 }
3735
3737 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3739 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
3740 std::move(Ret));
3741 }
3742
3744 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3745 const ASTConstraintSatisfaction &Satisfaction) {
3746 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3747 Satisfaction);
3748 }
3749
3751 return SemaRef.BuildNestedRequirement(Constraint);
3752 }
3753
3754 /// \brief Build a new Objective-C boxed expression.
3755 ///
3756 /// By default, performs semantic analysis to build the new expression.
3757 /// Subclasses may override this routine to provide different behavior.
3759 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3760 }
3761
3762 /// Build a new Objective-C array literal.
3763 ///
3764 /// By default, performs semantic analysis to build the new expression.
3765 /// Subclasses may override this routine to provide different behavior.
3767 Expr **Elements, unsigned NumElements) {
3769 Range, MultiExprArg(Elements, NumElements));
3770 }
3771
3773 Expr *Base, Expr *Key,
3774 ObjCMethodDecl *getterMethod,
3775 ObjCMethodDecl *setterMethod) {
3777 RB, Base, Key, getterMethod, setterMethod);
3778 }
3779
3780 /// Build a new Objective-C dictionary literal.
3781 ///
3782 /// By default, performs semantic analysis to build the new expression.
3783 /// Subclasses may override this routine to provide different behavior.
3786 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3787 }
3788
3789 /// Build a new Objective-C \@encode expression.
3790 ///
3791 /// By default, performs semantic analysis to build the new expression.
3792 /// Subclasses may override this routine to provide different behavior.
3794 TypeSourceInfo *EncodeTypeInfo,
3795 SourceLocation RParenLoc) {
3796 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
3797 RParenLoc);
3798 }
3799
3800 /// Build a new Objective-C class message.
3802 Selector Sel,
3803 ArrayRef<SourceLocation> SelectorLocs,
3804 ObjCMethodDecl *Method,
3805 SourceLocation LBracLoc,
3806 MultiExprArg Args,
3807 SourceLocation RBracLoc) {
3809 ReceiverTypeInfo, ReceiverTypeInfo->getType(),
3810 /*SuperLoc=*/SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3811 RBracLoc, Args);
3812 }
3813
3814 /// Build a new Objective-C instance message.
3816 Selector Sel,
3817 ArrayRef<SourceLocation> SelectorLocs,
3818 ObjCMethodDecl *Method,
3819 SourceLocation LBracLoc,
3820 MultiExprArg Args,
3821 SourceLocation RBracLoc) {
3822 return SemaRef.ObjC().BuildInstanceMessage(Receiver, Receiver->getType(),
3823 /*SuperLoc=*/SourceLocation(),
3824 Sel, Method, LBracLoc,
3825 SelectorLocs, RBracLoc, Args);
3826 }
3827
3828 /// Build a new Objective-C instance/class message to 'super'.
3830 Selector Sel,
3831 ArrayRef<SourceLocation> SelectorLocs,
3832 QualType SuperType,
3833 ObjCMethodDecl *Method,
3834 SourceLocation LBracLoc,
3835 MultiExprArg Args,
3836 SourceLocation RBracLoc) {
3837 return Method->isInstanceMethod()
3839 nullptr, SuperType, SuperLoc, Sel, Method, LBracLoc,
3840 SelectorLocs, RBracLoc, Args)
3841 : SemaRef.ObjC().BuildClassMessage(nullptr, SuperType, SuperLoc,
3842 Sel, Method, LBracLoc,
3843 SelectorLocs, RBracLoc, Args);
3844 }
3845
3846 /// Build a new Objective-C ivar reference expression.
3847 ///
3848 /// By default, performs semantic analysis to build the new expression.
3849 /// Subclasses may override this routine to provide different behavior.
3851 SourceLocation IvarLoc,
3852 bool IsArrow, bool IsFreeIvar) {
3853 CXXScopeSpec SS;
3854 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3856 BaseArg, BaseArg->getType(),
3857 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3858 /*FirstQualifierInScope=*/nullptr, NameInfo,
3859 /*TemplateArgs=*/nullptr,
3860 /*S=*/nullptr);
3861 if (IsFreeIvar && Result.isUsable())
3862 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
3863 return Result;
3864 }
3865
3866 /// Build a new Objective-C property reference expression.
3867 ///
3868 /// By default, performs semantic analysis to build the new expression.
3869 /// Subclasses may override this routine to provide different behavior.
3872 SourceLocation PropertyLoc) {
3873 CXXScopeSpec SS;
3874 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3875 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3876 /*FIXME:*/PropertyLoc,
3877 /*IsArrow=*/false,
3878 SS, SourceLocation(),
3879 /*FirstQualifierInScope=*/nullptr,
3880 NameInfo,
3881 /*TemplateArgs=*/nullptr,
3882 /*S=*/nullptr);
3883 }
3884
3885 /// Build a new Objective-C property reference expression.
3886 ///
3887 /// By default, performs semantic analysis to build the new expression.
3888 /// Subclasses may override this routine to provide different behavior.
3890 ObjCMethodDecl *Getter,
3891 ObjCMethodDecl *Setter,
3892 SourceLocation PropertyLoc) {
3893 // Since these expressions can only be value-dependent, we do not
3894 // need to perform semantic analysis again.
3895 return Owned(
3896 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3898 PropertyLoc, Base));
3899 }
3900
3901 /// Build a new Objective-C "isa" expression.
3902 ///
3903 /// By default, performs semantic analysis to build the new expression.
3904 /// Subclasses may override this routine to provide different behavior.
3906 SourceLocation OpLoc, bool IsArrow) {
3907 CXXScopeSpec SS;
3908 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3909 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3910 OpLoc, IsArrow,
3911 SS, SourceLocation(),
3912 /*FirstQualifierInScope=*/nullptr,
3913 NameInfo,
3914 /*TemplateArgs=*/nullptr,
3915 /*S=*/nullptr);
3916 }
3917
3918 /// Build a new shuffle vector expression.
3919 ///
3920 /// By default, performs semantic analysis to build the new expression.
3921 /// Subclasses may override this routine to provide different behavior.
3923 MultiExprArg SubExprs,
3924 SourceLocation RParenLoc) {
3925 // Find the declaration for __builtin_shufflevector
3926 const IdentifierInfo &Name
3927 = SemaRef.Context.Idents.get("__builtin_shufflevector");
3929 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
3930 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3931
3932 // Build a reference to the __builtin_shufflevector builtin
3933 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
3934 Expr *Callee = new (SemaRef.Context)
3935 DeclRefExpr(SemaRef.Context, Builtin, false,
3936 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3937 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
3938 Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
3939 CK_BuiltinFnToFnPtr).get();
3940
3941 // Build the CallExpr
3942 ExprResult TheCall = CallExpr::Create(
3943 SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
3944 Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc,
3946
3947 // Type-check the __builtin_shufflevector expression.
3948 return SemaRef.BuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
3949 }
3950
3951 /// Build a new convert vector expression.
3953 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3954 SourceLocation RParenLoc) {
3955 return SemaRef.ConvertVectorExpr(SrcExpr, DstTInfo, BuiltinLoc, RParenLoc);
3956 }
3957
3958 /// Build a new template argument pack expansion.
3959 ///
3960 /// By default, performs semantic analysis to build a new pack expansion
3961 /// for a template argument. Subclasses may override this routine to provide
3962 /// different behavior.
3965 std::optional<unsigned> NumExpansions) {
3966 switch (Pattern.getArgument().getKind()) {
3970 EllipsisLoc, NumExpansions);
3971 if (Result.isInvalid())
3972 return TemplateArgumentLoc();
3973
3974 return TemplateArgumentLoc(Result.get(), Result.get());
3975 }
3976
3978 return TemplateArgumentLoc(
3981 NumExpansions),
3982 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
3983 EllipsisLoc);
3984
3992 llvm_unreachable("Pack expansion pattern has no parameter packs");
3993
3995 if (TypeSourceInfo *Expansion
3996 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
3997 EllipsisLoc,
3998 NumExpansions))
3999 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4000 Expansion);
4001 break;
4002 }
4003
4004 return TemplateArgumentLoc();
4005 }
4006
4007 /// Build a new expression pack expansion.
4008 ///
4009 /// By default, performs semantic analysis to build a new pack expansion
4010 /// for an expression. Subclasses may override this routine to provide
4011 /// different behavior.
4013 std::optional<unsigned> NumExpansions) {
4014 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4015 }
4016
4017 /// Build a new C++1z fold-expression.
4018 ///
4019 /// By default, performs semantic analysis in order to build a new fold
4020 /// expression.
4022 SourceLocation LParenLoc, Expr *LHS,
4023 BinaryOperatorKind Operator,
4024 SourceLocation EllipsisLoc, Expr *RHS,
4025 SourceLocation RParenLoc,
4026 std::optional<unsigned> NumExpansions) {
4027 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4028 EllipsisLoc, RHS, RParenLoc,
4029 NumExpansions);
4030 }
4031
4033 LambdaScopeInfo *LSI) {
4034 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4035 if (Expr *Init = PVD->getInit())
4037 Init->containsUnexpandedParameterPack();
4038 else if (PVD->hasUninstantiatedDefaultArg())
4040 PVD->getUninstantiatedDefaultArg()
4041 ->containsUnexpandedParameterPack();
4042 }
4043 return getSema().BuildLambdaExpr(StartLoc, EndLoc, LSI);
4044 }
4045
4046 /// Build an empty C++1z fold-expression with the given operator.
4047 ///
4048 /// By default, produces the fallback value for the fold-expression, or
4049 /// produce an error if there is no fallback value.
4051 BinaryOperatorKind Operator) {
4052 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4053 }
4054
4055 /// Build a new atomic operation expression.
4056 ///
4057 /// By default, performs semantic analysis to build the new expression.
4058 /// Subclasses may override this routine to provide different behavior.
4061 SourceLocation RParenLoc) {
4062 // Use this for all of the locations, since we don't know the difference
4063 // between the call and the expr at this point.
4064 SourceRange Range{BuiltinLoc, RParenLoc};
4065 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4067 }
4068
4070 ArrayRef<Expr *> SubExprs, QualType Type) {
4071 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4072 }
4073
4075 SourceLocation BeginLoc,
4076 SourceLocation DirLoc,
4077 SourceLocation EndLoc,
4079 StmtResult StrBlock) {
4080 return getSema().OpenACC().ActOnEndStmtDirective(K, BeginLoc, DirLoc,
4081 EndLoc, Clauses, StrBlock);
4082 }
4083
4085 SourceLocation DirLoc,
4086 SourceLocation EndLoc,
4088 StmtResult Loop) {
4090 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, EndLoc, Clauses, Loop);
4091 }
4092
4093private:
4094 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
4095 QualType ObjectType,
4096 NamedDecl *FirstQualifierInScope,
4097 CXXScopeSpec &SS);
4098
4099 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4100 QualType ObjectType,
4101 NamedDecl *FirstQualifierInScope,
4102 CXXScopeSpec &SS);
4103
4104 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
4105 NamedDecl *FirstQualifierInScope,
4106 CXXScopeSpec &SS);
4107
4108 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4110 bool DeducibleTSTContext);
4111
4113 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4115
4117 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4118 OpenACCDirectiveKind DirKind,
4119 const OpenACCClause *OldClause);
4120};
4121
4122template <typename Derived>
4124 if (!S)
4125 return S;
4126
4127 switch (S->getStmtClass()) {
4128 case Stmt::NoStmtClass: break;
4129
4130 // Transform individual statement nodes
4131 // Pass SDK into statements that can produce a value
4132#define STMT(Node, Parent) \
4133 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4134#define VALUESTMT(Node, Parent) \
4135 case Stmt::Node##Class: \
4136 return getDerived().Transform##Node(cast<Node>(S), SDK);
4137#define ABSTRACT_STMT(Node)
4138#define EXPR(Node, Parent)
4139#include "clang/AST/StmtNodes.inc"
4140
4141 // Transform expressions by calling TransformExpr.
4142#define STMT(Node, Parent)
4143#define ABSTRACT_STMT(Stmt)
4144#define EXPR(Node, Parent) case Stmt::Node##Class:
4145#include "clang/AST/StmtNodes.inc"
4146 {
4147 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
4148
4149 if (SDK == SDK_StmtExprResult)
4150 E = getSema().ActOnStmtExprResult(E);
4151 return getSema().ActOnExprStmt(E, SDK == SDK_Discarded);
4152 }
4153 }
4154
4155 return S;
4156}
4157
4158template<typename Derived>
4160 if (!S)
4161 return S;
4162
4163 switch (S->getClauseKind()) {
4164 default: break;
4165 // Transform individual clause nodes
4166#define GEN_CLANG_CLAUSE_CLASS
4167#define CLAUSE_CLASS(Enum, Str, Class) \
4168 case Enum: \
4169 return getDerived().Transform##Class(cast<Class>(S));
4170#include "llvm/Frontend/OpenMP/OMP.inc"
4171 }
4172
4173 return S;
4174}
4175
4176
4177template<typename Derived>
4179 if (!E)
4180 return E;
4181
4182 switch (E->getStmtClass()) {
4183 case Stmt::NoStmtClass: break;
4184#define STMT(Node, Parent) case Stmt::Node##Class: break;
4185#define ABSTRACT_STMT(Stmt)
4186#define EXPR(Node, Parent) \
4187 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4188#include "clang/AST/StmtNodes.inc"
4189 }
4190
4191 return E;
4192}
4193
4194template<typename Derived>
4196 bool NotCopyInit) {
4197 // Initializers are instantiated like expressions, except that various outer
4198 // layers are stripped.
4199 if (!Init)
4200 return Init;
4201
4202 if (auto *FE = dyn_cast<FullExpr>(Init))
4203 Init = FE->getSubExpr();
4204
4205 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {
4206 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4207 Init = OVE->getSourceExpr();
4208 }
4209
4210 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
4211 Init = MTE->getSubExpr();
4212
4213 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
4214 Init = Binder->getSubExpr();
4215
4216 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
4217 Init = ICE->getSubExprAsWritten();
4218
4219 if (CXXStdInitializerListExpr *ILE =
4220 dyn_cast<CXXStdInitializerListExpr>(Init))
4221 return TransformInitializer(ILE->getSubExpr(), NotCopyInit);
4222
4223 // If this is copy-initialization, we only need to reconstruct
4224 // InitListExprs. Other forms of copy-initialization will be a no-op if
4225 // the initializer is already the right type.
4226 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
4227 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4228 return getDerived().TransformExpr(Init);
4229
4230 // Revert value-initialization back to empty parens.
4231 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
4232 SourceRange Parens = VIE->getSourceRange();
4233 return getDerived().RebuildParenListExpr(Parens.getBegin(), std::nullopt,
4234 Parens.getEnd());
4235 }
4236
4237 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4238 if (isa<ImplicitValueInitExpr>(Init))
4239 return getDerived().RebuildParenListExpr(SourceLocation(), std::nullopt,
4240 SourceLocation());
4241
4242 // Revert initialization by constructor back to a parenthesized or braced list
4243 // of expressions. Any other form of initializer can just be reused directly.
4244 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
4245 return getDerived().TransformExpr(Init);
4246
4247 // If the initialization implicitly converted an initializer list to a
4248 // std::initializer_list object, unwrap the std::initializer_list too.
4249 if (Construct && Construct->isStdInitListInitialization())
4250 return TransformInitializer(Construct->getArg(0), NotCopyInit);
4251
4252 // Enter a list-init context if this was list initialization.
4255 Construct->isListInitialization());
4256
4257 getSema().keepInLifetimeExtendingContext();
4258 SmallVector<Expr*, 8> NewArgs;
4259 bool ArgChanged = false;
4260 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4261 /*IsCall*/true, NewArgs, &ArgChanged))
4262 return ExprError();
4263
4264 // If this was list initialization, revert to syntactic list form.
4265 if (Construct->isListInitialization())
4266 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4267 Construct->getEndLoc());
4268
4269 // Build a ParenListExpr to represent anything else.
4271 if (Parens.isInvalid()) {
4272 // This was a variable declaration's initialization for which no initializer
4273 // was specified.
4274 assert(NewArgs.empty() &&
4275 "no parens or braces but have direct init with arguments?");
4276 return ExprEmpty();
4277 }
4278 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4279 Parens.getEnd());
4280}
4281
4282template<typename Derived>
4284 unsigned NumInputs,
4285 bool IsCall,
4286 SmallVectorImpl<Expr *> &Outputs,
4287 bool *ArgChanged) {
4288 for (unsigned I = 0; I != NumInputs; ++I) {
4289 // If requested, drop call arguments that need to be dropped.
4290 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4291 if (ArgChanged)
4292 *ArgChanged = true;
4293
4294 break;
4295 }
4296
4297 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
4298 Expr *Pattern = Expansion->getPattern();
4299
4301 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4302 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4303
4304 // Determine whether the set of unexpanded parameter packs can and should
4305 // be expanded.
4306 bool Expand = true;
4307 bool RetainExpansion = false;
4308 std::optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions();
4309 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4310 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4311 Pattern->getSourceRange(),
4312 Unexpanded,
4313 Expand, RetainExpansion,
4314 NumExpansions))
4315 return true;
4316
4317 if (!Expand) {
4318 // The transform has determined that we should perform a simple
4319 // transformation on the pack expansion, producing another pack
4320 // expansion.
4321 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4322 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4323 if (OutPattern.isInvalid())
4324 return true;
4325
4326 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4327 Expansion->getEllipsisLoc(),
4328 NumExpansions);
4329 if (Out.isInvalid())
4330 return true;
4331
4332 if (ArgChanged)
4333 *ArgChanged = true;
4334 Outputs.push_back(Out.get());
4335 continue;
4336 }
4337
4338 // Record right away that the argument was changed. This needs
4339 // to happen even if the array expands to nothing.
4340 if (ArgChanged) *ArgChanged = true;
4341
4342 // The transform has determined that we should perform an elementwise
4343 // expansion of the pattern. Do so.
4344 for (unsigned I = 0; I != *NumExpansions; ++I) {
4345 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4346 ExprResult Out = getDerived().TransformExpr(Pattern);
4347 if (Out.isInvalid())
4348 return true;
4349
4350 if (Out.get()->containsUnexpandedParameterPack()) {
4351 Out = getDerived().RebuildPackExpansion(
4352 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4353 if (Out.isInvalid())
4354 return true;
4355 }
4356
4357 Outputs.push_back(Out.get());
4358 }
4359
4360 // If we're supposed to retain a pack expansion, do so by temporarily
4361 // forgetting the partially-substituted parameter pack.
4362 if (RetainExpansion) {
4363 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4364
4365 ExprResult Out = getDerived().TransformExpr(Pattern);
4366 if (Out.isInvalid())
4367 return true;
4368
4369 Out = getDerived().RebuildPackExpansion(
4370 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4371 if (Out.isInvalid())
4372 return true;
4373
4374 Outputs.push_back(Out.get());
4375 }
4376
4377 continue;
4378 }
4379
4381 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4382 : getDerived().TransformExpr(Inputs[I]);
4383 if (Result.isInvalid())
4384 return true;
4385
4386 if (Result.get() != Inputs[I] && ArgChanged)
4387 *ArgChanged = true;
4388
4389 Outputs.push_back(Result.get());
4390 }
4391
4392 return false;
4393}
4394
4395template <typename Derived>
4398 if (Var) {
4399 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4400 getDerived().TransformDefinition(Var->getLocation(), Var));
4401
4402 if (!ConditionVar)
4403 return Sema::ConditionError();
4404
4405 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4406 }
4407
4408 if (Expr) {
4409 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4410
4411 if (CondExpr.isInvalid())
4412 return Sema::ConditionError();
4413
4414 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4415 /*MissingOK=*/true);
4416 }
4417
4418 return Sema::ConditionResult();
4419}
4420
4421template <typename Derived>
4423 NestedNameSpecifierLoc NNS, QualType ObjectType,
4424 NamedDecl *FirstQualifierInScope) {
4426
4427 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4428 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4429 Qualifier = Qualifier.getPrefix())
4430 Qualifiers.push_back(Qualifier);
4431 };
4432 insertNNS(NNS);
4433
4434 CXXScopeSpec SS;
4435 while (!Qualifiers.empty()) {
4436 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4438
4439 switch (QNNS->getKind()) {
4443 ObjectType);
4444 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false,
4445 SS, FirstQualifierInScope, false))
4446 return NestedNameSpecifierLoc();
4447 break;
4448 }
4449
4451 NamespaceDecl *NS =
4452 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4453 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4454 SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
4455 break;
4456 }
4457
4459 NamespaceAliasDecl *Alias =
4460 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4462 SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
4463 Q.getLocalEndLoc());
4464 break;
4465 }
4466
4468 // There is no meaningful transformation that one could perform on the
4469 // global scope.
4470 SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
4471 break;
4472
4474 CXXRecordDecl *RD =
4475 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4476 SourceLocation(), QNNS->getAsRecordDecl()));
4477 SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc());
4478 break;
4479 }
4480
4483 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4484 FirstQualifierInScope, SS);
4485
4486 if (!TL)
4487 return NestedNameSpecifierLoc();
4488
4489 QualType T = TL.getType();
4490 if (T->isDependentType() || T->isRecordType() ||
4491 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4492 if (T->isEnumeralType())
4493 SemaRef.Diag(TL.getBeginLoc(),
4494 diag::warn_cxx98_compat_enum_nested_name_spec);
4495
4496 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4497 SS.Adopt(ETL.getQualifierLoc());
4498 TL = ETL.getNamedTypeLoc();
4499 }
4500
4501 SS.Extend(SemaRef.Context, TL.getTemplateKeywordLoc(), TL,
4502 Q.getLocalEndLoc());
4503 break;
4504 }
4505 // If the nested-name-specifier is an invalid type def, don't emit an
4506 // error because a previous error should have already been emitted.
4508 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4509 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
4510 << T << SS.getRange();
4511 }
4512 return NestedNameSpecifierLoc();
4513 }
4514 }
4515
4516 // The qualifier-in-scope and object type only apply to the leftmost entity.
4517 FirstQualifierInScope = nullptr;
4518 ObjectType = QualType();
4519 }
4520
4521 // Don't rebuild the nested-name-specifier if we don't have to.
4522 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4523 !getDerived().AlwaysRebuild())
4524 return NNS;
4525
4526 // If we can re-use the source-location data from the original
4527 // nested-name-specifier, do so.
4528 if (SS.location_size() == NNS.getDataLength() &&
4529 memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)
4531
4532 // Allocate new nested-name-specifier location information.
4533 return SS.getWithLocInContext(SemaRef.Context);
4534}
4535
4536template<typename Derived>
4540 DeclarationName Name = NameInfo.getName();
4541 if (!Name)
4542 return DeclarationNameInfo();
4543
4544 switch (Name.getNameKind()) {
4552 return NameInfo;
4553
4555 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4556 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4557 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4558 if (!NewTemplate)
4559 return DeclarationNameInfo();
4560
4561 DeclarationNameInfo NewNameInfo(NameInfo);
4562 NewNameInfo.setName(
4564 return NewNameInfo;
4565 }
4566
4570 TypeSourceInfo *NewTInfo;
4571 CanQualType NewCanTy;
4572 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4573 NewTInfo = getDerived().TransformType(OldTInfo);
4574 if (!NewTInfo)
4575 return DeclarationNameInfo();
4576 NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
4577 }
4578 else {
4579 NewTInfo = nullptr;
4580 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4581 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4582 if (NewT.isNull())
4583 return DeclarationNameInfo();
4584 NewCanTy = SemaRef.Context.getCanonicalType(NewT);
4585 }
4586
4587 DeclarationName NewName
4588 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
4589 NewCanTy);
4590 DeclarationNameInfo NewNameInfo(NameInfo);
4591 NewNameInfo.setName(NewName);
4592 NewNameInfo.setNamedTypeInfo(NewTInfo);
4593 return NewNameInfo;
4594 }
4595 }
4596
4597 llvm_unreachable("Unknown name kind.");
4598}
4599
4600template<typename Derived>
4603 TemplateName Name,
4604 SourceLocation NameLoc,
4605 QualType ObjectType,
4606 NamedDecl *FirstQualifierInScope,
4607 bool AllowInjectedClassName) {
4608 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4609 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4610 assert(Template && "qualified template name must refer to a template");
4611
4612 TemplateDecl *TransTemplate
4613 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4614 Template));
4615 if (!TransTemplate)
4616 return TemplateName();
4617
4618 if (!getDerived().AlwaysRebuild() &&
4619 SS.getScopeRep() == QTN->getQualifier() &&
4620 TransTemplate == Template)
4621 return Name;
4622
4623 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4624 TransTemplate);
4625 }
4626
4627 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4628 if (SS.getScopeRep()) {
4629 // These apply to the scope specifier, not the template.
4630 ObjectType = QualType();
4631 FirstQualifierInScope = nullptr;
4632 }
4633
4634 if (!getDerived().AlwaysRebuild() &&
4635 SS.getScopeRep() == DTN->getQualifier() &&
4636 ObjectType.isNull())
4637 return Name;
4638
4639 // FIXME: Preserve the location of the "template" keyword.
4640 SourceLocation TemplateKWLoc = NameLoc;
4641
4642 if (DTN->isIdentifier()) {
4643 return getDerived().RebuildTemplateName(SS,
4644 TemplateKWLoc,
4645 *DTN->getIdentifier(),
4646 NameLoc,
4647 ObjectType,
4648 FirstQualifierInScope,
4649 AllowInjectedClassName);
4650 }
4651
4652 return getDerived().RebuildTemplateName(SS, TemplateKWLoc,
4653 DTN->getOperator(), NameLoc,
4654 ObjectType, AllowInjectedClassName);
4655 }
4656
4657 // FIXME: Try to preserve more of the TemplateName.
4658 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4659 TemplateDecl *TransTemplate
4660 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4661 Template));
4662 if (!TransTemplate)
4663 return TemplateName();
4664
4665 return getDerived().RebuildTemplateName(SS, /*TemplateKeyword=*/false,
4666 TransTemplate);
4667 }
4668
4670 = Name.getAsSubstTemplateTemplateParmPack()) {
4671 return getDerived().RebuildTemplateName(
4672 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4673 SubstPack->getIndex(), SubstPack->getFinal());
4674 }
4675
4676 // These should be getting filtered out before they reach the AST.
4677 llvm_unreachable("overloaded function decl survived to here");
4678}
4679
4680template<typename Derived>
4682 const TemplateArgument &Arg,
4683 TemplateArgumentLoc &Output) {
4684 Output = getSema().getTrivialTemplateArgumentLoc(
4685 Arg, QualType(), getDerived().getBaseLocation());
4686}
4687
4688template <typename Derived>
4690 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4691 bool Uneval) {
4692 const TemplateArgument &Arg = Input.getArgument();
4693 switch (Arg.getKind()) {
4696 llvm_unreachable("Unexpected TemplateArgument");
4697
4702 // Transform a resolved template argument straight to a resolved template
4703 // argument. We get here when substituting into an already-substituted
4704 // template type argument during concept satisfaction checking.
4706 QualType NewT = getDerived().TransformType(T);
4707 if (NewT.isNull())
4708 return true;
4709
4711 ? Arg.getAsDecl()
4712 : nullptr;
4713 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4714 getDerived().getBaseLocation(), D))
4715 : nullptr;
4716 if (D && !NewD)
4717 return true;
4718
4719 if (NewT == T && D == NewD)
4720 Output = Input;
4721 else if (Arg.getKind() == TemplateArgument::Integral)
4722 Output = TemplateArgumentLoc(
4723 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4725 else if (Arg.getKind() == TemplateArgument::NullPtr)
4726 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4728 else if (Arg.getKind() == TemplateArgument::Declaration)
4729 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4732 Output = TemplateArgumentLoc(
4733 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
4735 else
4736 llvm_unreachable("unexpected template argument kind");
4737
4738 return false;
4739 }
4740
4742 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4743 if (!DI)
4744 DI = InventTypeSourceInfo(Input.getArgument().getAsType());
4745
4746 DI = getDerived().TransformType(DI);
4747 if (!DI)
4748 return true;
4749
4750 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4751 return false;
4752 }
4753
4755 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4756 if (QualifierLoc) {
4757 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4758 if (!QualifierLoc)
4759 return true;
4760 }
4761
4762 CXXScopeSpec SS;
4763 SS.Adopt(QualifierLoc);
4764 TemplateName Template = getDerived().TransformTemplateName(
4765 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4766 if (Template.isNull())
4767 return true;
4768
4769 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4770 QualifierLoc, Input.getTemplateNameLoc());
4771 return false;
4772 }
4773
4775 llvm_unreachable("Caller should expand pack expansions");
4776
4778 // Template argument expressions are constant expressions.
4780 getSema(),
4783 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4785
4786 Expr *InputExpr = Input.getSourceExpression();
4787 if (!InputExpr)
4788 InputExpr = Input.getArgument().getAsExpr();
4789
4790 ExprResult E = getDerived().TransformExpr(InputExpr);
4791 E = SemaRef.ActOnConstantExpression(E);
4792 if (E.isInvalid())
4793 return true;
4794 Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
4795 return false;
4796 }
4797 }
4798
4799 // Work around bogus GCC warning
4800 return true;
4801}
4802
4803/// Iterator adaptor that invents template argument location information
4804/// for each of the template arguments in its underlying iterator.
4805template<typename Derived, typename InputIterator>
4808 InputIterator Iter;
4809
4810public:
4813 typedef typename std::iterator_traits<InputIterator>::difference_type
4815 typedef std::input_iterator_tag iterator_category;
4816
4817 class pointer {
4819
4820 public:
4821 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4822
4823 const TemplateArgumentLoc *operator->() const { return &Arg; }
4824 };
4825
4827 InputIterator Iter)
4828 : Self(Self), Iter(Iter) { }
4829
4831 ++Iter;
4832 return *this;
4833 }
4834
4837 ++(*this);
4838 return Old;
4839 }
4840
4843 Self.InventTemplateArgumentLoc(*Iter, Result);
4844 return Result;
4845 }
4846
4847 pointer operator->() const { return pointer(**this); }
4848
4851 return X.Iter == Y.Iter;
4852 }
4853
4856 return X.Iter != Y.Iter;
4857 }
4858};
4859
4860template<typename Derived>
4861template<typename InputIterator>
4863 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
4864 bool Uneval) {
4865 for (; First != Last; ++First) {
4868
4869 if (In.getArgument().getKind() == TemplateArgument::Pack) {
4870 // Unpack argument packs, which we translate them into separate
4871 // arguments.
4872 // FIXME: We could do much better if we could guarantee that the
4873 // TemplateArgumentLocInfo for the pack expansion would be usable for
4874 // all of the template arguments in the argument pack.
4875 typedef TemplateArgumentLocInventIterator<Derived,
4877 PackLocIterator;
4878 if (TransformTemplateArguments(PackLocIterator(*this,
4879 In.getArgument().pack_begin()),
4880 PackLocIterator(*this,
4881 In.getArgument().pack_end()),
4882 Outputs, Uneval))
4883 return true;
4884
4885 continue;
4886 }
4887
4888 if (In.getArgument().isPackExpansion()) {
4889 // We have a pack expansion, for which we will be substituting into
4890 // the pattern.
4891 SourceLocation Ellipsis;
4892 std::optional<unsigned> OrigNumExpansions;
4893 TemplateArgumentLoc Pattern
4894 = getSema().getTemplateArgumentPackExpansionPattern(
4895 In, Ellipsis, OrigNumExpansions);
4896
4898 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4899 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4900
4901 // Determine whether the set of unexpanded parameter packs can and should
4902 // be expanded.
4903 bool Expand = true;
4904 bool RetainExpansion = false;
4905 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4906 if (getDerived().TryExpandParameterPacks(Ellipsis,
4907 Pattern.getSourceRange(),
4908 Unexpanded,
4909 Expand,
4910 RetainExpansion,
4911 NumExpansions))
4912 return true;
4913
4914 if (!Expand) {
4915 // The transform has determined that we should perform a simple
4916 // transformation on the pack expansion, producing another pack
4917 // expansion.
4918 TemplateArgumentLoc OutPattern;
4919 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4920 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
4921 return true;
4922
4923 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
4924 NumExpansions);
4925 if (Out.getArgument().isNull())
4926 return true;
4927
4928 Outputs.addArgument(Out);
4929 continue;
4930 }
4931
4932 // The transform has determined that we should perform an elementwise
4933 // expansion of the pattern. Do so.
4934 for (unsigned I = 0; I != *NumExpansions; ++I) {
4935 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4936
4937 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4938 return true;
4939
4940 if (Out.getArgument().containsUnexpandedParameterPack()) {
4941 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4942 OrigNumExpansions);
4943 if (Out.getArgument().isNull())
4944 return true;
4945 }
4946
4947 Outputs.addArgument(Out);
4948 }
4949
4950 // If we're supposed to retain a pack expansion, do so by temporarily
4951 // forgetting the partially-substituted parameter pack.
4952 if (RetainExpansion) {
4953 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4954
4955 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4956 return true;
4957
4958 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4959 OrigNumExpansions);
4960 if (Out.getArgument().isNull())
4961 return true;
4962
4963 Outputs.addArgument(Out);
4964 }
4965
4966 continue;
4967 }
4968
4969 // The simple case:
4970 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
4971 return true;
4972
4973 Outputs.addArgument(Out);
4974 }
4975
4976 return false;
4977
4978}
4979
4980//===----------------------------------------------------------------------===//
4981// Type transformation
4982//===----------------------------------------------------------------------===//
4983
4984template<typename Derived>
4986 if (getDerived().AlreadyTransformed(T))
4987 return T;
4988
4989 // Temporary workaround. All of these transformations should
4990 // eventually turn into transformations on TypeLocs.
4991 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4992 getDerived().getBaseLocation());
4993
4994 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
4995
4996 if (!NewDI)
4997 return QualType();
4998
4999 return NewDI->getType();
5000}
5001
5002template<typename Derived>
5004 // Refine the base location to the type's location.
5005 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5006 getDerived().getBaseEntity());
5007 if (getDerived().AlreadyTransformed(DI->getType()))
5008 return DI;
5009
5010 TypeLocBuilder TLB;
5011
5012 TypeLoc TL = DI->getTypeLoc();
5013 TLB.reserve(TL.getFullDataSize());
5014
5015 QualType Result = getDerived().TransformType(TLB, TL);
5016 if (Result.isNull())
5017 return nullptr;
5018
5019 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5020}
5021
5022template<typename Derived>
5025 switch (T.getTypeLocClass()) {
5026#define ABSTRACT_TYPELOC(CLASS, PARENT)
5027#define TYPELOC(CLASS, PARENT) \
5028 case TypeLoc::CLASS: \
5029 return getDerived().Transform##CLASS##Type(TLB, \
5030 T.castAs<CLASS##TypeLoc>());
5031#include "clang/AST/TypeLocNodes.def"
5032 }
5033
5034 llvm_unreachable("unhandled type loc!");
5035}
5036
5037template<typename Derived>
5039 if (!isa<DependentNameType>(T))
5040 return TransformType(T);
5041
5042 if (getDerived().AlreadyTransformed(T))
5043 return T;
5044 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5045 getDerived().getBaseLocation());
5046 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
5047 return NewDI ? NewDI->getType() : QualType();
5048}
5049
5050template<typename Derived>
5053 if (!isa<DependentNameType>(DI->getType()))
5054 return TransformType(DI);
5055
5056 // Refine the base location to the type's location.
5057 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5058 getDerived().getBaseEntity());
5059 if (getDerived().AlreadyTransformed(DI->getType()))
5060 return DI;
5061
5062 TypeLocBuilder TLB;
5063
5064 TypeLoc TL = DI->getTypeLoc();
5065 TLB.reserve(TL.getFullDataSize());
5066
5067 auto QTL = TL.getAs<QualifiedTypeLoc>();
5068 if (QTL)
5069 TL = QTL.getUnqualifiedLoc();
5070
5071 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5072
5073 QualType Result = getDerived().TransformDependentNameType(
5074 TLB, DNTL, /*DeducedTSTContext*/true);
5075 if (Result.isNull())
5076 return nullptr;
5077
5078 if (QTL) {
5079 Result = getDerived().RebuildQualifiedType(Result, QTL);
5080 if (Result.isNull())
5081 return nullptr;
5083 }
5084
5085 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5086}
5087
5088template<typename Derived>
5093 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5094 auto SuppressObjCLifetime =
5095 T.getType().getLocalQualifiers().hasObjCLifetime();
5096 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5097 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5098 SuppressObjCLifetime);
5099 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5100 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5101 TLB, STTP, SuppressObjCLifetime);
5102 } else {
5103 Result = getDerived().TransformType(TLB, UnqualTL);
5104 }
5105
5106 if (Result.isNull())
5107 return QualType();
5108
5109 Result = getDerived().RebuildQualifiedType(Result, T);
5110
5111 if (Result.isNull())
5112 return QualType();
5113
5114 // RebuildQualifiedType might have updated the type, but not in a way
5115 // that invalidates the TypeLoc. (There's no location information for
5116 // qualifiers.)
5118
5119 return Result;
5120}
5121
5122template <typename Derived>
5124 QualifiedTypeLoc TL) {
5125
5127 Qualifiers Quals = TL.getType().getLocalQualifiers();
5128
5129 if ((T.getAddressSpace() != LangAS::Default &&
5130 Quals.getAddressSpace() != LangAS::Default) &&
5131 T.getAddressSpace() != Quals.getAddressSpace()) {
5132 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)
5133 << TL.getType() << T;
5134 return QualType();
5135 }
5136
5137 // C++ [dcl.fct]p7:
5138 // [When] adding cv-qualifications on top of the function type [...] the
5139 // cv-qualifiers are ignored.
5140 if (T->isFunctionType()) {
5142 Quals.getAddressSpace());
5143 return T;
5144 }
5145
5146 // C++ [dcl.ref]p1:
5147 // when the cv-qualifiers are introduced through the use of a typedef-name
5148 // or decltype-specifier [...] the cv-qualifiers are ignored.
5149 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5150 // applied to a reference type.
5151 if (T->isReferenceType()) {
5152 // The only qualifier that applies to a reference type is restrict.
5153 if (!Quals.hasRestrict())
5154 return T;
5156 }
5157
5158 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5159 // resulting type.
5160 if (Quals.hasObjCLifetime()) {
5161 if (!T->isObjCLifetimeType() && !T->isDependentType())
5162 Quals.removeObjCLifetime();
5163 else if (T.getObjCLifetime()) {
5164 // Objective-C ARC:
5165 // A lifetime qualifier applied to a substituted template parameter
5166 // overrides the lifetime qualifier from the template argument.
5167 const AutoType *AutoTy;
5168 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
5169 // 'auto' types behave the same way as template parameters.
5170 QualType Deduced = AutoTy->getDeducedType();
5171 Qualifiers Qs = Deduced.getQualifiers();
5172 Qs.removeObjCLifetime();
5173 Deduced =
5174 SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);
5175 T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),
5176 AutoTy->isDependentType(),
5177 /*isPack=*/false,
5178 AutoTy->getTypeConstraintConcept(),
5179 AutoTy->getTypeConstraintArguments());
5180 } else {
5181 // Otherwise, complain about the addition of a qualifier to an
5182 // already-qualified type.
5183 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5184 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
5185 Quals.removeObjCLifetime();
5186 }
5187 }
5188 }
5189
5190 return SemaRef.BuildQualifiedType(T, Loc, Quals);
5191}
5192
5193template<typename Derived>
5194TypeLoc
5196 QualType ObjectType,
5197 NamedDecl *UnqualLookup,
5198 CXXScopeSpec &SS) {
5199 if (getDerived().AlreadyTransformed(TL.getType()))
5200 return TL;
5201
5202 TypeSourceInfo *TSI =
5203 TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS);
5204 if (TSI)
5205 return TSI->getTypeLoc();
5206 return TypeLoc();
5207}
5208
5209template<typename Derived>
5210TypeSourceInfo *
5211TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5212 QualType ObjectType,
5213 NamedDecl *UnqualLookup,
5214 CXXScopeSpec &SS) {
5215 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5216 return TSInfo;
5217
5218 return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType,
5219 UnqualLookup, SS);
5220}
5221
5222template <typename Derived>
5223TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5224 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5225 CXXScopeSpec &SS) {
5226 QualType T = TL.getType();
5227 assert(!getDerived().AlreadyTransformed(T));
5228
5229 TypeLocBuilder TLB;
5230 QualType Result;
5231
5232 if (isa<TemplateSpecializationType>(T)) {
5233 TemplateSpecializationTypeLoc SpecTL =
5234 TL.castAs<TemplateSpecializationTypeLoc>();
5235
5236 TemplateName Template = getDerived().TransformTemplateName(
5237 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5238 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5239 if (Template.isNull())
5240 return nullptr;
5241
5242 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5243 Template);
5244 } else if (isa<DependentTemplateSpecializationType>(T)) {
5245 DependentTemplateSpecializationTypeLoc SpecTL =
5246 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5247
5248 TemplateName Template
5249 = getDerived().RebuildTemplateName(SS,
5250 SpecTL.getTemplateKeywordLoc(),
5251 *SpecTL.getTypePtr()->getIdentifier(),
5252 SpecTL.getTemplateNameLoc(),
5253 ObjectType, UnqualLookup,
5254 /*AllowInjectedClassName*/true);
5255 if (Template.isNull())
5256 return nullptr;
5257
5258 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5259 SpecTL,
5260 Template,
5261 SS);
5262 } else {
5263 // Nothing special needs to be done for these.
5264 Result = getDerived().TransformType(TLB, TL);
5265 }
5266
5267 if (Result.isNull())
5268 return nullptr;
5269
5270 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5271}
5272
5273template <class TyLoc> static inline
5275 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5276 NewT.setNameLoc(T.getNameLoc());
5277 return T.getType();
5278}
5279
5280template<typename Derived>
5281QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5282 BuiltinTypeLoc T) {
5283 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
5284 NewT.setBuiltinLoc(T.getBuiltinLoc());
5285 if (T.needsExtraLocalData())
5286 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5287 return T.getType();
5288}
5289
5290template<typename Derived>
5291QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5292 ComplexTypeLoc T) {
5293 // FIXME: recurse?
5294 return TransformTypeSpecType(TLB, T);
5295}
5296
5297template <typename Derived>
5298QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5299 AdjustedTypeLoc TL) {
5300 // Adjustments applied during transformation are handled elsewhere.
5301 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5302}
5303
5304template<typename Derived>
5305QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5306 DecayedTypeLoc TL) {
5307 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5308 if (OriginalType.isNull())
5309 return QualType();
5310
5311 QualType Result = TL.getType();
5312 if (getDerived().AlwaysRebuild() ||
5313 OriginalType != TL.getOriginalLoc().getType())
5314 Result = SemaRef.Context.getDecayedType(OriginalType);
5315 TLB.push<DecayedTypeLoc>(Result);
5316 // Nothing to set for DecayedTypeLoc.
5317 return Result;
5318}
5319
5320template <typename Derived>
5321QualType
5322TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5323 ArrayParameterTypeLoc TL) {
5324 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5325 if (OriginalType.isNull())
5326 return QualType();
5327
5328 QualType Result = TL.getType();
5329 if (getDerived().AlwaysRebuild() ||
5330 OriginalType != TL.getElementLoc().getType())
5331 Result = SemaRef.Context.getArrayParameterType(OriginalType);
5332 TLB.push<ArrayParameterTypeLoc>(Result);
5333 // Nothing to set for ArrayParameterTypeLoc.
5334 return Result;
5335}
5336
5337template<typename Derived>
5338QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5339 PointerTypeLoc TL) {
5340 QualType PointeeType
5341 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5342 if (PointeeType.isNull())
5343 return QualType();
5344
5345 QualType Result = TL.getType();
5346 if (PointeeType->getAs<ObjCObjectType>()) {
5347 // A dependent pointer type 'T *' has is being transformed such
5348 // that an Objective-C class type is being replaced for 'T'. The
5349 // resulting pointer type is an ObjCObjectPointerType, not a
5350 // PointerType.
5351 Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
5352
5353 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
5354 NewT.setStarLoc(TL.getStarLoc());
5355 return Result;
5356 }
5357
5358 if (getDerived().AlwaysRebuild() ||
5359 PointeeType != TL.getPointeeLoc().getType()) {
5360 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5361 if (Result.isNull())
5362 return QualType();
5363 }
5364
5365 // Objective-C ARC can add lifetime qualifiers to the type that we're
5366 // pointing to.
5367 TLB.TypeWasModifiedSafely(Result->getPointeeType());
5368
5369 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
5370 NewT.setSigilLoc(TL.getSigilLoc());
5371 return Result;
5372}
5373
5374template<typename Derived>
5375QualType
5376TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5377 BlockPointerTypeLoc TL) {
5378 QualType PointeeType
5379 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5380 if (PointeeType.isNull())
5381 return QualType();
5382
5383 QualType Result = TL.getType();
5384 if (getDerived().AlwaysRebuild() ||
5385 PointeeType != TL.getPointeeLoc().getType()) {
5386 Result = getDerived().RebuildBlockPointerType(PointeeType,
5387 TL.getSigilLoc());
5388 if (Result.isNull())
5389 return QualType();
5390 }
5391
5392 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
5393 NewT.setSigilLoc(TL.getSigilLoc());
5394 return Result;
5395}
5396
5397/// Transforms a reference type. Note that somewhat paradoxically we
5398/// don't care whether the type itself is an l-value type or an r-value
5399/// type; we only care if the type was *written* as an l-value type
5400/// or an r-value type.
5401template<typename Derived>
5402QualType
5404 ReferenceTypeLoc TL) {
5405 const ReferenceType *T = TL.getTypePtr();
5406
5407 // Note that this works with the pointee-as-written.
5408 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5409 if (PointeeType.isNull())
5410 return QualType();
5411
5412 QualType Result = TL.getType();
5413 if (getDerived().AlwaysRebuild() ||
5414 PointeeType != T->getPointeeTypeAsWritten()) {
5415 Result = getDerived().RebuildReferenceType(PointeeType,
5416 T->isSpelledAsLValue(),
5417 TL.getSigilLoc());
5418 if (Result.isNull())
5419 return QualType();
5420 }
5421
5422 // Objective-C ARC can add lifetime qualifiers to the type that we're
5423 // referring to.
5426
5427 // r-value references can be rebuilt as l-value references.
5428 ReferenceTypeLoc NewTL;
5429 if (isa<LValueReferenceType>(Result))
5430 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
5431 else
5432 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
5433 NewTL.setSigilLoc(TL.getSigilLoc());
5434
5435 return Result;
5436}
5437
5438template<typename Derived>
5442 return TransformReferenceType(TLB, TL);
5443}
5444
5445template<typename Derived>
5446QualType
5447TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5448 RValueReferenceTypeLoc TL) {
5449 return TransformReferenceType(TLB, TL);
5450}
5451
5452template<typename Derived>
5453QualType
5454TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5455 MemberPointerTypeLoc TL) {
5456 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5457 if (PointeeType.isNull())
5458 return QualType();
5459
5460 TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
5461 TypeSourceInfo *NewClsTInfo = nullptr;
5462 if (OldClsTInfo) {
5463 NewClsTInfo = getDerived().TransformType(OldClsTInfo);
5464 if (!NewClsTInfo)
5465 return QualType();
5466 }
5467
5468 const MemberPointerType *T = TL.getTypePtr();
5469 QualType OldClsType = QualType(T->getClass(), 0);
5470 QualType NewClsType;
5471 if (NewClsTInfo)
5472 NewClsType = NewClsTInfo->getType();
5473 else {
5474 NewClsType = getDerived().TransformType(OldClsType);
5475 if (NewClsType.isNull())
5476 return QualType();
5477 }
5478
5479 QualType Result = TL.getType();
5480 if (getDerived().AlwaysRebuild() ||
5481 PointeeType != T->getPointeeType() ||
5482 NewClsType != OldClsType) {
5483 Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
5484 TL.getStarLoc());
5485 if (Result.isNull())
5486 return QualType();
5487 }
5488
5489 // If we had to adjust the pointee type when building a member pointer, make
5490 // sure to push TypeLoc info for it.
5491 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5492 if (MPT && PointeeType != MPT->getPointeeType()) {
5493 assert(isa<AdjustedType>(MPT->getPointeeType()));
5494 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
5495 }
5496
5497 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
5498 NewTL.setSigilLoc(TL.getSigilLoc());
5499 NewTL.setClassTInfo(NewClsTInfo);
5500
5501 return Result;
5502}
5503
5504template<typename Derived>
5505QualType
5506TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5507 ConstantArrayTypeLoc TL) {
5508 const ConstantArrayType *T = TL.getTypePtr();
5509 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5510 if (ElementType.isNull())
5511 return QualType();
5512
5513 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5514 Expr *OldSize = TL.getSizeExpr();
5515 if (!OldSize)
5516 OldSize = const_cast<Expr*>(T->getSizeExpr());
5517 Expr *NewSize = nullptr;
5518 if (OldSize) {
5519 EnterExpressionEvaluationContext Unevaluated(
5521 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5522 NewSize = SemaRef.ActOnConstantExpression(NewSize).get();
5523 }
5524
5525 QualType Result = TL.getType();
5526 if (getDerived().AlwaysRebuild() ||
5527 ElementType != T->getElementType() ||
5528 (T->getSizeExpr() && NewSize != OldSize)) {
5529 Result = getDerived().RebuildConstantArrayType(ElementType,
5530 T->getSizeModifier(),
5531 T->getSize(), NewSize,
5532 T->getIndexTypeCVRQualifiers(),
5533 TL.getBracketsRange());
5534 if (Result.isNull())
5535 return QualType();
5536 }
5537
5538 // We might have either a ConstantArrayType or a VariableArrayType now:
5539 // a ConstantArrayType is allowed to have an element type which is a
5540 // VariableArrayType if the type is dependent. Fortunately, all array
5541 // types have the same location layout.
5542 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5543 NewTL.setLBracketLoc(TL.getLBracketLoc());
5544 NewTL.setRBracketLoc(TL.getRBracketLoc());
5545 NewTL.setSizeExpr(NewSize);
5546
5547 return Result;
5548}
5549
5550template<typename Derived>
5551QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5552 TypeLocBuilder &TLB,
5553 IncompleteArrayTypeLoc TL) {
5554 const IncompleteArrayType *T = TL.getTypePtr();
5555 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5556 if (ElementType.isNull())
5557 return QualType();
5558
5559 QualType Result = TL.getType();
5560 if (getDerived().AlwaysRebuild() ||
5561 ElementType != T->getElementType()) {
5562 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5563 T->getSizeModifier(),
5564 T->getIndexTypeCVRQualifiers(),
5565 TL.getBracketsRange());
5566 if (Result.isNull())
5567 return QualType();
5568 }
5569
5570 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
5571 NewTL.setLBracketLoc(TL.getLBracketLoc());
5572 NewTL.setRBracketLoc(TL.getRBracketLoc());
5573 NewTL.setSizeExpr(nullptr);
5574
5575 return Result;
5576}
5577
5578template<typename Derived>
5579QualType
5580TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5581 VariableArrayTypeLoc TL) {
5582 const VariableArrayType *T = TL.getTypePtr();
5583 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5584 if (ElementType.isNull())
5585 return QualType();
5586
5587 ExprResult SizeResult;
5588 {
5589 EnterExpressionEvaluationContext Context(
5591 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5592 }
5593 if (SizeResult.isInvalid())
5594 return QualType();
5595 SizeResult =
5596 SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);
5597 if (SizeResult.isInvalid())
5598 return QualType();
5599
5600 Expr *Size = SizeResult.get();
5601
5602 QualType Result = TL.getType();
5603 if (getDerived().AlwaysRebuild() ||
5604 ElementType != T->getElementType() ||
5605 Size != T->getSizeExpr()) {
5606 Result = getDerived().RebuildVariableArrayType(ElementType,
5607 T->getSizeModifier(),
5608 Size,
5609 T->getIndexTypeCVRQualifiers(),
5610 TL.getBracketsRange());
5611 if (Result.isNull())
5612 return QualType();
5613 }
5614
5615 // We might have constant size array now, but fortunately it has the same
5616 // location layout.
5617 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5618 NewTL.setLBracketLoc(TL.getLBracketLoc());
5619 NewTL.setRBracketLoc(TL.getRBracketLoc());
5620 NewTL.setSizeExpr(Size);
5621
5622 return Result;
5623}
5624
5625template<typename Derived>
5626QualType
5627TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5628 DependentSizedArrayTypeLoc TL) {
5629 const DependentSizedArrayType *T = TL.getTypePtr();
5630 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5631 if (ElementType.isNull())
5632 return QualType();
5633
5634 // Array bounds are constant expressions.
5635 EnterExpressionEvaluationContext Unevaluated(
5637
5638 // If we have a VLA then it won't be a constant.
5639 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5640
5641 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5642 Expr *origSize = TL.getSizeExpr();
5643 if (!origSize) origSize = T->getSizeExpr();
5644
5645 ExprResult sizeResult
5646 = getDerived().TransformExpr(origSize);
5647 sizeResult = SemaRef.ActOnConstantExpression(sizeResult);
5648 if (sizeResult.isInvalid())
5649 return QualType();
5650
5651 Expr *size = sizeResult.get();
5652
5653 QualType Result = TL.getType();
5654 if (getDerived().AlwaysRebuild() ||
5655 ElementType != T->getElementType() ||
5656 size != origSize) {
5657 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5658 T->getSizeModifier(),
5659 size,
5660 T->getIndexTypeCVRQualifiers(),
5661 TL.getBracketsRange());
5662 if (Result.isNull())
5663 return QualType();
5664 }
5665
5666 // We might have any sort of array type now, but fortunately they
5667 // all have the same location layout.
5668 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5669 NewTL.setLBracketLoc(TL.getLBracketLoc());
5670 NewTL.setRBracketLoc(TL.getRBracketLoc());
5671 NewTL.setSizeExpr(size);
5672
5673 return Result;
5674}
5675
5676template <typename Derived>
5677QualType TreeTransform<Derived>::TransformDependentVectorType(
5678 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5679 const DependentVectorType *T = TL.getTypePtr();
5680 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5681 if (ElementType.isNull())
5682 return QualType();
5683
5684 EnterExpressionEvaluationContext Unevaluated(
5686
5687 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5688 Size = SemaRef.ActOnConstantExpression(Size);
5689 if (Size.isInvalid())
5690 return QualType();
5691
5692 QualType Result = TL.getType();
5693 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5694 Size.get() != T->getSizeExpr()) {
5695 Result = getDerived().RebuildDependentVectorType(
5696 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5697 if (Result.isNull())
5698 return QualType();
5699 }
5700
5701 // Result might be dependent or not.
5702 if (isa<DependentVectorType>(Result)) {
5703 DependentVectorTypeLoc NewTL =
5704 TLB.push<DependentVectorTypeLoc>(Result);
5705 NewTL.setNameLoc(TL.getNameLoc());
5706 } else {
5707 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5708 NewTL.setNameLoc(TL.getNameLoc());
5709 }
5710
5711 return Result;
5712}
5713
5714template<typename Derived>
5715QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5716 TypeLocBuilder &TLB,
5717 DependentSizedExtVectorTypeLoc TL) {
5718 const DependentSizedExtVectorType *T = TL.getTypePtr();
5719
5720 // FIXME: ext vector locs should be nested
5721 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5722 if (ElementType.isNull())
5723 return QualType();
5724
5725 // Vector sizes are constant expressions.
5726 EnterExpressionEvaluationContext Unevaluated(
5728
5729 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5730 Size = SemaRef.ActOnConstantExpression(Size);
5731 if (Size.isInvalid())
5732 return QualType();
5733
5734 QualType Result = TL.getType();
5735 if (getDerived().AlwaysRebuild() ||
5736 ElementType != T->getElementType() ||
5737 Size.get() != T->getSizeExpr()) {
5738 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5739 Size.get(),
5740 T->getAttributeLoc());
5741 if (Result.isNull())
5742 return QualType();
5743 }
5744
5745 // Result might be dependent or not.
5746 if (isa<DependentSizedExtVectorType>(Result)) {
5747 DependentSizedExtVectorTypeLoc NewTL
5748 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
5749 NewTL.setNameLoc(TL.getNameLoc());
5750 } else {
5751 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5752 NewTL.setNameLoc(TL.getNameLoc());
5753 }
5754
5755 return Result;
5756}
5757
5758template <typename Derived>
5759QualType
5760TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5761 ConstantMatrixTypeLoc TL) {
5762 const ConstantMatrixType *T = TL.getTypePtr();
5763 QualType ElementType = getDerived().TransformType(T->getElementType());
5764 if (ElementType.isNull())
5765 return QualType();
5766
5767 QualType Result = TL.getType();
5768 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5769 Result = getDerived().RebuildConstantMatrixType(
5770 ElementType, T->getNumRows(), T->getNumColumns());
5771 if (Result.isNull())
5772 return QualType();
5773 }
5774
5775 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);
5776 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5777 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5778 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5779 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5780
5781 return Result;
5782}
5783
5784template <typename Derived>
5785QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5786 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5787 const DependentSizedMatrixType *T = TL.getTypePtr();
5788
5789 QualType ElementType = getDerived().TransformType(T->getElementType());
5790 if (ElementType.isNull()) {
5791 return QualType();
5792 }
5793
5794 // Matrix dimensions are constant expressions.
5795 EnterExpressionEvaluationContext Unevaluated(
5797
5798 Expr *origRows = TL.getAttrRowOperand();
5799 if (!origRows)
5800 origRows = T->getRowExpr();
5801 Expr *origColumns = TL.getAttrColumnOperand();
5802 if (!origColumns)
5803 origColumns = T->getColumnExpr();
5804
5805 ExprResult rowResult = getDerived().TransformExpr(origRows);
5806 rowResult = SemaRef.ActOnConstantExpression(rowResult);
5807 if (rowResult.isInvalid())
5808 return QualType();
5809
5810 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5811 columnResult = SemaRef.ActOnConstantExpression(columnResult);
5812 if (columnResult.isInvalid())
5813 return QualType();
5814
5815 Expr *rows = rowResult.get();
5816 Expr *columns = columnResult.get();
5817
5818 QualType Result = TL.getType();
5819 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5820 rows != origRows || columns != origColumns) {
5821 Result = getDerived().RebuildDependentSizedMatrixType(
5822 ElementType, rows, columns, T->getAttributeLoc());
5823
5824 if (Result.isNull())
5825 return QualType();
5826 }
5827
5828 // We might have any sort of matrix type now, but fortunately they
5829 // all have the same location layout.
5830 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);
5831 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5832 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5833 NewTL.setAttrRowOperand(rows);
5834 NewTL.setAttrColumnOperand(columns);
5835 return Result;
5836}
5837
5838template <typename Derived>
5839QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
5840 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
5841 const DependentAddressSpaceType *T = TL.getTypePtr();
5842
5843 QualType pointeeType =
5844 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
5845
5846 if (pointeeType.isNull())
5847 return QualType();
5848
5849 // Address spaces are constant expressions.
5850 EnterExpressionEvaluationContext Unevaluated(
5852
5853 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
5854 AddrSpace = SemaRef.ActOnConstantExpression(AddrSpace);
5855 if (AddrSpace.isInvalid())
5856 return QualType();
5857
5858 QualType Result = TL.getType();
5859 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
5860 AddrSpace.get() != T->getAddrSpaceExpr()) {
5861 Result = getDerived().RebuildDependentAddressSpaceType(
5862 pointeeType, AddrSpace.get(), T->getAttributeLoc());
5863 if (Result.isNull())
5864 return QualType();
5865 }
5866
5867 // Result might be dependent or not.
5868 if (isa<DependentAddressSpaceType>(Result)) {
5869 DependentAddressSpaceTypeLoc NewTL =
5870 TLB.push<DependentAddressSpaceTypeLoc>(Result);
5871
5872 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5873 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
5874 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5875
5876 } else {
5877 TLB.TypeWasModifiedSafely(Result);
5878 }
5879
5880 return Result;
5881}
5882
5883template <typename Derived>
5884QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
5885 VectorTypeLoc TL) {
5886 const VectorType *T = TL.getTypePtr();
5887 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5888 if (ElementType.isNull())
5889 return QualType();
5890
5891 QualType Result = TL.getType();
5892 if (getDerived().AlwaysRebuild() ||
5893 ElementType != T->getElementType()) {
5894 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
5895 T->getVectorKind());
5896 if (Result.isNull())
5897 return QualType();
5898 }
5899
5900 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5901 NewTL.setNameLoc(TL.getNameLoc());
5902
5903 return Result;
5904}
5905
5906template<typename Derived>
5907QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
5908 ExtVectorTypeLoc TL) {
5909 const VectorType *T = TL.getTypePtr();
5910 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5911 if (ElementType.isNull())
5912 return QualType();
5913
5914 QualType Result = TL.getType();
5915 if (getDerived().AlwaysRebuild() ||
5916 ElementType != T->getElementType()) {
5917 Result = getDerived().RebuildExtVectorType(ElementType,
5918 T->getNumElements(),
5919 /*FIXME*/ SourceLocation());
5920 if (Result.isNull())
5921 return QualType();
5922 }
5923
5924 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5925 NewTL.setNameLoc(TL.getNameLoc());
5926
5927 return Result;
5928}
5929
5930template <typename Derived>
5932 ParmVarDecl *OldParm, int indexAdjustment,
5933 std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
5934 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
5935 TypeSourceInfo *NewDI = nullptr;
5936
5937 if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
5938 // If we're substituting into a pack expansion type and we know the
5939 // length we want to expand to, just substitute for the pattern.
5940 TypeLoc OldTL = OldDI->getTypeLoc();
5941 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
5942
5943 TypeLocBuilder TLB;
5944 TypeLoc NewTL = OldDI->getTypeLoc();
5945 TLB.reserve(NewTL.getFullDataSize());
5946
5947 QualType Result = getDerived().TransformType(TLB,
5948 OldExpansionTL.getPatternLoc());
5949 if (Result.isNull())
5950 return nullptr;
5951
5952 Result = RebuildPackExpansionType(Result,
5953 OldExpansionTL.getPatternLoc().getSourceRange(),
5954 OldExpansionTL.getEllipsisLoc(),
5955 NumExpansions);
5956 if (Result.isNull())
5957 return nullptr;
5958
5959 PackExpansionTypeLoc NewExpansionTL
5960 = TLB.push<PackExpansionTypeLoc>(Result);
5961 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
5962 NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result);
5963 } else
5964 NewDI = getDerived().TransformType(OldDI);
5965 if (!NewDI)
5966 return nullptr;
5967
5968 if (NewDI == OldDI && indexAdjustment == 0)
5969 return OldParm;
5970
5971 ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context,
5972 OldParm->getDeclContext(),
5973 OldParm->getInnerLocStart(),
5974 OldParm->getLocation(),
5975 OldParm->getIdentifier(),
5976 NewDI->getType(),
5977 NewDI,
5978 OldParm->getStorageClass(),
5979 /* DefArg */ nullptr);
5980 newParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
5981 OldParm->getFunctionScopeIndex() + indexAdjustment);
5982 transformedLocalDecl(OldParm, {newParm});
5983 return newParm;
5984}
5985
5986template <typename Derived>
5989 const QualType *ParamTypes,
5990 const FunctionProtoType::ExtParameterInfo *ParamInfos,
5991 SmallVectorImpl<QualType> &OutParamTypes,
5994 unsigned *LastParamTransformed) {
5995 int indexAdjustment = 0;
5996
5997 unsigned NumParams = Params.size();
5998 for (unsigned i = 0; i != NumParams; ++i) {
5999 if (LastParamTransformed)
6000 *LastParamTransformed = i;
6001 if (ParmVarDecl *OldParm = Params[i]) {
6002 assert(OldParm->getFunctionScopeIndex() == i);
6003
6004 std::optional<unsigned> NumExpansions;
6005 ParmVarDecl *NewParm = nullptr;
6006 if (OldParm->isParameterPack()) {
6007 // We have a function parameter pack that may need to be expanded.
6009
6010 // Find the parameter packs that could be expanded.
6011 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6013 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6014 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
6015
6016 // Determine whether we should expand the parameter packs.
6017 bool ShouldExpand = false;
6018 bool RetainExpansion = false;
6019 std::optional<unsigned> OrigNumExpansions;
6020 if (Unexpanded.size() > 0) {
6021 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6022 NumExpansions = OrigNumExpansions;
6023 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
6024 Pattern.getSourceRange(),
6025 Unexpanded,
6026 ShouldExpand,
6027 RetainExpansion,
6028 NumExpansions)) {
6029 return true;
6030 }
6031 } else {
6032#ifndef NDEBUG
6033 const AutoType *AT =
6034 Pattern.getType().getTypePtr()->getContainedAutoType();
6035 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6036 "Could not find parameter packs or undeduced auto type!");
6037#endif
6038 }
6039
6040 if (ShouldExpand) {
6041 // Expand the function parameter pack into multiple, separate
6042 // parameters.
6043 getDerived().ExpandingFunctionParameterPack(OldParm);
6044 for (unsigned I = 0; I != *NumExpansions; ++I) {
6045 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6046 ParmVarDecl *NewParm
6047 = getDerived().TransformFunctionTypeParam(OldParm,
6048 indexAdjustment++,
6049 OrigNumExpansions,
6050 /*ExpectParameterPack=*/false);
6051 if (!NewParm)
6052 return true;
6053
6054 if (ParamInfos)
6055 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6056 OutParamTypes.push_back(NewParm->getType());
6057 if (PVars)
6058 PVars->push_back(NewParm);
6059 }
6060
6061 // If we're supposed to retain a pack expansion, do so by temporarily
6062 // forgetting the partially-substituted parameter pack.
6063 if (RetainExpansion) {
6064 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6065 ParmVarDecl *NewParm
6066 = getDerived().TransformFunctionTypeParam(OldParm,
6067 indexAdjustment++,
6068 OrigNumExpansions,
6069 /*ExpectParameterPack=*/false);
6070 if (!NewParm)
6071 return true;
6072
6073 if (ParamInfos)
6074 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6075 OutParamTypes.push_back(NewParm->getType());
6076 if (PVars)
6077 PVars->push_back(NewParm);
6078 }
6079
6080 // The next parameter should have the same adjustment as the
6081 // last thing we pushed, but we post-incremented indexAdjustment
6082 // on every push. Also, if we push nothing, the adjustment should
6083 // go down by one.
6084 indexAdjustment--;
6085
6086 // We're done with the pack expansion.
6087 continue;
6088 }
6089
6090 // We'll substitute the parameter now without expanding the pack
6091 // expansion.
6092 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6093 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6094 indexAdjustment,
6095 NumExpansions,
6096 /*ExpectParameterPack=*/true);
6097 assert(NewParm->isParameterPack() &&
6098 "Parameter pack no longer a parameter pack after "
6099 "transformation.");
6100 } else {
6101 NewParm = getDerived().TransformFunctionTypeParam(
6102 OldParm, indexAdjustment, std::nullopt,
6103 /*ExpectParameterPack=*/false);
6104 }
6105
6106 if (!NewParm)
6107 return true;
6108
6109 if (ParamInfos)
6110 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6111 OutParamTypes.push_back(NewParm->getType());
6112 if (PVars)
6113 PVars->push_back(NewParm);
6114 continue;
6115 }
6116
6117 // Deal with the possibility that we don't have a parameter
6118 // declaration for this parameter.
6119 assert(ParamTypes);
6120 QualType OldType = ParamTypes[i];
6121 bool IsPackExpansion = false;
6122 std::optional<unsigned> NumExpansions;
6123 QualType NewType;
6124 if (const PackExpansionType *Expansion
6125 = dyn_cast<PackExpansionType>(OldType)) {
6126 // We have a function parameter pack that may need to be expanded.
6127 QualType Pattern = Expansion->getPattern();
6129 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6130
6131 // Determine whether we should expand the parameter packs.
6132 bool ShouldExpand = false;
6133 bool RetainExpansion = false;
6134 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
6135 Unexpanded,
6136 ShouldExpand,
6137 RetainExpansion,
6138 NumExpansions)) {
6139 return true;
6140 }
6141
6142 if (ShouldExpand) {
6143 // Expand the function parameter pack into multiple, separate
6144 // parameters.
6145 for (unsigned I = 0; I != *NumExpansions; ++I) {
6146 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6147 QualType NewType = getDerived().TransformType(Pattern);
6148 if (NewType.isNull())
6149 return true;
6150
6151 if (NewType->containsUnexpandedParameterPack()) {
6152 NewType = getSema().getASTContext().getPackExpansionType(
6153 NewType, std::nullopt);
6154
6155 if (NewType.isNull())
6156 return true;
6157 }
6158
6159 if (ParamInfos)
6160 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6161 OutParamTypes.push_back(NewType);
6162 if (PVars)
6163 PVars->push_back(nullptr);
6164 }
6165
6166 // We're done with the pack expansion.
6167 continue;
6168 }
6169
6170 // If we're supposed to retain a pack expansion, do so by temporarily
6171 // forgetting the partially-substituted parameter pack.
6172 if (RetainExpansion) {
6173 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6174 QualType NewType = getDerived().TransformType(Pattern);
6175 if (NewType.isNull())
6176 return true;
6177
6178 if (ParamInfos)
6179 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6180 OutParamTypes.push_back(NewType);
6181 if (PVars)
6182 PVars->push_back(nullptr);
6183 }
6184
6185 // We'll substitute the parameter now without expanding the pack
6186 // expansion.
6187 OldType = Expansion->getPattern();
6188 IsPackExpansion = true;
6189 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6190 NewType = getDerived().TransformType(OldType);
6191 } else {
6192 NewType = getDerived().TransformType(OldType);
6193 }
6194
6195 if (NewType.isNull())
6196 return true;
6197
6198 if (IsPackExpansion)
6199 NewType = getSema().Context.getPackExpansionType(NewType,
6200 NumExpansions);
6201
6202 if (ParamInfos)
6203 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6204 OutParamTypes.push_back(NewType);
6205 if (PVars)
6206 PVars->push_back(nullptr);
6207 }
6208
6209#ifndef NDEBUG
6210 if (PVars) {
6211 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6212 if (ParmVarDecl *parm = (*PVars)[i])
6213 assert(parm->getFunctionScopeIndex() == i);
6214 }
6215#endif
6216
6217 return false;
6218}
6219
6220template<typename Derived>
6224 SmallVector<QualType, 4> ExceptionStorage;
6225 return getDerived().TransformFunctionProtoType(
6226 TLB, TL, nullptr, Qualifiers(),
6227 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6228 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6229 ExceptionStorage, Changed);
6230 });
6231}
6232
6233template<typename Derived> template<typename Fn>
6235 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6236 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6237
6238 // Transform the parameters and return type.
6239 //
6240 // We are required to instantiate the params and return type in source order.
6241 // When the function has a trailing return type, we instantiate the
6242 // parameters before the return type, since the return type can then refer
6243 // to the parameters themselves (via decltype, sizeof, etc.).
6244 //
6245 SmallVector<QualType, 4> ParamTypes;
6247 Sema::ExtParameterInfoBuilder ExtParamInfos;
6248 const FunctionProtoType *T = TL.getTypePtr();
6249
6250 QualType ResultType;
6251
6252 if (T->hasTrailingReturn()) {
6253 if (getDerived().TransformFunctionTypeParams(
6254 TL.getBeginLoc(), TL.getParams(),
6257 ParamTypes, &ParamDecls, ExtParamInfos))
6258 return QualType();
6259
6260 {
6261 // C++11 [expr.prim.general]p3:
6262 // If a declaration declares a member function or member function
6263 // template of a class X, the expression this is a prvalue of type
6264 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6265 // and the end of the function-definition, member-declarator, or
6266 // declarator.
6267 auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.getCurLexicalContext());
6268 Sema::CXXThisScopeRAII ThisScope(
6269 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6270
6271 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6272 if (ResultType.isNull())
6273 return QualType();
6274 }
6275 }
6276 else {
6277 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6278 if (ResultType.isNull())
6279 return QualType();
6280
6281 if (getDerived().TransformFunctionTypeParams(
6282 TL.getBeginLoc(), TL.getParams(),
6285 ParamTypes, &ParamDecls, ExtParamInfos))
6286 return QualType();
6287 }
6288
6290
6291 bool EPIChanged = false;
6292 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6293 return QualType();
6294
6295 // Handle extended parameter information.
6296 if (auto NewExtParamInfos =
6297 ExtParamInfos.getPointerOrNull(ParamTypes.size())) {
6298 if (!EPI.ExtParameterInfos ||
6300 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6301 EPIChanged = true;
6302 }
6303 EPI.ExtParameterInfos = NewExtParamInfos;
6304 } else if (EPI.ExtParameterInfos) {
6305 EPIChanged = true;
6306 EPI.ExtParameterInfos = nullptr;
6307 }
6308
6309 // Transform any function effects with unevaluated conditions.
6310 // Hold this set in a local for the rest of this function, since EPI
6311 // may need to hold a FunctionEffectsRef pointing into it.
6312 std::optional<FunctionEffectSet> NewFX;
6313 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6314 NewFX.emplace();
6317
6318 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6319 FunctionEffectWithCondition NewEC = PrevEC;
6320 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6321 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6322 if (NewExpr.isInvalid())
6323 return QualType();
6324 std::optional<FunctionEffectMode> Mode =
6325 SemaRef.ActOnEffectExpression(NewExpr.get(), PrevEC.Effect.name());
6326 if (!Mode)
6327 return QualType();
6328
6329 // The condition expression has been transformed, and re-evaluated.
6330 // It may or may not have become constant.
6331 switch (*Mode) {
6333 NewEC.Cond = {};
6334 break;
6336 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6337 NewEC.Cond = {};
6338 break;
6340 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6341 break;
6343 llvm_unreachable(
6344 "FunctionEffectMode::None shouldn't be possible here");
6345 }
6346 }
6347 if (!SemaRef.diagnoseConflictingFunctionEffect(*NewFX, NewEC,
6348 TL.getBeginLoc())) {
6350 NewFX->insert(NewEC, Errs);
6351 assert(Errs.empty());
6352 }
6353 }
6354 EPI.FunctionEffects = *NewFX;
6355 EPIChanged = true;
6356 }
6357
6358 QualType Result = TL.getType();
6359 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6360 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6361 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6362 if (Result.isNull())
6363 return QualType();
6364 }
6365
6368 NewTL.setLParenLoc(TL.getLParenLoc());
6369 NewTL.setRParenLoc(TL.getRParenLoc());
6372 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6373 NewTL.setParam(i, ParamDecls[i]);
6374
6375 return Result;
6376}
6377
6378template<typename Derived>
6381 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6382 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6383
6384 // Instantiate a dynamic noexcept expression, if any.
6385 if (isComputedNoexcept(ESI.Type)) {
6386 // Update this scrope because ContextDecl in Sema will be used in
6387 // TransformExpr.
6388 auto *Method = dyn_cast_if_present<CXXMethodDecl>(ESI.SourceTemplate);
6389 Sema::CXXThisScopeRAII ThisScope(
6390 SemaRef, Method ? Method->getParent() : nullptr,
6391 Method ? Method->getMethodQualifiers() : Qualifiers{},
6392 Method != nullptr);
6395 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6396 if (NoexceptExpr.isInvalid())
6397 return true;
6398
6400 NoexceptExpr =
6401 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6402 if (NoexceptExpr.isInvalid())
6403 return true;
6404
6405 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6406 Changed = true;
6407 ESI.NoexceptExpr = NoexceptExpr.get();
6408 ESI.Type = EST;
6409 }
6410
6411 if (ESI.Type != EST_Dynamic)
6412 return false;
6413
6414 // Instantiate a dynamic exception specification's type.
6415 for (QualType T : ESI.Exceptions) {
6416 if (const PackExpansionType *PackExpansion =
6418 Changed = true;
6419
6420 // We have a pack expansion. Instantiate it.
6422 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
6423 Unexpanded);
6424 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6425
6426 // Determine whether the set of unexpanded parameter packs can and
6427 // should
6428 // be expanded.
6429 bool Expand = false;
6430 bool RetainExpansion = false;
6431 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
6432 // FIXME: Track the location of the ellipsis (and track source location
6433 // information for the types in the exception specification in general).
6434 if (getDerived().TryExpandParameterPacks(
6435 Loc, SourceRange(), Unexpanded, Expand,
6436 RetainExpansion, NumExpansions))
6437 return true;
6438
6439 if (!Expand) {
6440 // We can't expand this pack expansion into separate arguments yet;
6441 // just substitute into the pattern and create a new pack expansion
6442 // type.
6443 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6444 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6445 if (U.isNull())
6446 return true;
6447
6448 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
6449 Exceptions.push_back(U);
6450 continue;
6451 }
6452
6453 // Substitute into the pack expansion pattern for each slice of the
6454 // pack.
6455 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6456 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
6457
6458 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6459 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6460 return true;
6461
6462 Exceptions.push_back(U);
6463 }
6464 } else {
6465 QualType U = getDerived().TransformType(T);
6466 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6467 return true;
6468 if (T != U)
6469 Changed = true;
6470
6471 Exceptions.push_back(U);
6472 }
6473 }
6474
6475 ESI.Exceptions = Exceptions;
6476 if (ESI.Exceptions.empty())
6477 ESI.Type = EST_DynamicNone;
6478 return false;
6479}
6480
6481template<typename Derived>
6483 TypeLocBuilder &TLB,
6485 const FunctionNoProtoType *T = TL.getTypePtr();
6486 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6487 if (ResultType.isNull())
6488 return QualType();
6489
6490 QualType Result = TL.getType();
6491 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6492 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6493
6496 NewTL.setLParenLoc(TL.getLParenLoc());
6497 NewTL.setRParenLoc(TL.getRParenLoc());
6499
6500 return Result;
6501}
6502
6503template <typename Derived>
6504QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6505 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6506 const UnresolvedUsingType *T = TL.getTypePtr();
6507 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6508 if (!D)
6509 return QualType();
6510
6511 QualType Result = TL.getType();
6512 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6513 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6514 if (Result.isNull())
6515 return QualType();
6516 }
6517
6518 // We might get an arbitrary type spec type back. We should at
6519 // least always get a type spec type, though.
6520 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result);
6521 NewTL.setNameLoc(TL.getNameLoc());
6522
6523 return Result;
6524}
6525
6526template <typename Derived>
6527QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6528 UsingTypeLoc TL) {
6529 const UsingType *T = TL.getTypePtr();
6530
6531 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6532 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6533 if (!Found)
6534 return QualType();
6535
6536 QualType Underlying = getDerived().TransformType(T->desugar());
6537 if (Underlying.isNull())
6538 return QualType();
6539
6540 QualType Result = TL.getType();
6541 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6542 Underlying != T->getUnderlyingType()) {
6543 Result = getDerived().RebuildUsingType(Found, Underlying);
6544 if (Result.isNull())
6545 return QualType();
6546 }
6547
6548 TLB.pushTypeSpec(Result).setNameLoc(TL.getNameLoc());
6549 return Result;
6550}
6551
6552template<typename Derived>
6553QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6554 TypedefTypeLoc TL) {
6555 const TypedefType *T = TL.getTypePtr();
6556 TypedefNameDecl *Typedef
6557 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6558 T->getDecl()));
6559 if (!Typedef)
6560 return QualType();
6561
6562 QualType Result = TL.getType();
6563 if (getDerived().AlwaysRebuild() ||
6564 Typedef != T->getDecl()) {
6565 Result = getDerived().RebuildTypedefType(Typedef);
6566 if (Result.isNull())
6567 return QualType();
6568 }
6569
6570 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
6571 NewTL.setNameLoc(TL.getNameLoc());
6572
6573 return Result;
6574}
6575
6576template<typename Derived>
6577QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6578 TypeOfExprTypeLoc TL) {
6579 // typeof expressions are not potentially evaluated contexts
6580 EnterExpressionEvaluationContext Unevaluated(
6583
6584 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6585 if (E.isInvalid())
6586 return QualType();
6587
6588 E = SemaRef.HandleExprEvaluationContextForTypeof(E.get());
6589 if (E.isInvalid())
6590 return QualType();
6591
6592 QualType Result = TL.getType();
6593 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
6594 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6595 Result =
6596 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6597 if (Result.isNull())
6598 return QualType();
6599 }
6600
6601 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
6602 NewTL.setTypeofLoc(TL.getTypeofLoc());
6603 NewTL.setLParenLoc(TL.getLParenLoc());
6604 NewTL.setRParenLoc(TL.getRParenLoc());
6605
6606 return Result;
6607}
6608
6609template<typename Derived>
6610QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6611 TypeOfTypeLoc TL) {
6612 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6613 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6614 if (!New_Under_TI)
6615 return QualType();
6616
6617 QualType Result = TL.getType();
6618 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
6619 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6620 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6621 if (Result.isNull())
6622 return QualType();
6623 }
6624
6625 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
6626 NewTL.setTypeofLoc(TL.getTypeofLoc());
6627 NewTL.setLParenLoc(TL.getLParenLoc());
6628 NewTL.setRParenLoc(TL.getRParenLoc());
6629 NewTL.setUnmodifiedTInfo(New_Under_TI);
6630
6631 return Result;
6632}
6633
6634template<typename Derived>
6635QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6636 DecltypeTypeLoc TL) {
6637 const DecltypeType *T = TL.getTypePtr();
6638
6639 // decltype expressions are not potentially evaluated contexts
6640 EnterExpressionEvaluationContext Unevaluated(
6643
6644 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6645 if (E.isInvalid())
6646 return QualType();
6647
6648 E = getSema().ActOnDecltypeExpression(E.get());
6649 if (E.isInvalid())
6650 return QualType();
6651
6652 QualType Result = TL.getType();
6653 if (getDerived().AlwaysRebuild() ||
6654 E.get() != T->getUnderlyingExpr()) {
6655 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6656 if (Result.isNull())
6657 return QualType();
6658 }
6659 else E.get();
6660
6661 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
6662 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6663 NewTL.setRParenLoc(TL.getRParenLoc());
6664 return Result;
6665}
6666
6667template <typename Derived>
6668QualType
6669TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
6670 PackIndexingTypeLoc TL) {
6671 // Transform the index
6672 ExprResult IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
6673 if (IndexExpr.isInvalid())
6674 return QualType();
6675 QualType Pattern = TL.getPattern();
6676
6677 const PackIndexingType *PIT = TL.getTypePtr();
6678 SmallVector<QualType, 5> SubtitutedTypes;
6679 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
6680
6681 bool NotYetExpanded = Types.empty();
6682 bool FullySubstituted = true;
6683
6684 if (Types.empty())
6685 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
6686
6687 for (const QualType &T : Types) {
6689 QualType Transformed = getDerived().TransformType(T);
6690 if (Transformed.isNull())
6691 return QualType();
6692 SubtitutedTypes.push_back(Transformed);
6693 continue;
6694 }
6695
6697 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
6698 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6699 // Determine whether the set of unexpanded parameter packs can and should
6700 // be expanded.
6701 bool ShouldExpand = true;
6702 bool RetainExpansion = false;
6703 std::optional<unsigned> OrigNumExpansions;
6704 std::optional<unsigned> NumExpansions = OrigNumExpansions;
6705 if (getDerived().TryExpandParameterPacks(TL.getEllipsisLoc(), SourceRange(),
6706 Unexpanded, ShouldExpand,
6707 RetainExpansion, NumExpansions))
6708 return QualType();
6709 if (!ShouldExpand) {
6710 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6711 // FIXME: should we keep TypeLoc for individual expansions in
6712 // PackIndexingTypeLoc?
6713 TypeSourceInfo *TI =
6714 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, TL.getBeginLoc());
6715 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
6716 if (Pack.isNull())
6717 return QualType();
6718 if (NotYetExpanded) {
6719 FullySubstituted = false;
6720 QualType Out = getDerived().RebuildPackIndexingType(
6721 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6722 FullySubstituted);
6723 if (Out.isNull())
6724 return QualType();
6725
6726 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6727 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6728 return Out;
6729 }
6730 SubtitutedTypes.push_back(Pack);
6731 continue;
6732 }
6733 for (unsigned I = 0; I != *NumExpansions; ++I) {
6734 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6735 QualType Out = getDerived().TransformType(T);
6736 if (Out.isNull())
6737 return QualType();
6738 SubtitutedTypes.push_back(Out);
6739 }
6740 // If we're supposed to retain a pack expansion, do so by temporarily
6741 // forgetting the partially-substituted parameter pack.
6742 if (RetainExpansion) {
6743 FullySubstituted = false;
6744 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6745 QualType Out = getDerived().TransformType(T);
6746 if (Out.isNull())
6747 return QualType();
6748 SubtitutedTypes.push_back(Out);
6749 }
6750 }
6751
6752 // A pack indexing type can appear in a larger pack expansion,
6753 // e.g. `Pack...[pack_of_indexes]...`
6754 // so we need to temporarily disable substitution of pack elements
6755 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6756 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
6757
6758 QualType Out = getDerived().RebuildPackIndexingType(
6759 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6760 FullySubstituted, SubtitutedTypes);
6761 if (Out.isNull())
6762 return Out;
6763
6764 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6765 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6766 return Out;
6767}
6768
6769template<typename Derived>
6770QualType TreeTransform<Derived>::TransformUnaryTransformType(
6771 TypeLocBuilder &TLB,
6772 UnaryTransformTypeLoc TL) {
6773 QualType Result = TL.getType();
6774 if (Result->isDependentType()) {
6775 const UnaryTransformType *T = TL.getTypePtr();
6776
6777 TypeSourceInfo *NewBaseTSI =
6778 getDerived().TransformType(TL.getUnderlyingTInfo());
6779 if (!NewBaseTSI)
6780 return QualType();
6781 QualType NewBase = NewBaseTSI->getType();
6782
6783 Result = getDerived().RebuildUnaryTransformType(NewBase,
6784 T->getUTTKind(),
6785 TL.getKWLoc());
6786 if (Result.isNull())
6787 return QualType();
6788 }
6789
6790 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
6791 NewTL.setKWLoc(TL.getKWLoc());
6792 NewTL.setParensRange(TL.getParensRange());
6793 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6794 return Result;
6795}
6796
6797template<typename Derived>
6798QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6799 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6800 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6801
6802 CXXScopeSpec SS;
6803 TemplateName TemplateName = getDerived().TransformTemplateName(
6804 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6805 if (TemplateName.isNull())
6806 return QualType();
6807
6808 QualType OldDeduced = T->getDeducedType();
6809 QualType NewDeduced;
6810 if (!OldDeduced.isNull()) {
6811 NewDeduced = getDerived().TransformType(OldDeduced);
6812 if (NewDeduced.isNull())
6813 return QualType();
6814 }
6815
6816 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
6817 TemplateName, NewDeduced);
6818 if (Result.isNull())
6819 return QualType();
6820
6821 DeducedTemplateSpecializationTypeLoc NewTL =
6822 TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
6823 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6824
6825 return Result;
6826}
6827
6828template<typename Derived>
6829QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
6830 RecordTypeLoc TL) {
6831 const RecordType *T = TL.getTypePtr();
6832 RecordDecl *Record
6833 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6834 T->getDecl()));
6835 if (!Record)
6836 return QualType();
6837
6838 QualType Result = TL.getType();
6839 if (getDerived().AlwaysRebuild() ||
6840 Record != T->getDecl()) {
6841 Result = getDerived().RebuildRecordType(Record);
6842 if (Result.isNull())
6843 return QualType();
6844 }
6845
6846 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
6847 NewTL.setNameLoc(TL.getNameLoc());
6848
6849 return Result;
6850}
6851
6852template<typename Derived>
6853QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
6854 EnumTypeLoc TL) {
6855 const EnumType *T = TL.getTypePtr();
6856 EnumDecl *Enum
6857 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6858 T->getDecl()));
6859 if (!Enum)
6860 return QualType();
6861
6862 QualType Result = TL.getType();
6863 if (getDerived().AlwaysRebuild() ||
6864 Enum != T->getDecl()) {
6865 Result = getDerived().RebuildEnumType(Enum);
6866 if (Result.isNull())
6867 return QualType();
6868 }
6869
6870 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
6871 NewTL.setNameLoc(TL.getNameLoc());
6872
6873 return Result;
6874}
6875
6876template<typename Derived>
6877QualType TreeTransform<Derived>::TransformInjectedClassNameType(
6878 TypeLocBuilder &TLB,
6879 InjectedClassNameTypeLoc TL) {
6880 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
6881 TL.getTypePtr()->getDecl());
6882 if (!D) return QualType();
6883
6884 QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
6885 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
6886 return T;
6887}
6888
6889template<typename Derived>
6891 TypeLocBuilder &TLB,
6893 return getDerived().TransformTemplateTypeParmType(
6894 TLB, TL,
6895 /*SuppressObjCLifetime=*/false);
6896}
6897
6898template <typename Derived>
6900 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
6901 return TransformTypeSpecType(TLB, TL);
6902}
6903
6904template<typename Derived>
6905QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
6906 TypeLocBuilder &TLB,
6907 SubstTemplateTypeParmTypeLoc TL) {
6908 const SubstTemplateTypeParmType *T = TL.getTypePtr();
6909
6910 Decl *NewReplaced =
6911 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
6912
6913 // Substitute into the replacement type, which itself might involve something
6914 // that needs to be transformed. This only tends to occur with default
6915 // template arguments of template template parameters.
6916 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
6917 QualType Replacement = getDerived().TransformType(T->getReplacementType());
6918 if (Replacement.isNull())
6919 return QualType();
6920
6921 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
6922 Replacement, NewReplaced, T->getIndex(), T->getPackIndex());
6923
6924 // Propagate type-source information.
6925 SubstTemplateTypeParmTypeLoc NewTL
6926 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
6927 NewTL.setNameLoc(TL.getNameLoc());
6928 return Result;
6929
6930}
6931
6932template<typename Derived>
6934 TypeLocBuilder &TLB,
6936 return getDerived().TransformSubstTemplateTypeParmPackType(
6937 TLB, TL, /*SuppressObjCLifetime=*/false);
6938}
6939
6940template <typename Derived>
6943 return TransformTypeSpecType(TLB, TL);
6944}
6945
6946template<typename Derived>
6948 TypeLocBuilder &TLB,
6951
6952 // The nested-name-specifier never matters in a TemplateSpecializationType,
6953 // because we can't have a dependent nested-name-specifier anyway.
6954 CXXScopeSpec SS;
6955 TemplateName Template
6956 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
6957 TL.getTemplateNameLoc());
6958 if (Template.isNull())
6959 return QualType();
6960
6961 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
6962}
6963
6964template<typename Derived>
6966 AtomicTypeLoc TL) {
6967 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6968 if (ValueType.isNull())
6969 return QualType();
6970
6971 QualType Result = TL.getType();
6972 if (getDerived().AlwaysRebuild() ||
6973 ValueType != TL.getValueLoc().getType()) {
6974 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
6975 if (Result.isNull())
6976 return QualType();
6977 }
6978
6979 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
6980 NewTL.setKWLoc(TL.getKWLoc());
6981 NewTL.setLParenLoc(TL.getLParenLoc());
6982 NewTL.setRParenLoc(TL.getRParenLoc());
6983
6984 return Result;
6985}
6986
6987template <typename Derived>
6988QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
6989 PipeTypeLoc TL) {
6990 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6991 if (ValueType.isNull())
6992 return QualType();
6993
6994 QualType Result = TL.getType();
6995 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
6996 const PipeType *PT = Result->castAs<PipeType>();
6997 bool isReadPipe = PT->isReadOnly();
6998 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
6999 if (Result.isNull())
7000 return QualType();
7001 }
7002
7003 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);
7004 NewTL.setKWLoc(TL.getKWLoc());
7005
7006 return Result;
7007}
7008
7009template <typename Derived>
7010QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7011 BitIntTypeLoc TL) {
7012 const BitIntType *EIT = TL.getTypePtr();
7013 QualType Result = TL.getType();
7014
7015 if (getDerived().AlwaysRebuild()) {
7016 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7017 EIT->getNumBits(), TL.getNameLoc());
7018 if (Result.isNull())
7019 return QualType();
7020 }
7021
7022 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
7023 NewTL.setNameLoc(TL.getNameLoc());
7024 return Result;
7025}
7026
7027template <typename Derived>
7028QualType TreeTransform<Derived>::TransformDependentBitIntType(
7029 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7030 const DependentBitIntType *EIT = TL.getTypePtr();
7031
7032 EnterExpressionEvaluationContext Unevaluated(
7034 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7035 BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr);
7036
7037 if (BitsExpr.isInvalid())
7038 return QualType();
7039
7040 QualType Result = TL.getType();
7041
7042 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7043 Result = getDerived().RebuildDependentBitIntType(
7044 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7045
7046 if (Result.isNull())
7047 return QualType();
7048 }
7049
7050 if (isa<DependentBitIntType>(Result)) {
7051 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);
7052 NewTL.setNameLoc(TL.getNameLoc());
7053 } else {
7054 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
7055 NewTL.setNameLoc(TL.getNameLoc());
7056 }
7057 return Result;
7058}
7059
7060 /// Simple iterator that traverses the template arguments in a
7061 /// container that provides a \c getArgLoc() member function.
7062 ///
7063 /// This iterator is intended to be used with the iterator form of
7064 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7065 template<typename ArgLocContainer>
7067 ArgLocContainer *Container;
7068 unsigned Index;
7069
7070 public:
7073 typedef int difference_type;
7074 typedef std::input_iterator_tag iterator_category;
7075
7076 class pointer {
7078
7079 public:
7080 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7081
7083 return &Arg;
7084 }
7085 };
7086
7087
7089
7090 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7091 unsigned Index)
7092 : Container(&Container), Index(Index) { }
7093
7095 ++Index;
7096 return *this;
7097 }
7098
7101 ++(*this);
7102 return Old;
7103 }
7104
7106 return Container->getArgLoc(Index);
7107 }
7108
7110 return pointer(Container->getArgLoc(Index));
7111 }
7112
7115 return X.Container == Y.Container && X.Index == Y.Index;
7116 }
7117
7120 return !(X == Y);
7121 }
7122 };
7123
7124template<typename Derived>
7125QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7126 AutoTypeLoc TL) {
7127 const AutoType *T = TL.getTypePtr();
7128 QualType OldDeduced = T->getDeducedType();
7129 QualType NewDeduced;
7130 if (!OldDeduced.isNull()) {
7131 NewDeduced = getDerived().TransformType(OldDeduced);
7132 if (NewDeduced.isNull())
7133 return QualType();
7134 }
7135
7136 ConceptDecl *NewCD = nullptr;
7137 TemplateArgumentListInfo NewTemplateArgs;
7138 NestedNameSpecifierLoc NewNestedNameSpec;
7139 if (T->isConstrained()) {
7140 assert(TL.getConceptReference());
7141 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7142 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7143
7144 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7145 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7146 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7147 if (getDerived().TransformTemplateArguments(
7148 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7149 NewTemplateArgs))
7150 return QualType();
7151
7152 if (TL.getNestedNameSpecifierLoc()) {
7153 NewNestedNameSpec
7154 = getDerived().TransformNestedNameSpecifierLoc(
7155 TL.getNestedNameSpecifierLoc());
7156 if (!NewNestedNameSpec)
7157 return QualType();
7158 }
7159 }
7160
7161 QualType Result = TL.getType();
7162 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7163 T->isDependentType() || T->isConstrained()) {
7164 // FIXME: Maybe don't rebuild if all template arguments are the same.
7166 NewArgList.reserve(NewTemplateArgs.size());
7167 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7168 NewArgList.push_back(ArgLoc.getArgument());
7169 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7170 NewArgList);
7171 if (Result.isNull())
7172 return QualType();
7173 }
7174
7175 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
7176 NewTL.setNameLoc(TL.getNameLoc());
7177 NewTL.setRParenLoc(TL.getRParenLoc());
7178 NewTL.setConceptReference(nullptr);
7179
7180 if (T->isConstrained()) {
7181 DeclarationNameInfo DNI = DeclarationNameInfo(
7182 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7183 TL.getConceptNameLoc(),
7184 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7185 auto *CR = ConceptReference::Create(
7186 SemaRef.Context, NewNestedNameSpec, TL.getTemplateKWLoc(), DNI,
7187 TL.getFoundDecl(), TL.getTypePtr()->getTypeConstraintConcept(),
7188 ASTTemplateArgumentListInfo::Create(SemaRef.Context, NewTemplateArgs));
7189 NewTL.setConceptReference(CR);
7190 }
7191
7192 return Result;
7193}
7194
7195template <typename Derived>
7197 TypeLocBuilder &TLB,
7198 TemplateSpecializationTypeLoc TL,
7199 TemplateName Template) {
7200 TemplateArgumentListInfo NewTemplateArgs;
7201 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7202 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7203 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7204 ArgIterator;
7205 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7206 ArgIterator(TL, TL.getNumArgs()),
7207 NewTemplateArgs))
7208 return QualType();
7209
7210 // FIXME: maybe don't rebuild if all the template arguments are the same.
7211
7212 QualType Result =
7213 getDerived().RebuildTemplateSpecializationType(Template,
7214 TL.getTemplateNameLoc(),
7215 NewTemplateArgs);
7216
7217 if (!Result.isNull()) {
7218 // Specializations of template template parameters are represented as
7219 // TemplateSpecializationTypes, and substitution of type alias templates
7220 // within a dependent context can transform them into
7221 // DependentTemplateSpecializationTypes.
7222 if (isa<DependentTemplateSpecializationType>(Result)) {
7223 DependentTemplateSpecializationTypeLoc NewTL
7224 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7225 NewTL.setElaboratedKeywordLoc(SourceLocation());
7226 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
7227 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7228 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7229 NewTL.setLAngleLoc(TL.getLAngleLoc());
7230 NewTL.setRAngleLoc(TL.getRAngleLoc());
7231 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7232 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7233 return Result;
7234 }
7235
7236 TemplateSpecializationTypeLoc NewTL
7237 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7238 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7239 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7240 NewTL.setLAngleLoc(TL.getLAngleLoc());
7241 NewTL.setRAngleLoc(TL.getRAngleLoc());
7242 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7243 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7244 }
7245
7246 return Result;
7247}
7248
7249template <typename Derived>
7251 TypeLocBuilder &TLB,
7253 TemplateName Template,
7254 CXXScopeSpec &SS) {
7255 TemplateArgumentListInfo NewTemplateArgs;
7256 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7257 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7260 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7261 ArgIterator(TL, TL.getNumArgs()),
7262 NewTemplateArgs))
7263 return QualType();
7264
7265 // FIXME: maybe don't rebuild if all the template arguments are the same.
7266
7267 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
7268 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
7269 TL.getTypePtr()->getKeyword(), DTN->getQualifier(),
7270 DTN->getIdentifier(), NewTemplateArgs.arguments());
7271
7275 NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
7278 NewTL.setLAngleLoc(TL.getLAngleLoc());
7279 NewTL.setRAngleLoc(TL.getRAngleLoc());
7280 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7281 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7282 return Result;
7283 }
7284
7286 = getDerived().RebuildTemplateSpecializationType(Template,
7287 TL.getTemplateNameLoc(),
7288 NewTemplateArgs);
7289
7290 if (!Result.isNull()) {
7291 /// FIXME: Wrap this in an elaborated-type-specifier?
7296 NewTL.setLAngleLoc(TL.getLAngleLoc());
7297 NewTL.setRAngleLoc(TL.getRAngleLoc());
7298 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7299 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7300 }
7301
7302 return Result;
7303}
7304
7305template<typename Derived>
7308 ElaboratedTypeLoc TL) {
7309 const ElaboratedType *T = TL.getTypePtr();
7310
7311 NestedNameSpecifierLoc QualifierLoc;
7312 // NOTE: the qualifier in an ElaboratedType is optional.
7313 if (TL.getQualifierLoc()) {
7314 QualifierLoc
7315 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7316 if (!QualifierLoc)
7317 return QualType();
7318 }
7319
7320 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7321 if (NamedT.isNull())
7322 return QualType();
7323
7324 // C++0x [dcl.type.elab]p2:
7325 // If the identifier resolves to a typedef-name or the simple-template-id
7326 // resolves to an alias template specialization, the
7327 // elaborated-type-specifier is ill-formed.
7328 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7329 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7330 if (const TemplateSpecializationType *TST =
7331 NamedT->getAs<TemplateSpecializationType>()) {
7332 TemplateName Template = TST->getTemplateName();
7333 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7334 Template.getAsTemplateDecl())) {
7335 SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
7336 diag::err_tag_reference_non_tag)
7338 << llvm::to_underlying(
7340 SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
7341 }
7342 }
7343 }
7344
7345 QualType Result = TL.getType();
7346 if (getDerived().AlwaysRebuild() ||
7347 QualifierLoc != TL.getQualifierLoc() ||
7348 NamedT != T->getNamedType()) {
7349 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7350 T->getKeyword(),
7351 QualifierLoc, NamedT);
7352 if (Result.isNull())
7353 return QualType();
7354 }
7355
7356 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7357 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7358 NewTL.setQualifierLoc(QualifierLoc);
7359 return Result;
7360}
7361
7362template <typename Derived>
7363template <typename Fn>
7365 TypeLocBuilder &TLB, AttributedTypeLoc TL, Fn TransformModifiedTypeFn) {
7366 const AttributedType *oldType = TL.getTypePtr();
7367 QualType modifiedType = TransformModifiedTypeFn(TLB, TL.getModifiedLoc());
7368 if (modifiedType.isNull())
7369 return QualType();
7370
7371 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7372 const Attr *oldAttr = TL.getAttr();
7373 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7374 if (oldAttr && !newAttr)
7375 return QualType();
7376
7377 QualType result = TL.getType();
7378
7379 // FIXME: dependent operand expressions?
7380 if (getDerived().AlwaysRebuild() ||
7381 modifiedType != oldType->getModifiedType()) {
7382 TypeLocBuilder AuxiliaryTLB;
7383 AuxiliaryTLB.reserve(TL.getFullDataSize());
7384 QualType equivalentType =
7385 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7386 if (equivalentType.isNull())
7387 return QualType();
7388
7389 // Check whether we can add nullability; it is only represented as
7390 // type sugar, and therefore cannot be diagnosed in any other way.
7391 if (auto nullability = oldType->getImmediateNullability()) {
7392 if (!modifiedType->canHaveNullability()) {
7393 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
7394 : TL.getModifiedLoc().getBeginLoc()),
7395 diag::err_nullability_nonpointer)
7396 << DiagNullabilityKind(*nullability, false) << modifiedType;
7397 return QualType();
7398 }
7399 }
7400
7401 result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
7402 modifiedType,
7403 equivalentType);
7404 }
7405
7406 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
7407 newTL.setAttr(newAttr);
7408 return result;
7409}
7410
7411template <typename Derived>
7413 AttributedTypeLoc TL) {
7414 return getDerived().TransformAttributedType(
7415 TLB, TL, [&](TypeLocBuilder &TLB, TypeLoc ModifiedLoc) -> QualType {
7416 return getDerived().TransformType(TLB, ModifiedLoc);
7417 });
7418}
7419
7420template <typename Derived>
7423 const CountAttributedType *OldTy = TL.getTypePtr();
7424 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7425 if (InnerTy.isNull())
7426 return QualType();
7427
7428 Expr *OldCount = TL.getCountExpr();
7429 Expr *NewCount = nullptr;
7430 if (OldCount) {
7431 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7432 if (CountResult.isInvalid())
7433 return QualType();
7434 NewCount = CountResult.get();
7435 }
7436
7437 QualType Result = TL.getType();
7438 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7439 OldCount != NewCount) {
7440 // Currently, CountAttributedType can only wrap incomplete array types.
7442 InnerTy, NewCount, OldTy->isCountInBytes(), OldTy->isOrNull());
7443 }
7444
7445 TLB.push<CountAttributedTypeLoc>(Result);
7446 return Result;
7447}
7448
7449template <typename Derived>
7450QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7451 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7452 // The BTFTagAttributedType is available for C only.
7453 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7454}
7455
7456template<typename Derived>
7457QualType
7458TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7459 ParenTypeLoc TL) {
7460 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7461 if (Inner.isNull())
7462 return QualType();
7463
7464 QualType Result = TL.getType();
7465 if (getDerived().AlwaysRebuild() ||
7466 Inner != TL.getInnerLoc().getType()) {
7467 Result = getDerived().RebuildParenType(Inner);
7468 if (Result.isNull())
7469 return QualType();
7470 }
7471
7472 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
7473 NewTL.setLParenLoc(TL.getLParenLoc());
7474 NewTL.setRParenLoc(TL.getRParenLoc());
7475 return Result;
7476}
7477
7478template <typename Derived>
7479QualType
7480TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7481 MacroQualifiedTypeLoc TL) {
7482 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7483 if (Inner.isNull())
7484 return QualType();
7485
7486 QualType Result = TL.getType();
7487 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7488 Result =
7489 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7490 if (Result.isNull())
7491 return QualType();
7492 }
7493
7494 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
7495 NewTL.setExpansionLoc(TL.getExpansionLoc());
7496 return Result;
7497}
7498
7499template<typename Derived>
7500QualType TreeTransform<Derived>::TransformDependentNameType(
7501 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7502 return TransformDependentNameType(TLB, TL, false);
7503}
7504
7505template<typename Derived>
7506QualType TreeTransform<Derived>::TransformDependentNameType(
7507 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7508 const DependentNameType *T = TL.getTypePtr();
7509
7510 NestedNameSpecifierLoc QualifierLoc
7511 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7512 if (!QualifierLoc)
7513 return QualType();
7514
7515 QualType Result
7516 = getDerived().RebuildDependentNameType(T->getKeyword(),
7517 TL.getElaboratedKeywordLoc(),
7518 QualifierLoc,
7519 T->getIdentifier(),
7520 TL.getNameLoc(),
7521 DeducedTSTContext);
7522 if (Result.isNull())
7523 return QualType();
7524
7525 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7526 QualType NamedT = ElabT->getNamedType();
7527 TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
7528
7529 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7530 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7531 NewTL.setQualifierLoc(QualifierLoc);
7532 } else {
7533 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
7534 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7535 NewTL.setQualifierLoc(QualifierLoc);
7536 NewTL.setNameLoc(TL.getNameLoc());
7537 }
7538 return Result;
7539}
7540
7541template<typename Derived>
7544 DependentTemplateSpecializationTypeLoc TL) {
7545 NestedNameSpecifierLoc QualifierLoc;
7546 if (TL.getQualifierLoc()) {
7547 QualifierLoc
7548 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7549 if (!QualifierLoc)
7550 return QualType();
7551 }
7552
7553 return getDerived()
7554 .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
7555}
7556
7557template<typename Derived>
7561 NestedNameSpecifierLoc QualifierLoc) {
7563
7564 TemplateArgumentListInfo NewTemplateArgs;
7565 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7566 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7567
7570 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7571 ArgIterator(TL, TL.getNumArgs()),
7572 NewTemplateArgs))
7573 return QualType();
7574
7575 QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
7576 T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(),
7577 T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs,
7578 /*AllowInjectedClassName*/ false);
7579 if (Result.isNull())
7580 return QualType();
7581
7582 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
7583 QualType NamedT = ElabT->getNamedType();
7584
7585 // Copy information relevant to the template specialization.
7587 = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
7590 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7591 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7592 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7593 NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7594
7595 // Copy information relevant to the elaborated type.
7598 NewTL.setQualifierLoc(QualifierLoc);
7599 } else if (isa<DependentTemplateSpecializationType>(Result)) {
7603 SpecTL.setQualifierLoc(QualifierLoc);
7606 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7607 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7608 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7609 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7610 } else {
7615 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7616 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7617 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7618 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7619 }
7620 return Result;
7621}
7622
7623template<typename Derived>
7626 QualType Pattern
7627 = getDerived().TransformType(TLB, TL.getPatternLoc());
7628 if (Pattern.isNull())
7629 return QualType();
7630
7631 QualType Result = TL.getType();
7632 if (getDerived().AlwaysRebuild() ||
7633 Pattern != TL.getPatternLoc().getType()) {
7634 Result = getDerived().RebuildPackExpansionType(Pattern,
7636 TL.getEllipsisLoc(),
7638 if (Result.isNull())
7639 return QualType();
7640 }
7641
7642 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
7643 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7644 return Result;
7645}
7646
7647template<typename Derived>
7648QualType
7649TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7650 ObjCInterfaceTypeLoc TL) {
7651 // ObjCInterfaceType is never dependent.
7652 TLB.pushFullCopy(TL);
7653 return TL.getType();
7654}
7655
7656template<typename Derived>
7657QualType
7658TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7659 ObjCTypeParamTypeLoc TL) {
7660 const ObjCTypeParamType *T = TL.getTypePtr();
7661 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7662 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7663 if (!OTP)
7664 return QualType();
7665
7666 QualType Result = TL.getType();
7667 if (getDerived().AlwaysRebuild() ||
7668 OTP != T->getDecl()) {
7669 Result = getDerived().RebuildObjCTypeParamType(
7670 OTP, TL.getProtocolLAngleLoc(),
7671 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7672 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7673 if (Result.isNull())
7674 return QualType();
7675 }
7676
7677 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
7678 if (TL.getNumProtocols()) {
7679 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7680 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7681 NewTL.setProtocolLoc(i, TL.getProtocolLoc(i));
7682 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7683 }
7684 return Result;
7685}
7686
7687template<typename Derived>
7688QualType
7689TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7690 ObjCObjectTypeLoc TL) {
7691 // Transform base type.
7692 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7693 if (BaseType.isNull())
7694 return QualType();
7695
7696 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7697
7698 // Transform type arguments.
7699 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7700 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7701 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7702 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7703 QualType TypeArg = TypeArgInfo->getType();
7704 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7705 AnyChanged = true;
7706
7707 // We have a pack expansion. Instantiate it.
7708 const auto *PackExpansion = PackExpansionLoc.getType()
7709 ->castAs<PackExpansionType>();
7711 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
7712 Unexpanded);
7713 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7714
7715 // Determine whether the set of unexpanded parameter packs can
7716 // and should be expanded.
7717 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7718 bool Expand = false;
7719 bool RetainExpansion = false;
7720 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
7721 if (getDerived().TryExpandParameterPacks(
7722 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7723 Unexpanded, Expand, RetainExpansion, NumExpansions))
7724 return QualType();
7725
7726 if (!Expand) {
7727 // We can't expand this pack expansion into separate arguments yet;
7728 // just substitute into the pattern and create a new pack expansion
7729 // type.
7730 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
7731
7732 TypeLocBuilder TypeArgBuilder;
7733 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7734 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7735 PatternLoc);
7736 if (NewPatternType.isNull())
7737 return QualType();
7738
7739 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7740 NewPatternType, NumExpansions);
7741 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);
7742 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7743 NewTypeArgInfos.push_back(
7744 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewExpansionType));
7745 continue;
7746 }
7747
7748 // Substitute into the pack expansion pattern for each slice of the
7749 // pack.
7750 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
7751 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
7752
7753 TypeLocBuilder TypeArgBuilder;
7754 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7755
7756 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
7757 PatternLoc);
7758 if (NewTypeArg.isNull())
7759 return QualType();
7760
7761 NewTypeArgInfos.push_back(
7762 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7763 }
7764
7765 continue;
7766 }
7767
7768 TypeLocBuilder TypeArgBuilder;
7769 TypeArgBuilder.reserve(TypeArgLoc.getFullDataSize());
7770 QualType NewTypeArg =
7771 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
7772 if (NewTypeArg.isNull())
7773 return QualType();
7774
7775 // If nothing changed, just keep the old TypeSourceInfo.
7776 if (NewTypeArg == TypeArg) {
7777 NewTypeArgInfos.push_back(TypeArgInfo);
7778 continue;
7779 }
7780
7781 NewTypeArgInfos.push_back(
7782 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7783 AnyChanged = true;
7784 }
7785
7786 QualType Result = TL.getType();
7787 if (getDerived().AlwaysRebuild() || AnyChanged) {
7788 // Rebuild the type.
7789 Result = getDerived().RebuildObjCObjectType(
7790 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
7791 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
7792 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7793 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7794
7795 if (Result.isNull())
7796 return QualType();
7797 }
7798
7799 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);
7800 NewT.setHasBaseTypeAsWritten(true);
7801 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
7802 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
7803 NewT.setTypeArgTInfo(i, NewTypeArgInfos[i]);
7804 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
7805 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7806 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7807 NewT.setProtocolLoc(i, TL.getProtocolLoc(i));
7808 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7809 return Result;
7810}
7811
7812template<typename Derived>
7813QualType
7814TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
7815 ObjCObjectPointerTypeLoc TL) {
7816 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
7817 if (PointeeType.isNull())
7818 return QualType();
7819
7820 QualType Result = TL.getType();
7821 if (getDerived().AlwaysRebuild() ||
7822 PointeeType != TL.getPointeeLoc().getType()) {
7823 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
7824 TL.getStarLoc());
7825 if (Result.isNull())
7826 return QualType();
7827 }
7828
7829 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
7830 NewT.setStarLoc(TL.getStarLoc());
7831 return Result;
7832}
7833
7834//===----------------------------------------------------------------------===//
7835// Statement transformation
7836//===----------------------------------------------------------------------===//
7837template<typename Derived>
7839TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
7840 return S;
7841}
7842
7843template<typename Derived>
7846 return getDerived().TransformCompoundStmt(S, false);
7847}
7848
7849template<typename Derived>
7852 bool IsStmtExpr) {
7853 Sema::CompoundScopeRAII CompoundScope(getSema());
7854 Sema::FPFeaturesStateRAII FPSave(getSema());
7855 if (S->hasStoredFPFeatures())
7856 getSema().resetFPOptions(
7857 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
7858
7859 const Stmt *ExprResult = S->getStmtExprResult();
7860 bool SubStmtInvalid = false;
7861 bool SubStmtChanged = false;
7862 SmallVector<Stmt*, 8> Statements;
7863 for (auto *B : S->body()) {
7864 StmtResult Result = getDerived().TransformStmt(
7865 B, IsStmtExpr && B == ExprResult ? SDK_StmtExprResult : SDK_Discarded);
7866
7867 if (Result.isInvalid()) {
7868 // Immediately fail if this was a DeclStmt, since it's very
7869 // likely that this will cause problems for future statements.
7870 if (isa<DeclStmt>(B))
7871 return StmtError();
7872
7873 // Otherwise, just keep processing substatements and fail later.
7874 SubStmtInvalid = true;
7875 continue;
7876 }
7877
7878 SubStmtChanged = SubStmtChanged || Result.get() != B;
7879 Statements.push_back(Result.getAs<Stmt>());
7880 }
7881
7882 if (SubStmtInvalid)
7883 return StmtError();
7884
7885 if (!getDerived().AlwaysRebuild() &&
7886 !SubStmtChanged)
7887 return S;
7888
7889 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
7890 Statements,
7891 S->getRBracLoc(),
7892 IsStmtExpr);
7893}
7894
7895template<typename Derived>
7897TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
7898 ExprResult LHS, RHS;
7899 {
7900 EnterExpressionEvaluationContext Unevaluated(
7902
7903 // Transform the left-hand case value.
7904 LHS = getDerived().TransformExpr(S->getLHS());
7905 LHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), LHS);
7906 if (LHS.isInvalid())
7907 return StmtError();
7908
7909 // Transform the right-hand case value (for the GNU case-range extension).
7910 RHS = getDerived().TransformExpr(S->getRHS());
7911 RHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), RHS);
7912 if (RHS.isInvalid())
7913 return StmtError();
7914 }
7915
7916 // Build the case statement.
7917 // Case statements are always rebuilt so that they will attached to their
7918 // transformed switch statement.
7919 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
7920 LHS.get(),
7921 S->getEllipsisLoc(),
7922 RHS.get(),
7923 S->getColonLoc());
7924 if (Case.isInvalid())
7925 return StmtError();
7926
7927 // Transform the statement following the case
7928 StmtResult SubStmt =
7929 getDerived().TransformStmt(S->getSubStmt());
7930 if (SubStmt.isInvalid())
7931 return StmtError();
7932
7933 // Attach the body to the case statement
7934 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
7935}
7936
7937template <typename Derived>
7938StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
7939 // Transform the statement following the default case
7940 StmtResult SubStmt =
7941 getDerived().TransformStmt(S->getSubStmt());
7942 if (SubStmt.isInvalid())
7943 return StmtError();
7944
7945 // Default statements are always rebuilt
7946 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
7947 SubStmt.get());
7948}
7949
7950template<typename Derived>
7952TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
7953 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7954 if (SubStmt.isInvalid())
7955 return StmtError();
7956
7957 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
7958 S->getDecl());
7959 if (!LD)
7960 return StmtError();
7961
7962 // If we're transforming "in-place" (we're not creating new local
7963 // declarations), assume we're replacing the old label statement
7964 // and clear out the reference to it.
7965 if (LD == S->getDecl())
7966 S->getDecl()->setStmt(nullptr);
7967
7968 // FIXME: Pass the real colon location in.
7969 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
7970 cast<LabelDecl>(LD), SourceLocation(),
7971 SubStmt.get());
7972}
7973
7974template <typename Derived>
7976 if (!R)
7977 return R;
7978
7979 switch (R->getKind()) {
7980// Transform attributes by calling TransformXXXAttr.
7981#define ATTR(X) \
7982 case attr::X: \
7983 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
7984#include "clang/Basic/AttrList.inc"
7985 }
7986 return R;
7987}
7988
7989template <typename Derived>
7991 const Stmt *InstS,
7992 const Attr *R) {
7993 if (!R)
7994 return R;
7995
7996 switch (R->getKind()) {
7997// Transform attributes by calling TransformStmtXXXAttr.
7998#define ATTR(X) \
7999 case attr::X: \
8000 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8001#include "clang/Basic/AttrList.inc"
8002 }
8003 return TransformAttr(R);
8004}
8005
8006template <typename Derived>
8009 StmtDiscardKind SDK) {
8010 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8011 if (SubStmt.isInvalid())
8012 return StmtError();
8013
8014 bool AttrsChanged = false;
8016
8017 // Visit attributes and keep track if any are transformed.
8018 for (const auto *I : S->getAttrs()) {
8019 const Attr *R =
8020 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8021 AttrsChanged |= (I != R);
8022 if (R)
8023 Attrs.push_back(R);
8024 }
8025
8026 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8027 return S;
8028
8029 // If transforming the attributes failed for all of the attributes in the
8030 // statement, don't make an AttributedStmt without attributes.
8031 if (Attrs.empty())
8032 return SubStmt;
8033
8034 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8035 SubStmt.get());
8036}
8037
8038template<typename Derived>
8040TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8041 // Transform the initialization statement
8042 StmtResult Init = getDerived().TransformStmt(S->getInit());
8043 if (Init.isInvalid())
8044 return StmtError();
8045
8046 Sema::ConditionResult Cond;
8047 if (!S->isConsteval()) {
8048 // Transform the condition
8049 Cond = getDerived().TransformCondition(
8050 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8051 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8053 if (Cond.isInvalid())
8054 return StmtError();
8055 }
8056
8057 // If this is a constexpr if, determine which arm we should instantiate.
8058 std::optional<bool> ConstexprConditionValue;
8059 if (S->isConstexpr())
8060 ConstexprConditionValue = Cond.getKnownValue();
8061
8062 // Transform the "then" branch.
8063 StmtResult Then;
8064 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8065 EnterExpressionEvaluationContext Ctx(
8068 S->isNonNegatedConsteval());
8069
8070 Then = getDerived().TransformStmt(S->getThen());
8071 if (Then.isInvalid())
8072 return StmtError();
8073 } else {
8074 // Discarded branch is replaced with empty CompoundStmt so we can keep
8075 // proper source location for start and end of original branch, so
8076 // subsequent transformations like CoverageMapping work properly
8077 Then = new (getSema().Context)
8078 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8079 }
8080
8081 // Transform the "else" branch.
8082 StmtResult Else;
8083 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8084 EnterExpressionEvaluationContext Ctx(
8087 S->isNegatedConsteval());
8088
8089 Else = getDerived().TransformStmt(S->getElse());
8090 if (Else.isInvalid())
8091 return StmtError();
8092 } else if (S->getElse() && ConstexprConditionValue &&
8093 *ConstexprConditionValue) {
8094 // Same thing here as with <then> branch, we are discarding it, we can't
8095 // replace it with NULL nor NullStmt as we need to keep for source location
8096 // range, for CoverageMapping
8097 Else = new (getSema().Context)
8098 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8099 }
8100
8101 if (!getDerived().AlwaysRebuild() &&
8102 Init.get() == S->getInit() &&
8103 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8104 Then.get() == S->getThen() &&
8105 Else.get() == S->getElse())
8106 return S;
8107
8108 return getDerived().RebuildIfStmt(
8109 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8110 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8111}
8112
8113template<typename Derived>
8115TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8116 // Transform the initialization statement
8117 StmtResult Init = getDerived().TransformStmt(S->getInit());
8118 if (Init.isInvalid())
8119 return StmtError();
8120
8121 // Transform the condition.
8122 Sema::ConditionResult Cond = getDerived().TransformCondition(
8123 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8125 if (Cond.isInvalid())
8126 return StmtError();
8127
8128 // Rebuild the switch statement.
8130 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8131 Init.get(), Cond, S->getRParenLoc());
8132 if (Switch.isInvalid())
8133 return StmtError();
8134
8135 // Transform the body of the switch statement.
8136 StmtResult Body = getDerived().TransformStmt(S->getBody());
8137 if (Body.isInvalid())
8138 return StmtError();
8139
8140 // Complete the switch statement.
8141 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8142 Body.get());
8143}
8144
8145template<typename Derived>
8147TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8148 // Transform the condition
8149 Sema::ConditionResult Cond = getDerived().TransformCondition(
8150 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8152 if (Cond.isInvalid())
8153 return StmtError();
8154
8155 // Transform the body
8156 StmtResult Body = getDerived().TransformStmt(S->getBody());
8157 if (Body.isInvalid())
8158 return StmtError();
8159
8160 if (!getDerived().AlwaysRebuild() &&
8161 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8162 Body.get() == S->getBody())
8163 return Owned(S);
8164
8165 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8166 Cond, S->getRParenLoc(), Body.get());
8167}
8168
8169template<typename Derived>
8171TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8172 // Transform the body
8173 StmtResult Body = getDerived().TransformStmt(S->getBody());
8174 if (Body.isInvalid())
8175 return StmtError();
8176
8177 // Transform the condition
8178 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8179 if (Cond.isInvalid())
8180 return StmtError();
8181
8182 if (!getDerived().AlwaysRebuild() &&
8183 Cond.get() == S->getCond() &&
8184 Body.get() == S->getBody())
8185 return S;
8186
8187 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8188 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8189 S->getRParenLoc());
8190}
8191
8192template<typename Derived>
8194TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8195 if (getSema().getLangOpts().OpenMP)
8196 getSema().OpenMP().startOpenMPLoop();
8197
8198 // Transform the initialization statement
8199 StmtResult Init = getDerived().TransformStmt(S->getInit());
8200 if (Init.isInvalid())
8201 return StmtError();
8202
8203 // In OpenMP loop region loop control variable must be captured and be
8204 // private. Perform analysis of first part (if any).
8205 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8206 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8207 Init.get());
8208
8209 // Transform the condition
8210 Sema::ConditionResult Cond = getDerived().TransformCondition(
8211 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8213 if (Cond.isInvalid())
8214 return StmtError();
8215
8216 // Transform the increment
8217 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8218 if (Inc.isInvalid())
8219 return StmtError();
8220
8221 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8222 if (S->getInc() && !FullInc.get())
8223 return StmtError();
8224
8225 // Transform the body
8226 StmtResult Body = getDerived().TransformStmt(S->getBody());
8227 if (Body.isInvalid())
8228 return StmtError();
8229
8230 if (!getDerived().AlwaysRebuild() &&
8231 Init.get() == S->getInit() &&
8232 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8233 Inc.get() == S->getInc() &&
8234 Body.get() == S->getBody())
8235 return S;
8236
8237 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8238 Init.get(), Cond, FullInc,
8239 S->getRParenLoc(), Body.get());
8240}
8241
8242template<typename Derived>
8244TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8245 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8246 S->getLabel());
8247 if (!LD)
8248 return StmtError();
8249
8250 // Goto statements must always be rebuilt, to resolve the label.
8251 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8252 cast<LabelDecl>(LD));
8253}
8254
8255template<typename Derived>
8257TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8258 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8259 if (Target.isInvalid())
8260 return StmtError();
8261 Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());
8262
8263 if (!getDerived().AlwaysRebuild() &&
8264 Target.get() == S->getTarget())
8265 return S;
8266
8267 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8268 Target.get());
8269}
8270
8271template<typename Derived>
8273TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8274 return S;
8275}
8276
8277template<typename Derived>
8279TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8280 return S;
8281}
8282
8283template<typename Derived>
8285TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8286 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8287 /*NotCopyInit*/false);
8288 if (Result.isInvalid())
8289 return StmtError();
8290
8291 // FIXME: We always rebuild the return statement because there is no way
8292 // to tell whether the return type of the function has changed.
8293 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8294}
8295
8296template<typename Derived>
8298TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8299 bool DeclChanged = false;
8301 LambdaScopeInfo *LSI = getSema().getCurLambda();
8302 for (auto *D : S->decls()) {
8303 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8304 if (!Transformed)
8305 return StmtError();
8306
8307 if (Transformed != D)
8308 DeclChanged = true;
8309
8310 if (LSI && isa<TypeDecl>(Transformed))
8311 LSI->ContainsUnexpandedParameterPack |=
8312 getSema()
8313 .getASTContext()
8314 .getTypeDeclType(cast<TypeDecl>(Transformed))
8315 .getCanonicalType()
8316 .getTypePtr()
8317 ->containsUnexpandedParameterPack();
8318
8319 Decls.push_back(Transformed);
8320 }
8321
8322 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8323 return S;
8324
8325 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8326}
8327
8328template<typename Derived>
8330TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8331
8332 SmallVector<Expr*, 8> Constraints;
8335
8336 ExprResult AsmString;
8337 SmallVector<Expr*, 8> Clobbers;
8338
8339 bool ExprsChanged = false;
8340
8341 // Go through the outputs.
8342 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8343 Names.push_back(S->getOutputIdentifier(I));
8344
8345 // No need to transform the constraint literal.
8346 Constraints.push_back(S->getOutputConstraintLiteral(I));
8347
8348 // Transform the output expr.
8349 Expr *OutputExpr = S->getOutputExpr(I);
8350 ExprResult Result = getDerived().TransformExpr(OutputExpr);
8351 if (Result.isInvalid())
8352 return StmtError();
8353
8354 ExprsChanged |= Result.get() != OutputExpr;
8355
8356 Exprs.push_back(Result.get());
8357 }
8358
8359 // Go through the inputs.
8360 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8361 Names.push_back(S->getInputIdentifier(I));
8362
8363 // No need to transform the constraint literal.
8364 Constraints.push_back(S->getInputConstraintLiteral(I));
8365
8366 // Transform the input expr.
8367 Expr *InputExpr = S->getInputExpr(I);
8368 ExprResult Result = getDerived().TransformExpr(InputExpr);
8369 if (Result.isInvalid())
8370 return StmtError();
8371
8372 ExprsChanged |= Result.get() != InputExpr;
8373
8374 Exprs.push_back(Result.get());
8375 }
8376
8377 // Go through the Labels.
8378 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8379 Names.push_back(S->getLabelIdentifier(I));
8380
8381 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(I));
8382 if (Result.isInvalid())
8383 return StmtError();
8384 ExprsChanged |= Result.get() != S->getLabelExpr(I);
8385 Exprs.push_back(Result.get());
8386 }
8387 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8388 return S;
8389
8390 // Go through the clobbers.
8391 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
8392 Clobbers.push_back(S->getClobberStringLiteral(I));
8393
8394 // No need to transform the asm string literal.
8395 AsmString = S->getAsmString();
8396 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8397 S->isVolatile(), S->getNumOutputs(),
8398 S->getNumInputs(), Names.data(),
8399 Constraints, Exprs, AsmString.get(),
8400 Clobbers, S->getNumLabels(),
8401 S->getRParenLoc());
8402}
8403
8404template<typename Derived>
8406TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8407 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8408
8409 bool HadError = false, HadChange = false;
8410
8411 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8412 SmallVector<Expr*, 8> TransformedExprs;
8413 TransformedExprs.reserve(SrcExprs.size());
8414 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8415 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8416 if (!Result.isUsable()) {
8417 HadError = true;
8418 } else {
8419 HadChange |= (Result.get() != SrcExprs[i]);
8420 TransformedExprs.push_back(Result.get());
8421 }
8422 }
8423
8424 if (HadError) return StmtError();
8425 if (!HadChange && !getDerived().AlwaysRebuild())
8426 return Owned(S);
8427
8428 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8429 AsmToks, S->getAsmString(),
8430 S->getNumOutputs(), S->getNumInputs(),
8431 S->getAllConstraints(), S->getClobbers(),
8432 TransformedExprs, S->getEndLoc());
8433}
8434
8435// C++ Coroutines
8436template<typename Derived>
8438TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8439 auto *ScopeInfo = SemaRef.getCurFunction();
8440 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
8441 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8442 ScopeInfo->NeedsCoroutineSuspends &&
8443 ScopeInfo->CoroutineSuspends.first == nullptr &&
8444 ScopeInfo->CoroutineSuspends.second == nullptr &&
8445 "expected clean scope info");
8446
8447 // Set that we have (possibly-invalid) suspend points before we do anything
8448 // that may fail.
8449 ScopeInfo->setNeedsCoroutineSuspends(false);
8450
8451 // We re-build the coroutine promise object (and the coroutine parameters its
8452 // type and constructor depend on) based on the types used in our current
8453 // function. We must do so, and set it on the current FunctionScopeInfo,
8454 // before attempting to transform the other parts of the coroutine body
8455 // statement, such as the implicit suspend statements (because those
8456 // statements reference the FunctionScopeInfo::CoroutinePromise).
8457 if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation()))
8458 return StmtError();
8459 auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());
8460 if (!Promise)
8461 return StmtError();
8462 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8463 ScopeInfo->CoroutinePromise = Promise;
8464
8465 // Transform the implicit coroutine statements constructed using dependent
8466 // types during the previous parse: initial and final suspensions, the return
8467 // object, and others. We also transform the coroutine function's body.
8468 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8469 if (InitSuspend.isInvalid())
8470 return StmtError();
8471 StmtResult FinalSuspend =
8472 getDerived().TransformStmt(S->getFinalSuspendStmt());
8473 if (FinalSuspend.isInvalid() ||
8474 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get()))
8475 return StmtError();
8476 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
8477 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8478
8479 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8480 if (BodyRes.isInvalid())
8481 return StmtError();
8482
8483 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8484 if (Builder.isInvalid())
8485 return StmtError();
8486
8487 Expr *ReturnObject = S->getReturnValueInit();
8488 assert(ReturnObject && "the return object is expected to be valid");
8489 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8490 /*NoCopyInit*/ false);
8491 if (Res.isInvalid())
8492 return StmtError();
8493 Builder.ReturnValue = Res.get();
8494
8495 // If during the previous parse the coroutine still had a dependent promise
8496 // statement, we may need to build some implicit coroutine statements
8497 // (such as exception and fallthrough handlers) for the first time.
8498 if (S->hasDependentPromiseType()) {
8499 // We can only build these statements, however, if the current promise type
8500 // is not dependent.
8501 if (!Promise->getType()->isDependentType()) {
8502 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8503 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8504 "these nodes should not have been built yet");
8505 if (!Builder.buildDependentStatements())
8506 return StmtError();
8507 }
8508 } else {
8509 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8510 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8511 if (Res.isInvalid())
8512 return StmtError();
8513 Builder.OnFallthrough = Res.get();
8514 }
8515
8516 if (auto *OnException = S->getExceptionHandler()) {
8517 StmtResult Res = getDerived().TransformStmt(OnException);
8518 if (Res.isInvalid())
8519 return StmtError();
8520 Builder.OnException = Res.get();
8521 }
8522
8523 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8524 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8525 if (Res.isInvalid())
8526 return StmtError();
8527 Builder.ReturnStmtOnAllocFailure = Res.get();
8528 }
8529
8530 // Transform any additional statements we may have already built
8531 assert(S->getAllocate() && S->getDeallocate() &&
8532 "allocation and deallocation calls must already be built");
8533 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8534 if (AllocRes.isInvalid())
8535 return StmtError();
8536 Builder.Allocate = AllocRes.get();
8537
8538 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8539 if (DeallocRes.isInvalid())
8540 return StmtError();
8541 Builder.Deallocate = DeallocRes.get();
8542
8543 if (auto *ResultDecl = S->getResultDecl()) {
8544 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8545 if (Res.isInvalid())
8546 return StmtError();
8547 Builder.ResultDecl = Res.get();
8548 }
8549
8550 if (auto *ReturnStmt = S->getReturnStmt()) {
8551 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8552 if (Res.isInvalid())
8553 return StmtError();
8554 Builder.ReturnStmt = Res.get();
8555 }
8556 }
8557
8558 return getDerived().RebuildCoroutineBodyStmt(Builder);
8559}
8560
8561template<typename Derived>
8563TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8564 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8565 /*NotCopyInit*/false);
8566 if (Result.isInvalid())
8567 return StmtError();
8568
8569 // Always rebuild; we don't know if this needs to be injected into a new
8570 // context or if the promise type has changed.
8571 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8572 S->isImplicit());
8573}
8574
8575template <typename Derived>
8576ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8577 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8578 /*NotCopyInit*/ false);
8579 if (Operand.isInvalid())
8580 return ExprError();
8581
8582 // Rebuild the common-expr from the operand rather than transforming it
8583 // separately.
8584
8585 // FIXME: getCurScope() should not be used during template instantiation.
8586 // We should pick up the set of unqualified lookup results for operator
8587 // co_await during the initial parse.
8588 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8589 getSema().getCurScope(), E->getKeywordLoc());
8590
8591 // Always rebuild; we don't know if this needs to be injected into a new
8592 // context or if the promise type has changed.
8593 return getDerived().RebuildCoawaitExpr(
8594 E->getKeywordLoc(), Operand.get(),
8595 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());
8596}
8597
8598template <typename Derived>
8600TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8601 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8602 /*NotCopyInit*/ false);
8603 if (OperandResult.isInvalid())
8604 return ExprError();
8605
8606 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8607 E->getOperatorCoawaitLookup());
8608
8609 if (LookupResult.isInvalid())
8610 return ExprError();
8611
8612 // Always rebuild; we don't know if this needs to be injected into a new
8613 // context or if the promise type has changed.
8614 return getDerived().RebuildDependentCoawaitExpr(
8615 E->getKeywordLoc(), OperandResult.get(),
8616 cast<UnresolvedLookupExpr>(LookupResult.get()));
8617}
8618
8619template<typename Derived>
8621TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8622 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8623 /*NotCopyInit*/false);
8624 if (Result.isInvalid())
8625 return ExprError();
8626
8627 // Always rebuild; we don't know if this needs to be injected into a new
8628 // context or if the promise type has changed.
8629 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8630}
8631
8632// Objective-C Statements.
8633
8634template<typename Derived>
8636TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8637 // Transform the body of the @try.
8638 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8639 if (TryBody.isInvalid())
8640 return StmtError();
8641
8642 // Transform the @catch statements (if present).
8643 bool AnyCatchChanged = false;
8644 SmallVector<Stmt*, 8> CatchStmts;
8645 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8646 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8647 if (Catch.isInvalid())
8648 return StmtError();
8649 if (Catch.get() != S->getCatchStmt(I))
8650 AnyCatchChanged = true;
8651 CatchStmts.push_back(Catch.get());
8652 }
8653
8654 // Transform the @finally statement (if present).
8655 StmtResult Finally;
8656 if (S->getFinallyStmt()) {
8657 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8658 if (Finally.isInvalid())
8659 return StmtError();
8660 }
8661
8662 // If nothing changed, just retain this statement.
8663 if (!getDerived().AlwaysRebuild() &&
8664 TryBody.get() == S->getTryBody() &&
8665 !AnyCatchChanged &&
8666 Finally.get() == S->getFinallyStmt())
8667 return S;
8668
8669 // Build a new statement.
8670 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8671 CatchStmts, Finally.get());
8672}
8673
8674template<typename Derived>
8676TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8677 // Transform the @catch parameter, if there is one.
8678 VarDecl *Var = nullptr;
8679 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8680 TypeSourceInfo *TSInfo = nullptr;
8681 if (FromVar->getTypeSourceInfo()) {
8682 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8683 if (!TSInfo)
8684 return StmtError();
8685 }
8686
8687 QualType T;
8688 if (TSInfo)
8689 T = TSInfo->getType();
8690 else {
8691 T = getDerived().TransformType(FromVar->getType());
8692 if (T.isNull())
8693 return StmtError();
8694 }
8695
8696 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8697 if (!Var)
8698 return StmtError();
8699 }
8700
8701 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8702 if (Body.isInvalid())
8703 return StmtError();
8704
8705 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
8706 S->getRParenLoc(),
8707 Var, Body.get());
8708}
8709
8710template<typename Derived>
8712TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
8713 // Transform the body.
8714 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
8715 if (Body.isInvalid())
8716 return StmtError();
8717
8718 // If nothing changed, just retain this statement.
8719 if (!getDerived().AlwaysRebuild() &&
8720 Body.get() == S->getFinallyBody())
8721 return S;
8722
8723 // Build a new statement.
8724 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
8725 Body.get());
8726}
8727
8728template<typename Derived>
8730TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
8732 if (S->getThrowExpr()) {
8733 Operand = getDerived().TransformExpr(S->getThrowExpr());
8734 if (Operand.isInvalid())
8735 return StmtError();
8736 }
8737
8738 if (!getDerived().AlwaysRebuild() &&
8739 Operand.get() == S->getThrowExpr())
8740 return S;
8741
8742 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
8743}
8744
8745template<typename Derived>
8747TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
8748 ObjCAtSynchronizedStmt *S) {
8749 // Transform the object we are locking.
8750 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
8751 if (Object.isInvalid())
8752 return StmtError();
8753 Object =
8754 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
8755 Object.get());
8756 if (Object.isInvalid())
8757 return StmtError();
8758
8759 // Transform the body.
8760 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
8761 if (Body.isInvalid())
8762 return StmtError();
8763
8764 // If nothing change, just retain the current statement.
8765 if (!getDerived().AlwaysRebuild() &&
8766 Object.get() == S->getSynchExpr() &&
8767 Body.get() == S->getSynchBody())
8768 return S;
8769
8770 // Build a new statement.
8771 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
8772 Object.get(), Body.get());
8773}
8774
8775template<typename Derived>
8777TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
8778 ObjCAutoreleasePoolStmt *S) {
8779 // Transform the body.
8780 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
8781 if (Body.isInvalid())
8782 return StmtError();
8783
8784 // If nothing changed, just retain this statement.
8785 if (!getDerived().AlwaysRebuild() &&
8786 Body.get() == S->getSubStmt())
8787 return S;
8788
8789 // Build a new statement.
8790 return getDerived().RebuildObjCAutoreleasePoolStmt(
8791 S->getAtLoc(), Body.get());
8792}
8793
8794template<typename Derived>
8796TreeTransform<Derived>::TransformObjCForCollectionStmt(
8797 ObjCForCollectionStmt *S) {
8798 // Transform the element statement.
8799 StmtResult Element =
8800 getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded);
8801 if (Element.isInvalid())
8802 return StmtError();
8803
8804 // Transform the collection expression.
8805 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
8806 if (Collection.isInvalid())
8807 return StmtError();
8808
8809 // Transform the body.
8810 StmtResult Body = getDerived().TransformStmt(S->getBody());
8811 if (Body.isInvalid())
8812 return StmtError();
8813
8814 // If nothing changed, just retain this statement.
8815 if (!getDerived().AlwaysRebuild() &&
8816 Element.get() == S->getElement() &&
8817 Collection.get() == S->getCollection() &&
8818 Body.get() == S->getBody())
8819 return S;
8820
8821 // Build a new statement.
8822 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
8823 Element.get(),
8824 Collection.get(),
8825 S->getRParenLoc(),
8826 Body.get());
8827}
8828
8829template <typename Derived>
8830StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
8831 // Transform the exception declaration, if any.
8832 VarDecl *Var = nullptr;
8833 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
8834 TypeSourceInfo *T =
8835 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
8836 if (!T)
8837 return StmtError();
8838
8839 Var = getDerived().RebuildExceptionDecl(
8840 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
8841 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
8842 if (!Var || Var->isInvalidDecl())
8843 return StmtError();
8844 }
8845
8846 // Transform the actual exception handler.
8847 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
8848 if (Handler.isInvalid())
8849 return StmtError();
8850
8851 if (!getDerived().AlwaysRebuild() && !Var &&
8852 Handler.get() == S->getHandlerBlock())
8853 return S;
8854
8855 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
8856}
8857
8858template <typename Derived>
8859StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
8860 // Transform the try block itself.
8861 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8862 if (TryBlock.isInvalid())
8863 return StmtError();
8864
8865 // Transform the handlers.
8866 bool HandlerChanged = false;
8867 SmallVector<Stmt *, 8> Handlers;
8868 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
8869 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I));
8870 if (Handler.isInvalid())
8871 return StmtError();
8872
8873 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
8874 Handlers.push_back(Handler.getAs<Stmt>());
8875 }
8876
8877 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8878 !HandlerChanged)
8879 return S;
8880
8881 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
8882 Handlers);
8883}
8884
8885template<typename Derived>
8887TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
8888 EnterExpressionEvaluationContext ForRangeInitContext(
8890 /*LambdaContextDecl=*/nullptr,
8892 getSema().getLangOpts().CPlusPlus23);
8893
8894 // P2718R0 - Lifetime extension in range-based for loops.
8895 if (getSema().getLangOpts().CPlusPlus23) {
8896 auto &LastRecord = getSema().ExprEvalContexts.back();
8897 LastRecord.InLifetimeExtendingContext = true;
8898 }
8900 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
8901 if (Init.isInvalid())
8902 return StmtError();
8903
8904 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
8905 if (Range.isInvalid())
8906 return StmtError();
8907
8908 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
8909 assert(getSema().getLangOpts().CPlusPlus23 ||
8910 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
8911 auto ForRangeLifetimeExtendTemps =
8912 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
8913
8914 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
8915 if (Begin.isInvalid())
8916 return StmtError();
8917 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
8918 if (End.isInvalid())
8919 return StmtError();
8920
8921 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8922 if (Cond.isInvalid())
8923 return StmtError();
8924 if (Cond.get())
8925 Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());
8926 if (Cond.isInvalid())
8927 return StmtError();
8928 if (Cond.get())
8929 Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());
8930
8931 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8932 if (Inc.isInvalid())
8933 return StmtError();
8934 if (Inc.get())
8935 Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());
8936
8937 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
8938 if (LoopVar.isInvalid())
8939 return StmtError();
8940
8941 StmtResult NewStmt = S;
8942 if (getDerived().AlwaysRebuild() ||
8943 Init.get() != S->getInit() ||
8944 Range.get() != S->getRangeStmt() ||
8945 Begin.get() != S->getBeginStmt() ||
8946 End.get() != S->getEndStmt() ||
8947 Cond.get() != S->getCond() ||
8948 Inc.get() != S->getInc() ||
8949 LoopVar.get() != S->getLoopVarStmt()) {
8950 NewStmt = getDerived().RebuildCXXForRangeStmt(
8951 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
8952 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
8953 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
8954 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
8955 // Might not have attached any initializer to the loop variable.
8956 getSema().ActOnInitializerError(
8957 cast<DeclStmt>(LoopVar.get())->getSingleDecl());
8958 return StmtError();
8959 }
8960 }
8961
8962 StmtResult Body = getDerived().TransformStmt(S->getBody());
8963 if (Body.isInvalid())
8964 return StmtError();
8965
8966 // Body has changed but we didn't rebuild the for-range statement. Rebuild
8967 // it now so we have a new statement to attach the body to.
8968 if (Body.get() != S->getBody() && NewStmt.get() == S) {
8969 NewStmt = getDerived().RebuildCXXForRangeStmt(
8970 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
8971 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
8972 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
8973 if (NewStmt.isInvalid())
8974 return StmtError();
8975 }
8976
8977 if (NewStmt.get() == S)
8978 return S;
8979
8980 return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
8981}
8982
8983template<typename Derived>
8985TreeTransform<Derived>::TransformMSDependentExistsStmt(
8986 MSDependentExistsStmt *S) {
8987 // Transform the nested-name-specifier, if any.
8988 NestedNameSpecifierLoc QualifierLoc;
8989 if (S->getQualifierLoc()) {
8990 QualifierLoc
8991 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
8992 if (!QualifierLoc)
8993 return StmtError();
8994 }
8995
8996 // Transform the declaration name.
8997 DeclarationNameInfo NameInfo = S->getNameInfo();
8998 if (NameInfo.getName()) {
8999 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9000 if (!NameInfo.getName())
9001 return StmtError();
9002 }
9003
9004 // Check whether anything changed.
9005 if (!getDerived().AlwaysRebuild() &&
9006 QualifierLoc == S->getQualifierLoc() &&
9007 NameInfo.getName() == S->getNameInfo().getName())
9008 return S;
9009
9010 // Determine whether this name exists, if we can.
9011 CXXScopeSpec SS;
9012 SS.Adopt(QualifierLoc);
9013 bool Dependent = false;
9014 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9015 case Sema::IER_Exists:
9016 if (S->isIfExists())
9017 break;
9018
9019 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9020
9022 if (S->isIfNotExists())
9023 break;
9024
9025 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9026
9028 Dependent = true;
9029 break;
9030
9031 case Sema::IER_Error:
9032 return StmtError();
9033 }
9034
9035 // We need to continue with the instantiation, so do so now.
9036 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9037 if (SubStmt.isInvalid())
9038 return StmtError();
9039
9040 // If we have resolved the name, just transform to the substatement.
9041 if (!Dependent)
9042 return SubStmt;
9043
9044 // The name is still dependent, so build a dependent expression again.
9045 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9046 S->isIfExists(),
9047 QualifierLoc,
9048 NameInfo,
9049 SubStmt.get());
9050}
9051
9052template<typename Derived>
9054TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9055 NestedNameSpecifierLoc QualifierLoc;
9056 if (E->getQualifierLoc()) {
9057 QualifierLoc
9058 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9059 if (!QualifierLoc)
9060 return ExprError();
9061 }
9062
9063 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9064 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9065 if (!PD)
9066 return ExprError();
9067
9068 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9069 if (Base.isInvalid())
9070 return ExprError();
9071
9072 return new (SemaRef.getASTContext())
9073 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9075 QualifierLoc, E->getMemberLoc());
9076}
9077
9078template <typename Derived>
9079ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9080 MSPropertySubscriptExpr *E) {
9081 auto BaseRes = getDerived().TransformExpr(E->getBase());
9082 if (BaseRes.isInvalid())
9083 return ExprError();
9084 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9085 if (IdxRes.isInvalid())
9086 return ExprError();
9087
9088 if (!getDerived().AlwaysRebuild() &&
9089 BaseRes.get() == E->getBase() &&
9090 IdxRes.get() == E->getIdx())
9091 return E;
9092
9093 return getDerived().RebuildArraySubscriptExpr(
9094 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9095}
9096
9097template <typename Derived>
9098StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9099 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9100 if (TryBlock.isInvalid())
9101 return StmtError();
9102
9103 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9104 if (Handler.isInvalid())
9105 return StmtError();
9106
9107 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9108 Handler.get() == S->getHandler())
9109 return S;
9110
9111 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9112 TryBlock.get(), Handler.get());
9113}
9114
9115template <typename Derived>
9116StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9117 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9118 if (Block.isInvalid())
9119 return StmtError();
9120
9121 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9122}
9123
9124template <typename Derived>
9125StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9126 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9127 if (FilterExpr.isInvalid())
9128 return StmtError();
9129
9130 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9131 if (Block.isInvalid())
9132 return StmtError();
9133
9134 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9135 Block.get());
9136}
9137
9138template <typename Derived>
9140 if (isa<SEHFinallyStmt>(Handler))
9141 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
9142 else
9143 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
9144}
9145
9146template<typename Derived>
9149 return S;
9150}
9151
9152//===----------------------------------------------------------------------===//
9153// OpenMP directive transformation
9154//===----------------------------------------------------------------------===//
9155
9156template <typename Derived>
9158TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9159 // OMPCanonicalLoops are eliminated during transformation, since they will be
9160 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9161 // after transformation.
9162 return getDerived().TransformStmt(L->getLoopStmt());
9163}
9164
9165template <typename Derived>
9168
9169 // Transform the clauses
9171 ArrayRef<OMPClause *> Clauses = D->clauses();
9172 TClauses.reserve(Clauses.size());
9173 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9174 I != E; ++I) {
9175 if (*I) {
9176 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9177 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9178 getDerived().getSema().OpenMP().EndOpenMPClause();
9179 if (Clause)
9180 TClauses.push_back(Clause);
9181 } else {
9182 TClauses.push_back(nullptr);
9183 }
9184 }
9185 StmtResult AssociatedStmt;
9186 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9187 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9188 D->getDirectiveKind(),
9189 /*CurScope=*/nullptr);
9190 StmtResult Body;
9191 {
9192 Sema::CompoundScopeRAII CompoundScope(getSema());
9193 Stmt *CS;
9194 if (D->getDirectiveKind() == OMPD_atomic ||
9195 D->getDirectiveKind() == OMPD_critical ||
9196 D->getDirectiveKind() == OMPD_section ||
9197 D->getDirectiveKind() == OMPD_master)
9198 CS = D->getAssociatedStmt();
9199 else
9200 CS = D->getRawStmt();
9201 Body = getDerived().TransformStmt(CS);
9202 if (Body.isUsable() && isOpenMPLoopDirective(D->getDirectiveKind()) &&
9203 getSema().getLangOpts().OpenMPIRBuilder)
9204 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9205 }
9206 AssociatedStmt =
9207 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9208 if (AssociatedStmt.isInvalid()) {
9209 return StmtError();
9210 }
9211 }
9212 if (TClauses.size() != Clauses.size()) {
9213 return StmtError();
9214 }
9215
9216 // Transform directive name for 'omp critical' directive.
9217 DeclarationNameInfo DirName;
9218 if (D->getDirectiveKind() == OMPD_critical) {
9219 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
9220 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9221 }
9222 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9223 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9224 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();
9225 } else if (D->getDirectiveKind() == OMPD_cancel) {
9226 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();
9227 }
9228
9229 return getDerived().RebuildOMPExecutableDirective(
9230 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9231 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
9232}
9233
9234/// This is mostly the same as above, but allows 'informational' class
9235/// directives when rebuilding the stmt. It still takes an
9236/// OMPExecutableDirective-type argument because we're reusing that as the
9237/// superclass for the 'assume' directive at present, instead of defining a
9238/// mostly-identical OMPInformationalDirective parent class.
9239template <typename Derived>
9242
9243 // Transform the clauses
9245 ArrayRef<OMPClause *> Clauses = D->clauses();
9246 TClauses.reserve(Clauses.size());
9247 for (OMPClause *C : Clauses) {
9248 if (C) {
9249 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
9250 OMPClause *Clause = getDerived().TransformOMPClause(C);
9251 getDerived().getSema().OpenMP().EndOpenMPClause();
9252 if (Clause)
9253 TClauses.push_back(Clause);
9254 } else {
9255 TClauses.push_back(nullptr);
9256 }
9257 }
9258 StmtResult AssociatedStmt;
9259 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9260 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9261 D->getDirectiveKind(),
9262 /*CurScope=*/nullptr);
9263 StmtResult Body;
9264 {
9265 Sema::CompoundScopeRAII CompoundScope(getSema());
9266 assert(D->getDirectiveKind() == OMPD_assume &&
9267 "Unexpected informational directive");
9268 Stmt *CS = D->getAssociatedStmt();
9269 Body = getDerived().TransformStmt(CS);
9270 }
9271 AssociatedStmt =
9272 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9273 if (AssociatedStmt.isInvalid())
9274 return StmtError();
9275 }
9276 if (TClauses.size() != Clauses.size())
9277 return StmtError();
9278
9279 DeclarationNameInfo DirName;
9280
9281 return getDerived().RebuildOMPInformationalDirective(
9282 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
9283 D->getBeginLoc(), D->getEndLoc());
9284}
9285
9286template <typename Derived>
9289 // TODO: Fix This
9290 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)
9291 << getOpenMPDirectiveName(D->getDirectiveKind());
9292 return StmtError();
9293}
9294
9295template <typename Derived>
9297TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9298 DeclarationNameInfo DirName;
9299 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9300 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9301 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9302 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9303 return Res;
9304}
9305
9306template <typename Derived>
9308TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9309 DeclarationNameInfo DirName;
9310 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9311 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9312 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9313 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9314 return Res;
9315}
9316
9317template <typename Derived>
9319TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9320 DeclarationNameInfo DirName;
9321 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9322 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9323 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9324 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9325 return Res;
9326}
9327
9328template <typename Derived>
9330TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9331 DeclarationNameInfo DirName;
9332 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9333 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9334 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9335 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9336 return Res;
9337}
9338
9339template <typename Derived>
9341TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
9342 DeclarationNameInfo DirName;
9343 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9344 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9345 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9346 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9347 return Res;
9348}
9349
9350template <typename Derived>
9351StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
9352 OMPInterchangeDirective *D) {
9353 DeclarationNameInfo DirName;
9354 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9355 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9356 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9357 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9358 return Res;
9359}
9360
9361template <typename Derived>
9363TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9364 DeclarationNameInfo DirName;
9365 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9366 OMPD_for, DirName, nullptr, D->getBeginLoc());
9367 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9368 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9369 return Res;
9370}
9371
9372template <typename Derived>
9374TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9375 DeclarationNameInfo DirName;
9376 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9377 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9378 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9379 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9380 return Res;
9381}
9382
9383template <typename Derived>
9385TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9386 DeclarationNameInfo DirName;
9387 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9388 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9389 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9390 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9391 return Res;
9392}
9393
9394template <typename Derived>
9396TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9397 DeclarationNameInfo DirName;
9398 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9399 OMPD_section, DirName, nullptr, D->getBeginLoc());
9400 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9401 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9402 return Res;
9403}
9404
9405template <typename Derived>
9407TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9408 DeclarationNameInfo DirName;
9409 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9410 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9411 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9412 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9413 return Res;
9414}
9415
9416template <typename Derived>
9418TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9419 DeclarationNameInfo DirName;
9420 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9421 OMPD_single, DirName, nullptr, D->getBeginLoc());
9422 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9423 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9424 return Res;
9425}
9426
9427template <typename Derived>
9429TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9430 DeclarationNameInfo DirName;
9431 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9432 OMPD_master, DirName, nullptr, D->getBeginLoc());
9433 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9434 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9435 return Res;
9436}
9437
9438template <typename Derived>
9440TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9441 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9442 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9443 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9444 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9445 return Res;
9446}
9447
9448template <typename Derived>
9449StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9450 OMPParallelForDirective *D) {
9451 DeclarationNameInfo DirName;
9452 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9453 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9454 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9455 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9456 return Res;
9457}
9458
9459template <typename Derived>
9460StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9461 OMPParallelForSimdDirective *D) {
9462 DeclarationNameInfo DirName;
9463 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9464 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9465 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9466 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9467 return Res;
9468}
9469
9470template <typename Derived>
9471StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9472 OMPParallelMasterDirective *D) {
9473 DeclarationNameInfo DirName;
9474 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9475 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
9476 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9477 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9478 return Res;
9479}
9480
9481template <typename Derived>
9482StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9483 OMPParallelMaskedDirective *D) {
9484 DeclarationNameInfo DirName;
9485 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9486 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
9487 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9488 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9489 return Res;
9490}
9491
9492template <typename Derived>
9493StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9494 OMPParallelSectionsDirective *D) {
9495 DeclarationNameInfo DirName;
9496 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9497 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
9498 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9499 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9500 return Res;
9501}
9502
9503template <typename Derived>
9505TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9506 DeclarationNameInfo DirName;
9507 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9508 OMPD_task, DirName, nullptr, D->getBeginLoc());
9509 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9510 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9511 return Res;
9512}
9513
9514template <typename Derived>
9515StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9516 OMPTaskyieldDirective *D) {
9517 DeclarationNameInfo DirName;
9518 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9519 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
9520 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9521 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9522 return Res;
9523}
9524
9525template <typename Derived>
9527TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9528 DeclarationNameInfo DirName;
9529 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9530 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
9531 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9532 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9533 return Res;
9534}
9535
9536template <typename Derived>
9538TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9539 DeclarationNameInfo DirName;
9540 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9541 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
9542 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9543 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9544 return Res;
9545}
9546
9547template <typename Derived>
9549TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
9550 DeclarationNameInfo DirName;
9551 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9552 OMPD_assume, DirName, nullptr, D->getBeginLoc());
9553 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
9554 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9555 return Res;
9556}
9557
9558template <typename Derived>
9560TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9561 DeclarationNameInfo DirName;
9562 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9563 OMPD_error, DirName, nullptr, D->getBeginLoc());
9564 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9565 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9566 return Res;
9567}
9568
9569template <typename Derived>
9570StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9571 OMPTaskgroupDirective *D) {
9572 DeclarationNameInfo DirName;
9573 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9574 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
9575 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9576 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9577 return Res;
9578}
9579
9580template <typename Derived>
9582TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9583 DeclarationNameInfo DirName;
9584 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9585 OMPD_flush, DirName, nullptr, D->getBeginLoc());
9586 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9587 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9588 return Res;
9589}
9590
9591template <typename Derived>
9593TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9594 DeclarationNameInfo DirName;
9595 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9596 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
9597 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9598 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9599 return Res;
9600}
9601
9602template <typename Derived>
9604TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9605 DeclarationNameInfo DirName;
9606 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9607 OMPD_scan, DirName, nullptr, D->getBeginLoc());
9608 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9609 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9610 return Res;
9611}
9612
9613template <typename Derived>
9615TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9616 DeclarationNameInfo DirName;
9617 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9618 OMPD_ordered, DirName, nullptr, D->getBeginLoc());
9619 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9620 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9621 return Res;
9622}
9623
9624template <typename Derived>
9626TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9627 DeclarationNameInfo DirName;
9628 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9629 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
9630 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9631 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9632 return Res;
9633}
9634
9635template <typename Derived>
9637TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9638 DeclarationNameInfo DirName;
9639 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9640 OMPD_target, DirName, nullptr, D->getBeginLoc());
9641 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9642 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9643 return Res;
9644}
9645
9646template <typename Derived>
9647StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9648 OMPTargetDataDirective *D) {
9649 DeclarationNameInfo DirName;
9650 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9651 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
9652 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9653 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9654 return Res;
9655}
9656
9657template <typename Derived>
9658StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9659 OMPTargetEnterDataDirective *D) {
9660 DeclarationNameInfo DirName;
9661 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9662 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
9663 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9664 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9665 return Res;
9666}
9667
9668template <typename Derived>
9669StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9670 OMPTargetExitDataDirective *D) {
9671 DeclarationNameInfo DirName;
9672 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9673 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
9674 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9675 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9676 return Res;
9677}
9678
9679template <typename Derived>
9680StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
9681 OMPTargetParallelDirective *D) {
9682 DeclarationNameInfo DirName;
9683 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9684 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
9685 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9686 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9687 return Res;
9688}
9689
9690template <typename Derived>
9691StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
9692 OMPTargetParallelForDirective *D) {
9693 DeclarationNameInfo DirName;
9694 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9695 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
9696 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9697 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9698 return Res;
9699}
9700
9701template <typename Derived>
9702StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
9703 OMPTargetUpdateDirective *D) {
9704 DeclarationNameInfo DirName;
9705 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9706 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
9707 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9708 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9709 return Res;
9710}
9711
9712template <typename Derived>
9714TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
9715 DeclarationNameInfo DirName;
9716 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9717 OMPD_teams, DirName, nullptr, D->getBeginLoc());
9718 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9719 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9720 return Res;
9721}
9722
9723template <typename Derived>
9724StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
9725 OMPCancellationPointDirective *D) {
9726 DeclarationNameInfo DirName;
9727 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9728 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
9729 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9730 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9731 return Res;
9732}
9733
9734template <typename Derived>
9736TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
9737 DeclarationNameInfo DirName;
9738 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9739 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
9740 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9741 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9742 return Res;
9743}
9744
9745template <typename Derived>
9747TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
9748 DeclarationNameInfo DirName;
9749 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9750 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
9751 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9752 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9753 return Res;
9754}
9755
9756template <typename Derived>
9757StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
9758 OMPTaskLoopSimdDirective *D) {
9759 DeclarationNameInfo DirName;
9760 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9761 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9762 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9763 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9764 return Res;
9765}
9766
9767template <typename Derived>
9768StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
9769 OMPMasterTaskLoopDirective *D) {
9770 DeclarationNameInfo DirName;
9771 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9772 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
9773 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9774 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9775 return Res;
9776}
9777
9778template <typename Derived>
9779StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
9780 OMPMaskedTaskLoopDirective *D) {
9781 DeclarationNameInfo DirName;
9782 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9783 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9784 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9785 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9786 return Res;
9787}
9788
9789template <typename Derived>
9790StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
9791 OMPMasterTaskLoopSimdDirective *D) {
9792 DeclarationNameInfo DirName;
9793 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9794 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9795 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9796 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9797 return Res;
9798}
9799
9800template <typename Derived>
9801StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
9802 OMPMaskedTaskLoopSimdDirective *D) {
9803 DeclarationNameInfo DirName;
9804 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9805 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9806 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9807 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9808 return Res;
9809}
9810
9811template <typename Derived>
9812StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
9813 OMPParallelMasterTaskLoopDirective *D) {
9814 DeclarationNameInfo DirName;
9815 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9816 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
9817 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9818 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9819 return Res;
9820}
9821
9822template <typename Derived>
9823StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
9824 OMPParallelMaskedTaskLoopDirective *D) {
9825 DeclarationNameInfo DirName;
9826 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9827 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9828 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9829 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9830 return Res;
9831}
9832
9833template <typename Derived>
9835TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
9836 OMPParallelMasterTaskLoopSimdDirective *D) {
9837 DeclarationNameInfo DirName;
9838 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9839 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9840 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9841 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9842 return Res;
9843}
9844
9845template <typename Derived>
9847TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
9848 OMPParallelMaskedTaskLoopSimdDirective *D) {
9849 DeclarationNameInfo DirName;
9850 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9851 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9852 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9853 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9854 return Res;
9855}
9856
9857template <typename Derived>
9858StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
9859 OMPDistributeDirective *D) {
9860 DeclarationNameInfo DirName;
9861 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9862 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
9863 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9864 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9865 return Res;
9866}
9867
9868template <typename Derived>
9869StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
9870 OMPDistributeParallelForDirective *D) {
9871 DeclarationNameInfo DirName;
9872 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9873 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9874 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9875 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9876 return Res;
9877}
9878
9879template <typename Derived>
9881TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
9882 OMPDistributeParallelForSimdDirective *D) {
9883 DeclarationNameInfo DirName;
9884 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9885 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9886 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9887 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9888 return Res;
9889}
9890
9891template <typename Derived>
9892StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
9893 OMPDistributeSimdDirective *D) {
9894 DeclarationNameInfo DirName;
9895 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9896 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
9897 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9898 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9899 return Res;
9900}
9901
9902template <typename Derived>
9903StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
9904 OMPTargetParallelForSimdDirective *D) {
9905 DeclarationNameInfo DirName;
9906 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9907 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9908 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9909 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9910 return Res;
9911}
9912
9913template <typename Derived>
9914StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
9915 OMPTargetSimdDirective *D) {
9916 DeclarationNameInfo DirName;
9917 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9918 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
9919 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9920 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9921 return Res;
9922}
9923
9924template <typename Derived>
9925StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
9926 OMPTeamsDistributeDirective *D) {
9927 DeclarationNameInfo DirName;
9928 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9929 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
9930 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9931 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9932 return Res;
9933}
9934
9935template <typename Derived>
9936StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
9937 OMPTeamsDistributeSimdDirective *D) {
9938 DeclarationNameInfo DirName;
9939 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9940 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9941 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9942 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9943 return Res;
9944}
9945
9946template <typename Derived>
9947StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
9948 OMPTeamsDistributeParallelForSimdDirective *D) {
9949 DeclarationNameInfo DirName;
9950 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9951 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
9952 D->getBeginLoc());
9953 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9954 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9955 return Res;
9956}
9957
9958template <typename Derived>
9959StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
9960 OMPTeamsDistributeParallelForDirective *D) {
9961 DeclarationNameInfo DirName;
9962 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9963 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9964 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9965 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9966 return Res;
9967}
9968
9969template <typename Derived>
9970StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
9971 OMPTargetTeamsDirective *D) {
9972 DeclarationNameInfo DirName;
9973 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9974 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
9975 auto Res = getDerived().TransformOMPExecutableDirective(D);
9976 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9977 return Res;
9978}
9979
9980template <typename Derived>
9981StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
9982 OMPTargetTeamsDistributeDirective *D) {
9983 DeclarationNameInfo DirName;
9984 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9985 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
9986 auto Res = getDerived().TransformOMPExecutableDirective(D);
9987 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9988 return Res;
9989}
9990
9991template <typename Derived>
9993TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
9994 OMPTargetTeamsDistributeParallelForDirective *D) {
9995 DeclarationNameInfo DirName;
9996 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9997 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
9998 D->getBeginLoc());
9999 auto Res = getDerived().TransformOMPExecutableDirective(D);
10000 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10001 return Res;
10002}
10003
10004template <typename Derived>
10005StmtResult TreeTransform<Derived>::
10006 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10007 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10008 DeclarationNameInfo DirName;
10009 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10010 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10011 D->getBeginLoc());
10012 auto Res = getDerived().TransformOMPExecutableDirective(D);
10013 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10014 return Res;
10015}
10016
10017template <typename Derived>
10019TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10020 OMPTargetTeamsDistributeSimdDirective *D) {
10021 DeclarationNameInfo DirName;
10022 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10023 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10024 auto Res = getDerived().TransformOMPExecutableDirective(D);
10025 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10026 return Res;
10027}
10028
10029template <typename Derived>
10031TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10032 DeclarationNameInfo DirName;
10033 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10034 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10035 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10036 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10037 return Res;
10038}
10039
10040template <typename Derived>
10042TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10043 DeclarationNameInfo DirName;
10044 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10045 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10046 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10047 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10048 return Res;
10049}
10050
10051template <typename Derived>
10053TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10054 DeclarationNameInfo DirName;
10055 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10056 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10057 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10058 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10059 return Res;
10060}
10061
10062template <typename Derived>
10063StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10064 OMPGenericLoopDirective *D) {
10065 DeclarationNameInfo DirName;
10066 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10067 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10068 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10069 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10070 return Res;
10071}
10072
10073template <typename Derived>
10074StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10075 OMPTeamsGenericLoopDirective *D) {
10076 DeclarationNameInfo DirName;
10077 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10078 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10079 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10080 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10081 return Res;
10082}
10083
10084template <typename Derived>
10085StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10086 OMPTargetTeamsGenericLoopDirective *D) {
10087 DeclarationNameInfo DirName;
10088 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10089 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10090 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10091 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10092 return Res;
10093}
10094
10095template <typename Derived>
10096StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10097 OMPParallelGenericLoopDirective *D) {
10098 DeclarationNameInfo DirName;
10099 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10100 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10101 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10102 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10103 return Res;
10104}
10105
10106template <typename Derived>
10108TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10109 OMPTargetParallelGenericLoopDirective *D) {
10110 DeclarationNameInfo DirName;
10111 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10112 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10113 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10114 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10115 return Res;
10116}
10117
10118//===----------------------------------------------------------------------===//
10119// OpenMP clause transformation
10120//===----------------------------------------------------------------------===//
10121template <typename Derived>
10122OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10123 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10124 if (Cond.isInvalid())
10125 return nullptr;
10126 return getDerived().RebuildOMPIfClause(
10127 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10128 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10129}
10130
10131template <typename Derived>
10132OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10133 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10134 if (Cond.isInvalid())
10135 return nullptr;
10136 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10137 C->getLParenLoc(), C->getEndLoc());
10138}
10139
10140template <typename Derived>
10141OMPClause *
10142TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10143 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10144 if (NumThreads.isInvalid())
10145 return nullptr;
10146 return getDerived().RebuildOMPNumThreadsClause(
10147 NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10148}
10149
10150template <typename Derived>
10151OMPClause *
10152TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10153 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10154 if (E.isInvalid())
10155 return nullptr;
10156 return getDerived().RebuildOMPSafelenClause(
10157 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10158}
10159
10160template <typename Derived>
10161OMPClause *
10162TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10163 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10164 if (E.isInvalid())
10165 return nullptr;
10166 return getDerived().RebuildOMPAllocatorClause(
10167 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10168}
10169
10170template <typename Derived>
10171OMPClause *
10172TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10173 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10174 if (E.isInvalid())
10175 return nullptr;
10176 return getDerived().RebuildOMPSimdlenClause(
10177 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10178}
10179
10180template <typename Derived>
10181OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10182 SmallVector<Expr *, 4> TransformedSizes;
10183 TransformedSizes.reserve(C->getNumSizes());
10184 bool Changed = false;
10185 for (Expr *E : C->getSizesRefs()) {
10186 if (!E) {
10187 TransformedSizes.push_back(nullptr);
10188 continue;
10189 }
10190
10191 ExprResult T = getDerived().TransformExpr(E);
10192 if (T.isInvalid())
10193 return nullptr;
10194 if (E != T.get())
10195 Changed = true;
10196 TransformedSizes.push_back(T.get());
10197 }
10198
10199 if (!Changed && !getDerived().AlwaysRebuild())
10200 return C;
10201 return RebuildOMPSizesClause(TransformedSizes, C->getBeginLoc(),
10202 C->getLParenLoc(), C->getEndLoc());
10203}
10204
10205template <typename Derived>
10206OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10207 if (!getDerived().AlwaysRebuild())
10208 return C;
10209 return RebuildOMPFullClause(C->getBeginLoc(), C->getEndLoc());
10210}
10211
10212template <typename Derived>
10213OMPClause *
10214TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10215 ExprResult T = getDerived().TransformExpr(C->getFactor());
10216 if (T.isInvalid())
10217 return nullptr;
10218 Expr *Factor = T.get();
10219 bool Changed = Factor != C->getFactor();
10220
10221 if (!Changed && !getDerived().AlwaysRebuild())
10222 return C;
10223 return RebuildOMPPartialClause(Factor, C->getBeginLoc(), C->getLParenLoc(),
10224 C->getEndLoc());
10225}
10226
10227template <typename Derived>
10228OMPClause *
10229TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10230 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10231 if (E.isInvalid())
10232 return nullptr;
10233 return getDerived().RebuildOMPCollapseClause(
10234 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10235}
10236
10237template <typename Derived>
10238OMPClause *
10239TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10240 return getDerived().RebuildOMPDefaultClause(
10241 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
10242 C->getLParenLoc(), C->getEndLoc());
10243}
10244
10245template <typename Derived>
10246OMPClause *
10247TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10248 return getDerived().RebuildOMPProcBindClause(
10249 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10250 C->getLParenLoc(), C->getEndLoc());
10251}
10252
10253template <typename Derived>
10254OMPClause *
10255TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10256 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10257 if (E.isInvalid())
10258 return nullptr;
10259 return getDerived().RebuildOMPScheduleClause(
10260 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10261 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10262 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10263 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10264}
10265
10266template <typename Derived>
10267OMPClause *
10268TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10269 ExprResult E;
10270 if (auto *Num = C->getNumForLoops()) {
10271 E = getDerived().TransformExpr(Num);
10272 if (E.isInvalid())
10273 return nullptr;
10274 }
10275 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10276 C->getLParenLoc(), E.get());
10277}
10278
10279template <typename Derived>
10280OMPClause *
10281TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10282 ExprResult E;
10283 if (Expr *Evt = C->getEventHandler()) {
10284 E = getDerived().TransformExpr(Evt);
10285 if (E.isInvalid())
10286 return nullptr;
10287 }
10288 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10289 C->getLParenLoc(), C->getEndLoc());
10290}
10291
10292template <typename Derived>
10293OMPClause *
10294TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10295 // No need to rebuild this clause, no template-dependent parameters.
10296 return C;
10297}
10298
10299template <typename Derived>
10300OMPClause *
10301TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10302 // No need to rebuild this clause, no template-dependent parameters.
10303 return C;
10304}
10305
10306template <typename Derived>
10307OMPClause *
10308TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10309 // No need to rebuild this clause, no template-dependent parameters.
10310 return C;
10311}
10312
10313template <typename Derived>
10314OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10315 // No need to rebuild this clause, no template-dependent parameters.
10316 return C;
10317}
10318
10319template <typename Derived>
10320OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10321 // No need to rebuild this clause, no template-dependent parameters.
10322 return C;
10323}
10324
10325template <typename Derived>
10326OMPClause *
10327TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10328 // No need to rebuild this clause, no template-dependent parameters.
10329 return C;
10330}
10331
10332template <typename Derived>
10333OMPClause *
10334TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10335 // No need to rebuild this clause, no template-dependent parameters.
10336 return C;
10337}
10338
10339template <typename Derived>
10340OMPClause *
10341TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10342 // No need to rebuild this clause, no template-dependent parameters.
10343 return C;
10344}
10345
10346template <typename Derived>
10347OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10348 // No need to rebuild this clause, no template-dependent parameters.
10349 return C;
10350}
10351
10352template <typename Derived>
10353OMPClause *
10354TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
10355 return C;
10356}
10357
10358template <typename Derived>
10359OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
10360 ExprResult E = getDerived().TransformExpr(C->getExpr());
10361 if (E.isInvalid())
10362 return nullptr;
10363 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
10364 C->getLParenLoc(), C->getEndLoc());
10365}
10366
10367template <typename Derived>
10368OMPClause *
10369TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
10370 return C;
10371}
10372
10373template <typename Derived>
10374OMPClause *
10375TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
10376 return C;
10377}
10378template <typename Derived>
10379OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
10380 OMPNoOpenMPRoutinesClause *C) {
10381 return C;
10382}
10383template <typename Derived>
10384OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
10385 OMPNoParallelismClause *C) {
10386 return C;
10387}
10388
10389template <typename Derived>
10390OMPClause *
10391TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10392 // No need to rebuild this clause, no template-dependent parameters.
10393 return C;
10394}
10395
10396template <typename Derived>
10397OMPClause *
10398TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10399 // No need to rebuild this clause, no template-dependent parameters.
10400 return C;
10401}
10402
10403template <typename Derived>
10404OMPClause *
10405TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10406 // No need to rebuild this clause, no template-dependent parameters.
10407 return C;
10408}
10409
10410template <typename Derived>
10411OMPClause *
10412TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10413 // No need to rebuild this clause, no template-dependent parameters.
10414 return C;
10415}
10416
10417template <typename Derived>
10418OMPClause *
10419TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10420 // No need to rebuild this clause, no template-dependent parameters.
10421 return C;
10422}
10423
10424template <typename Derived>
10425OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10426 // No need to rebuild this clause, no template-dependent parameters.
10427 return C;
10428}
10429
10430template <typename Derived>
10431OMPClause *
10432TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10433 // No need to rebuild this clause, no template-dependent parameters.
10434 return C;
10435}
10436
10437template <typename Derived>
10438OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10439 // No need to rebuild this clause, no template-dependent parameters.
10440 return C;
10441}
10442
10443template <typename Derived>
10444OMPClause *
10445TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10446 // No need to rebuild this clause, no template-dependent parameters.
10447 return C;
10448}
10449
10450template <typename Derived>
10451OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10452 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10453 if (IVR.isInvalid())
10454 return nullptr;
10455
10456 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10457 InteropInfo.PreferTypes.reserve(C->varlist_size() - 1);
10458 for (Expr *E : llvm::drop_begin(C->varlist())) {
10459 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
10460 if (ER.isInvalid())
10461 return nullptr;
10462 InteropInfo.PreferTypes.push_back(ER.get());
10463 }
10464 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10465 C->getBeginLoc(), C->getLParenLoc(),
10466 C->getVarLoc(), C->getEndLoc());
10467}
10468
10469template <typename Derived>
10470OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10471 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10472 if (ER.isInvalid())
10473 return nullptr;
10474 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10475 C->getLParenLoc(), C->getVarLoc(),
10476 C->getEndLoc());
10477}
10478
10479template <typename Derived>
10480OMPClause *
10481TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10482 ExprResult ER;
10483 if (Expr *IV = C->getInteropVar()) {
10484 ER = getDerived().TransformExpr(IV);
10485 if (ER.isInvalid())
10486 return nullptr;
10487 }
10488 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10489 C->getLParenLoc(), C->getVarLoc(),
10490 C->getEndLoc());
10491}
10492
10493template <typename Derived>
10494OMPClause *
10495TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10496 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10497 if (Cond.isInvalid())
10498 return nullptr;
10499 return getDerived().RebuildOMPNovariantsClause(
10500 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10501}
10502
10503template <typename Derived>
10504OMPClause *
10505TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
10506 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10507 if (Cond.isInvalid())
10508 return nullptr;
10509 return getDerived().RebuildOMPNocontextClause(
10510 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10511}
10512
10513template <typename Derived>
10514OMPClause *
10515TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
10516 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
10517 if (ThreadID.isInvalid())
10518 return nullptr;
10519 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10520 C->getLParenLoc(), C->getEndLoc());
10521}
10522
10523template <typename Derived>
10524OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10525 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10526 if (E.isInvalid())
10527 return nullptr;
10528 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10529 C->getLParenLoc(), C->getEndLoc());
10530}
10531
10532template <typename Derived>
10533OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10534 OMPUnifiedAddressClause *C) {
10535 llvm_unreachable("unified_address clause cannot appear in dependent context");
10536}
10537
10538template <typename Derived>
10539OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10540 OMPUnifiedSharedMemoryClause *C) {
10541 llvm_unreachable(
10542 "unified_shared_memory clause cannot appear in dependent context");
10543}
10544
10545template <typename Derived>
10546OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10547 OMPReverseOffloadClause *C) {
10548 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10549}
10550
10551template <typename Derived>
10552OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10553 OMPDynamicAllocatorsClause *C) {
10554 llvm_unreachable(
10555 "dynamic_allocators clause cannot appear in dependent context");
10556}
10557
10558template <typename Derived>
10559OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10560 OMPAtomicDefaultMemOrderClause *C) {
10561 llvm_unreachable(
10562 "atomic_default_mem_order clause cannot appear in dependent context");
10563}
10564
10565template <typename Derived>
10566OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10567 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10568 C->getBeginLoc(), C->getLParenLoc(),
10569 C->getEndLoc());
10570}
10571
10572template <typename Derived>
10573OMPClause *
10574TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10575 return getDerived().RebuildOMPSeverityClause(
10576 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10577 C->getLParenLoc(), C->getEndLoc());
10578}
10579
10580template <typename Derived>
10581OMPClause *
10582TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10583 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10584 if (E.isInvalid())
10585 return nullptr;
10586 return getDerived().RebuildOMPMessageClause(
10587 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10588 C->getEndLoc());
10589}
10590
10591template <typename Derived>
10592OMPClause *
10593TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10595 Vars.reserve(C->varlist_size());
10596 for (auto *VE : C->varlist()) {
10597 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10598 if (EVar.isInvalid())
10599 return nullptr;
10600 Vars.push_back(EVar.get());
10601 }
10602 return getDerived().RebuildOMPPrivateClause(
10603 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10604}
10605
10606template <typename Derived>
10607OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10608 OMPFirstprivateClause *C) {
10610 Vars.reserve(C->varlist_size());
10611 for (auto *VE : C->varlist()) {
10612 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10613 if (EVar.isInvalid())
10614 return nullptr;
10615 Vars.push_back(EVar.get());
10616 }
10617 return getDerived().RebuildOMPFirstprivateClause(
10618 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10619}
10620
10621template <typename Derived>
10622OMPClause *
10623TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10625 Vars.reserve(C->varlist_size());
10626 for (auto *VE : C->varlist()) {
10627 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10628 if (EVar.isInvalid())
10629 return nullptr;
10630 Vars.push_back(EVar.get());
10631 }
10632 return getDerived().RebuildOMPLastprivateClause(
10633 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10634 C->getLParenLoc(), C->getEndLoc());
10635}
10636
10637template <typename Derived>
10638OMPClause *
10639TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
10641 Vars.reserve(C->varlist_size());
10642 for (auto *VE : C->varlist()) {
10643 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10644 if (EVar.isInvalid())
10645 return nullptr;
10646 Vars.push_back(EVar.get());
10647 }
10648 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
10649 C->getLParenLoc(), C->getEndLoc());
10650}
10651
10652template <typename Derived>
10653OMPClause *
10654TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
10656 Vars.reserve(C->varlist_size());
10657 for (auto *VE : C->varlist()) {
10658 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10659 if (EVar.isInvalid())
10660 return nullptr;
10661 Vars.push_back(EVar.get());
10662 }
10663 CXXScopeSpec ReductionIdScopeSpec;
10664 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10665
10666 DeclarationNameInfo NameInfo = C->getNameInfo();
10667 if (NameInfo.getName()) {
10668 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10669 if (!NameInfo.getName())
10670 return nullptr;
10671 }
10672 // Build a list of all UDR decls with the same names ranged by the Scopes.
10673 // The Scope boundary is a duplication of the previous decl.
10674 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10675 for (auto *E : C->reduction_ops()) {
10676 // Transform all the decls.
10677 if (E) {
10678 auto *ULE = cast<UnresolvedLookupExpr>(E);
10679 UnresolvedSet<8> Decls;
10680 for (auto *D : ULE->decls()) {
10681 NamedDecl *InstD =
10682 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10683 Decls.addDecl(InstD, InstD->getAccess());
10684 }
10685 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10686 SemaRef.Context, /*NamingClass=*/nullptr,
10687 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10688 /*ADL=*/true, Decls.begin(), Decls.end(),
10689 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
10690 } else
10691 UnresolvedReductions.push_back(nullptr);
10692 }
10693 return getDerived().RebuildOMPReductionClause(
10694 Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(),
10695 C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
10696 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10697}
10698
10699template <typename Derived>
10700OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
10701 OMPTaskReductionClause *C) {
10703 Vars.reserve(C->varlist_size());
10704 for (auto *VE : C->varlist()) {
10705 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10706 if (EVar.isInvalid())
10707 return nullptr;
10708 Vars.push_back(EVar.get());
10709 }
10710 CXXScopeSpec ReductionIdScopeSpec;
10711 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10712
10713 DeclarationNameInfo NameInfo = C->getNameInfo();
10714 if (NameInfo.getName()) {
10715 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10716 if (!NameInfo.getName())
10717 return nullptr;
10718 }
10719 // Build a list of all UDR decls with the same names ranged by the Scopes.
10720 // The Scope boundary is a duplication of the previous decl.
10721 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10722 for (auto *E : C->reduction_ops()) {
10723 // Transform all the decls.
10724 if (E) {
10725 auto *ULE = cast<UnresolvedLookupExpr>(E);
10726 UnresolvedSet<8> Decls;
10727 for (auto *D : ULE->decls()) {
10728 NamedDecl *InstD =
10729 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10730 Decls.addDecl(InstD, InstD->getAccess());
10731 }
10732 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10733 SemaRef.Context, /*NamingClass=*/nullptr,
10734 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10735 /*ADL=*/true, Decls.begin(), Decls.end(),
10736 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
10737 } else
10738 UnresolvedReductions.push_back(nullptr);
10739 }
10740 return getDerived().RebuildOMPTaskReductionClause(
10741 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10742 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10743}
10744
10745template <typename Derived>
10746OMPClause *
10747TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
10749 Vars.reserve(C->varlist_size());
10750 for (auto *VE : C->varlist()) {
10751 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10752 if (EVar.isInvalid())
10753 return nullptr;
10754 Vars.push_back(EVar.get());
10755 }
10756 CXXScopeSpec ReductionIdScopeSpec;
10757 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10758
10759 DeclarationNameInfo NameInfo = C->getNameInfo();
10760 if (NameInfo.getName()) {
10761 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10762 if (!NameInfo.getName())
10763 return nullptr;
10764 }
10765 // Build a list of all UDR decls with the same names ranged by the Scopes.
10766 // The Scope boundary is a duplication of the previous decl.
10767 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10768 for (auto *E : C->reduction_ops()) {
10769 // Transform all the decls.
10770 if (E) {
10771 auto *ULE = cast<UnresolvedLookupExpr>(E);
10772 UnresolvedSet<8> Decls;
10773 for (auto *D : ULE->decls()) {
10774 NamedDecl *InstD =
10775 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10776 Decls.addDecl(InstD, InstD->getAccess());
10777 }
10778 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10779 SemaRef.Context, /*NamingClass=*/nullptr,
10780 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10781 /*ADL=*/true, Decls.begin(), Decls.end(),
10782 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
10783 } else
10784 UnresolvedReductions.push_back(nullptr);
10785 }
10786 return getDerived().RebuildOMPInReductionClause(
10787 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10788 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10789}
10790
10791template <typename Derived>
10792OMPClause *
10793TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
10795 Vars.reserve(C->varlist_size());
10796 for (auto *VE : C->varlist()) {
10797 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10798 if (EVar.isInvalid())
10799 return nullptr;
10800 Vars.push_back(EVar.get());
10801 }
10802 ExprResult Step = getDerived().TransformExpr(C->getStep());
10803 if (Step.isInvalid())
10804 return nullptr;
10805 return getDerived().RebuildOMPLinearClause(
10806 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
10807 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
10808 C->getEndLoc());
10809}
10810
10811template <typename Derived>
10812OMPClause *
10813TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
10815 Vars.reserve(C->varlist_size());
10816 for (auto *VE : C->varlist()) {
10817 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10818 if (EVar.isInvalid())
10819 return nullptr;
10820 Vars.push_back(EVar.get());
10821 }
10822 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
10823 if (Alignment.isInvalid())
10824 return nullptr;
10825 return getDerived().RebuildOMPAlignedClause(
10826 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
10827 C->getColonLoc(), C->getEndLoc());
10828}
10829
10830template <typename Derived>
10831OMPClause *
10832TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
10834 Vars.reserve(C->varlist_size());
10835 for (auto *VE : C->varlist()) {
10836 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10837 if (EVar.isInvalid())
10838 return nullptr;
10839 Vars.push_back(EVar.get());
10840 }
10841 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
10842 C->getLParenLoc(), C->getEndLoc());
10843}
10844
10845template <typename Derived>
10846OMPClause *
10847TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
10849 Vars.reserve(C->varlist_size());
10850 for (auto *VE : C->varlist()) {
10851 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10852 if (EVar.isInvalid())
10853 return nullptr;
10854 Vars.push_back(EVar.get());
10855 }
10856 return getDerived().RebuildOMPCopyprivateClause(
10857 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10858}
10859
10860template <typename Derived>
10861OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
10863 Vars.reserve(C->varlist_size());
10864 for (auto *VE : C->varlist()) {
10865 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10866 if (EVar.isInvalid())
10867 return nullptr;
10868 Vars.push_back(EVar.get());
10869 }
10870 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
10871 C->getLParenLoc(), C->getEndLoc());
10872}
10873
10874template <typename Derived>
10875OMPClause *
10876TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
10877 ExprResult E = getDerived().TransformExpr(C->getDepobj());
10878 if (E.isInvalid())
10879 return nullptr;
10880 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
10881 C->getLParenLoc(), C->getEndLoc());
10882}
10883
10884template <typename Derived>
10885OMPClause *
10886TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
10888 Expr *DepModifier = C->getModifier();
10889 if (DepModifier) {
10890 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
10891 if (DepModRes.isInvalid())
10892 return nullptr;
10893 DepModifier = DepModRes.get();
10894 }
10895 Vars.reserve(C->varlist_size());
10896 for (auto *VE : C->varlist()) {
10897 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10898 if (EVar.isInvalid())
10899 return nullptr;
10900 Vars.push_back(EVar.get());
10901 }
10902 return getDerived().RebuildOMPDependClause(
10903 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
10904 C->getOmpAllMemoryLoc()},
10905 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10906}
10907
10908template <typename Derived>
10909OMPClause *
10910TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
10911 ExprResult E = getDerived().TransformExpr(C->getDevice());
10912 if (E.isInvalid())
10913 return nullptr;
10914 return getDerived().RebuildOMPDeviceClause(
10915 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10916 C->getModifierLoc(), C->getEndLoc());
10917}
10918
10919template <typename Derived, class T>
10922 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
10923 DeclarationNameInfo &MapperIdInfo,
10924 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
10925 // Transform expressions in the list.
10926 Vars.reserve(C->varlist_size());
10927 for (auto *VE : C->varlist()) {
10928 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
10929 if (EVar.isInvalid())
10930 return true;
10931 Vars.push_back(EVar.get());
10932 }
10933 // Transform mapper scope specifier and identifier.
10934 NestedNameSpecifierLoc QualifierLoc;
10935 if (C->getMapperQualifierLoc()) {
10936 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
10937 C->getMapperQualifierLoc());
10938 if (!QualifierLoc)
10939 return true;
10940 }
10941 MapperIdScopeSpec.Adopt(QualifierLoc);
10942 MapperIdInfo = C->getMapperIdInfo();
10943 if (MapperIdInfo.getName()) {
10944 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
10945 if (!MapperIdInfo.getName())
10946 return true;
10947 }
10948 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
10949 // the previous user-defined mapper lookup in dependent environment.
10950 for (auto *E : C->mapperlists()) {
10951 // Transform all the decls.
10952 if (E) {
10953 auto *ULE = cast<UnresolvedLookupExpr>(E);
10954 UnresolvedSet<8> Decls;
10955 for (auto *D : ULE->decls()) {
10956 NamedDecl *InstD =
10957 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
10958 Decls.addDecl(InstD, InstD->getAccess());
10959 }
10960 UnresolvedMappers.push_back(UnresolvedLookupExpr::Create(
10961 TT.getSema().Context, /*NamingClass=*/nullptr,
10962 MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
10963 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
10964 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
10965 } else {
10966 UnresolvedMappers.push_back(nullptr);
10967 }
10968 }
10969 return false;
10970}
10971
10972template <typename Derived>
10973OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
10974 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10976 Expr *IteratorModifier = C->getIteratorModifier();
10977 if (IteratorModifier) {
10978 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
10979 if (MapModRes.isInvalid())
10980 return nullptr;
10981 IteratorModifier = MapModRes.get();
10982 }
10983 CXXScopeSpec MapperIdScopeSpec;
10984 DeclarationNameInfo MapperIdInfo;
10985 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10986 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
10987 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10988 return nullptr;
10989 return getDerived().RebuildOMPMapClause(
10990 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
10991 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
10992 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10993}
10994
10995template <typename Derived>
10996OMPClause *
10997TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
10998 Expr *Allocator = C->getAllocator();
10999 if (Allocator) {
11000 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11001 if (AllocatorRes.isInvalid())
11002 return nullptr;
11003 Allocator = AllocatorRes.get();
11004 }
11006 Vars.reserve(C->varlist_size());
11007 for (auto *VE : C->varlist()) {
11008 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11009 if (EVar.isInvalid())
11010 return nullptr;
11011 Vars.push_back(EVar.get());
11012 }
11013 return getDerived().RebuildOMPAllocateClause(
11014 Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11015 C->getEndLoc());
11016}
11017
11018template <typename Derived>
11019OMPClause *
11020TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11022 Vars.reserve(C->varlist_size());
11023 for (auto *VE : C->varlist()) {
11024 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11025 if (EVar.isInvalid())
11026 return nullptr;
11027 Vars.push_back(EVar.get());
11028 }
11029 return getDerived().RebuildOMPNumTeamsClause(
11030 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11031}
11032
11033template <typename Derived>
11034OMPClause *
11035TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
11037 Vars.reserve(C->varlist_size());
11038 for (auto *VE : C->varlist()) {
11039 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11040 if (EVar.isInvalid())
11041 return nullptr;
11042 Vars.push_back(EVar.get());
11043 }
11044 return getDerived().RebuildOMPThreadLimitClause(
11045 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11046}
11047
11048template <typename Derived>
11049OMPClause *
11050TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
11051 ExprResult E = getDerived().TransformExpr(C->getPriority());
11052 if (E.isInvalid())
11053 return nullptr;
11054 return getDerived().RebuildOMPPriorityClause(
11055 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11056}
11057
11058template <typename Derived>
11059OMPClause *
11060TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
11061 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
11062 if (E.isInvalid())
11063 return nullptr;
11064 return getDerived().RebuildOMPGrainsizeClause(
11065 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11066 C->getModifierLoc(), C->getEndLoc());
11067}
11068
11069template <typename Derived>
11070OMPClause *
11071TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
11072 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
11073 if (E.isInvalid())
11074 return nullptr;
11075 return getDerived().RebuildOMPNumTasksClause(
11076 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11077 C->getModifierLoc(), C->getEndLoc());
11078}
11079
11080template <typename Derived>
11081OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
11082 ExprResult E = getDerived().TransformExpr(C->getHint());
11083 if (E.isInvalid())
11084 return nullptr;
11085 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
11086 C->getLParenLoc(), C->getEndLoc());
11087}
11088
11089template <typename Derived>
11090OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
11091 OMPDistScheduleClause *C) {
11092 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11093 if (E.isInvalid())
11094 return nullptr;
11095 return getDerived().RebuildOMPDistScheduleClause(
11096 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11097 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11098}
11099
11100template <typename Derived>
11101OMPClause *
11102TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
11103 // Rebuild Defaultmap Clause since we need to invoke the checking of
11104 // defaultmap(none:variable-category) after template initialization.
11105 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
11106 C->getDefaultmapKind(),
11107 C->getBeginLoc(),
11108 C->getLParenLoc(),
11109 C->getDefaultmapModifierLoc(),
11110 C->getDefaultmapKindLoc(),
11111 C->getEndLoc());
11112}
11113
11114template <typename Derived>
11115OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
11116 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11118 CXXScopeSpec MapperIdScopeSpec;
11119 DeclarationNameInfo MapperIdInfo;
11120 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11121 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
11122 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11123 return nullptr;
11124 return getDerived().RebuildOMPToClause(
11125 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11126 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11127}
11128
11129template <typename Derived>
11130OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
11131 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11133 CXXScopeSpec MapperIdScopeSpec;
11134 DeclarationNameInfo MapperIdInfo;
11135 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11136 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
11137 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11138 return nullptr;
11139 return getDerived().RebuildOMPFromClause(
11140 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11141 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11142}
11143
11144template <typename Derived>
11145OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
11146 OMPUseDevicePtrClause *C) {
11148 Vars.reserve(C->varlist_size());
11149 for (auto *VE : C->varlist()) {
11150 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11151 if (EVar.isInvalid())
11152 return nullptr;
11153 Vars.push_back(EVar.get());
11154 }
11155 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11156 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
11157}
11158
11159template <typename Derived>
11160OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11161 OMPUseDeviceAddrClause *C) {
11163 Vars.reserve(C->varlist_size());
11164 for (auto *VE : C->varlist()) {
11165 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11166 if (EVar.isInvalid())
11167 return nullptr;
11168 Vars.push_back(EVar.get());
11169 }
11170 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11171 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11172}
11173
11174template <typename Derived>
11175OMPClause *
11176TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11178 Vars.reserve(C->varlist_size());
11179 for (auto *VE : C->varlist()) {
11180 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11181 if (EVar.isInvalid())
11182 return nullptr;
11183 Vars.push_back(EVar.get());
11184 }
11185 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11186 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
11187}
11188
11189template <typename Derived>
11190OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
11191 OMPHasDeviceAddrClause *C) {
11193 Vars.reserve(C->varlist_size());
11194 for (auto *VE : C->varlist()) {
11195 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11196 if (EVar.isInvalid())
11197 return nullptr;
11198 Vars.push_back(EVar.get());
11199 }
11200 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11201 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
11202}
11203
11204template <typename Derived>
11205OMPClause *
11206TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
11208 Vars.reserve(C->varlist_size());
11209 for (auto *VE : C->varlist()) {
11210 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11211 if (EVar.isInvalid())
11212 return nullptr;
11213 Vars.push_back(EVar.get());
11214 }
11215 return getDerived().RebuildOMPNontemporalClause(
11216 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11217}
11218
11219template <typename Derived>
11220OMPClause *
11221TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
11223 Vars.reserve(C->varlist_size());
11224 for (auto *VE : C->varlist()) {
11225 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11226 if (EVar.isInvalid())
11227 return nullptr;
11228 Vars.push_back(EVar.get());
11229 }
11230 return getDerived().RebuildOMPInclusiveClause(
11231 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11232}
11233
11234template <typename Derived>
11235OMPClause *
11236TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
11238 Vars.reserve(C->varlist_size());
11239 for (auto *VE : C->varlist()) {
11240 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11241 if (EVar.isInvalid())
11242 return nullptr;
11243 Vars.push_back(EVar.get());
11244 }
11245 return getDerived().RebuildOMPExclusiveClause(
11246 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11247}
11248
11249template <typename Derived>
11250OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11251 OMPUsesAllocatorsClause *C) {
11253 Data.reserve(C->getNumberOfAllocators());
11254 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11255 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11256 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11257 if (Allocator.isInvalid())
11258 continue;
11259 ExprResult AllocatorTraits;
11260 if (Expr *AT = D.AllocatorTraits) {
11261 AllocatorTraits = getDerived().TransformExpr(AT);
11262 if (AllocatorTraits.isInvalid())
11263 continue;
11264 }
11265 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11266 NewD.Allocator = Allocator.get();
11267 NewD.AllocatorTraits = AllocatorTraits.get();
11268 NewD.LParenLoc = D.LParenLoc;
11269 NewD.RParenLoc = D.RParenLoc;
11270 }
11271 return getDerived().RebuildOMPUsesAllocatorsClause(
11272 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11273}
11274
11275template <typename Derived>
11276OMPClause *
11277TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11278 SmallVector<Expr *, 4> Locators;
11279 Locators.reserve(C->varlist_size());
11280 ExprResult ModifierRes;
11281 if (Expr *Modifier = C->getModifier()) {
11282 ModifierRes = getDerived().TransformExpr(Modifier);
11283 if (ModifierRes.isInvalid())
11284 return nullptr;
11285 }
11286 for (Expr *E : C->varlist()) {
11287 ExprResult Locator = getDerived().TransformExpr(E);
11288 if (Locator.isInvalid())
11289 continue;
11290 Locators.push_back(Locator.get());
11291 }
11292 return getDerived().RebuildOMPAffinityClause(
11293 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11294 ModifierRes.get(), Locators);
11295}
11296
11297template <typename Derived>
11298OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11299 return getDerived().RebuildOMPOrderClause(
11300 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11301 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11302}
11303
11304template <typename Derived>
11305OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11306 return getDerived().RebuildOMPBindClause(
11307 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11308 C->getLParenLoc(), C->getEndLoc());
11309}
11310
11311template <typename Derived>
11312OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11313 OMPXDynCGroupMemClause *C) {
11314 ExprResult Size = getDerived().TransformExpr(C->getSize());
11315 if (Size.isInvalid())
11316 return nullptr;
11317 return getDerived().RebuildOMPXDynCGroupMemClause(
11318 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11319}
11320
11321template <typename Derived>
11322OMPClause *
11323TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11325 Vars.reserve(C->varlist_size());
11326 for (auto *VE : C->varlist()) {
11327 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11328 if (EVar.isInvalid())
11329 return nullptr;
11330 Vars.push_back(EVar.get());
11331 }
11332 return getDerived().RebuildOMPDoacrossClause(
11333 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11334 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11335}
11336
11337template <typename Derived>
11338OMPClause *
11339TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11341 for (auto *A : C->getAttrs())
11342 NewAttrs.push_back(getDerived().TransformAttr(A));
11343 return getDerived().RebuildOMPXAttributeClause(
11344 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11345}
11346
11347template <typename Derived>
11348OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11349 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11350}
11351
11352//===----------------------------------------------------------------------===//
11353// OpenACC transformation
11354//===----------------------------------------------------------------------===//
11355namespace {
11356template <typename Derived>
11357class OpenACCClauseTransform final
11358 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11359 TreeTransform<Derived> &Self;
11360 ArrayRef<const OpenACCClause *> ExistingClauses;
11361 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11362 OpenACCClause *NewClause = nullptr;
11363
11364 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11365 llvm::SmallVector<Expr *> InstantiatedVarList;
11366 for (Expr *CurVar : VarList) {
11367 ExprResult Res = Self.TransformExpr(CurVar);
11368
11369 if (!Res.isUsable())
11370 continue;
11371
11372 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getClauseKind(),
11373 Res.get());
11374
11375 if (Res.isUsable())
11376 InstantiatedVarList.push_back(Res.get());
11377 }
11378
11379 return InstantiatedVarList;
11380 }
11381
11382public:
11383 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11384 ArrayRef<const OpenACCClause *> ExistingClauses,
11385 SemaOpenACC::OpenACCParsedClause &PC)
11386 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
11387
11388 OpenACCClause *CreatedClause() const { return NewClause; }
11389
11390#define VISIT_CLAUSE(CLAUSE_NAME) \
11391 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11392#include "clang/Basic/OpenACCClauses.def"
11393};
11394
11395template <typename Derived>
11396void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11397 const OpenACCDefaultClause &C) {
11398 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11399
11400 NewClause = OpenACCDefaultClause::Create(
11401 Self.getSema().getASTContext(), ParsedClause.getDefaultClauseKind(),
11402 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11403 ParsedClause.getEndLoc());
11404}
11405
11406template <typename Derived>
11407void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11408 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11409 assert(Cond && "If constructed with invalid Condition");
11410 Sema::ConditionResult Res = Self.TransformCondition(
11411 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11412
11413 if (Res.isInvalid() || !Res.get().second)
11414 return;
11415
11416 ParsedClause.setConditionDetails(Res.get().second);
11417
11418 NewClause = OpenACCIfClause::Create(
11419 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11420 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11421 ParsedClause.getEndLoc());
11422}
11423
11424template <typename Derived>
11425void OpenACCClauseTransform<Derived>::VisitSelfClause(
11426 const OpenACCSelfClause &C) {
11427
11428 if (C.hasConditionExpr()) {
11429 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11430 Sema::ConditionResult Res =
11431 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
11433
11434 if (Res.isInvalid() || !Res.get().second)
11435 return;
11436
11437 ParsedClause.setConditionDetails(Res.get().second);
11438 }
11439
11440 NewClause = OpenACCSelfClause::Create(
11441 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11442 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11443 ParsedClause.getEndLoc());
11444}
11445
11446template <typename Derived>
11447void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
11448 const OpenACCNumGangsClause &C) {
11449 llvm::SmallVector<Expr *> InstantiatedIntExprs;
11450
11451 for (Expr *CurIntExpr : C.getIntExprs()) {
11452 ExprResult Res = Self.TransformExpr(CurIntExpr);
11453
11454 if (!Res.isUsable())
11455 return;
11456
11457 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11458 C.getClauseKind(),
11459 C.getBeginLoc(), Res.get());
11460 if (!Res.isUsable())
11461 return;
11462
11463 InstantiatedIntExprs.push_back(Res.get());
11464 }
11465
11466 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
11468 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11469 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs(),
11470 ParsedClause.getEndLoc());
11471}
11472
11473template <typename Derived>
11474void OpenACCClauseTransform<Derived>::VisitPrivateClause(
11475 const OpenACCPrivateClause &C) {
11476 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11477 /*IsReadOnly=*/false, /*IsZero=*/false);
11478
11479 NewClause = OpenACCPrivateClause::Create(
11480 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11481 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11482 ParsedClause.getEndLoc());
11483}
11484
11485template <typename Derived>
11486void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
11487 const OpenACCFirstPrivateClause &C) {
11488 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11489 /*IsReadOnly=*/false, /*IsZero=*/false);
11490
11492 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11493 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11494 ParsedClause.getEndLoc());
11495}
11496
11497template <typename Derived>
11498void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
11499 const OpenACCNoCreateClause &C) {
11500 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11501 /*IsReadOnly=*/false, /*IsZero=*/false);
11502
11504 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11505 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11506 ParsedClause.getEndLoc());
11507}
11508
11509template <typename Derived>
11510void OpenACCClauseTransform<Derived>::VisitPresentClause(
11511 const OpenACCPresentClause &C) {
11512 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11513 /*IsReadOnly=*/false, /*IsZero=*/false);
11514
11515 NewClause = OpenACCPresentClause::Create(
11516 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11517 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11518 ParsedClause.getEndLoc());
11519}
11520
11521template <typename Derived>
11522void OpenACCClauseTransform<Derived>::VisitCopyClause(
11523 const OpenACCCopyClause &C) {
11524 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11525 /*IsReadOnly=*/false, /*IsZero=*/false);
11526
11527 NewClause = OpenACCCopyClause::Create(
11528 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11529 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11530 ParsedClause.getVarList(), ParsedClause.getEndLoc());
11531}
11532
11533template <typename Derived>
11534void OpenACCClauseTransform<Derived>::VisitCopyInClause(
11535 const OpenACCCopyInClause &C) {
11536 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()), C.isReadOnly(),
11537 /*IsZero=*/false);
11538
11539 NewClause = OpenACCCopyInClause::Create(
11540 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11541 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11542 ParsedClause.isReadOnly(), ParsedClause.getVarList(),
11543 ParsedClause.getEndLoc());
11544}
11545
11546template <typename Derived>
11547void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
11548 const OpenACCCopyOutClause &C) {
11549 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11550 /*IsReadOnly=*/false, C.isZero());
11551
11552 NewClause = OpenACCCopyOutClause::Create(
11553 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11554 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11555 ParsedClause.isZero(), ParsedClause.getVarList(),
11556 ParsedClause.getEndLoc());
11557}
11558
11559template <typename Derived>
11560void OpenACCClauseTransform<Derived>::VisitCreateClause(
11561 const OpenACCCreateClause &C) {
11562 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11563 /*IsReadOnly=*/false, C.isZero());
11564
11565 NewClause = OpenACCCreateClause::Create(
11566 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11567 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11568 ParsedClause.isZero(), ParsedClause.getVarList(),
11569 ParsedClause.getEndLoc());
11570}
11571template <typename Derived>
11572void OpenACCClauseTransform<Derived>::VisitAttachClause(
11573 const OpenACCAttachClause &C) {
11574 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
11575
11576 // Ensure each var is a pointer type.
11577 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
11578 return Self.getSema().OpenACC().CheckVarIsPointerType(
11579 OpenACCClauseKind::Attach, E);
11580 }), VarList.end());
11581
11582 ParsedClause.setVarListDetails(VarList,
11583 /*IsReadOnly=*/false, /*IsZero=*/false);
11584 NewClause = OpenACCAttachClause::Create(
11585 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11586 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11587 ParsedClause.getEndLoc());
11588}
11589
11590template <typename Derived>
11591void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
11592 const OpenACCDevicePtrClause &C) {
11593 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
11594
11595 // Ensure each var is a pointer type.
11596 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
11597 return Self.getSema().OpenACC().CheckVarIsPointerType(
11598 OpenACCClauseKind::DevicePtr, E);
11599 }), VarList.end());
11600
11601 ParsedClause.setVarListDetails(VarList,
11602 /*IsReadOnly=*/false, /*IsZero=*/false);
11604 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11605 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11606 ParsedClause.getEndLoc());
11607}
11608
11609template <typename Derived>
11610void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
11611 const OpenACCNumWorkersClause &C) {
11612 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11613 assert(IntExpr && "num_workers clause constructed with invalid int expr");
11614
11615 ExprResult Res = Self.TransformExpr(IntExpr);
11616 if (!Res.isUsable())
11617 return;
11618
11619 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11620 C.getClauseKind(),
11621 C.getBeginLoc(), Res.get());
11622 if (!Res.isUsable())
11623 return;
11624
11625 ParsedClause.setIntExprDetails(Res.get());
11627 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11628 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
11629 ParsedClause.getEndLoc());
11630}
11631
11632template <typename Derived>
11633void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
11634 const OpenACCVectorLengthClause &C) {
11635 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11636 assert(IntExpr && "vector_length clause constructed with invalid int expr");
11637
11638 ExprResult Res = Self.TransformExpr(IntExpr);
11639 if (!Res.isUsable())
11640 return;
11641
11642 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11643 C.getClauseKind(),
11644 C.getBeginLoc(), Res.get());
11645 if (!Res.isUsable())
11646 return;
11647
11648 ParsedClause.setIntExprDetails(Res.get());
11650 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11651 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
11652 ParsedClause.getEndLoc());
11653}
11654
11655template <typename Derived>
11656void OpenACCClauseTransform<Derived>::VisitAsyncClause(
11657 const OpenACCAsyncClause &C) {
11658 if (C.hasIntExpr()) {
11659 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
11660 if (!Res.isUsable())
11661 return;
11662
11663 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11664 C.getClauseKind(),
11665 C.getBeginLoc(), Res.get());
11666 if (!Res.isUsable())
11667 return;
11668 ParsedClause.setIntExprDetails(Res.get());
11669 }
11670
11671 NewClause = OpenACCAsyncClause::Create(
11672 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11673 ParsedClause.getLParenLoc(),
11674 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
11675 : nullptr,
11676 ParsedClause.getEndLoc());
11677}
11678template <typename Derived>
11679void OpenACCClauseTransform<Derived>::VisitWaitClause(
11680 const OpenACCWaitClause &C) {
11681 if (!C.getLParenLoc().isInvalid()) {
11682 Expr *DevNumExpr = nullptr;
11683 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
11684
11685 // Instantiate devnum expr if it exists.
11686 if (C.getDevNumExpr()) {
11687 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
11688 if (!Res.isUsable())
11689 return;
11690 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11691 C.getClauseKind(),
11692 C.getBeginLoc(), Res.get());
11693 if (!Res.isUsable())
11694 return;
11695
11696 DevNumExpr = Res.get();
11697 }
11698
11699 // Instantiate queue ids.
11700 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
11701 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
11702 if (!Res.isUsable())
11703 return;
11704 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11705 C.getClauseKind(),
11706 C.getBeginLoc(), Res.get());
11707 if (!Res.isUsable())
11708 return;
11709
11710 InstantiatedQueueIdExprs.push_back(Res.get());
11711 }
11712
11713 ParsedClause.setWaitDetails(DevNumExpr, C.getQueuesLoc(),
11714 std::move(InstantiatedQueueIdExprs));
11715 }
11716
11717 NewClause = OpenACCWaitClause::Create(
11718 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11719 ParsedClause.getLParenLoc(), ParsedClause.getDevNumExpr(),
11720 ParsedClause.getQueuesLoc(), ParsedClause.getQueueIdExprs(),
11721 ParsedClause.getEndLoc());
11722}
11723
11724template <typename Derived>
11725void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
11726 const OpenACCDeviceTypeClause &C) {
11727 // Nothing to transform here, just create a new version of 'C'.
11729 Self.getSema().getASTContext(), C.getClauseKind(),
11730 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11731 C.getArchitectures(), ParsedClause.getEndLoc());
11732}
11733
11734template <typename Derived>
11735void OpenACCClauseTransform<Derived>::VisitAutoClause(
11736 const OpenACCAutoClause &C) {
11737 // Nothing to do, so just create a new node.
11738 NewClause = OpenACCAutoClause::Create(Self.getSema().getASTContext(),
11739 ParsedClause.getBeginLoc(),
11740 ParsedClause.getEndLoc());
11741}
11742
11743template <typename Derived>
11744void OpenACCClauseTransform<Derived>::VisitIndependentClause(
11745 const OpenACCIndependentClause &C) {
11746 NewClause = OpenACCIndependentClause::Create(Self.getSema().getASTContext(),
11747 ParsedClause.getBeginLoc(),
11748 ParsedClause.getEndLoc());
11749}
11750
11751template <typename Derived>
11752void OpenACCClauseTransform<Derived>::VisitSeqClause(
11753 const OpenACCSeqClause &C) {
11754 NewClause = OpenACCSeqClause::Create(Self.getSema().getASTContext(),
11755 ParsedClause.getBeginLoc(),
11756 ParsedClause.getEndLoc());
11757}
11758
11759template <typename Derived>
11760void OpenACCClauseTransform<Derived>::VisitReductionClause(
11761 const OpenACCReductionClause &C) {
11762 SmallVector<Expr *> TransformedVars = VisitVarList(C.getVarList());
11763 SmallVector<Expr *> ValidVars;
11764
11765 for (Expr *Var : TransformedVars) {
11766 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(Var);
11767 if (Res.isUsable())
11768 ValidVars.push_back(Res.get());
11769 }
11770
11772 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11773 ParsedClause.getLParenLoc(), C.getReductionOp(), ValidVars,
11774 ParsedClause.getEndLoc());
11775}
11776} // namespace
11777template <typename Derived>
11778OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
11779 ArrayRef<const OpenACCClause *> ExistingClauses,
11780 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
11781
11782 SemaOpenACC::OpenACCParsedClause ParsedClause(
11783 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
11784 ParsedClause.setEndLoc(OldClause->getEndLoc());
11785
11786 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(OldClause))
11787 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
11788
11789 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
11790 ParsedClause};
11791 Transform.Visit(OldClause);
11792
11793 return Transform.CreatedClause();
11794}
11795
11796template <typename Derived>
11798TreeTransform<Derived>::TransformOpenACCClauseList(
11800 llvm::SmallVector<OpenACCClause *> TransformedClauses;
11801 for (const auto *Clause : OldClauses) {
11802 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
11803 TransformedClauses, DirKind, Clause))
11804 TransformedClauses.push_back(TransformedClause);
11805 }
11806 return TransformedClauses;
11807}
11808
11809template <typename Derived>
11810StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
11811 OpenACCComputeConstruct *C) {
11812 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
11813
11814 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
11815 C->getBeginLoc()))
11816 return StmtError();
11817
11818 llvm::SmallVector<OpenACCClause *> TransformedClauses =
11819 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
11820 C->clauses());
11821 // Transform Structured Block.
11822 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(getSema().OpenACC(),
11823 C->getDirectiveKind());
11824 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
11825 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
11826 C->getBeginLoc(), C->getDirectiveKind(), StrBlock);
11827
11828 return getDerived().RebuildOpenACCComputeConstruct(
11829 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
11830 C->getEndLoc(), TransformedClauses, StrBlock);
11831}
11832
11833template <typename Derived>
11835TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
11836
11837 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
11838
11839 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
11840 C->getBeginLoc()))
11841 return StmtError();
11842
11843 llvm::SmallVector<OpenACCClause *> TransformedClauses =
11844 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
11845 C->clauses());
11846
11847 // Transform Loop.
11848 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(getSema().OpenACC(),
11849 C->getDirectiveKind());
11850 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
11851 Loop = getSema().OpenACC().ActOnAssociatedStmt(C->getBeginLoc(),
11852 C->getDirectiveKind(), Loop);
11853
11854 return getDerived().RebuildOpenACCLoopConstruct(
11855 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
11856 TransformedClauses, Loop);
11857}
11858
11859//===----------------------------------------------------------------------===//
11860// Expression transformation
11861//===----------------------------------------------------------------------===//
11862template<typename Derived>
11864TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
11865 return TransformExpr(E->getSubExpr());
11866}
11867
11868template <typename Derived>
11869ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
11870 SYCLUniqueStableNameExpr *E) {
11871 if (!E->isTypeDependent())
11872 return E;
11873
11874 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
11875
11876 if (!NewT)
11877 return ExprError();
11878
11879 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
11880 return E;
11881
11882 return getDerived().RebuildSYCLUniqueStableNameExpr(
11883 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
11884}
11885
11886template<typename Derived>
11888TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
11889 if (!E->isTypeDependent())
11890 return E;
11891
11892 return getDerived().RebuildPredefinedExpr(E->getLocation(),
11893 E->getIdentKind());
11894}
11895
11896template<typename Derived>
11898TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
11899 NestedNameSpecifierLoc QualifierLoc;
11900 if (E->getQualifierLoc()) {
11901 QualifierLoc
11902 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
11903 if (!QualifierLoc)
11904 return ExprError();
11905 }
11906
11907 ValueDecl *ND
11908 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
11909 E->getDecl()));
11910 if (!ND)
11911 return ExprError();
11912
11913 NamedDecl *Found = ND;
11914 if (E->getFoundDecl() != E->getDecl()) {
11915 Found = cast_or_null<NamedDecl>(
11916 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
11917 if (!Found)
11918 return ExprError();
11919 }
11920
11921 DeclarationNameInfo NameInfo = E->getNameInfo();
11922 if (NameInfo.getName()) {
11923 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11924 if (!NameInfo.getName())
11925 return ExprError();
11926 }
11927
11928 if (!getDerived().AlwaysRebuild() &&
11929 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
11930 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
11931 Found == E->getFoundDecl() &&
11932 NameInfo.getName() == E->getDecl()->getDeclName() &&
11933 !E->hasExplicitTemplateArgs()) {
11934
11935 // Mark it referenced in the new context regardless.
11936 // FIXME: this is a bit instantiation-specific.
11937 SemaRef.MarkDeclRefReferenced(E);
11938
11939 return E;
11940 }
11941
11942 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
11943 if (E->hasExplicitTemplateArgs()) {
11944 TemplateArgs = &TransArgs;
11945 TransArgs.setLAngleLoc(E->getLAngleLoc());
11946 TransArgs.setRAngleLoc(E->getRAngleLoc());
11947 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
11948 E->getNumTemplateArgs(),
11949 TransArgs))
11950 return ExprError();
11951 }
11952
11953 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
11954 Found, TemplateArgs);
11955}
11956
11957template<typename Derived>
11959TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
11960 return E;
11961}
11962
11963template <typename Derived>
11964ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
11965 FixedPointLiteral *E) {
11966 return E;
11967}
11968
11969template<typename Derived>
11971TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
11972 return E;
11973}
11974
11975template<typename Derived>
11977TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
11978 return E;
11979}
11980
11981template<typename Derived>
11983TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
11984 return E;
11985}
11986
11987template<typename Derived>
11989TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
11990 return E;
11991}
11992
11993template<typename Derived>
11995TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
11996 return getDerived().TransformCallExpr(E);
11997}
11998
11999template<typename Derived>
12001TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
12002 ExprResult ControllingExpr;
12003 TypeSourceInfo *ControllingType = nullptr;
12004 if (E->isExprPredicate())
12005 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
12006 else
12007 ControllingType = getDerived().TransformType(E->getControllingType());
12008
12009 if (ControllingExpr.isInvalid() && !ControllingType)
12010 return ExprError();
12011
12012 SmallVector<Expr *, 4> AssocExprs;
12014 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
12015 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
12016 if (TSI) {
12017 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
12018 if (!AssocType)
12019 return ExprError();
12020 AssocTypes.push_back(AssocType);
12021 } else {
12022 AssocTypes.push_back(nullptr);
12023 }
12024
12025 ExprResult AssocExpr =
12026 getDerived().TransformExpr(Assoc.getAssociationExpr());
12027 if (AssocExpr.isInvalid())
12028 return ExprError();
12029 AssocExprs.push_back(AssocExpr.get());
12030 }
12031
12032 if (!ControllingType)
12033 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
12034 E->getDefaultLoc(),
12035 E->getRParenLoc(),
12036 ControllingExpr.get(),
12037 AssocTypes,
12038 AssocExprs);
12039 return getDerived().RebuildGenericSelectionExpr(
12040 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
12041 ControllingType, AssocTypes, AssocExprs);
12042}
12043
12044template<typename Derived>
12046TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
12047 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12048 if (SubExpr.isInvalid())
12049 return ExprError();
12050
12051 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
12052 return E;
12053
12054 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
12055 E->getRParen());
12056}
12057
12058/// The operand of a unary address-of operator has special rules: it's
12059/// allowed to refer to a non-static member of a class even if there's no 'this'
12060/// object available.
12061template<typename Derived>
12064 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
12065 return getDerived().TransformDependentScopeDeclRefExpr(
12066 DRE, /*IsAddressOfOperand=*/true, nullptr);
12067 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E))
12068 return getDerived().TransformUnresolvedLookupExpr(
12069 ULE, /*IsAddressOfOperand=*/true);
12070 else
12071 return getDerived().TransformExpr(E);
12072}
12073
12074template<typename Derived>
12077 ExprResult SubExpr;
12078 if (E->getOpcode() == UO_AddrOf)
12079 SubExpr = TransformAddressOfOperand(E->getSubExpr());
12080 else
12081 SubExpr = TransformExpr(E->getSubExpr());
12082 if (SubExpr.isInvalid())
12083 return ExprError();
12084
12085 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
12086 return E;
12087
12088 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
12089 E->getOpcode(),
12090 SubExpr.get());
12091}
12092
12093template<typename Derived>
12095TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
12096 // Transform the type.
12097 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
12098 if (!Type)
12099 return ExprError();
12100
12101 // Transform all of the components into components similar to what the
12102 // parser uses.
12103 // FIXME: It would be slightly more efficient in the non-dependent case to
12104 // just map FieldDecls, rather than requiring the rebuilder to look for
12105 // the fields again. However, __builtin_offsetof is rare enough in
12106 // template code that we don't care.
12107 bool ExprChanged = false;
12108 typedef Sema::OffsetOfComponent Component;
12109 SmallVector<Component, 4> Components;
12110 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
12111 const OffsetOfNode &ON = E->getComponent(I);
12112 Component Comp;
12113 Comp.isBrackets = true;
12114 Comp.LocStart = ON.getSourceRange().getBegin();
12115 Comp.LocEnd = ON.getSourceRange().getEnd();
12116 switch (ON.getKind()) {
12117 case OffsetOfNode::Array: {
12118 Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
12119 ExprResult Index = getDerived().TransformExpr(FromIndex);
12120 if (Index.isInvalid())
12121 return ExprError();
12122
12123 ExprChanged = ExprChanged || Index.get() != FromIndex;
12124 Comp.isBrackets = true;
12125 Comp.U.E = Index.get();
12126 break;
12127 }
12128
12131 Comp.isBrackets = false;
12132 Comp.U.IdentInfo = ON.getFieldName();
12133 if (!Comp.U.IdentInfo)
12134 continue;
12135
12136 break;
12137
12138 case OffsetOfNode::Base:
12139 // Will be recomputed during the rebuild.
12140 continue;
12141 }
12142
12143 Components.push_back(Comp);
12144 }
12145
12146 // If nothing changed, retain the existing expression.
12147 if (!getDerived().AlwaysRebuild() &&
12148 Type == E->getTypeSourceInfo() &&
12149 !ExprChanged)
12150 return E;
12151
12152 // Build a new offsetof expression.
12153 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
12154 Components, E->getRParenLoc());
12155}
12156
12157template<typename Derived>
12159TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
12160 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
12161 "opaque value expression requires transformation");
12162 return E;
12163}
12164
12165template<typename Derived>
12167TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
12168 return E;
12169}
12170
12171template <typename Derived>
12172ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
12174 bool Changed = false;
12175 for (Expr *C : E->subExpressions()) {
12176 ExprResult NewC = getDerived().TransformExpr(C);
12177 if (NewC.isInvalid())
12178 return ExprError();
12179 Children.push_back(NewC.get());
12180
12181 Changed |= NewC.get() != C;
12182 }
12183 if (!getDerived().AlwaysRebuild() && !Changed)
12184 return E;
12185 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
12186 Children, E->getType());
12187}
12188
12189template<typename Derived>
12191TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
12192 // Rebuild the syntactic form. The original syntactic form has
12193 // opaque-value expressions in it, so strip those away and rebuild
12194 // the result. This is a really awful way of doing this, but the
12195 // better solution (rebuilding the semantic expressions and
12196 // rebinding OVEs as necessary) doesn't work; we'd need
12197 // TreeTransform to not strip away implicit conversions.
12198 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
12199 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
12200 if (result.isInvalid()) return ExprError();
12201
12202 // If that gives us a pseudo-object result back, the pseudo-object
12203 // expression must have been an lvalue-to-rvalue conversion which we
12204 // should reapply.
12205 if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
12206 result = SemaRef.PseudoObject().checkRValue(result.get());
12207
12208 return result;
12209}
12210
12211template<typename Derived>
12213TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
12214 UnaryExprOrTypeTraitExpr *E) {
12215 if (E->isArgumentType()) {
12216 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
12217
12218 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
12219 if (!NewT)
12220 return ExprError();
12221
12222 if (!getDerived().AlwaysRebuild() && OldT == NewT)
12223 return E;
12224
12225 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
12226 E->getKind(),
12227 E->getSourceRange());
12228 }
12229
12230 // C++0x [expr.sizeof]p1:
12231 // The operand is either an expression, which is an unevaluated operand
12232 // [...]
12233 EnterExpressionEvaluationContext Unevaluated(
12236
12237 // Try to recover if we have something like sizeof(T::X) where X is a type.
12238 // Notably, there must be *exactly* one set of parens if X is a type.
12239 TypeSourceInfo *RecoveryTSI = nullptr;
12240 ExprResult SubExpr;
12241 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
12242 if (auto *DRE =
12243 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
12244 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
12245 PE, DRE, false, &RecoveryTSI);
12246 else
12247 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
12248
12249 if (RecoveryTSI) {
12250 return getDerived().RebuildUnaryExprOrTypeTrait(
12251 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
12252 } else if (SubExpr.isInvalid())
12253 return ExprError();
12254
12255 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
12256 return E;
12257
12258 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
12259 E->getOperatorLoc(),
12260 E->getKind(),
12261 E->getSourceRange());
12262}
12263
12264template<typename Derived>
12266TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
12267 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12268 if (LHS.isInvalid())
12269 return ExprError();
12270
12271 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
12272 if (RHS.isInvalid())
12273 return ExprError();
12274
12275
12276 if (!getDerived().AlwaysRebuild() &&
12277 LHS.get() == E->getLHS() &&
12278 RHS.get() == E->getRHS())
12279 return E;
12280
12281 return getDerived().RebuildArraySubscriptExpr(
12282 LHS.get(),
12283 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
12284}
12285
12286template <typename Derived>
12288TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
12289 ExprResult Base = getDerived().TransformExpr(E->getBase());
12290 if (Base.isInvalid())
12291 return ExprError();
12292
12293 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
12294 if (RowIdx.isInvalid())
12295 return ExprError();
12296
12297 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
12298 if (ColumnIdx.isInvalid())
12299 return ExprError();
12300
12301 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
12302 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
12303 return E;
12304
12305 return getDerived().RebuildMatrixSubscriptExpr(
12306 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
12307}
12308
12309template <typename Derived>
12311TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
12312 ExprResult Base = getDerived().TransformExpr(E->getBase());
12313 if (Base.isInvalid())
12314 return ExprError();
12315
12316 ExprResult LowerBound;
12317 if (E->getLowerBound()) {
12318 LowerBound = getDerived().TransformExpr(E->getLowerBound());
12319 if (LowerBound.isInvalid())
12320 return ExprError();
12321 }
12322
12323 ExprResult Length;
12324 if (E->getLength()) {
12325 Length = getDerived().TransformExpr(E->getLength());
12326 if (Length.isInvalid())
12327 return ExprError();
12328 }
12329
12330 ExprResult Stride;
12331 if (E->isOMPArraySection()) {
12332 if (Expr *Str = E->getStride()) {
12333 Stride = getDerived().TransformExpr(Str);
12334 if (Stride.isInvalid())
12335 return ExprError();
12336 }
12337 }
12338
12339 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
12340 LowerBound.get() == E->getLowerBound() &&
12341 Length.get() == E->getLength() &&
12342 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
12343 return E;
12344
12345 return getDerived().RebuildArraySectionExpr(
12346 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
12347 LowerBound.get(), E->getColonLocFirst(),
12348 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
12349 Length.get(), Stride.get(), E->getRBracketLoc());
12350}
12351
12352template <typename Derived>
12354TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
12355 ExprResult Base = getDerived().TransformExpr(E->getBase());
12356 if (Base.isInvalid())
12357 return ExprError();
12358
12360 bool ErrorFound = false;
12361 for (Expr *Dim : E->getDimensions()) {
12362 ExprResult DimRes = getDerived().TransformExpr(Dim);
12363 if (DimRes.isInvalid()) {
12364 ErrorFound = true;
12365 continue;
12366 }
12367 Dims.push_back(DimRes.get());
12368 }
12369
12370 if (ErrorFound)
12371 return ExprError();
12372 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
12373 E->getRParenLoc(), Dims,
12374 E->getBracketsRanges());
12375}
12376
12377template <typename Derived>
12379TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
12380 unsigned NumIterators = E->numOfIterators();
12382
12383 bool ErrorFound = false;
12384 bool NeedToRebuild = getDerived().AlwaysRebuild();
12385 for (unsigned I = 0; I < NumIterators; ++I) {
12386 auto *D = cast<VarDecl>(E->getIteratorDecl(I));
12387 Data[I].DeclIdent = D->getIdentifier();
12388 Data[I].DeclIdentLoc = D->getLocation();
12389 if (D->getLocation() == D->getBeginLoc()) {
12390 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
12391 "Implicit type must be int.");
12392 } else {
12393 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
12394 QualType DeclTy = getDerived().TransformType(D->getType());
12395 Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI);
12396 }
12397 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
12398 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
12399 ExprResult End = getDerived().TransformExpr(Range.End);
12400 ExprResult Step = getDerived().TransformExpr(Range.Step);
12401 ErrorFound = ErrorFound ||
12402 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
12403 !Data[I].Type.get().isNull())) ||
12404 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
12405 if (ErrorFound)
12406 continue;
12407 Data[I].Range.Begin = Begin.get();
12408 Data[I].Range.End = End.get();
12409 Data[I].Range.Step = Step.get();
12410 Data[I].AssignLoc = E->getAssignLoc(I);
12411 Data[I].ColonLoc = E->getColonLoc(I);
12412 Data[I].SecColonLoc = E->getSecondColonLoc(I);
12413 NeedToRebuild =
12414 NeedToRebuild ||
12415 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
12416 D->getType().getTypePtrOrNull()) ||
12417 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
12418 Range.Step != Data[I].Range.Step;
12419 }
12420 if (ErrorFound)
12421 return ExprError();
12422 if (!NeedToRebuild)
12423 return E;
12424
12425 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
12426 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
12427 if (!Res.isUsable())
12428 return Res;
12429 auto *IE = cast<OMPIteratorExpr>(Res.get());
12430 for (unsigned I = 0; I < NumIterators; ++I)
12431 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
12432 IE->getIteratorDecl(I));
12433 return Res;
12434}
12435
12436template<typename Derived>
12438TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
12439 // Transform the callee.
12440 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
12441 if (Callee.isInvalid())
12442 return ExprError();
12443
12444 // Transform arguments.
12445 bool ArgChanged = false;
12447 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
12448 &ArgChanged))
12449 return ExprError();
12450
12451 if (!getDerived().AlwaysRebuild() &&
12452 Callee.get() == E->getCallee() &&
12453 !ArgChanged)
12454 return SemaRef.MaybeBindToTemporary(E);
12455
12456 // FIXME: Wrong source location information for the '('.
12457 SourceLocation FakeLParenLoc
12458 = ((Expr *)Callee.get())->getSourceRange().getBegin();
12459
12460 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12461 if (E->hasStoredFPFeatures()) {
12462 FPOptionsOverride NewOverrides = E->getFPFeatures();
12463 getSema().CurFPFeatures =
12464 NewOverrides.applyOverrides(getSema().getLangOpts());
12465 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12466 }
12467
12468 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
12469 Args,
12470 E->getRParenLoc());
12471}
12472
12473template<typename Derived>
12475TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
12476 ExprResult Base = getDerived().TransformExpr(E->getBase());
12477 if (Base.isInvalid())
12478 return ExprError();
12479
12480 NestedNameSpecifierLoc QualifierLoc;
12481 if (E->hasQualifier()) {
12482 QualifierLoc
12483 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
12484
12485 if (!QualifierLoc)
12486 return ExprError();
12487 }
12488 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
12489
12490 ValueDecl *Member
12491 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
12492 E->getMemberDecl()));
12493 if (!Member)
12494 return ExprError();
12495
12496 NamedDecl *FoundDecl = E->getFoundDecl();
12497 if (FoundDecl == E->getMemberDecl()) {
12498 FoundDecl = Member;
12499 } else {
12500 FoundDecl = cast_or_null<NamedDecl>(
12501 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
12502 if (!FoundDecl)
12503 return ExprError();
12504 }
12505
12506 if (!getDerived().AlwaysRebuild() &&
12507 Base.get() == E->getBase() &&
12508 QualifierLoc == E->getQualifierLoc() &&
12509 Member == E->getMemberDecl() &&
12510 FoundDecl == E->getFoundDecl() &&
12511 !E->hasExplicitTemplateArgs()) {
12512
12513 // Skip for member expression of (this->f), rebuilt thisi->f is needed
12514 // for Openmp where the field need to be privatizized in the case.
12515 if (!(isa<CXXThisExpr>(E->getBase()) &&
12516 getSema().OpenMP().isOpenMPRebuildMemberExpr(
12517 cast<ValueDecl>(Member)))) {
12518 // Mark it referenced in the new context regardless.
12519 // FIXME: this is a bit instantiation-specific.
12520 SemaRef.MarkMemberReferenced(E);
12521 return E;
12522 }
12523 }
12524
12525 TemplateArgumentListInfo TransArgs;
12526 if (E->hasExplicitTemplateArgs()) {
12527 TransArgs.setLAngleLoc(E->getLAngleLoc());
12528 TransArgs.setRAngleLoc(E->getRAngleLoc());
12529 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
12530 E->getNumTemplateArgs(),
12531 TransArgs))
12532 return ExprError();
12533 }
12534
12535 // FIXME: Bogus source location for the operator
12536 SourceLocation FakeOperatorLoc =
12537 SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
12538
12539 // FIXME: to do this check properly, we will need to preserve the
12540 // first-qualifier-in-scope here, just in case we had a dependent
12541 // base (and therefore couldn't do the check) and a
12542 // nested-name-qualifier (and therefore could do the lookup).
12543 NamedDecl *FirstQualifierInScope = nullptr;
12544 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
12545 if (MemberNameInfo.getName()) {
12546 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
12547 if (!MemberNameInfo.getName())
12548 return ExprError();
12549 }
12550
12551 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
12552 E->isArrow(),
12553 QualifierLoc,
12554 TemplateKWLoc,
12555 MemberNameInfo,
12556 Member,
12557 FoundDecl,
12558 (E->hasExplicitTemplateArgs()
12559 ? &TransArgs : nullptr),
12560 FirstQualifierInScope);
12561}
12562
12563template<typename Derived>
12565TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
12566 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12567 if (LHS.isInvalid())
12568 return ExprError();
12569
12570 ExprResult RHS =
12571 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
12572 if (RHS.isInvalid())
12573 return ExprError();
12574
12575 if (!getDerived().AlwaysRebuild() &&
12576 LHS.get() == E->getLHS() &&
12577 RHS.get() == E->getRHS())
12578 return E;
12579
12580 if (E->isCompoundAssignmentOp())
12581 // FPFeatures has already been established from trailing storage
12582 return getDerived().RebuildBinaryOperator(
12583 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
12584 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12585 FPOptionsOverride NewOverrides(E->getFPFeatures());
12586 getSema().CurFPFeatures =
12587 NewOverrides.applyOverrides(getSema().getLangOpts());
12588 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12589 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
12590 LHS.get(), RHS.get());
12591}
12592
12593template <typename Derived>
12594ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
12595 CXXRewrittenBinaryOperator *E) {
12596 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
12597
12598 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
12599 if (LHS.isInvalid())
12600 return ExprError();
12601
12602 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
12603 if (RHS.isInvalid())
12604 return ExprError();
12605
12606 // Extract the already-resolved callee declarations so that we can restrict
12607 // ourselves to using them as the unqualified lookup results when rebuilding.
12608 UnresolvedSet<2> UnqualLookups;
12609 bool ChangedAnyLookups = false;
12610 Expr *PossibleBinOps[] = {E->getSemanticForm(),
12611 const_cast<Expr *>(Decomp.InnerBinOp)};
12612 for (Expr *PossibleBinOp : PossibleBinOps) {
12613 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());
12614 if (!Op)
12615 continue;
12616 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());
12617 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))
12618 continue;
12619
12620 // Transform the callee in case we built a call to a local extern
12621 // declaration.
12622 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
12623 E->getOperatorLoc(), Callee->getFoundDecl()));
12624 if (!Found)
12625 return ExprError();
12626 if (Found != Callee->getFoundDecl())
12627 ChangedAnyLookups = true;
12628 UnqualLookups.addDecl(Found);
12629 }
12630
12631 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
12632 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
12633 // Mark all functions used in the rewrite as referenced. Note that when
12634 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
12635 // function calls, and/or there might be a user-defined conversion sequence
12636 // applied to the operands of the <.
12637 // FIXME: this is a bit instantiation-specific.
12638 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
12639 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);
12640 return E;
12641 }
12642
12643 return getDerived().RebuildCXXRewrittenBinaryOperator(
12644 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
12645}
12646
12647template<typename Derived>
12649TreeTransform<Derived>::TransformCompoundAssignOperator(
12650 CompoundAssignOperator *E) {
12651 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12652 FPOptionsOverride NewOverrides(E->getFPFeatures());
12653 getSema().CurFPFeatures =
12654 NewOverrides.applyOverrides(getSema().getLangOpts());
12655 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12656 return getDerived().TransformBinaryOperator(E);
12657}
12658
12659template<typename Derived>
12660ExprResult TreeTransform<Derived>::
12661TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
12662 // Just rebuild the common and RHS expressions and see whether we
12663 // get any changes.
12664
12665 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
12666 if (commonExpr.isInvalid())
12667 return ExprError();
12668
12669 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
12670 if (rhs.isInvalid())
12671 return ExprError();
12672
12673 if (!getDerived().AlwaysRebuild() &&
12674 commonExpr.get() == e->getCommon() &&
12675 rhs.get() == e->getFalseExpr())
12676 return e;
12677
12678 return getDerived().RebuildConditionalOperator(commonExpr.get(),
12679 e->getQuestionLoc(),
12680 nullptr,
12681 e->getColonLoc(),
12682 rhs.get());
12683}
12684
12685template<typename Derived>
12687TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
12688 ExprResult Cond = getDerived().TransformExpr(E->getCond());
12689 if (Cond.isInvalid())
12690 return ExprError();
12691
12692 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12693 if (LHS.isInvalid())
12694 return ExprError();
12695
12696 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
12697 if (RHS.isInvalid())
12698 return ExprError();
12699
12700 if (!getDerived().AlwaysRebuild() &&
12701 Cond.get() == E->getCond() &&
12702 LHS.get() == E->getLHS() &&
12703 RHS.get() == E->getRHS())
12704 return E;
12705
12706 return getDerived().RebuildConditionalOperator(Cond.get(),
12707 E->getQuestionLoc(),
12708 LHS.get(),
12709 E->getColonLoc(),
12710 RHS.get());
12711}
12712
12713template<typename Derived>
12715TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
12716 // Implicit casts are eliminated during transformation, since they
12717 // will be recomputed by semantic analysis after transformation.
12718 return getDerived().TransformExpr(E->getSubExprAsWritten());
12719}
12720
12721template<typename Derived>
12723TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
12724 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
12725 if (!Type)
12726 return ExprError();
12727
12728 ExprResult SubExpr
12729 = getDerived().TransformExpr(E->getSubExprAsWritten());
12730 if (SubExpr.isInvalid())
12731 return ExprError();
12732
12733 if (!getDerived().AlwaysRebuild() &&
12734 Type == E->getTypeInfoAsWritten() &&
12735 SubExpr.get() == E->getSubExpr())
12736 return E;
12737
12738 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
12739 Type,
12740 E->getRParenLoc(),
12741 SubExpr.get());
12742}
12743
12744template<typename Derived>
12746TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
12747 TypeSourceInfo *OldT = E->getTypeSourceInfo();
12748 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
12749 if (!NewT)
12750 return ExprError();
12751
12752 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
12753 if (Init.isInvalid())
12754 return ExprError();
12755
12756 if (!getDerived().AlwaysRebuild() &&
12757 OldT == NewT &&
12758 Init.get() == E->getInitializer())
12759 return SemaRef.MaybeBindToTemporary(E);
12760
12761 // Note: the expression type doesn't necessarily match the
12762 // type-as-written, but that's okay, because it should always be
12763 // derivable from the initializer.
12764
12765 return getDerived().RebuildCompoundLiteralExpr(
12766 E->getLParenLoc(), NewT,
12767 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
12768}
12769
12770template<typename Derived>
12772TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
12773 ExprResult Base = getDerived().TransformExpr(E->getBase());
12774 if (Base.isInvalid())
12775 return ExprError();
12776
12777 if (!getDerived().AlwaysRebuild() &&
12778 Base.get() == E->getBase())
12779 return E;
12780
12781 // FIXME: Bad source location
12782 SourceLocation FakeOperatorLoc =
12783 SemaRef.getLocForEndOfToken(E->getBase()->getEndLoc());
12784 return getDerived().RebuildExtVectorElementExpr(
12785 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
12786 E->getAccessor());
12787}
12788
12789template<typename Derived>
12791TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
12792 if (InitListExpr *Syntactic = E->getSyntacticForm())
12793 E = Syntactic;
12794
12795 bool InitChanged = false;
12796
12797 EnterExpressionEvaluationContext Context(
12799
12801 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
12802 Inits, &InitChanged))
12803 return ExprError();
12804
12805 if (!getDerived().AlwaysRebuild() && !InitChanged) {
12806 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
12807 // in some cases. We can't reuse it in general, because the syntactic and
12808 // semantic forms are linked, and we can't know that semantic form will
12809 // match even if the syntactic form does.
12810 }
12811
12812 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
12813 E->getRBraceLoc());
12814}
12815
12816template<typename Derived>
12818TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
12819 Designation Desig;
12820
12821 // transform the initializer value
12822 ExprResult Init = getDerived().TransformExpr(E->getInit());
12823 if (Init.isInvalid())
12824 return ExprError();
12825
12826 // transform the designators.
12827 SmallVector<Expr*, 4> ArrayExprs;
12828 bool ExprChanged = false;
12829 for (const DesignatedInitExpr::Designator &D : E->designators()) {
12830 if (D.isFieldDesignator()) {
12831 if (D.getFieldDecl()) {
12832 FieldDecl *Field = cast_or_null<FieldDecl>(
12833 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
12834 if (Field != D.getFieldDecl())
12835 // Rebuild the expression when the transformed FieldDecl is
12836 // different to the already assigned FieldDecl.
12837 ExprChanged = true;
12838 if (Field->isAnonymousStructOrUnion())
12839 continue;
12840 } else {
12841 // Ensure that the designator expression is rebuilt when there isn't
12842 // a resolved FieldDecl in the designator as we don't want to assign
12843 // a FieldDecl to a pattern designator that will be instantiated again.
12844 ExprChanged = true;
12845 }
12846 Desig.AddDesignator(Designator::CreateFieldDesignator(
12847 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
12848 continue;
12849 }
12850
12851 if (D.isArrayDesignator()) {
12852 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
12853 if (Index.isInvalid())
12854 return ExprError();
12855
12856 Desig.AddDesignator(
12857 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
12858
12859 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
12860 ArrayExprs.push_back(Index.get());
12861 continue;
12862 }
12863
12864 assert(D.isArrayRangeDesignator() && "New kind of designator?");
12865 ExprResult Start
12866 = getDerived().TransformExpr(E->getArrayRangeStart(D));
12867 if (Start.isInvalid())
12868 return ExprError();
12869
12870 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
12871 if (End.isInvalid())
12872 return ExprError();
12873
12874 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
12875 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
12876
12877 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
12878 End.get() != E->getArrayRangeEnd(D);
12879
12880 ArrayExprs.push_back(Start.get());
12881 ArrayExprs.push_back(End.get());
12882 }
12883
12884 if (!getDerived().AlwaysRebuild() &&
12885 Init.get() == E->getInit() &&
12886 !ExprChanged)
12887 return E;
12888
12889 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
12890 E->getEqualOrColonLoc(),
12891 E->usesGNUSyntax(), Init.get());
12892}
12893
12894// Seems that if TransformInitListExpr() only works on the syntactic form of an
12895// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
12896template<typename Derived>
12898TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
12899 DesignatedInitUpdateExpr *E) {
12900 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
12901 "initializer");
12902 return ExprError();
12903}
12904
12905template<typename Derived>
12907TreeTransform<Derived>::TransformNoInitExpr(
12908 NoInitExpr *E) {
12909 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
12910 return ExprError();
12911}
12912
12913template<typename Derived>
12915TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
12916 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
12917 return ExprError();
12918}
12919
12920template<typename Derived>
12922TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
12923 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
12924 return ExprError();
12925}
12926
12927template<typename Derived>
12929TreeTransform<Derived>::TransformImplicitValueInitExpr(
12930 ImplicitValueInitExpr *E) {
12931 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
12932
12933 // FIXME: Will we ever have proper type location here? Will we actually
12934 // need to transform the type?
12935 QualType T = getDerived().TransformType(E->getType());
12936 if (T.isNull())
12937 return ExprError();
12938
12939 if (!getDerived().AlwaysRebuild() &&
12940 T == E->getType())
12941 return E;
12942
12943 return getDerived().RebuildImplicitValueInitExpr(T);
12944}
12945
12946template<typename Derived>
12948TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
12949 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
12950 if (!TInfo)
12951 return ExprError();
12952
12953 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12954 if (SubExpr.isInvalid())
12955 return ExprError();
12956
12957 if (!getDerived().AlwaysRebuild() &&
12958 TInfo == E->getWrittenTypeInfo() &&
12959 SubExpr.get() == E->getSubExpr())
12960 return E;
12961
12962 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
12963 TInfo, E->getRParenLoc());
12964}
12965
12966template<typename Derived>
12968TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
12969 bool ArgumentChanged = false;
12971 if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits,
12972 &ArgumentChanged))
12973 return ExprError();
12974
12975 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
12976 Inits,
12977 E->getRParenLoc());
12978}
12979
12980/// Transform an address-of-label expression.
12981///
12982/// By default, the transformation of an address-of-label expression always
12983/// rebuilds the expression, so that the label identifier can be resolved to
12984/// the corresponding label statement by semantic analysis.
12985template<typename Derived>
12987TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
12988 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
12989 E->getLabel());
12990 if (!LD)
12991 return ExprError();
12992
12993 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
12994 cast<LabelDecl>(LD));
12995}
12996
12997template<typename Derived>
12999TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
13000 SemaRef.ActOnStartStmtExpr();
13001 StmtResult SubStmt
13002 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
13003 if (SubStmt.isInvalid()) {
13004 SemaRef.ActOnStmtExprError();
13005 return ExprError();
13006 }
13007
13008 unsigned OldDepth = E->getTemplateDepth();
13009 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
13010
13011 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
13012 SubStmt.get() == E->getSubStmt()) {
13013 // Calling this an 'error' is unintuitive, but it does the right thing.
13014 SemaRef.ActOnStmtExprError();
13015 return SemaRef.MaybeBindToTemporary(E);
13016 }
13017
13018 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
13019 E->getRParenLoc(), NewDepth);
13020}
13021
13022template<typename Derived>
13024TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
13025 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13026 if (Cond.isInvalid())
13027 return ExprError();
13028
13029 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13030 if (LHS.isInvalid())
13031 return ExprError();
13032
13033 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13034 if (RHS.isInvalid())
13035 return ExprError();
13036
13037 if (!getDerived().AlwaysRebuild() &&
13038 Cond.get() == E->getCond() &&
13039 LHS.get() == E->getLHS() &&
13040 RHS.get() == E->getRHS())
13041 return E;
13042
13043 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
13044 Cond.get(), LHS.get(), RHS.get(),
13045 E->getRParenLoc());
13046}
13047
13048template<typename Derived>
13050TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
13051 return E;
13052}
13053
13054template<typename Derived>
13056TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
13057 switch (E->getOperator()) {
13058 case OO_New:
13059 case OO_Delete:
13060 case OO_Array_New:
13061 case OO_Array_Delete:
13062 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
13063
13064 case OO_Subscript:
13065 case OO_Call: {
13066 // This is a call to an object's operator().
13067 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
13068
13069 // Transform the object itself.
13070 ExprResult Object = getDerived().TransformExpr(E->getArg(0));
13071 if (Object.isInvalid())
13072 return ExprError();
13073
13074 // FIXME: Poor location information
13075 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
13076 static_cast<Expr *>(Object.get())->getEndLoc());
13077
13078 // Transform the call arguments.
13080 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
13081 Args))
13082 return ExprError();
13083
13084 if (E->getOperator() == OO_Subscript)
13085 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
13086 Args, E->getEndLoc());
13087
13088 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
13089 E->getEndLoc());
13090 }
13091
13092#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
13093 case OO_##Name: \
13094 break;
13095
13096#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
13097#include "clang/Basic/OperatorKinds.def"
13098
13099 case OO_Conditional:
13100 llvm_unreachable("conditional operator is not actually overloadable");
13101
13102 case OO_None:
13104 llvm_unreachable("not an overloaded operator?");
13105 }
13106
13108 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
13109 First = getDerived().TransformAddressOfOperand(E->getArg(0));
13110 else
13111 First = getDerived().TransformExpr(E->getArg(0));
13112 if (First.isInvalid())
13113 return ExprError();
13114
13115 ExprResult Second;
13116 if (E->getNumArgs() == 2) {
13117 Second =
13118 getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);
13119 if (Second.isInvalid())
13120 return ExprError();
13121 }
13122
13123 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13124 FPOptionsOverride NewOverrides(E->getFPFeatures());
13125 getSema().CurFPFeatures =
13126 NewOverrides.applyOverrides(getSema().getLangOpts());
13127 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13128
13129 Expr *Callee = E->getCallee();
13130 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
13131 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
13133 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
13134 return ExprError();
13135
13136 return getDerived().RebuildCXXOperatorCallExpr(
13137 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
13138 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
13139 }
13140
13141 UnresolvedSet<1> Functions;
13142 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
13143 Callee = ICE->getSubExprAsWritten();
13144 NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();
13145 ValueDecl *VD = cast_or_null<ValueDecl>(
13146 getDerived().TransformDecl(DR->getLocation(), DR));
13147 if (!VD)
13148 return ExprError();
13149
13150 if (!isa<CXXMethodDecl>(VD))
13151 Functions.addDecl(VD);
13152
13153 return getDerived().RebuildCXXOperatorCallExpr(
13154 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
13155 /*RequiresADL=*/false, Functions, First.get(), Second.get());
13156}
13157
13158template<typename Derived>
13160TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
13161 return getDerived().TransformCallExpr(E);
13162}
13163
13164template <typename Derived>
13165ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
13166 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(E->getIdentKind()) &&
13167 getSema().CurContext != E->getParentContext();
13168
13169 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
13170 return E;
13171
13172 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
13173 E->getBeginLoc(), E->getEndLoc(),
13174 getSema().CurContext);
13175}
13176
13177template <typename Derived>
13178ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
13179 return E;
13180}
13181
13182template<typename Derived>
13184TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
13185 // Transform the callee.
13186 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13187 if (Callee.isInvalid())
13188 return ExprError();
13189
13190 // Transform exec config.
13191 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
13192 if (EC.isInvalid())
13193 return ExprError();
13194
13195 // Transform arguments.
13196 bool ArgChanged = false;
13198 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13199 &ArgChanged))
13200 return ExprError();
13201
13202 if (!getDerived().AlwaysRebuild() &&
13203 Callee.get() == E->getCallee() &&
13204 !ArgChanged)
13205 return SemaRef.MaybeBindToTemporary(E);
13206
13207 // FIXME: Wrong source location information for the '('.
13208 SourceLocation FakeLParenLoc
13209 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13210 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13211 Args,
13212 E->getRParenLoc(), EC.get());
13213}
13214
13215template<typename Derived>
13218 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13219 if (!Type)
13220 return ExprError();
13221
13222 ExprResult SubExpr
13223 = getDerived().TransformExpr(E->getSubExprAsWritten());
13224 if (SubExpr.isInvalid())
13225 return ExprError();
13226
13227 if (!getDerived().AlwaysRebuild() &&
13228 Type == E->getTypeInfoAsWritten() &&
13229 SubExpr.get() == E->getSubExpr())
13230 return E;
13231 return getDerived().RebuildCXXNamedCastExpr(
13232 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
13233 Type, E->getAngleBrackets().getEnd(),
13234 // FIXME. this should be '(' location
13235 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
13236}
13237
13238template<typename Derived>
13241 TypeSourceInfo *TSI =
13242 getDerived().TransformType(BCE->getTypeInfoAsWritten());
13243 if (!TSI)
13244 return ExprError();
13245
13246 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
13247 if (Sub.isInvalid())
13248 return ExprError();
13249
13250 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
13251 Sub.get(), BCE->getEndLoc());
13252}
13253
13254template<typename Derived>
13256TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
13257 return getDerived().TransformCXXNamedCastExpr(E);
13258}
13259
13260template<typename Derived>
13262TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
13263 return getDerived().TransformCXXNamedCastExpr(E);
13264}
13265
13266template<typename Derived>
13268TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
13269 CXXReinterpretCastExpr *E) {
13270 return getDerived().TransformCXXNamedCastExpr(E);
13271}
13272
13273template<typename Derived>
13275TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
13276 return getDerived().TransformCXXNamedCastExpr(E);
13277}
13278
13279template<typename Derived>
13281TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
13282 return getDerived().TransformCXXNamedCastExpr(E);
13283}
13284
13285template<typename Derived>
13287TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
13288 CXXFunctionalCastExpr *E) {
13289 TypeSourceInfo *Type =
13290 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
13291 if (!Type)
13292 return ExprError();
13293
13294 ExprResult SubExpr
13295 = getDerived().TransformExpr(E->getSubExprAsWritten());
13296 if (SubExpr.isInvalid())
13297 return ExprError();
13298
13299 if (!getDerived().AlwaysRebuild() &&
13300 Type == E->getTypeInfoAsWritten() &&
13301 SubExpr.get() == E->getSubExpr())
13302 return E;
13303
13304 return getDerived().RebuildCXXFunctionalCastExpr(Type,
13305 E->getLParenLoc(),
13306 SubExpr.get(),
13307 E->getRParenLoc(),
13308 E->isListInitialization());
13309}
13310
13311template<typename Derived>
13313TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
13314 if (E->isTypeOperand()) {
13315 TypeSourceInfo *TInfo
13316 = getDerived().TransformType(E->getTypeOperandSourceInfo());
13317 if (!TInfo)
13318 return ExprError();
13319
13320 if (!getDerived().AlwaysRebuild() &&
13321 TInfo == E->getTypeOperandSourceInfo())
13322 return E;
13323
13324 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
13325 TInfo, E->getEndLoc());
13326 }
13327
13328 // Typeid's operand is an unevaluated context, unless it's a polymorphic
13329 // type. We must not unilaterally enter unevaluated context here, as then
13330 // semantic processing can re-transform an already transformed operand.
13331 Expr *Op = E->getExprOperand();
13333 if (E->isGLValue())
13334 if (auto *RecordT = Op->getType()->getAs<RecordType>())
13335 if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
13336 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
13337
13338 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
13340
13341 ExprResult SubExpr = getDerived().TransformExpr(Op);
13342 if (SubExpr.isInvalid())
13343 return ExprError();
13344
13345 if (!getDerived().AlwaysRebuild() &&
13346 SubExpr.get() == E->getExprOperand())
13347 return E;
13348
13349 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
13350 SubExpr.get(), E->getEndLoc());
13351}
13352
13353template<typename Derived>
13355TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
13356 if (E->isTypeOperand()) {
13357 TypeSourceInfo *TInfo
13358 = getDerived().TransformType(E->getTypeOperandSourceInfo());
13359 if (!TInfo)
13360 return ExprError();
13361
13362 if (!getDerived().AlwaysRebuild() &&
13363 TInfo == E->getTypeOperandSourceInfo())
13364 return E;
13365
13366 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
13367 TInfo, E->getEndLoc());
13368 }
13369
13370 EnterExpressionEvaluationContext Unevaluated(
13372
13373 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
13374 if (SubExpr.isInvalid())
13375 return ExprError();
13376
13377 if (!getDerived().AlwaysRebuild() &&
13378 SubExpr.get() == E->getExprOperand())
13379 return E;
13380
13381 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
13382 SubExpr.get(), E->getEndLoc());
13383}
13384
13385template<typename Derived>
13387TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
13388 return E;
13389}
13390
13391template<typename Derived>
13393TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
13394 CXXNullPtrLiteralExpr *E) {
13395 return E;
13396}
13397
13398template<typename Derived>
13400TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
13401
13402 // In lambdas, the qualifiers of the type depends of where in
13403 // the call operator `this` appear, and we do not have a good way to
13404 // rebuild this information, so we transform the type.
13405 //
13406 // In other contexts, the type of `this` may be overrided
13407 // for type deduction, so we need to recompute it.
13408 //
13409 // Always recompute the type if we're in the body of a lambda, and
13410 // 'this' is dependent on a lambda's explicit object parameter.
13411 QualType T = [&]() {
13412 auto &S = getSema();
13413 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
13414 return S.getCurrentThisType();
13415 if (S.getCurLambda())
13416 return getDerived().TransformType(E->getType());
13417 return S.getCurrentThisType();
13418 }();
13419
13420 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
13421 // Mark it referenced in the new context regardless.
13422 // FIXME: this is a bit instantiation-specific.
13423 getSema().MarkThisReferenced(E);
13424 return E;
13425 }
13426
13427 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
13428}
13429
13430template<typename Derived>
13432TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
13433 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13434 if (SubExpr.isInvalid())
13435 return ExprError();
13436
13437 if (!getDerived().AlwaysRebuild() &&
13438 SubExpr.get() == E->getSubExpr())
13439 return E;
13440
13441 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
13442 E->isThrownVariableInScope());
13443}
13444
13445template<typename Derived>
13447TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
13448 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
13449 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
13450 if (!Param)
13451 return ExprError();
13452
13453 ExprResult InitRes;
13454 if (E->hasRewrittenInit()) {
13455 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
13456 if (InitRes.isInvalid())
13457 return ExprError();
13458 }
13459
13460 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
13461 E->getUsedContext() == SemaRef.CurContext &&
13462 InitRes.get() == E->getRewrittenExpr())
13463 return E;
13464
13465 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
13466 InitRes.get());
13467}
13468
13469template<typename Derived>
13471TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
13472 FieldDecl *Field = cast_or_null<FieldDecl>(
13473 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
13474 if (!Field)
13475 return ExprError();
13476
13477 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
13478 E->getUsedContext() == SemaRef.CurContext)
13479 return E;
13480
13481 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
13482}
13483
13484template<typename Derived>
13486TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
13487 CXXScalarValueInitExpr *E) {
13488 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
13489 if (!T)
13490 return ExprError();
13491
13492 if (!getDerived().AlwaysRebuild() &&
13493 T == E->getTypeSourceInfo())
13494 return E;
13495
13496 return getDerived().RebuildCXXScalarValueInitExpr(T,
13497 /*FIXME:*/T->getTypeLoc().getEndLoc(),
13498 E->getRParenLoc());
13499}
13500
13501template<typename Derived>
13503TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
13504 // Transform the type that we're allocating
13505 TypeSourceInfo *AllocTypeInfo =
13506 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
13507 if (!AllocTypeInfo)
13508 return ExprError();
13509
13510 // Transform the size of the array we're allocating (if any).
13511 std::optional<Expr *> ArraySize;
13512 if (E->isArray()) {
13513 ExprResult NewArraySize;
13514 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
13515 NewArraySize = getDerived().TransformExpr(*OldArraySize);
13516 if (NewArraySize.isInvalid())
13517 return ExprError();
13518 }
13519 ArraySize = NewArraySize.get();
13520 }
13521
13522 // Transform the placement arguments (if any).
13523 bool ArgumentChanged = false;
13524 SmallVector<Expr*, 8> PlacementArgs;
13525 if (getDerived().TransformExprs(E->getPlacementArgs(),
13526 E->getNumPlacementArgs(), true,
13527 PlacementArgs, &ArgumentChanged))
13528 return ExprError();
13529
13530 // Transform the initializer (if any).
13531 Expr *OldInit = E->getInitializer();
13532 ExprResult NewInit;
13533 if (OldInit)
13534 NewInit = getDerived().TransformInitializer(OldInit, true);
13535 if (NewInit.isInvalid())
13536 return ExprError();
13537
13538 // Transform new operator and delete operator.
13539 FunctionDecl *OperatorNew = nullptr;
13540 if (E->getOperatorNew()) {
13541 OperatorNew = cast_or_null<FunctionDecl>(
13542 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
13543 if (!OperatorNew)
13544 return ExprError();
13545 }
13546
13547 FunctionDecl *OperatorDelete = nullptr;
13548 if (E->getOperatorDelete()) {
13549 OperatorDelete = cast_or_null<FunctionDecl>(
13550 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
13551 if (!OperatorDelete)
13552 return ExprError();
13553 }
13554
13555 if (!getDerived().AlwaysRebuild() &&
13556 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
13557 ArraySize == E->getArraySize() &&
13558 NewInit.get() == OldInit &&
13559 OperatorNew == E->getOperatorNew() &&
13560 OperatorDelete == E->getOperatorDelete() &&
13561 !ArgumentChanged) {
13562 // Mark any declarations we need as referenced.
13563 // FIXME: instantiation-specific.
13564 if (OperatorNew)
13565 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorNew);
13566 if (OperatorDelete)
13567 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
13568
13569 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
13570 QualType ElementType
13571 = SemaRef.Context.getBaseElementType(E->getAllocatedType());
13572 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
13573 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
13574 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
13576 }
13577 }
13578 }
13579
13580 return E;
13581 }
13582
13583 QualType AllocType = AllocTypeInfo->getType();
13584 if (!ArraySize) {
13585 // If no array size was specified, but the new expression was
13586 // instantiated with an array type (e.g., "new T" where T is
13587 // instantiated with "int[4]"), extract the outer bound from the
13588 // array type as our array size. We do this with constant and
13589 // dependently-sized array types.
13590 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);
13591 if (!ArrayT) {
13592 // Do nothing
13593 } else if (const ConstantArrayType *ConsArrayT
13594 = dyn_cast<ConstantArrayType>(ArrayT)) {
13595 ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),
13596 SemaRef.Context.getSizeType(),
13597 /*FIXME:*/ E->getBeginLoc());
13598 AllocType = ConsArrayT->getElementType();
13599 } else if (const DependentSizedArrayType *DepArrayT
13600 = dyn_cast<DependentSizedArrayType>(ArrayT)) {
13601 if (DepArrayT->getSizeExpr()) {
13602 ArraySize = DepArrayT->getSizeExpr();
13603 AllocType = DepArrayT->getElementType();
13604 }
13605 }
13606 }
13607
13608 return getDerived().RebuildCXXNewExpr(
13609 E->getBeginLoc(), E->isGlobalNew(),
13610 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
13611 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
13612 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
13613}
13614
13615template<typename Derived>
13617TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
13618 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
13619 if (Operand.isInvalid())
13620 return ExprError();
13621
13622 // Transform the delete operator, if known.
13623 FunctionDecl *OperatorDelete = nullptr;
13624 if (E->getOperatorDelete()) {
13625 OperatorDelete = cast_or_null<FunctionDecl>(
13626 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
13627 if (!OperatorDelete)
13628 return ExprError();
13629 }
13630
13631 if (!getDerived().AlwaysRebuild() &&
13632 Operand.get() == E->getArgument() &&
13633 OperatorDelete == E->getOperatorDelete()) {
13634 // Mark any declarations we need as referenced.
13635 // FIXME: instantiation-specific.
13636 if (OperatorDelete)
13637 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
13638
13639 if (!E->getArgument()->isTypeDependent()) {
13640 QualType Destroyed = SemaRef.Context.getBaseElementType(
13641 E->getDestroyedType());
13642 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
13643 CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
13645 SemaRef.LookupDestructor(Record));
13646 }
13647 }
13648
13649 return E;
13650 }
13651
13652 return getDerived().RebuildCXXDeleteExpr(
13653 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
13654}
13655
13656template<typename Derived>
13658TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
13659 CXXPseudoDestructorExpr *E) {
13660 ExprResult Base = getDerived().TransformExpr(E->getBase());
13661 if (Base.isInvalid())
13662 return ExprError();
13663
13664 ParsedType ObjectTypePtr;
13665 bool MayBePseudoDestructor = false;
13666 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
13667 E->getOperatorLoc(),
13668 E->isArrow()? tok::arrow : tok::period,
13669 ObjectTypePtr,
13670 MayBePseudoDestructor);
13671 if (Base.isInvalid())
13672 return ExprError();
13673
13674 QualType ObjectType = ObjectTypePtr.get();
13675 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
13676 if (QualifierLoc) {
13677 QualifierLoc
13678 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
13679 if (!QualifierLoc)
13680 return ExprError();
13681 }
13682 CXXScopeSpec SS;
13683 SS.Adopt(QualifierLoc);
13684
13685 PseudoDestructorTypeStorage Destroyed;
13686 if (E->getDestroyedTypeInfo()) {
13687 TypeSourceInfo *DestroyedTypeInfo
13688 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
13689 ObjectType, nullptr, SS);
13690 if (!DestroyedTypeInfo)
13691 return ExprError();
13692 Destroyed = DestroyedTypeInfo;
13693 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
13694 // We aren't likely to be able to resolve the identifier down to a type
13695 // now anyway, so just retain the identifier.
13696 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
13697 E->getDestroyedTypeLoc());
13698 } else {
13699 // Look for a destructor known with the given name.
13700 ParsedType T = SemaRef.getDestructorName(
13701 *E->getDestroyedTypeIdentifier(), E->getDestroyedTypeLoc(),
13702 /*Scope=*/nullptr, SS, ObjectTypePtr, false);
13703 if (!T)
13704 return ExprError();
13705
13706 Destroyed
13708 E->getDestroyedTypeLoc());
13709 }
13710
13711 TypeSourceInfo *ScopeTypeInfo = nullptr;
13712 if (E->getScopeTypeInfo()) {
13713 CXXScopeSpec EmptySS;
13714 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
13715 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
13716 if (!ScopeTypeInfo)
13717 return ExprError();
13718 }
13719
13720 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
13721 E->getOperatorLoc(),
13722 E->isArrow(),
13723 SS,
13724 ScopeTypeInfo,
13725 E->getColonColonLoc(),
13726 E->getTildeLoc(),
13727 Destroyed);
13728}
13729
13730template <typename Derived>
13732 bool RequiresADL,
13733 LookupResult &R) {
13734 // Transform all the decls.
13735 bool AllEmptyPacks = true;
13736 for (auto *OldD : Old->decls()) {
13737 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
13738 if (!InstD) {
13739 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
13740 // This can happen because of dependent hiding.
13741 if (isa<UsingShadowDecl>(OldD))
13742 continue;
13743 else {
13744 R.clear();
13745 return true;
13746 }
13747 }
13748
13749 // Expand using pack declarations.
13750 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
13751 ArrayRef<NamedDecl*> Decls = SingleDecl;
13752 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
13753 Decls = UPD->expansions();
13754
13755 // Expand using declarations.
13756 for (auto *D : Decls) {
13757 if (auto *UD = dyn_cast<UsingDecl>(D)) {
13758 for (auto *SD : UD->shadows())
13759 R.addDecl(SD);
13760 } else {
13761 R.addDecl(D);
13762 }
13763 }
13764
13765 AllEmptyPacks &= Decls.empty();
13766 };
13767
13768 // C++ [temp.res]/8.4.2:
13769 // The program is ill-formed, no diagnostic required, if [...] lookup for
13770 // a name in the template definition found a using-declaration, but the
13771 // lookup in the corresponding scope in the instantiation odoes not find
13772 // any declarations because the using-declaration was a pack expansion and
13773 // the corresponding pack is empty
13774 if (AllEmptyPacks && !RequiresADL) {
13775 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
13776 << isa<UnresolvedMemberExpr>(Old) << Old->getName();
13777 return true;
13778 }
13779
13780 // Resolve a kind, but don't do any further analysis. If it's
13781 // ambiguous, the callee needs to deal with it.
13782 R.resolveKind();
13783
13784 if (Old->hasTemplateKeyword() && !R.empty()) {
13786 getSema().FilterAcceptableTemplateNames(R,
13787 /*AllowFunctionTemplates=*/true,
13788 /*AllowDependent=*/true);
13789 if (R.empty()) {
13790 // If a 'template' keyword was used, a lookup that finds only non-template
13791 // names is an error.
13792 getSema().Diag(R.getNameLoc(),
13793 diag::err_template_kw_refers_to_non_template)
13795 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
13796 getSema().Diag(FoundDecl->getLocation(),
13797 diag::note_template_kw_refers_to_non_template)
13798 << R.getLookupName();
13799 return true;
13800 }
13801 }
13802
13803 return false;
13804}
13805
13806template <typename Derived>
13808 UnresolvedLookupExpr *Old) {
13809 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
13810}
13811
13812template <typename Derived>
13815 bool IsAddressOfOperand) {
13816 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
13818
13819 // Transform the declaration set.
13820 if (TransformOverloadExprDecls(Old, Old->requiresADL(), R))
13821 return ExprError();
13822
13823 // Rebuild the nested-name qualifier, if present.
13824 CXXScopeSpec SS;
13825 if (Old->getQualifierLoc()) {
13826 NestedNameSpecifierLoc QualifierLoc
13827 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
13828 if (!QualifierLoc)
13829 return ExprError();
13830
13831 SS.Adopt(QualifierLoc);
13832 }
13833
13834 if (Old->getNamingClass()) {
13835 CXXRecordDecl *NamingClass
13836 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
13837 Old->getNameLoc(),
13838 Old->getNamingClass()));
13839 if (!NamingClass) {
13840 R.clear();
13841 return ExprError();
13842 }
13843
13844 R.setNamingClass(NamingClass);
13845 }
13846
13847 // Rebuild the template arguments, if any.
13848 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
13849 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
13850 if (Old->hasExplicitTemplateArgs() &&
13851 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
13852 Old->getNumTemplateArgs(),
13853 TransArgs)) {
13854 R.clear();
13855 return ExprError();
13856 }
13857
13858 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
13859 // a non-static data member is named in an unevaluated operand, or when
13860 // a member is named in a dependent class scope function template explicit
13861 // specialization that is neither declared static nor with an explicit object
13862 // parameter.
13863 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
13864 return SemaRef.BuildPossibleImplicitMemberExpr(
13865 SS, TemplateKWLoc, R,
13866 Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
13867 /*S=*/nullptr);
13868
13869 // If we have neither explicit template arguments, nor the template keyword,
13870 // it's a normal declaration name or member reference.
13871 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
13872 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
13873
13874 // If we have template arguments, then rebuild the template-id expression.
13875 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
13876 Old->requiresADL(), &TransArgs);
13877}
13878
13879template<typename Derived>
13881TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
13882 bool ArgChanged = false;
13884 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
13885 TypeSourceInfo *From = E->getArg(I);
13886 TypeLoc FromTL = From->getTypeLoc();
13887 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
13888 TypeLocBuilder TLB;
13889 TLB.reserve(FromTL.getFullDataSize());
13890 QualType To = getDerived().TransformType(TLB, FromTL);
13891 if (To.isNull())
13892 return ExprError();
13893
13894 if (To == From->getType())
13895 Args.push_back(From);
13896 else {
13897 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
13898 ArgChanged = true;
13899 }
13900 continue;
13901 }
13902
13903 ArgChanged = true;
13904
13905 // We have a pack expansion. Instantiate it.
13906 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
13907 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
13909 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
13910
13911 // Determine whether the set of unexpanded parameter packs can and should
13912 // be expanded.
13913 bool Expand = true;
13914 bool RetainExpansion = false;
13915 std::optional<unsigned> OrigNumExpansions =
13916 ExpansionTL.getTypePtr()->getNumExpansions();
13917 std::optional<unsigned> NumExpansions = OrigNumExpansions;
13918 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
13919 PatternTL.getSourceRange(),
13920 Unexpanded,
13921 Expand, RetainExpansion,
13922 NumExpansions))
13923 return ExprError();
13924
13925 if (!Expand) {
13926 // The transform has determined that we should perform a simple
13927 // transformation on the pack expansion, producing another pack
13928 // expansion.
13929 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
13930
13931 TypeLocBuilder TLB;
13932 TLB.reserve(From->getTypeLoc().getFullDataSize());
13933
13934 QualType To = getDerived().TransformType(TLB, PatternTL);
13935 if (To.isNull())
13936 return ExprError();
13937
13938 To = getDerived().RebuildPackExpansionType(To,
13939 PatternTL.getSourceRange(),
13940 ExpansionTL.getEllipsisLoc(),
13941 NumExpansions);
13942 if (To.isNull())
13943 return ExprError();
13944
13945 PackExpansionTypeLoc ToExpansionTL
13946 = TLB.push<PackExpansionTypeLoc>(To);
13947 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13948 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
13949 continue;
13950 }
13951
13952 // Expand the pack expansion by substituting for each argument in the
13953 // pack(s).
13954 for (unsigned I = 0; I != *NumExpansions; ++I) {
13955 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
13956 TypeLocBuilder TLB;
13957 TLB.reserve(PatternTL.getFullDataSize());
13958 QualType To = getDerived().TransformType(TLB, PatternTL);
13959 if (To.isNull())
13960 return ExprError();
13961
13962 if (To->containsUnexpandedParameterPack()) {
13963 To = getDerived().RebuildPackExpansionType(To,
13964 PatternTL.getSourceRange(),
13965 ExpansionTL.getEllipsisLoc(),
13966 NumExpansions);
13967 if (To.isNull())
13968 return ExprError();
13969
13970 PackExpansionTypeLoc ToExpansionTL
13971 = TLB.push<PackExpansionTypeLoc>(To);
13972 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13973 }
13974
13975 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
13976 }
13977
13978 if (!RetainExpansion)
13979 continue;
13980
13981 // If we're supposed to retain a pack expansion, do so by temporarily
13982 // forgetting the partially-substituted parameter pack.
13983 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
13984
13985 TypeLocBuilder TLB;
13986 TLB.reserve(From->getTypeLoc().getFullDataSize());
13987
13988 QualType To = getDerived().TransformType(TLB, PatternTL);
13989 if (To.isNull())
13990 return ExprError();
13991
13992 To = getDerived().RebuildPackExpansionType(To,
13993 PatternTL.getSourceRange(),
13994 ExpansionTL.getEllipsisLoc(),
13995 NumExpansions);
13996 if (To.isNull())
13997 return ExprError();
13998
13999 PackExpansionTypeLoc ToExpansionTL
14000 = TLB.push<PackExpansionTypeLoc>(To);
14001 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14002 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14003 }
14004
14005 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14006 return E;
14007
14008 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
14009 E->getEndLoc());
14010}
14011
14012template<typename Derived>
14014TreeTransform<Derived>::TransformConceptSpecializationExpr(
14015 ConceptSpecializationExpr *E) {
14016 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
14017 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
14018 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14019 Old->NumTemplateArgs, TransArgs))
14020 return ExprError();
14021
14022 return getDerived().RebuildConceptSpecializationExpr(
14023 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
14024 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
14025 &TransArgs);
14026}
14027
14028template<typename Derived>
14030TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
14031 SmallVector<ParmVarDecl*, 4> TransParams;
14032 SmallVector<QualType, 4> TransParamTypes;
14033 Sema::ExtParameterInfoBuilder ExtParamInfos;
14034
14035 // C++2a [expr.prim.req]p2
14036 // Expressions appearing within a requirement-body are unevaluated operands.
14037 EnterExpressionEvaluationContext Ctx(
14040
14041 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
14042 getSema().Context, getSema().CurContext,
14043 E->getBody()->getBeginLoc());
14044
14045 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
14046
14047 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
14048 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
14049 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
14050
14051 for (ParmVarDecl *Param : TransParams)
14052 if (Param)
14053 Param->setDeclContext(Body);
14054
14055 // On failure to transform, TransformRequiresTypeParams returns an expression
14056 // in the event that the transformation of the type params failed in some way.
14057 // It is expected that this will result in a 'not satisfied' Requires clause
14058 // when instantiating.
14059 if (!TypeParamResult.isUnset())
14060 return TypeParamResult;
14061
14063 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
14064 TransReqs))
14065 return ExprError();
14066
14067 for (concepts::Requirement *Req : TransReqs) {
14068 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
14069 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
14070 ER->getReturnTypeRequirement()
14071 .getTypeConstraintTemplateParameterList()->getParam(0)
14072 ->setDeclContext(Body);
14073 }
14074 }
14075 }
14076
14077 return getDerived().RebuildRequiresExpr(
14078 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
14079 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
14080}
14081
14082template<typename Derived>
14086 for (concepts::Requirement *Req : Reqs) {
14087 concepts::Requirement *TransReq = nullptr;
14088 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
14089 TransReq = getDerived().TransformTypeRequirement(TypeReq);
14090 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
14091 TransReq = getDerived().TransformExprRequirement(ExprReq);
14092 else
14093 TransReq = getDerived().TransformNestedRequirement(
14094 cast<concepts::NestedRequirement>(Req));
14095 if (!TransReq)
14096 return true;
14097 Transformed.push_back(TransReq);
14098 }
14099 return false;
14100}
14101
14102template<typename Derived>
14106 if (Req->isSubstitutionFailure()) {
14107 if (getDerived().AlwaysRebuild())
14108 return getDerived().RebuildTypeRequirement(
14110 return Req;
14111 }
14112 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
14113 if (!TransType)
14114 return nullptr;
14115 return getDerived().RebuildTypeRequirement(TransType);
14116}
14117
14118template<typename Derived>
14121 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
14122 if (Req->isExprSubstitutionFailure())
14123 TransExpr = Req->getExprSubstitutionDiagnostic();
14124 else {
14125 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
14126 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
14127 TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
14128 if (TransExprRes.isInvalid())
14129 return nullptr;
14130 TransExpr = TransExprRes.get();
14131 }
14132
14133 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
14134 const auto &RetReq = Req->getReturnTypeRequirement();
14135 if (RetReq.isEmpty())
14136 TransRetReq.emplace();
14137 else if (RetReq.isSubstitutionFailure())
14138 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
14139 else if (RetReq.isTypeConstraint()) {
14140 TemplateParameterList *OrigTPL =
14141 RetReq.getTypeConstraintTemplateParameterList();
14143 getDerived().TransformTemplateParameterList(OrigTPL);
14144 if (!TPL)
14145 return nullptr;
14146 TransRetReq.emplace(TPL);
14147 }
14148 assert(TransRetReq && "All code paths leading here must set TransRetReq");
14149 if (Expr *E = TransExpr.dyn_cast<Expr *>())
14150 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
14151 Req->getNoexceptLoc(),
14152 std::move(*TransRetReq));
14153 return getDerived().RebuildExprRequirement(
14155 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
14156}
14157
14158template<typename Derived>
14162 if (Req->hasInvalidConstraint()) {
14163 if (getDerived().AlwaysRebuild())
14164 return getDerived().RebuildNestedRequirement(
14166 return Req;
14167 }
14168 ExprResult TransConstraint =
14169 getDerived().TransformExpr(Req->getConstraintExpr());
14170 if (TransConstraint.isInvalid())
14171 return nullptr;
14172 return getDerived().RebuildNestedRequirement(TransConstraint.get());
14173}
14174
14175template<typename Derived>
14178 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
14179 if (!T)
14180 return ExprError();
14181
14182 if (!getDerived().AlwaysRebuild() &&
14183 T == E->getQueriedTypeSourceInfo())
14184 return E;
14185
14186 ExprResult SubExpr;
14187 {
14190 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
14191 if (SubExpr.isInvalid())
14192 return ExprError();
14193
14194 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
14195 return E;
14196 }
14197
14198 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
14199 SubExpr.get(), E->getEndLoc());
14200}
14201
14202template<typename Derived>
14204TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
14205 ExprResult SubExpr;
14206 {
14207 EnterExpressionEvaluationContext Unevaluated(
14209 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
14210 if (SubExpr.isInvalid())
14211 return ExprError();
14212
14213 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
14214 return E;
14215 }
14216
14217 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
14218 SubExpr.get(), E->getEndLoc());
14219}
14220
14221template <typename Derived>
14223 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
14224 TypeSourceInfo **RecoveryTSI) {
14225 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
14226 DRE, AddrTaken, RecoveryTSI);
14227
14228 // Propagate both errors and recovered types, which return ExprEmpty.
14229 if (!NewDRE.isUsable())
14230 return NewDRE;
14231
14232 // We got an expr, wrap it up in parens.
14233 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
14234 return PE;
14235 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
14236 PE->getRParen());
14237}
14238
14239template <typename Derived>
14242 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
14243 nullptr);
14244}
14245
14246template <typename Derived>
14248 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
14249 TypeSourceInfo **RecoveryTSI) {
14250 assert(E->getQualifierLoc());
14251 NestedNameSpecifierLoc QualifierLoc =
14252 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
14253 if (!QualifierLoc)
14254 return ExprError();
14255 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
14256
14257 // TODO: If this is a conversion-function-id, verify that the
14258 // destination type name (if present) resolves the same way after
14259 // instantiation as it did in the local scope.
14260
14261 DeclarationNameInfo NameInfo =
14262 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
14263 if (!NameInfo.getName())
14264 return ExprError();
14265
14266 if (!E->hasExplicitTemplateArgs()) {
14267 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
14268 // Note: it is sufficient to compare the Name component of NameInfo:
14269 // if name has not changed, DNLoc has not changed either.
14270 NameInfo.getName() == E->getDeclName())
14271 return E;
14272
14273 return getDerived().RebuildDependentScopeDeclRefExpr(
14274 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
14275 IsAddressOfOperand, RecoveryTSI);
14276 }
14277
14278 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
14279 if (getDerived().TransformTemplateArguments(
14280 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
14281 return ExprError();
14282
14283 return getDerived().RebuildDependentScopeDeclRefExpr(
14284 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
14285 RecoveryTSI);
14286}
14287
14288template<typename Derived>
14290TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
14291 // CXXConstructExprs other than for list-initialization and
14292 // CXXTemporaryObjectExpr are always implicit, so when we have
14293 // a 1-argument construction we just transform that argument.
14294 if (getDerived().AllowSkippingCXXConstructExpr() &&
14295 ((E->getNumArgs() == 1 ||
14296 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) &&
14297 (!getDerived().DropCallArgument(E->getArg(0))) &&
14298 !E->isListInitialization()))
14299 return getDerived().TransformInitializer(E->getArg(0),
14300 /*DirectInit*/ false);
14301
14302 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
14303
14304 QualType T = getDerived().TransformType(E->getType());
14305 if (T.isNull())
14306 return ExprError();
14307
14308 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
14309 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
14310 if (!Constructor)
14311 return ExprError();
14312
14313 bool ArgumentChanged = false;
14315 {
14316 EnterExpressionEvaluationContext Context(
14318 E->isListInitialization());
14319 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14320 &ArgumentChanged))
14321 return ExprError();
14322 }
14323
14324 if (!getDerived().AlwaysRebuild() &&
14325 T == E->getType() &&
14326 Constructor == E->getConstructor() &&
14327 !ArgumentChanged) {
14328 // Mark the constructor as referenced.
14329 // FIXME: Instantiation-specific
14330 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
14331 return E;
14332 }
14333
14334 return getDerived().RebuildCXXConstructExpr(
14335 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
14336 E->hadMultipleCandidates(), E->isListInitialization(),
14337 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
14338 E->getConstructionKind(), E->getParenOrBraceRange());
14339}
14340
14341template<typename Derived>
14342ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
14343 CXXInheritedCtorInitExpr *E) {
14344 QualType T = getDerived().TransformType(E->getType());
14345 if (T.isNull())
14346 return ExprError();
14347
14348 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
14349 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
14350 if (!Constructor)
14351 return ExprError();
14352
14353 if (!getDerived().AlwaysRebuild() &&
14354 T == E->getType() &&
14355 Constructor == E->getConstructor()) {
14356 // Mark the constructor as referenced.
14357 // FIXME: Instantiation-specific
14358 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
14359 return E;
14360 }
14361
14362 return getDerived().RebuildCXXInheritedCtorInitExpr(
14363 T, E->getLocation(), Constructor,
14364 E->constructsVBase(), E->inheritedFromVBase());
14365}
14366
14367/// Transform a C++ temporary-binding expression.
14368///
14369/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
14370/// transform the subexpression and return that.
14371template<typename Derived>
14373TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
14374 if (auto *Dtor = E->getTemporary()->getDestructor())
14376 const_cast<CXXDestructorDecl *>(Dtor));
14377 return getDerived().TransformExpr(E->getSubExpr());
14378}
14379
14380/// Transform a C++ expression that contains cleanups that should
14381/// be run after the expression is evaluated.
14382///
14383/// Since ExprWithCleanups nodes are implicitly generated, we
14384/// just transform the subexpression and return that.
14385template<typename Derived>
14387TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
14388 return getDerived().TransformExpr(E->getSubExpr());
14389}
14390
14391template<typename Derived>
14393TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
14394 CXXTemporaryObjectExpr *E) {
14395 TypeSourceInfo *T =
14396 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
14397 if (!T)
14398 return ExprError();
14399
14400 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
14401 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
14402 if (!Constructor)
14403 return ExprError();
14404
14405 bool ArgumentChanged = false;
14407 Args.reserve(E->getNumArgs());
14408 {
14409 EnterExpressionEvaluationContext Context(
14411 E->isListInitialization());
14412 if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14413 &ArgumentChanged))
14414 return ExprError();
14415 }
14416
14417 if (!getDerived().AlwaysRebuild() &&
14418 T == E->getTypeSourceInfo() &&
14419 Constructor == E->getConstructor() &&
14420 !ArgumentChanged) {
14421 // FIXME: Instantiation-specific
14422 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
14423 return SemaRef.MaybeBindToTemporary(E);
14424 }
14425
14426 // FIXME: We should just pass E->isListInitialization(), but we're not
14427 // prepared to handle list-initialization without a child InitListExpr.
14428 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
14429 return getDerived().RebuildCXXTemporaryObjectExpr(
14430 T, LParenLoc, Args, E->getEndLoc(),
14431 /*ListInitialization=*/LParenLoc.isInvalid());
14432}
14433
14434template<typename Derived>
14436TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
14437 // Transform any init-capture expressions before entering the scope of the
14438 // lambda body, because they are not semantically within that scope.
14439 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
14440 struct TransformedInitCapture {
14441 // The location of the ... if the result is retaining a pack expansion.
14442 SourceLocation EllipsisLoc;
14443 // Zero or more expansions of the init-capture.
14445 };
14447 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
14448 for (LambdaExpr::capture_iterator C = E->capture_begin(),
14449 CEnd = E->capture_end();
14450 C != CEnd; ++C) {
14451 if (!E->isInitCapture(C))
14452 continue;
14453
14454 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
14455 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
14456
14457 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
14458 std::optional<unsigned> NumExpansions) {
14459 ExprResult NewExprInitResult = getDerived().TransformInitializer(
14460 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
14461
14462 if (NewExprInitResult.isInvalid()) {
14463 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
14464 return;
14465 }
14466 Expr *NewExprInit = NewExprInitResult.get();
14467
14468 QualType NewInitCaptureType =
14469 getSema().buildLambdaInitCaptureInitialization(
14470 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
14471 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
14472 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=
14474 NewExprInit);
14475 Result.Expansions.push_back(
14476 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
14477 };
14478
14479 // If this is an init-capture pack, consider expanding the pack now.
14480 if (OldVD->isParameterPack()) {
14481 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
14482 ->getTypeLoc()
14483 .castAs<PackExpansionTypeLoc>();
14485 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
14486
14487 // Determine whether the set of unexpanded parameter packs can and should
14488 // be expanded.
14489 bool Expand = true;
14490 bool RetainExpansion = false;
14491 std::optional<unsigned> OrigNumExpansions =
14492 ExpansionTL.getTypePtr()->getNumExpansions();
14493 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14494 if (getDerived().TryExpandParameterPacks(
14495 ExpansionTL.getEllipsisLoc(),
14496 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
14497 RetainExpansion, NumExpansions))
14498 return ExprError();
14499 assert(!RetainExpansion && "Should not need to retain expansion after a "
14500 "capture since it cannot be extended");
14501 if (Expand) {
14502 for (unsigned I = 0; I != *NumExpansions; ++I) {
14503 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14504 SubstInitCapture(SourceLocation(), std::nullopt);
14505 }
14506 } else {
14507 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
14508 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
14509 }
14510 } else {
14511 SubstInitCapture(SourceLocation(), std::nullopt);
14512 }
14513 }
14514
14515 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
14516 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
14517
14518 // Create the local class that will describe the lambda.
14519
14520 // FIXME: DependencyKind below is wrong when substituting inside a templated
14521 // context that isn't a DeclContext (such as a variable template), or when
14522 // substituting an unevaluated lambda inside of a function's parameter's type
14523 // - as parameter types are not instantiated from within a function's DC. We
14524 // use evaluation contexts to distinguish the function parameter case.
14527 DeclContext *DC = getSema().CurContext;
14528 // A RequiresExprBodyDecl is not interesting for dependencies.
14529 // For the following case,
14530 //
14531 // template <typename>
14532 // concept C = requires { [] {}; };
14533 //
14534 // template <class F>
14535 // struct Widget;
14536 //
14537 // template <C F>
14538 // struct Widget<F> {};
14539 //
14540 // While we are substituting Widget<F>, the parent of DC would be
14541 // the template specialization itself. Thus, the lambda expression
14542 // will be deemed as dependent even if there are no dependent template
14543 // arguments.
14544 // (A ClassTemplateSpecializationDecl is always a dependent context.)
14545 while (DC->isRequiresExprBody())
14546 DC = DC->getParent();
14547 if ((getSema().isUnevaluatedContext() ||
14548 getSema().isConstantEvaluatedContext()) &&
14549 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
14550 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
14551
14552 CXXRecordDecl *OldClass = E->getLambdaClass();
14553 CXXRecordDecl *Class = getSema().createLambdaClosureType(
14554 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
14555 E->getCaptureDefault());
14556 getDerived().transformedLocalDecl(OldClass, {Class});
14557
14558 CXXMethodDecl *NewCallOperator =
14559 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
14560
14561 // Enter the scope of the lambda.
14562 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
14563 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
14564 E->hasExplicitParameters(), E->isMutable());
14565
14566 // Introduce the context of the call operator.
14567 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
14568 /*NewThisContext*/false);
14569
14570 bool Invalid = false;
14571
14572 // Transform captures.
14573 for (LambdaExpr::capture_iterator C = E->capture_begin(),
14574 CEnd = E->capture_end();
14575 C != CEnd; ++C) {
14576 // When we hit the first implicit capture, tell Sema that we've finished
14577 // the list of explicit captures.
14578 if (C->isImplicit())
14579 break;
14580
14581 // Capturing 'this' is trivial.
14582 if (C->capturesThis()) {
14583 // If this is a lambda that is part of a default member initialiser
14584 // and which we're instantiating outside the class that 'this' is
14585 // supposed to refer to, adjust the type of 'this' accordingly.
14586 //
14587 // Otherwise, leave the type of 'this' as-is.
14588 Sema::CXXThisScopeRAII ThisScope(
14589 getSema(),
14590 dyn_cast_if_present<CXXRecordDecl>(
14591 getSema().getFunctionLevelDeclContext()),
14592 Qualifiers());
14593 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
14594 /*BuildAndDiagnose*/ true, nullptr,
14595 C->getCaptureKind() == LCK_StarThis);
14596 continue;
14597 }
14598 // Captured expression will be recaptured during captured variables
14599 // rebuilding.
14600 if (C->capturesVLAType())
14601 continue;
14602
14603 // Rebuild init-captures, including the implied field declaration.
14604 if (E->isInitCapture(C)) {
14605 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
14606
14607 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
14609
14610 for (InitCaptureInfoTy &Info : NewC.Expansions) {
14611 ExprResult Init = Info.first;
14612 QualType InitQualType = Info.second;
14613 if (Init.isInvalid() || InitQualType.isNull()) {
14614 Invalid = true;
14615 break;
14616 }
14617 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
14618 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
14619 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
14620 getSema().CurContext);
14621 if (!NewVD) {
14622 Invalid = true;
14623 break;
14624 }
14625 NewVDs.push_back(NewVD);
14626 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
14627 // Cases we want to tackle:
14628 // ([C(Pack)] {}, ...)
14629 // But rule out cases e.g.
14630 // [...C = Pack()] {}
14631 if (NewC.EllipsisLoc.isInvalid())
14632 LSI->ContainsUnexpandedParameterPack |=
14633 Init.get()->containsUnexpandedParameterPack();
14634 }
14635
14636 if (Invalid)
14637 break;
14638
14639 getDerived().transformedLocalDecl(OldVD, NewVDs);
14640 continue;
14641 }
14642
14643 assert(C->capturesVariable() && "unexpected kind of lambda capture");
14644
14645 // Determine the capture kind for Sema.
14647 = C->isImplicit()? Sema::TryCapture_Implicit
14648 : C->getCaptureKind() == LCK_ByCopy
14651 SourceLocation EllipsisLoc;
14652 if (C->isPackExpansion()) {
14653 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
14654 bool ShouldExpand = false;
14655 bool RetainExpansion = false;
14656 std::optional<unsigned> NumExpansions;
14657 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
14658 C->getLocation(),
14659 Unexpanded,
14660 ShouldExpand, RetainExpansion,
14661 NumExpansions)) {
14662 Invalid = true;
14663 continue;
14664 }
14665
14666 if (ShouldExpand) {
14667 // The transform has determined that we should perform an expansion;
14668 // transform and capture each of the arguments.
14669 // expansion of the pattern. Do so.
14670 auto *Pack = cast<VarDecl>(C->getCapturedVar());
14671 for (unsigned I = 0; I != *NumExpansions; ++I) {
14672 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14673 VarDecl *CapturedVar
14674 = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
14675 Pack));
14676 if (!CapturedVar) {
14677 Invalid = true;
14678 continue;
14679 }
14680
14681 // Capture the transformed variable.
14682 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
14683 }
14684
14685 // FIXME: Retain a pack expansion if RetainExpansion is true.
14686
14687 continue;
14688 }
14689
14690 EllipsisLoc = C->getEllipsisLoc();
14691 }
14692
14693 // Transform the captured variable.
14694 auto *CapturedVar = cast_or_null<ValueDecl>(
14695 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
14696 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
14697 Invalid = true;
14698 continue;
14699 }
14700
14701 // This is not an init-capture; however it contains an unexpanded pack e.g.
14702 // ([Pack] {}(), ...)
14703 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
14704 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
14705
14706 // Capture the transformed variable.
14707 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
14708 EllipsisLoc);
14709 }
14710 getSema().finishLambdaExplicitCaptures(LSI);
14711
14712 // Transform the template parameters, and add them to the current
14713 // instantiation scope. The null case is handled correctly.
14714 auto TPL = getDerived().TransformTemplateParameterList(
14715 E->getTemplateParameterList());
14716 LSI->GLTemplateParameterList = TPL;
14717 if (TPL) {
14718 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
14719 TPL);
14720 LSI->ContainsUnexpandedParameterPack |=
14721 TPL->containsUnexpandedParameterPack();
14722 }
14723
14724 // Transform the type of the original lambda's call operator.
14725 // The transformation MUST be done in the CurrentInstantiationScope since
14726 // it introduces a mapping of the original to the newly created
14727 // transformed parameters.
14728 TypeSourceInfo *NewCallOpTSI = nullptr;
14729 {
14730 auto OldCallOpTypeLoc =
14731 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
14732
14733 auto TransformFunctionProtoTypeLoc =
14734 [this](TypeLocBuilder &TLB, FunctionProtoTypeLoc FPTL) -> QualType {
14735 SmallVector<QualType, 4> ExceptionStorage;
14736 return this->TransformFunctionProtoType(
14737 TLB, FPTL, nullptr, Qualifiers(),
14738 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
14739 return TransformExceptionSpec(FPTL.getBeginLoc(), ESI,
14740 ExceptionStorage, Changed);
14741 });
14742 };
14743
14744 QualType NewCallOpType;
14745 TypeLocBuilder NewCallOpTLBuilder;
14746
14747 if (auto ATL = OldCallOpTypeLoc.getAs<AttributedTypeLoc>()) {
14748 NewCallOpType = this->TransformAttributedType(
14749 NewCallOpTLBuilder, ATL,
14750 [&](TypeLocBuilder &TLB, TypeLoc TL) -> QualType {
14751 return TransformFunctionProtoTypeLoc(
14752 TLB, TL.castAs<FunctionProtoTypeLoc>());
14753 });
14754 } else {
14755 auto FPTL = OldCallOpTypeLoc.castAs<FunctionProtoTypeLoc>();
14756 NewCallOpType = TransformFunctionProtoTypeLoc(NewCallOpTLBuilder, FPTL);
14757 }
14758
14759 if (NewCallOpType.isNull())
14760 return ExprError();
14761 LSI->ContainsUnexpandedParameterPack |=
14762 NewCallOpType->containsUnexpandedParameterPack();
14763 NewCallOpTSI =
14764 NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
14765 }
14766
14768 if (auto ATL = NewCallOpTSI->getTypeLoc().getAs<AttributedTypeLoc>()) {
14769 Params = ATL.getModifiedLoc().castAs<FunctionProtoTypeLoc>().getParams();
14770 } else {
14771 auto FPTL = NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
14772 Params = FPTL.getParams();
14773 }
14774
14775 getSema().CompleteLambdaCallOperator(
14776 NewCallOperator, E->getCallOperator()->getLocation(),
14777 E->getCallOperator()->getInnerLocStart(),
14778 E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
14779 E->getCallOperator()->getConstexprKind(),
14780 E->getCallOperator()->getStorageClass(), Params,
14781 E->hasExplicitResultType());
14782
14783 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
14784 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
14785
14786 {
14787 // Number the lambda for linkage purposes if necessary.
14788 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
14789
14790 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
14791 if (getDerived().ReplacingOriginal()) {
14792 Numbering = OldClass->getLambdaNumbering();
14793 }
14794
14795 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
14796 }
14797
14798 // FIXME: Sema's lambda-building mechanism expects us to push an expression
14799 // evaluation context even if we're not transforming the function body.
14800 getSema().PushExpressionEvaluationContext(
14801 E->getCallOperator()->isConsteval() ?
14804 getSema().currentEvaluationContext().InImmediateEscalatingFunctionContext =
14805 getSema().getLangOpts().CPlusPlus20 &&
14806 E->getCallOperator()->isImmediateEscalating();
14807
14808 Sema::CodeSynthesisContext C;
14810 C.PointOfInstantiation = E->getBody()->getBeginLoc();
14811 getSema().pushCodeSynthesisContext(C);
14812
14813 // Instantiate the body of the lambda expression.
14814 StmtResult Body =
14815 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
14816
14817 getSema().popCodeSynthesisContext();
14818
14819 // ActOnLambda* will pop the function scope for us.
14820 FuncScopeCleanup.disable();
14821
14822 if (Body.isInvalid()) {
14823 SavedContext.pop();
14824 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
14825 /*IsInstantiation=*/true);
14826 return ExprError();
14827 }
14828
14829 // Copy the LSI before ActOnFinishFunctionBody removes it.
14830 // FIXME: This is dumb. Store the lambda information somewhere that outlives
14831 // the call operator.
14832 auto LSICopy = *LSI;
14833 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
14834 /*IsInstantiation*/ true);
14835 SavedContext.pop();
14836
14837 // Recompute the dependency of the lambda so that we can defer the lambda call
14838 // construction until after we have all the necessary template arguments. For
14839 // example, given
14840 //
14841 // template <class> struct S {
14842 // template <class U>
14843 // using Type = decltype([](U){}(42.0));
14844 // };
14845 // void foo() {
14846 // using T = S<int>::Type<float>;
14847 // ^~~~~~
14848 // }
14849 //
14850 // We would end up here from instantiating S<int> when ensuring its
14851 // completeness. That would transform the lambda call expression regardless of
14852 // the absence of the corresponding argument for U.
14853 //
14854 // Going ahead with unsubstituted type U makes things worse: we would soon
14855 // compare the argument type (which is float) against the parameter U
14856 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
14857 // error suggesting unmatched types 'U' and 'float'!
14858 //
14859 // That said, everything will be fine if we defer that semantic checking.
14860 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
14861 // dependent. Since the CallExpr's dependency boils down to the lambda's
14862 // dependency in this case, we can harness that by recomputing the dependency
14863 // from the instantiation arguments.
14864 //
14865 // FIXME: Creating the type of a lambda requires us to have a dependency
14866 // value, which happens before its substitution. We update its dependency
14867 // *after* the substitution in case we can't decide the dependency
14868 // so early, e.g. because we want to see if any of the *substituted*
14869 // parameters are dependent.
14870 DependencyKind = getDerived().ComputeLambdaDependency(&LSICopy);
14871 Class->setLambdaDependencyKind(DependencyKind);
14872 // Clean up the type cache created previously. Then, we re-create a type for
14873 // such Decl with the new DependencyKind.
14874 Class->setTypeForDecl(nullptr);
14875 getSema().Context.getTypeDeclType(Class);
14876
14877 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
14878 Body.get()->getEndLoc(), &LSICopy);
14879}
14880
14881template<typename Derived>
14884 return TransformStmt(S);
14885}
14886
14887template<typename Derived>
14890 // Transform captures.
14891 for (LambdaExpr::capture_iterator C = E->capture_begin(),
14892 CEnd = E->capture_end();
14893 C != CEnd; ++C) {
14894 // When we hit the first implicit capture, tell Sema that we've finished
14895 // the list of explicit captures.
14896 if (!C->isImplicit())
14897 continue;
14898
14899 // Capturing 'this' is trivial.
14900 if (C->capturesThis()) {
14901 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
14902 /*BuildAndDiagnose*/ true, nullptr,
14903 C->getCaptureKind() == LCK_StarThis);
14904 continue;
14905 }
14906 // Captured expression will be recaptured during captured variables
14907 // rebuilding.
14908 if (C->capturesVLAType())
14909 continue;
14910
14911 assert(C->capturesVariable() && "unexpected kind of lambda capture");
14912 assert(!E->isInitCapture(C) && "implicit init-capture?");
14913
14914 // Transform the captured variable.
14915 VarDecl *CapturedVar = cast_or_null<VarDecl>(
14916 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
14917 if (!CapturedVar || CapturedVar->isInvalidDecl())
14918 return StmtError();
14919
14920 // Capture the transformed variable.
14921 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
14922 }
14923
14924 return S;
14925}
14926
14927template<typename Derived>
14931 TypeSourceInfo *T =
14932 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
14933 if (!T)
14934 return ExprError();
14935
14936 bool ArgumentChanged = false;
14938 Args.reserve(E->getNumArgs());
14939 {
14942 E->isListInitialization());
14943 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
14944 &ArgumentChanged))
14945 return ExprError();
14946 }
14947
14948 if (!getDerived().AlwaysRebuild() &&
14949 T == E->getTypeSourceInfo() &&
14950 !ArgumentChanged)
14951 return E;
14952
14953 // FIXME: we're faking the locations of the commas
14954 return getDerived().RebuildCXXUnresolvedConstructExpr(
14955 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
14956}
14957
14958template<typename Derived>
14960TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
14961 CXXDependentScopeMemberExpr *E) {
14962 // Transform the base of the expression.
14963 ExprResult Base((Expr*) nullptr);
14964 Expr *OldBase;
14965 QualType BaseType;
14966 QualType ObjectType;
14967 if (!E->isImplicitAccess()) {
14968 OldBase = E->getBase();
14969 Base = getDerived().TransformExpr(OldBase);
14970 if (Base.isInvalid())
14971 return ExprError();
14972
14973 // Start the member reference and compute the object's type.
14974 ParsedType ObjectTy;
14975 bool MayBePseudoDestructor = false;
14976 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
14977 E->getOperatorLoc(),
14978 E->isArrow()? tok::arrow : tok::period,
14979 ObjectTy,
14980 MayBePseudoDestructor);
14981 if (Base.isInvalid())
14982 return ExprError();
14983
14984 ObjectType = ObjectTy.get();
14985 BaseType = ((Expr*) Base.get())->getType();
14986 } else {
14987 OldBase = nullptr;
14988 BaseType = getDerived().TransformType(E->getBaseType());
14989 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
14990 }
14991
14992 // Transform the first part of the nested-name-specifier that qualifies
14993 // the member name.
14994 NamedDecl *FirstQualifierInScope
14995 = getDerived().TransformFirstQualifierInScope(
14996 E->getFirstQualifierFoundInScope(),
14997 E->getQualifierLoc().getBeginLoc());
14998
14999 NestedNameSpecifierLoc QualifierLoc;
15000 if (E->getQualifier()) {
15001 QualifierLoc
15002 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
15003 ObjectType,
15004 FirstQualifierInScope);
15005 if (!QualifierLoc)
15006 return ExprError();
15007 }
15008
15009 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15010
15011 // TODO: If this is a conversion-function-id, verify that the
15012 // destination type name (if present) resolves the same way after
15013 // instantiation as it did in the local scope.
15014
15015 DeclarationNameInfo NameInfo
15016 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
15017 if (!NameInfo.getName())
15018 return ExprError();
15019
15020 if (!E->hasExplicitTemplateArgs()) {
15021 // This is a reference to a member without an explicitly-specified
15022 // template argument list. Optimize for this common case.
15023 if (!getDerived().AlwaysRebuild() &&
15024 Base.get() == OldBase &&
15025 BaseType == E->getBaseType() &&
15026 QualifierLoc == E->getQualifierLoc() &&
15027 NameInfo.getName() == E->getMember() &&
15028 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
15029 return E;
15030
15031 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15032 BaseType,
15033 E->isArrow(),
15034 E->getOperatorLoc(),
15035 QualifierLoc,
15036 TemplateKWLoc,
15037 FirstQualifierInScope,
15038 NameInfo,
15039 /*TemplateArgs*/nullptr);
15040 }
15041
15042 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15043 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
15044 E->getNumTemplateArgs(),
15045 TransArgs))
15046 return ExprError();
15047
15048 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15049 BaseType,
15050 E->isArrow(),
15051 E->getOperatorLoc(),
15052 QualifierLoc,
15053 TemplateKWLoc,
15054 FirstQualifierInScope,
15055 NameInfo,
15056 &TransArgs);
15057}
15058
15059template <typename Derived>
15060ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
15061 UnresolvedMemberExpr *Old) {
15062 // Transform the base of the expression.
15063 ExprResult Base((Expr *)nullptr);
15064 QualType BaseType;
15065 if (!Old->isImplicitAccess()) {
15066 Base = getDerived().TransformExpr(Old->getBase());
15067 if (Base.isInvalid())
15068 return ExprError();
15069 Base =
15070 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
15071 if (Base.isInvalid())
15072 return ExprError();
15073 BaseType = Base.get()->getType();
15074 } else {
15075 BaseType = getDerived().TransformType(Old->getBaseType());
15076 }
15077
15078 NestedNameSpecifierLoc QualifierLoc;
15079 if (Old->getQualifierLoc()) {
15080 QualifierLoc =
15081 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
15082 if (!QualifierLoc)
15083 return ExprError();
15084 }
15085
15086 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
15087
15088 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
15089
15090 // Transform the declaration set.
15091 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ false, R))
15092 return ExprError();
15093
15094 // Determine the naming class.
15095 if (Old->getNamingClass()) {
15096 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
15097 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
15098 if (!NamingClass)
15099 return ExprError();
15100
15101 R.setNamingClass(NamingClass);
15102 }
15103
15104 TemplateArgumentListInfo TransArgs;
15105 if (Old->hasExplicitTemplateArgs()) {
15106 TransArgs.setLAngleLoc(Old->getLAngleLoc());
15107 TransArgs.setRAngleLoc(Old->getRAngleLoc());
15108 if (getDerived().TransformTemplateArguments(
15109 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
15110 return ExprError();
15111 }
15112
15113 // FIXME: to do this check properly, we will need to preserve the
15114 // first-qualifier-in-scope here, just in case we had a dependent
15115 // base (and therefore couldn't do the check) and a
15116 // nested-name-qualifier (and therefore could do the lookup).
15117 NamedDecl *FirstQualifierInScope = nullptr;
15118
15119 return getDerived().RebuildUnresolvedMemberExpr(
15120 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
15121 TemplateKWLoc, FirstQualifierInScope, R,
15122 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
15123}
15124
15125template<typename Derived>
15127TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
15128 EnterExpressionEvaluationContext Unevaluated(
15130 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
15131 if (SubExpr.isInvalid())
15132 return ExprError();
15133
15134 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
15135 return E;
15136
15137 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
15138}
15139
15140template<typename Derived>
15142TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
15143 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
15144 if (Pattern.isInvalid())
15145 return ExprError();
15146
15147 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
15148 return E;
15149
15150 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
15151 E->getNumExpansions());
15152}
15153
15154template<typename Derived>
15156TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
15157 // If E is not value-dependent, then nothing will change when we transform it.
15158 // Note: This is an instantiation-centric view.
15159 if (!E->isValueDependent())
15160 return E;
15161
15162 EnterExpressionEvaluationContext Unevaluated(
15164
15166 TemplateArgument ArgStorage;
15167
15168 // Find the argument list to transform.
15169 if (E->isPartiallySubstituted()) {
15170 PackArgs = E->getPartialArguments();
15171 } else if (E->isValueDependent()) {
15172 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
15173 bool ShouldExpand = false;
15174 bool RetainExpansion = false;
15175 std::optional<unsigned> NumExpansions;
15176 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
15177 Unexpanded,
15178 ShouldExpand, RetainExpansion,
15179 NumExpansions))
15180 return ExprError();
15181
15182 // If we need to expand the pack, build a template argument from it and
15183 // expand that.
15184 if (ShouldExpand) {
15185 auto *Pack = E->getPack();
15186 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) {
15187 ArgStorage = getSema().Context.getPackExpansionType(
15188 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
15189 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {
15190 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
15191 } else {
15192 auto *VD = cast<ValueDecl>(Pack);
15193 ExprResult DRE = getSema().BuildDeclRefExpr(
15194 VD, VD->getType().getNonLValueExprType(getSema().Context),
15195 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
15196 E->getPackLoc());
15197 if (DRE.isInvalid())
15198 return ExprError();
15199 ArgStorage = new (getSema().Context)
15200 PackExpansionExpr(getSema().Context.DependentTy, DRE.get(),
15201 E->getPackLoc(), std::nullopt);
15202 }
15203 PackArgs = ArgStorage;
15204 }
15205 }
15206
15207 // If we're not expanding the pack, just transform the decl.
15208 if (!PackArgs.size()) {
15209 auto *Pack = cast_or_null<NamedDecl>(
15210 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
15211 if (!Pack)
15212 return ExprError();
15213 return getDerived().RebuildSizeOfPackExpr(
15214 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
15215 std::nullopt, std::nullopt);
15216 }
15217
15218 // Try to compute the result without performing a partial substitution.
15219 std::optional<unsigned> Result = 0;
15220 for (const TemplateArgument &Arg : PackArgs) {
15221 if (!Arg.isPackExpansion()) {
15222 Result = *Result + 1;
15223 continue;
15224 }
15225
15226 TemplateArgumentLoc ArgLoc;
15227 InventTemplateArgumentLoc(Arg, ArgLoc);
15228
15229 // Find the pattern of the pack expansion.
15230 SourceLocation Ellipsis;
15231 std::optional<unsigned> OrigNumExpansions;
15232 TemplateArgumentLoc Pattern =
15233 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
15234 OrigNumExpansions);
15235
15236 // Substitute under the pack expansion. Do not expand the pack (yet).
15237 TemplateArgumentLoc OutPattern;
15238 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15239 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
15240 /*Uneval*/ true))
15241 return true;
15242
15243 // See if we can determine the number of arguments from the result.
15244 std::optional<unsigned> NumExpansions =
15245 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
15246 if (!NumExpansions) {
15247 // No: we must be in an alias template expansion, and we're going to need
15248 // to actually expand the packs.
15249 Result = std::nullopt;
15250 break;
15251 }
15252
15253 Result = *Result + *NumExpansions;
15254 }
15255
15256 // Common case: we could determine the number of expansions without
15257 // substituting.
15258 if (Result)
15259 return getDerived().RebuildSizeOfPackExpr(
15260 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
15261 *Result, std::nullopt);
15262
15263 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
15264 E->getPackLoc());
15265 {
15266 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
15267 typedef TemplateArgumentLocInventIterator<
15268 Derived, const TemplateArgument*> PackLocIterator;
15269 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
15270 PackLocIterator(*this, PackArgs.end()),
15271 TransformedPackArgs, /*Uneval*/true))
15272 return ExprError();
15273 }
15274
15275 // Check whether we managed to fully-expand the pack.
15276 // FIXME: Is it possible for us to do so and not hit the early exit path?
15278 bool PartialSubstitution = false;
15279 for (auto &Loc : TransformedPackArgs.arguments()) {
15280 Args.push_back(Loc.getArgument());
15281 if (Loc.getArgument().isPackExpansion())
15282 PartialSubstitution = true;
15283 }
15284
15285 if (PartialSubstitution)
15286 return getDerived().RebuildSizeOfPackExpr(
15287 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
15288 std::nullopt, Args);
15289
15290 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
15291 E->getPackLoc(), E->getRParenLoc(),
15292 Args.size(), std::nullopt);
15293}
15294
15295template <typename Derived>
15297TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
15298 if (!E->isValueDependent())
15299 return E;
15300
15301 // Transform the index
15302 ExprResult IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
15303 if (IndexExpr.isInvalid())
15304 return ExprError();
15305
15306 SmallVector<Expr *, 5> ExpandedExprs;
15307 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
15308 Expr *Pattern = E->getPackIdExpression();
15310 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
15311 Unexpanded);
15312 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
15313
15314 // Determine whether the set of unexpanded parameter packs can and should
15315 // be expanded.
15316 bool ShouldExpand = true;
15317 bool RetainExpansion = false;
15318 std::optional<unsigned> OrigNumExpansions;
15319 std::optional<unsigned> NumExpansions = OrigNumExpansions;
15320 if (getDerived().TryExpandParameterPacks(
15321 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
15322 ShouldExpand, RetainExpansion, NumExpansions))
15323 return true;
15324 if (!ShouldExpand) {
15325 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15326 ExprResult Pack = getDerived().TransformExpr(Pattern);
15327 if (Pack.isInvalid())
15328 return ExprError();
15329 return getDerived().RebuildPackIndexingExpr(
15330 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
15331 std::nullopt);
15332 }
15333 for (unsigned I = 0; I != *NumExpansions; ++I) {
15334 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
15335 ExprResult Out = getDerived().TransformExpr(Pattern);
15336 if (Out.isInvalid())
15337 return true;
15338 if (Out.get()->containsUnexpandedParameterPack()) {
15339 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
15340 OrigNumExpansions);
15341 if (Out.isInvalid())
15342 return true;
15343 }
15344 ExpandedExprs.push_back(Out.get());
15345 }
15346 // If we're supposed to retain a pack expansion, do so by temporarily
15347 // forgetting the partially-substituted parameter pack.
15348 if (RetainExpansion) {
15349 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15350
15351 ExprResult Out = getDerived().TransformExpr(Pattern);
15352 if (Out.isInvalid())
15353 return true;
15354
15355 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
15356 OrigNumExpansions);
15357 if (Out.isInvalid())
15358 return true;
15359 ExpandedExprs.push_back(Out.get());
15360 }
15361 } else if (!E->expandsToEmptyPack()) {
15362 if (getDerived().TransformExprs(E->getExpressions().data(),
15363 E->getExpressions().size(), false,
15364 ExpandedExprs))
15365 return ExprError();
15366 }
15367
15368 return getDerived().RebuildPackIndexingExpr(
15369 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
15370 IndexExpr.get(), ExpandedExprs,
15371 /*EmptyPack=*/ExpandedExprs.size() == 0);
15372}
15373
15374template<typename Derived>
15376TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
15377 SubstNonTypeTemplateParmPackExpr *E) {
15378 // Default behavior is to do nothing with this transformation.
15379 return E;
15380}
15381
15382template<typename Derived>
15384TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
15385 SubstNonTypeTemplateParmExpr *E) {
15386 // Default behavior is to do nothing with this transformation.
15387 return E;
15388}
15389
15390template<typename Derived>
15392TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
15393 // Default behavior is to do nothing with this transformation.
15394 return E;
15395}
15396
15397template<typename Derived>
15399TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
15400 MaterializeTemporaryExpr *E) {
15401 return getDerived().TransformExpr(E->getSubExpr());
15402}
15403
15404template<typename Derived>
15406TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
15407 UnresolvedLookupExpr *Callee = nullptr;
15408 if (Expr *OldCallee = E->getCallee()) {
15409 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
15410 if (CalleeResult.isInvalid())
15411 return ExprError();
15412 Callee = cast<UnresolvedLookupExpr>(CalleeResult.get());
15413 }
15414
15415 Expr *Pattern = E->getPattern();
15416
15418 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
15419 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
15420
15421 // Determine whether the set of unexpanded parameter packs can and should
15422 // be expanded.
15423 bool Expand = true;
15424 bool RetainExpansion = false;
15425 std::optional<unsigned> OrigNumExpansions = E->getNumExpansions(),
15426 NumExpansions = OrigNumExpansions;
15427 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
15428 Pattern->getSourceRange(),
15429 Unexpanded,
15430 Expand, RetainExpansion,
15431 NumExpansions))
15432 return true;
15433
15434 if (!Expand) {
15435 // Do not expand any packs here, just transform and rebuild a fold
15436 // expression.
15437 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15438
15439 ExprResult LHS =
15440 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
15441 if (LHS.isInvalid())
15442 return true;
15443
15444 ExprResult RHS =
15445 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
15446 if (RHS.isInvalid())
15447 return true;
15448
15449 if (!getDerived().AlwaysRebuild() &&
15450 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
15451 return E;
15452
15453 return getDerived().RebuildCXXFoldExpr(
15454 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
15455 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
15456 }
15457
15458 // Formally a fold expression expands to nested parenthesized expressions.
15459 // Enforce this limit to avoid creating trees so deep we can't safely traverse
15460 // them.
15461 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) {
15462 SemaRef.Diag(E->getEllipsisLoc(),
15463 clang::diag::err_fold_expression_limit_exceeded)
15464 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
15465 << E->getSourceRange();
15466 SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);
15467 return ExprError();
15468 }
15469
15470 // The transform has determined that we should perform an elementwise
15471 // expansion of the pattern. Do so.
15472 ExprResult Result = getDerived().TransformExpr(E->getInit());
15473 if (Result.isInvalid())
15474 return true;
15475 bool LeftFold = E->isLeftFold();
15476
15477 // If we're retaining an expansion for a right fold, it is the innermost
15478 // component and takes the init (if any).
15479 if (!LeftFold && RetainExpansion) {
15480 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15481
15482 ExprResult Out = getDerived().TransformExpr(Pattern);
15483 if (Out.isInvalid())
15484 return true;
15485
15486 Result = getDerived().RebuildCXXFoldExpr(
15487 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
15488 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
15489 if (Result.isInvalid())
15490 return true;
15491 }
15492
15493 for (unsigned I = 0; I != *NumExpansions; ++I) {
15494 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(
15495 getSema(), LeftFold ? I : *NumExpansions - I - 1);
15496 ExprResult Out = getDerived().TransformExpr(Pattern);
15497 if (Out.isInvalid())
15498 return true;
15499
15500 if (Out.get()->containsUnexpandedParameterPack()) {
15501 // We still have a pack; retain a pack expansion for this slice.
15502 Result = getDerived().RebuildCXXFoldExpr(
15503 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
15504 E->getOperator(), E->getEllipsisLoc(),
15505 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
15506 OrigNumExpansions);
15507 } else if (Result.isUsable()) {
15508 // We've got down to a single element; build a binary operator.
15509 Expr *LHS = LeftFold ? Result.get() : Out.get();
15510 Expr *RHS = LeftFold ? Out.get() : Result.get();
15511 if (Callee) {
15512 UnresolvedSet<16> Functions;
15513 Functions.append(Callee->decls_begin(), Callee->decls_end());
15514 Result = getDerived().RebuildCXXOperatorCallExpr(
15516 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
15517 Functions, LHS, RHS);
15518 } else {
15519 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
15520 E->getOperator(), LHS, RHS);
15521 }
15522 } else
15523 Result = Out;
15524
15525 if (Result.isInvalid())
15526 return true;
15527 }
15528
15529 // If we're retaining an expansion for a left fold, it is the outermost
15530 // component and takes the complete expansion so far as its init (if any).
15531 if (LeftFold && RetainExpansion) {
15532 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15533
15534 ExprResult Out = getDerived().TransformExpr(Pattern);
15535 if (Out.isInvalid())
15536 return true;
15537
15538 Result = getDerived().RebuildCXXFoldExpr(
15539 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
15540 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
15541 if (Result.isInvalid())
15542 return true;
15543 }
15544
15545 // If we had no init and an empty pack, and we're not retaining an expansion,
15546 // then produce a fallback value or error.
15547 if (Result.isUnset())
15548 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
15549 E->getOperator());
15550
15551 return Result;
15552}
15553
15554template <typename Derived>
15556TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
15557 SmallVector<Expr *, 4> TransformedInits;
15558 ArrayRef<Expr *> InitExprs = E->getInitExprs();
15559 if (TransformExprs(InitExprs.data(), InitExprs.size(), true,
15560 TransformedInits))
15561 return ExprError();
15562
15563 return getDerived().RebuildParenListExpr(E->getBeginLoc(), TransformedInits,
15564 E->getEndLoc());
15565}
15566
15567template<typename Derived>
15569TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
15570 CXXStdInitializerListExpr *E) {
15571 return getDerived().TransformExpr(E->getSubExpr());
15572}
15573
15574template<typename Derived>
15576TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
15577 return SemaRef.MaybeBindToTemporary(E);
15578}
15579
15580template<typename Derived>
15582TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
15583 return E;
15584}
15585
15586template<typename Derived>
15588TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
15589 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
15590 if (SubExpr.isInvalid())
15591 return ExprError();
15592
15593 if (!getDerived().AlwaysRebuild() &&
15594 SubExpr.get() == E->getSubExpr())
15595 return E;
15596
15597 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
15598}
15599
15600template<typename Derived>
15602TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
15603 // Transform each of the elements.
15604 SmallVector<Expr *, 8> Elements;
15605 bool ArgChanged = false;
15606 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
15607 /*IsCall=*/false, Elements, &ArgChanged))
15608 return ExprError();
15609
15610 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15611 return SemaRef.MaybeBindToTemporary(E);
15612
15613 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
15614 Elements.data(),
15615 Elements.size());
15616}
15617
15618template<typename Derived>
15620TreeTransform<Derived>::TransformObjCDictionaryLiteral(
15621 ObjCDictionaryLiteral *E) {
15622 // Transform each of the elements.
15624 bool ArgChanged = false;
15625 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
15626 ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);
15627
15628 if (OrigElement.isPackExpansion()) {
15629 // This key/value element is a pack expansion.
15631 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
15632 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
15633 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
15634
15635 // Determine whether the set of unexpanded parameter packs can
15636 // and should be expanded.
15637 bool Expand = true;
15638 bool RetainExpansion = false;
15639 std::optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
15640 std::optional<unsigned> NumExpansions = OrigNumExpansions;
15641 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
15642 OrigElement.Value->getEndLoc());
15643 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
15644 PatternRange, Unexpanded, Expand,
15645 RetainExpansion, NumExpansions))
15646 return ExprError();
15647
15648 if (!Expand) {
15649 // The transform has determined that we should perform a simple
15650 // transformation on the pack expansion, producing another pack
15651 // expansion.
15652 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15653 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15654 if (Key.isInvalid())
15655 return ExprError();
15656
15657 if (Key.get() != OrigElement.Key)
15658 ArgChanged = true;
15659
15660 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
15661 if (Value.isInvalid())
15662 return ExprError();
15663
15664 if (Value.get() != OrigElement.Value)
15665 ArgChanged = true;
15666
15667 ObjCDictionaryElement Expansion = {
15668 Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions
15669 };
15670 Elements.push_back(Expansion);
15671 continue;
15672 }
15673
15674 // Record right away that the argument was changed. This needs
15675 // to happen even if the array expands to nothing.
15676 ArgChanged = true;
15677
15678 // The transform has determined that we should perform an elementwise
15679 // expansion of the pattern. Do so.
15680 for (unsigned I = 0; I != *NumExpansions; ++I) {
15681 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
15682 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15683 if (Key.isInvalid())
15684 return ExprError();
15685
15686 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
15687 if (Value.isInvalid())
15688 return ExprError();
15689
15690 ObjCDictionaryElement Element = {
15691 Key.get(), Value.get(), SourceLocation(), NumExpansions
15692 };
15693
15694 // If any unexpanded parameter packs remain, we still have a
15695 // pack expansion.
15696 // FIXME: Can this really happen?
15697 if (Key.get()->containsUnexpandedParameterPack() ||
15698 Value.get()->containsUnexpandedParameterPack())
15699 Element.EllipsisLoc = OrigElement.EllipsisLoc;
15700
15701 Elements.push_back(Element);
15702 }
15703
15704 // FIXME: Retain a pack expansion if RetainExpansion is true.
15705
15706 // We've finished with this pack expansion.
15707 continue;
15708 }
15709
15710 // Transform and check key.
15711 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15712 if (Key.isInvalid())
15713 return ExprError();
15714
15715 if (Key.get() != OrigElement.Key)
15716 ArgChanged = true;
15717
15718 // Transform and check value.
15720 = getDerived().TransformExpr(OrigElement.Value);
15721 if (Value.isInvalid())
15722 return ExprError();
15723
15724 if (Value.get() != OrigElement.Value)
15725 ArgChanged = true;
15726
15727 ObjCDictionaryElement Element = {Key.get(), Value.get(), SourceLocation(),
15728 std::nullopt};
15729 Elements.push_back(Element);
15730 }
15731
15732 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15733 return SemaRef.MaybeBindToTemporary(E);
15734
15735 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
15736 Elements);
15737}
15738
15739template<typename Derived>
15741TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
15742 TypeSourceInfo *EncodedTypeInfo
15743 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
15744 if (!EncodedTypeInfo)
15745 return ExprError();
15746
15747 if (!getDerived().AlwaysRebuild() &&
15748 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
15749 return E;
15750
15751 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
15752 EncodedTypeInfo,
15753 E->getRParenLoc());
15754}
15755
15756template<typename Derived>
15757ExprResult TreeTransform<Derived>::
15758TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
15759 // This is a kind of implicit conversion, and it needs to get dropped
15760 // and recomputed for the same general reasons that ImplicitCastExprs
15761 // do, as well a more specific one: this expression is only valid when
15762 // it appears *immediately* as an argument expression.
15763 return getDerived().TransformExpr(E->getSubExpr());
15764}
15765
15766template<typename Derived>
15767ExprResult TreeTransform<Derived>::
15768TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
15769 TypeSourceInfo *TSInfo
15770 = getDerived().TransformType(E->getTypeInfoAsWritten());
15771 if (!TSInfo)
15772 return ExprError();
15773
15774 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
15775 if (Result.isInvalid())
15776 return ExprError();
15777
15778 if (!getDerived().AlwaysRebuild() &&
15779 TSInfo == E->getTypeInfoAsWritten() &&
15780 Result.get() == E->getSubExpr())
15781 return E;
15782
15783 return SemaRef.ObjC().BuildObjCBridgedCast(
15784 E->getLParenLoc(), E->getBridgeKind(), E->getBridgeKeywordLoc(), TSInfo,
15785 Result.get());
15786}
15787
15788template <typename Derived>
15789ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
15790 ObjCAvailabilityCheckExpr *E) {
15791 return E;
15792}
15793
15794template<typename Derived>
15796TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
15797 // Transform arguments.
15798 bool ArgChanged = false;
15800 Args.reserve(E->getNumArgs());
15801 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
15802 &ArgChanged))
15803 return ExprError();
15804
15805 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
15806 // Class message: transform the receiver type.
15807 TypeSourceInfo *ReceiverTypeInfo
15808 = getDerived().TransformType(E->getClassReceiverTypeInfo());
15809 if (!ReceiverTypeInfo)
15810 return ExprError();
15811
15812 // If nothing changed, just retain the existing message send.
15813 if (!getDerived().AlwaysRebuild() &&
15814 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
15815 return SemaRef.MaybeBindToTemporary(E);
15816
15817 // Build a new class message send.
15819 E->getSelectorLocs(SelLocs);
15820 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
15821 E->getSelector(),
15822 SelLocs,
15823 E->getMethodDecl(),
15824 E->getLeftLoc(),
15825 Args,
15826 E->getRightLoc());
15827 }
15828 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
15829 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
15830 if (!E->getMethodDecl())
15831 return ExprError();
15832
15833 // Build a new class message send to 'super'.
15835 E->getSelectorLocs(SelLocs);
15836 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
15837 E->getSelector(),
15838 SelLocs,
15839 E->getReceiverType(),
15840 E->getMethodDecl(),
15841 E->getLeftLoc(),
15842 Args,
15843 E->getRightLoc());
15844 }
15845
15846 // Instance message: transform the receiver
15847 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
15848 "Only class and instance messages may be instantiated");
15849 ExprResult Receiver
15850 = getDerived().TransformExpr(E->getInstanceReceiver());
15851 if (Receiver.isInvalid())
15852 return ExprError();
15853
15854 // If nothing changed, just retain the existing message send.
15855 if (!getDerived().AlwaysRebuild() &&
15856 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
15857 return SemaRef.MaybeBindToTemporary(E);
15858
15859 // Build a new instance message send.
15861 E->getSelectorLocs(SelLocs);
15862 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
15863 E->getSelector(),
15864 SelLocs,
15865 E->getMethodDecl(),
15866 E->getLeftLoc(),
15867 Args,
15868 E->getRightLoc());
15869}
15870
15871template<typename Derived>
15873TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
15874 return E;
15875}
15876
15877template<typename Derived>
15879TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
15880 return E;
15881}
15882
15883template<typename Derived>
15885TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
15886 // Transform the base expression.
15887 ExprResult Base = getDerived().TransformExpr(E->getBase());
15888 if (Base.isInvalid())
15889 return ExprError();
15890
15891 // We don't need to transform the ivar; it will never change.
15892
15893 // If nothing changed, just retain the existing expression.
15894 if (!getDerived().AlwaysRebuild() &&
15895 Base.get() == E->getBase())
15896 return E;
15897
15898 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
15899 E->getLocation(),
15900 E->isArrow(), E->isFreeIvar());
15901}
15902
15903template<typename Derived>
15905TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
15906 // 'super' and types never change. Property never changes. Just
15907 // retain the existing expression.
15908 if (!E->isObjectReceiver())
15909 return E;
15910
15911 // Transform the base expression.
15912 ExprResult Base = getDerived().TransformExpr(E->getBase());
15913 if (Base.isInvalid())
15914 return ExprError();
15915
15916 // We don't need to transform the property; it will never change.
15917
15918 // If nothing changed, just retain the existing expression.
15919 if (!getDerived().AlwaysRebuild() &&
15920 Base.get() == E->getBase())
15921 return E;
15922
15923 if (E->isExplicitProperty())
15924 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
15925 E->getExplicitProperty(),
15926 E->getLocation());
15927
15928 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
15929 SemaRef.Context.PseudoObjectTy,
15930 E->getImplicitPropertyGetter(),
15931 E->getImplicitPropertySetter(),
15932 E->getLocation());
15933}
15934
15935template<typename Derived>
15937TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
15938 // Transform the base expression.
15939 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
15940 if (Base.isInvalid())
15941 return ExprError();
15942
15943 // Transform the key expression.
15944 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
15945 if (Key.isInvalid())
15946 return ExprError();
15947
15948 // If nothing changed, just retain the existing expression.
15949 if (!getDerived().AlwaysRebuild() &&
15950 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
15951 return E;
15952
15953 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
15954 Base.get(), Key.get(),
15955 E->getAtIndexMethodDecl(),
15956 E->setAtIndexMethodDecl());
15957}
15958
15959template<typename Derived>
15961TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
15962 // Transform the base expression.
15963 ExprResult Base = getDerived().TransformExpr(E->getBase());
15964 if (Base.isInvalid())
15965 return ExprError();
15966
15967 // If nothing changed, just retain the existing expression.
15968 if (!getDerived().AlwaysRebuild() &&
15969 Base.get() == E->getBase())
15970 return E;
15971
15972 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
15973 E->getOpLoc(),
15974 E->isArrow());
15975}
15976
15977template<typename Derived>
15979TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
15980 bool ArgumentChanged = false;
15981 SmallVector<Expr*, 8> SubExprs;
15982 SubExprs.reserve(E->getNumSubExprs());
15983 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
15984 SubExprs, &ArgumentChanged))
15985 return ExprError();
15986
15987 if (!getDerived().AlwaysRebuild() &&
15988 !ArgumentChanged)
15989 return E;
15990
15991 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
15992 SubExprs,
15993 E->getRParenLoc());
15994}
15995
15996template<typename Derived>
15998TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
15999 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
16000 if (SrcExpr.isInvalid())
16001 return ExprError();
16002
16003 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
16004 if (!Type)
16005 return ExprError();
16006
16007 if (!getDerived().AlwaysRebuild() &&
16008 Type == E->getTypeSourceInfo() &&
16009 SrcExpr.get() == E->getSrcExpr())
16010 return E;
16011
16012 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
16013 SrcExpr.get(), Type,
16014 E->getRParenLoc());
16015}
16016
16017template<typename Derived>
16019TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
16020 BlockDecl *oldBlock = E->getBlockDecl();
16021
16022 SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr);
16023 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
16024
16025 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
16026 blockScope->TheDecl->setBlockMissingReturnType(
16027 oldBlock->blockMissingReturnType());
16028
16030 SmallVector<QualType, 4> paramTypes;
16031
16032 const FunctionProtoType *exprFunctionType = E->getFunctionType();
16033
16034 // Parameter substitution.
16035 Sema::ExtParameterInfoBuilder extParamInfos;
16036 if (getDerived().TransformFunctionTypeParams(
16037 E->getCaretLocation(), oldBlock->parameters(), nullptr,
16038 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
16039 extParamInfos)) {
16040 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
16041 return ExprError();
16042 }
16043
16044 QualType exprResultType =
16045 getDerived().TransformType(exprFunctionType->getReturnType());
16046
16047 auto epi = exprFunctionType->getExtProtoInfo();
16048 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size());
16049
16050 QualType functionType =
16051 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
16052 blockScope->FunctionType = functionType;
16053
16054 // Set the parameters on the block decl.
16055 if (!params.empty())
16056 blockScope->TheDecl->setParams(params);
16057
16058 if (!oldBlock->blockMissingReturnType()) {
16059 blockScope->HasImplicitReturnType = false;
16060 blockScope->ReturnType = exprResultType;
16061 }
16062
16063 // Transform the body
16064 StmtResult body = getDerived().TransformStmt(E->getBody());
16065 if (body.isInvalid()) {
16066 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
16067 return ExprError();
16068 }
16069
16070#ifndef NDEBUG
16071 // In builds with assertions, make sure that we captured everything we
16072 // captured before.
16073 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
16074 for (const auto &I : oldBlock->captures()) {
16075 VarDecl *oldCapture = I.getVariable();
16076
16077 // Ignore parameter packs.
16078 if (oldCapture->isParameterPack())
16079 continue;
16080
16081 VarDecl *newCapture =
16082 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
16083 oldCapture));
16084 assert(blockScope->CaptureMap.count(newCapture));
16085 }
16086
16087 // The this pointer may not be captured by the instantiated block, even when
16088 // it's captured by the original block, if the expression causing the
16089 // capture is in the discarded branch of a constexpr if statement.
16090 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
16091 "this pointer isn't captured in the old block");
16092 }
16093#endif
16094
16095 return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(),
16096 /*Scope=*/nullptr);
16097}
16098
16099template<typename Derived>
16101TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
16102 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
16103 if (SrcExpr.isInvalid())
16104 return ExprError();
16105
16106 QualType Type = getDerived().TransformType(E->getType());
16107
16108 return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(),
16109 E->getRParenLoc());
16110}
16111
16112template<typename Derived>
16114TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
16115 bool ArgumentChanged = false;
16116 SmallVector<Expr*, 8> SubExprs;
16117 SubExprs.reserve(E->getNumSubExprs());
16118 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
16119 SubExprs, &ArgumentChanged))
16120 return ExprError();
16121
16122 if (!getDerived().AlwaysRebuild() &&
16123 !ArgumentChanged)
16124 return E;
16125
16126 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
16127 E->getOp(), E->getRParenLoc());
16128}
16129
16130//===----------------------------------------------------------------------===//
16131// Type reconstruction
16132//===----------------------------------------------------------------------===//
16133
16134template<typename Derived>
16137 return SemaRef.BuildPointerType(PointeeType, Star,
16138 getDerived().getBaseEntity());
16139}
16140
16141template<typename Derived>
16144 return SemaRef.BuildBlockPointerType(PointeeType, Star,
16145 getDerived().getBaseEntity());
16146}
16147
16148template<typename Derived>
16151 bool WrittenAsLValue,
16152 SourceLocation Sigil) {
16153 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue,
16154 Sigil, getDerived().getBaseEntity());
16155}
16156
16157template<typename Derived>
16160 QualType ClassType,
16161 SourceLocation Sigil) {
16162 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil,
16163 getDerived().getBaseEntity());
16164}
16165
16166template<typename Derived>
16168 const ObjCTypeParamDecl *Decl,
16169 SourceLocation ProtocolLAngleLoc,
16171 ArrayRef<SourceLocation> ProtocolLocs,
16172 SourceLocation ProtocolRAngleLoc) {
16173 return SemaRef.ObjC().BuildObjCTypeParamType(
16174 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
16175 /*FailOnError=*/true);
16176}
16177
16178template<typename Derived>
16180 QualType BaseType,
16182 SourceLocation TypeArgsLAngleLoc,
16184 SourceLocation TypeArgsRAngleLoc,
16185 SourceLocation ProtocolLAngleLoc,
16187 ArrayRef<SourceLocation> ProtocolLocs,
16188 SourceLocation ProtocolRAngleLoc) {
16189 return SemaRef.ObjC().BuildObjCObjectType(
16190 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
16191 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
16192 /*FailOnError=*/true,
16193 /*Rebuilding=*/true);
16194}
16195
16196template<typename Derived>
16198 QualType PointeeType,
16200 return SemaRef.Context.getObjCObjectPointerType(PointeeType);
16201}
16202
16203template <typename Derived>
16205 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
16206 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
16207 if (SizeExpr || !Size)
16208 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
16209 IndexTypeQuals, BracketsRange,
16210 getDerived().getBaseEntity());
16211
16212 QualType Types[] = {
16216 };
16217 QualType SizeType;
16218 for (const auto &T : Types)
16219 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
16220 SizeType = T;
16221 break;
16222 }
16223
16224 // Note that we can return a VariableArrayType here in the case where
16225 // the element type was a dependent VariableArrayType.
16226 IntegerLiteral *ArraySize
16227 = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType,
16228 /*FIXME*/BracketsRange.getBegin());
16229 return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize,
16230 IndexTypeQuals, BracketsRange,
16231 getDerived().getBaseEntity());
16232}
16233
16234template <typename Derived>
16236 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
16237 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
16238 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
16239 IndexTypeQuals, BracketsRange);
16240}
16241
16242template <typename Derived>
16244 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
16245 SourceRange BracketsRange) {
16246 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
16247 IndexTypeQuals, BracketsRange);
16248}
16249
16250template <typename Derived>
16252 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
16253 unsigned IndexTypeQuals, SourceRange BracketsRange) {
16254 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
16255 SizeExpr,
16256 IndexTypeQuals, BracketsRange);
16257}
16258
16259template <typename Derived>
16261 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
16262 unsigned IndexTypeQuals, SourceRange BracketsRange) {
16263 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
16264 SizeExpr,
16265 IndexTypeQuals, BracketsRange);
16266}
16267
16268template <typename Derived>
16270 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
16271 return SemaRef.BuildAddressSpaceAttr(PointeeType, AddrSpaceExpr,
16272 AttributeLoc);
16273}
16274
16275template <typename Derived>
16277 unsigned NumElements,
16278 VectorKind VecKind) {
16279 // FIXME: semantic checking!
16280 return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);
16281}
16282
16283template <typename Derived>
16285 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
16286 VectorKind VecKind) {
16287 return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc);
16288}
16289
16290template<typename Derived>
16292 unsigned NumElements,
16293 SourceLocation AttributeLoc) {
16294 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
16295 NumElements, true);
16296 IntegerLiteral *VectorSize
16297 = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
16298 AttributeLoc);
16299 return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
16300}
16301
16302template<typename Derived>
16305 Expr *SizeExpr,
16306 SourceLocation AttributeLoc) {
16307 return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
16308}
16309
16310template <typename Derived>
16312 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
16313 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
16314 NumColumns);
16315}
16316
16317template <typename Derived>
16319 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
16320 SourceLocation AttributeLoc) {
16321 return SemaRef.BuildMatrixType(ElementType, RowExpr, ColumnExpr,
16322 AttributeLoc);
16323}
16324
16325template<typename Derived>
16327 QualType T,
16328 MutableArrayRef<QualType> ParamTypes,
16330 return SemaRef.BuildFunctionType(T, ParamTypes,
16331 getDerived().getBaseLocation(),
16332 getDerived().getBaseEntity(),
16333 EPI);
16334}
16335
16336template<typename Derived>
16338 return SemaRef.Context.getFunctionNoProtoType(T);
16339}
16340
16341template<typename Derived>
16343 Decl *D) {
16344 assert(D && "no decl found");
16345 if (D->isInvalidDecl()) return QualType();
16346
16347 // FIXME: Doesn't account for ObjCInterfaceDecl!
16348 if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
16349 // A valid resolved using typename pack expansion decl can have multiple
16350 // UsingDecls, but they must each have exactly one type, and it must be
16351 // the same type in every case. But we must have at least one expansion!
16352 if (UPD->expansions().empty()) {
16353 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
16354 << UPD->isCXXClassMember() << UPD;
16355 return QualType();
16356 }
16357
16358 // We might still have some unresolved types. Try to pick a resolved type
16359 // if we can. The final instantiation will check that the remaining
16360 // unresolved types instantiate to the type we pick.
16361 QualType FallbackT;
16362 QualType T;
16363 for (auto *E : UPD->expansions()) {
16364 QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
16365 if (ThisT.isNull())
16366 continue;
16367 else if (ThisT->getAs<UnresolvedUsingType>())
16368 FallbackT = ThisT;
16369 else if (T.isNull())
16370 T = ThisT;
16371 else
16372 assert(getSema().Context.hasSameType(ThisT, T) &&
16373 "mismatched resolved types in using pack expansion");
16374 }
16375 return T.isNull() ? FallbackT : T;
16376 } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
16377 assert(Using->hasTypename() &&
16378 "UnresolvedUsingTypenameDecl transformed to non-typename using");
16379
16380 // A valid resolved using typename decl points to exactly one type decl.
16381 assert(++Using->shadow_begin() == Using->shadow_end());
16382
16383 UsingShadowDecl *Shadow = *Using->shadow_begin();
16384 if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), Loc))
16385 return QualType();
16386 return SemaRef.Context.getUsingType(
16387 Shadow, SemaRef.Context.getTypeDeclType(
16388 cast<TypeDecl>(Shadow->getTargetDecl())));
16389 } else {
16390 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
16391 "UnresolvedUsingTypenameDecl transformed to non-using decl");
16392 return SemaRef.Context.getTypeDeclType(
16393 cast<UnresolvedUsingTypenameDecl>(D));
16394 }
16395}
16396
16397template <typename Derived>
16399 TypeOfKind Kind) {
16400 return SemaRef.BuildTypeofExprType(E, Kind);
16401}
16402
16403template<typename Derived>
16405 TypeOfKind Kind) {
16406 return SemaRef.Context.getTypeOfType(Underlying, Kind);
16407}
16408
16409template <typename Derived>
16411 return SemaRef.BuildDecltypeType(E);
16412}
16413
16414template <typename Derived>
16416 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
16417 SourceLocation EllipsisLoc, bool FullySubstituted,
16418 ArrayRef<QualType> Expansions) {
16419 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
16420 FullySubstituted, Expansions);
16421}
16422
16423template<typename Derived>
16427 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
16428}
16429
16430template<typename Derived>
16432 TemplateName Template,
16433 SourceLocation TemplateNameLoc,
16434 TemplateArgumentListInfo &TemplateArgs) {
16435 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
16436}
16437
16438template<typename Derived>
16440 SourceLocation KWLoc) {
16441 return SemaRef.BuildAtomicType(ValueType, KWLoc);
16442}
16443
16444template<typename Derived>
16446 SourceLocation KWLoc,
16447 bool isReadPipe) {
16448 return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc)
16449 : SemaRef.BuildWritePipeType(ValueType, KWLoc);
16450}
16451
16452template <typename Derived>
16454 unsigned NumBits,
16456 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
16457 NumBits, true);
16458 IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,
16459 SemaRef.Context.IntTy, Loc);
16460 return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc);
16461}
16462
16463template <typename Derived>
16465 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
16466 return SemaRef.BuildBitIntType(IsUnsigned, NumBitsExpr, Loc);
16467}
16468
16469template<typename Derived>
16472 bool TemplateKW,
16473 TemplateDecl *Template) {
16474 return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW,
16475 TemplateName(Template));
16476}
16477
16478template<typename Derived>
16481 SourceLocation TemplateKWLoc,
16482 const IdentifierInfo &Name,
16483 SourceLocation NameLoc,
16484 QualType ObjectType,
16485 NamedDecl *FirstQualifierInScope,
16486 bool AllowInjectedClassName) {
16488 TemplateName.setIdentifier(&Name, NameLoc);
16489 Sema::TemplateTy Template;
16490 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
16491 TemplateName, ParsedType::make(ObjectType),
16492 /*EnteringContext=*/false, Template,
16493 AllowInjectedClassName);
16494 return Template.get();
16495}
16496
16497template<typename Derived>
16500 SourceLocation TemplateKWLoc,
16501 OverloadedOperatorKind Operator,
16502 SourceLocation NameLoc,
16503 QualType ObjectType,
16504 bool AllowInjectedClassName) {
16505 UnqualifiedId Name;
16506 // FIXME: Bogus location information.
16507 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
16508 Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);
16509 Sema::TemplateTy Template;
16510 getSema().ActOnTemplateName(
16511 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(ObjectType),
16512 /*EnteringContext=*/false, Template, AllowInjectedClassName);
16513 return Template.get();
16514}
16515
16516template <typename Derived>
16519 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
16520 Expr *Second) {
16521 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
16522
16523 if (First->getObjectKind() == OK_ObjCProperty) {
16526 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/nullptr, OpLoc,
16527 Opc, First, Second);
16529 if (Result.isInvalid())
16530 return ExprError();
16531 First = Result.get();
16532 }
16533
16534 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
16535 ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
16536 if (Result.isInvalid())
16537 return ExprError();
16538 Second = Result.get();
16539 }
16540
16541 // Determine whether this should be a builtin operation.
16542 if (Op == OO_Subscript) {
16543 if (!First->getType()->isOverloadableType() &&
16544 !Second->getType()->isOverloadableType())
16545 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
16546 OpLoc);
16547 } else if (Op == OO_Arrow) {
16548 // It is possible that the type refers to a RecoveryExpr created earlier
16549 // in the tree transformation.
16550 if (First->getType()->isDependentType())
16551 return ExprError();
16552 // -> is never a builtin operation.
16553 return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);
16554 } else if (Second == nullptr || isPostIncDec) {
16555 if (!First->getType()->isOverloadableType() ||
16556 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
16557 // The argument is not of overloadable type, or this is an expression
16558 // of the form &Class::member, so try to create a built-in unary
16559 // operation.
16561 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
16562
16563 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
16564 }
16565 } else {
16566 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
16567 !First->getType()->isOverloadableType() &&
16568 !Second->getType()->isOverloadableType()) {
16569 // Neither of the arguments is type-dependent or has an overloadable
16570 // type, so try to create a built-in binary operation.
16573 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
16574 if (Result.isInvalid())
16575 return ExprError();
16576
16577 return Result;
16578 }
16579 }
16580
16581 // Create the overloaded operator invocation for unary operators.
16582 if (!Second || isPostIncDec) {
16584 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
16585 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First,
16586 RequiresADL);
16587 }
16588
16589 // Create the overloaded operator invocation for binary operators.
16591 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions,
16592 First, Second, RequiresADL);
16593 if (Result.isInvalid())
16594 return ExprError();
16595
16596 return Result;
16597}
16598
16599template<typename Derived>
16602 SourceLocation OperatorLoc,
16603 bool isArrow,
16604 CXXScopeSpec &SS,
16605 TypeSourceInfo *ScopeType,
16606 SourceLocation CCLoc,
16607 SourceLocation TildeLoc,
16608 PseudoDestructorTypeStorage Destroyed) {
16609 QualType BaseType = Base->getType();
16610 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
16611 (!isArrow && !BaseType->getAs<RecordType>()) ||
16612 (isArrow && BaseType->getAs<PointerType>() &&
16613 !BaseType->castAs<PointerType>()->getPointeeType()
16614 ->template getAs<RecordType>())){
16615 // This pseudo-destructor expression is still a pseudo-destructor.
16616 return SemaRef.BuildPseudoDestructorExpr(
16617 Base, OperatorLoc, isArrow ? tok::arrow : tok::period, SS, ScopeType,
16618 CCLoc, TildeLoc, Destroyed);
16619 }
16620
16621 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
16623 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
16624 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
16625 NameInfo.setNamedTypeInfo(DestroyedType);
16626
16627 // The scope type is now known to be a valid nested name specifier
16628 // component. Tack it on to the end of the nested name specifier.
16629 if (ScopeType) {
16630 if (!ScopeType->getType()->getAs<TagType>()) {
16631 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
16632 diag::err_expected_class_or_namespace)
16633 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
16634 return ExprError();
16635 }
16636 SS.Extend(SemaRef.Context, SourceLocation(), ScopeType->getTypeLoc(),
16637 CCLoc);
16638 }
16639
16640 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
16641 return getSema().BuildMemberReferenceExpr(Base, BaseType,
16642 OperatorLoc, isArrow,
16643 SS, TemplateKWLoc,
16644 /*FIXME: FirstQualifier*/ nullptr,
16645 NameInfo,
16646 /*TemplateArgs*/ nullptr,
16647 /*S*/nullptr);
16648}
16649
16650template<typename Derived>
16653 SourceLocation Loc = S->getBeginLoc();
16654 CapturedDecl *CD = S->getCapturedDecl();
16655 unsigned NumParams = CD->getNumParams();
16656 unsigned ContextParamPos = CD->getContextParamPosition();
16658 for (unsigned I = 0; I < NumParams; ++I) {
16659 if (I != ContextParamPos) {
16660 Params.push_back(
16661 std::make_pair(
16662 CD->getParam(I)->getName(),
16663 getDerived().TransformType(CD->getParam(I)->getType())));
16664 } else {
16665 Params.push_back(std::make_pair(StringRef(), QualType()));
16666 }
16667 }
16668 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
16669 S->getCapturedRegionKind(), Params);
16670 StmtResult Body;
16671 {
16672 Sema::CompoundScopeRAII CompoundScope(getSema());
16673 Body = getDerived().TransformStmt(S->getCapturedStmt());
16674 }
16675
16676 if (Body.isInvalid()) {
16677 getSema().ActOnCapturedRegionError();
16678 return StmtError();
16679 }
16680
16681 return getSema().ActOnCapturedRegionEnd(Body.get());
16682}
16683
16684} // end namespace clang
16685
16686#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
MatchType Type
const Decl * D
Expr * E
unsigned OldSize
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:1171
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines Expressions and AST nodes for C++2a concepts.
int Priority
Definition: Format.cpp:3005
unsigned Iter
Definition: HTMLLogger.cpp:154
#define X(type, name)
Definition: Value.h:143
llvm::MachO::Target Target
Definition: MachO.h:51
llvm::MachO::Record Record
Definition: MachO.h:31
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
uint32_t Id
Definition: SemaARM.cpp:1143
SourceRange Range
Definition: SemaObjC.cpp:757
SourceLocation Loc
Definition: SemaObjC.cpp:758
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenACC constructs and clauses.
This file declares semantic analysis for OpenMP constructs and clauses.
This file declares semantic analysis for expressions involving.
This file declares semantic analysis for SYCL constructs.
Defines the Objective-C statement AST node classes.
This file defines OpenACC AST classes for statement-level contructs.
This file defines OpenMP AST classes for executable directives and clauses.
static QualType getPointeeType(const MemRegion *R)
SourceLocation Begin
std::string Label
QualType getUsingType(const UsingShadowDecl *Found, QualType Underlying) const
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1101
unsigned getIntWidth(QualType T) const
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType) const
QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent, bool IsPack=false, ConceptDecl *TypeConstraintConcept=nullptr, ArrayRef< TemplateArgument > TypeConstraintArgs={}) const
C++11 deduced auto type.
QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, ArrayRef< TemplateArgumentLoc > Args) const
DeclarationNameTable DeclarationNames
Definition: ASTContext.h:664
QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const
Return a K&R style C function type like 'int()'.
QualType getArrayParameterType(QualType Ty) const
Return the uniqued reference to a specified array parameter type from the original array type.
QualType getPackExpansionType(QualType Pattern, std::optional< unsigned > NumExpansions, bool ExpectPackInType=true)
Form a pack expansion type with the given pattern.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2628
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2644
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateName Template) const
Retrieve the template name that represents a qualified template name such as std::vector.
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
Definition: ASTContext.h:1637
IdentifierTable & Idents
Definition: ASTContext.h:660
QualType getMacroQualifiedType(QualType UnderlyingTy, const IdentifierInfo *MacroII) const
QualType getDecayedType(QualType T) const
Return the uniqued reference to the decayed version of the given type.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
QualType getDeducedTemplateSpecializationType(TemplateName Template, QualType DeducedType, bool IsDependent) const
C++17 deduced class template specialization type.
CanQualType UnsignedLongTy
Definition: ASTContext.h:1129
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
CanQualType IntTy
Definition: ASTContext.h:1128
CanQualType PseudoObjectTy
Definition: ASTContext.h:1150
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2210
QualType getElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType, TagDecl *OwnedTagDecl=nullptr) const
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
CanQualType UnsignedInt128Ty
Definition: ASTContext.h:1130
CanQualType BuiltinFnTy
Definition: ASTContext.h:1149
CanQualType UnsignedCharTy
Definition: ASTContext.h:1129
CanQualType UnsignedIntTy
Definition: ASTContext.h:1129
CanQualType UnsignedLongLongTy
Definition: ASTContext.h:1130
CanQualType UnsignedShortTy
Definition: ASTContext.h:1129
QualType getDependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, QualType Canon=QualType()) const
TemplateName getSubstTemplateTemplateParmPack(const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index, bool Final) const
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
QualType getTypeOfType(QualType QT, TypeOfKind Kind) const
getTypeOfType - Unlike many "get<Type>" functions, we don't unique TypeOfType nodes.
QualType getSubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl, unsigned Index, std::optional< unsigned > PackIndex) const
Retrieve a substitution-result type.
QualType getConstantMatrixType(QualType ElementType, unsigned NumRows, unsigned NumColumns) const
Return the unique reference to the matrix type of the specified element type and size.
PtrTy get() const
Definition: Ownership.h:170
bool isInvalid() const
Definition: Ownership.h:166
bool isUsable() const
Definition: Ownership.h:168
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition: ExprCXX.h:2852
SourceLocation getRParenLoc() const
Definition: TypeLoc.h:2634
TypeLoc getValueLoc() const
Definition: TypeLoc.h:2610
SourceLocation getKWLoc() const
Definition: TypeLoc.h:2618
SourceLocation getLParenLoc() const
Definition: TypeLoc.h:2626
Attr - This represents one attribute.
Definition: Attr.h:42
attr::Kind getKind() const
Definition: Attr.h:88
SourceLocation getLocation() const
Definition: Attr.h:95
Represents an attribute applied to a statement.
Definition: Stmt.h:2085
Type source information for an attributed type.
Definition: TypeLoc.h:875
const Attr * getAttr() const
The type attribute.
Definition: TypeLoc.h:898
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
Definition: TypeLoc.h:889
TypeLoc getEquivalentTypeLoc() const
Definition: TypeLoc.h:893
void setAttr(const Attr *A)
Definition: TypeLoc.h:901
attr::Kind getAttrKind() const
Definition: TypeLoc.h:877
An attributed type is a type to which a type attribute has been applied.
Definition: Type.h:6020
QualType getModifiedType() const
Definition: Type.h:6042
std::optional< NullabilityKind > getImmediateNullability() const
Definition: Type.cpp:4852
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:6375
ArrayRef< TemplateArgument > getTypeConstraintArguments() const
Definition: Type.h:6385
ConceptDecl * getTypeConstraintConcept() const
Definition: Type.h:6390
AutoTypeKeyword getKeyword() const
Definition: Type.h:6406
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:2181
bool isAssignmentOp() const
Definition: Expr.h:3998
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO)
Retrieve the binary opcode that corresponds to the given overloaded operator.
Definition: Expr.cpp:2143
void setIsVariadic(bool value)
Definition: Decl.h:4547
TypeLoc getInnerLoc() const
Definition: TypeLoc.h:1128
QualType desugar() const
Definition: Type.h:3257
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition: ExprCXX.h:5291
SourceLocation getEndLoc() const LLVM_READONLY
Definition: ExprCXX.h:5310
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprCXX.h:5309
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1491
CXXCatchStmt - This represents a C++ catch block.
Definition: StmtCXX.h:28
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1546
SourceRange getParenOrBraceRange() const
Definition: ExprCXX.h:1714
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition: ExprCXX.h:1689
bool isStdInitListInitialization() const
Whether this constructor call was written as list-initialization, but was interpreted as forming a st...
Definition: ExprCXX.h:1639
SourceLocation getEndLoc() const LLVM_READONLY
Definition: ExprCXX.cpp:569
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprCXX.cpp:563
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
Definition: ExprCXX.h:1628
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Definition: ExprCXX.h:1686
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2539
static CXXDefaultArgExpr * Create(const ASTContext &C, SourceLocation Loc, ParmVarDecl *Param, Expr *RewrittenExpr, DeclContext *UsedContext)
Definition: ExprCXX.cpp:1019
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition: ExprCXX.h:1737
Abstract class common to all of the C++ "named"/"keyword" casts.
Definition: ExprCXX.h:372
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
unsigned getLambdaDependencyKind() const
Definition: DeclCXX.h:1860
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type.
Definition: ExprCXX.h:2181
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:74
char * location_data() const
Retrieve the data associated with the source-location information.
Definition: DeclSpec.h:236
SourceRange getRange() const
Definition: DeclSpec.h:80
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc)
Turn this (empty) nested-name-specifier into the global nested-name-specifier '::'.
Definition: DeclSpec.cpp:104
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
Definition: DeclSpec.cpp:152
NestedNameSpecifier * getScopeRep() const
Retrieve the representation of the nested-name-specifier.
Definition: DeclSpec.h:95
unsigned location_size() const
Retrieve the size of the data associated with source-location information.
Definition: DeclSpec.h:240
void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, SourceLocation SuperLoc, SourceLocation ColonColonLoc)
Turns this (empty) nested-name-specifier into '__super' nested-name-specifier.
Definition: DeclSpec.cpp:114
void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL, SourceLocation ColonColonLoc)
Extend the current nested-name-specifier by another nested-name-specifier component of the form 'type...
Definition: DeclSpec.cpp:54
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
Definition: DeclSpec.cpp:132
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Definition: ExprCXX.h:797
Describes an explicit type conversion that uses functional notion but could not be resolved because o...
Definition: ExprCXX.h:3556
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
Definition: Expr.cpp:1494
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition: Decl.h:4670
unsigned getNumParams() const
Definition: Decl.h:4712
unsigned getContextParamPosition() const
Definition: Decl.h:4741
ImplicitParamDecl * getParam(unsigned i) const
Definition: Decl.h:4714
This captures a statement into a function.
Definition: Stmt.h:3762
Expr * getSubExpr()
Definition: Expr.h:3548
SourceLocation getBegin() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1606
Declaration of a C++20 concept.
static ConceptReference * Create(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten)
Definition: ASTConcept.cpp:88
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:421
Expr * getCountExpr() const
Definition: TypeLoc.h:1142
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Definition: Type.h:3295
bool isOrNull() const
Definition: Type.h:3323
bool isCountInBytes() const
Definition: Type.h:3322
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1369
reference front() const
Definition: DeclBase.h:1392
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1852
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1766
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1265
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1497
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
SourceLocation getEndLoc() const LLVM_READONLY
Definition: DeclBase.h:442
bool isInvalidDecl() const
Definition: DeclBase.h:595
SourceLocation getLocation() const
Definition: DeclBase.h:446
DeclContext * getDeclContext()
Definition: DeclBase.h:455
AccessSpecifier getAccess() const
Definition: DeclBase.h:514
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:438
DeclarationName getCXXDestructorName(CanQualType Ty)
Returns the name of a C++ destructor for the given Type.
DeclarationName getCXXSpecialName(DeclarationName::NameKind Kind, CanQualType Ty)
Returns a declaration name for special kind of C++ name, e.g., for a constructor, destructor,...
DeclarationName getCXXDeductionGuideName(TemplateDecl *TD)
Returns the name of a C++ deduction guide for the given template.
The name of a declaration.
SourceLocation getInnerLocStart() const
Return start of source range ignoring outer template declarations.
Definition: Decl.h:774
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:760
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1903
QualType getDeducedType() const
Get the type deduced for this placeholder type, or null if it has not been deduced.
Definition: Type.h:6362
bool isDeduced() const
Definition: Type.h:6363
A qualified reference to a name whose declaration cannot yet be resolved.
Definition: ExprCXX.h:3322
Represents a dependent template name that cannot be resolved prior to template instantiation.
Definition: TemplateName.h:491
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc)
Definition: TypeLoc.h:2472
SourceLocation getTemplateNameLoc() const
Definition: TypeLoc.h:2496
void setTemplateKeywordLoc(SourceLocation Loc)
Definition: TypeLoc.h:2492
SourceLocation getTemplateKeywordLoc() const
Definition: TypeLoc.h:2488
void setElaboratedKeywordLoc(SourceLocation Loc)
Definition: TypeLoc.h:2460
void setRAngleLoc(SourceLocation Loc)
Definition: TypeLoc.h:2516
SourceLocation getElaboratedKeywordLoc() const
Definition: TypeLoc.h:2456
void setLAngleLoc(SourceLocation Loc)
Definition: TypeLoc.h:2508
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI)
Definition: TypeLoc.h:2524
void setTemplateNameLoc(SourceLocation Loc)
Definition: TypeLoc.h:2500
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: Type.h:6895
Designation - Represent a full designation, which is a sequence of designators.
Definition: Designator.h:208
static Designator CreateArrayRangeDesignator(Expr *Start, Expr *End, SourceLocation LBracketLoc, SourceLocation EllipsisLoc)
Creates a GNU array-range designator.
Definition: Designator.h:172
static Designator CreateArrayDesignator(Expr *Index, SourceLocation LBracketLoc)
Creates an array designator.
Definition: Designator.h:142
static Designator CreateFieldDesignator(const IdentifierInfo *FieldName, SourceLocation DotLoc, SourceLocation FieldLoc)
Creates a field designator.
Definition: Designator.h:115
bool hasErrorOccurred() const
Definition: Diagnostic.h:843
Wrap a function effect's condition expression in another struct so that FunctionProtoType's TrailingO...
Definition: Type.h:4803
Expr * getCondition() const
Definition: Type.h:4810
SourceLocation getElaboratedKeywordLoc() const
Definition: TypeLoc.h:2319
NestedNameSpecifierLoc getQualifierLoc() const
Definition: TypeLoc.h:2331
void setElaboratedKeywordLoc(SourceLocation Loc)
Definition: TypeLoc.h:2323
TypeLoc getNamedTypeLoc() const
Definition: TypeLoc.h:2361
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc)
Definition: TypeLoc.h:2337
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:6762
RAII object that enters a new expression evaluation context.
Represents an enum.
Definition: Decl.h:3844
TypeSourceInfo * getTypeInfoAsWritten() const
getTypeInfoAsWritten - Returns the type source info for the type that this expression is casting to.
Definition: Expr.h:3772
This represents one expression.
Definition: Expr.h:110
bool isGLValue() const
Definition: Expr.h:280
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition: Expr.h:175
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition: Expr.h:192
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Definition: Expr.h:444
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:277
QualType getType() const
Definition: Expr.h:142
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
Definition: Expr.h:516
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
Definition: Expr.h:427
Represents difference between two FPOptions values.
Definition: LangOptions.h:919
Represents a member of a struct/union/class.
Definition: Decl.h:3030
Represents a function declaration or definition.
Definition: Decl.h:1932
QualType getReturnType() const
Definition: Decl.h:2717
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2646
QualType getCallResultType() const
Determine the type of an expression that calls this function.
Definition: Decl.h:2753
Represents an abstract function effect, using just an enumeration describing its kind.
Definition: Type.h:4703
StringRef name() const
The description printed in diagnostics, e.g. 'nonblocking'.
Definition: Type.cpp:5124
Kind oppositeKind() const
Return the opposite kind, for effects which have opposites.
Definition: Type.cpp:5108
ArrayRef< EffectConditionExpr > conditions() const
Definition: Type.h:4916
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: Type.h:4668
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5002
QualType desugar() const
Definition: Type.h:5546
param_type_iterator param_type_begin() const
Definition: Type.h:5415
const ExtParameterInfo * getExtParameterInfosOrNull() const
Return a pointer to the beginning of the array of extra parameter information, if present,...
Definition: Type.h:5453
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition: Type.h:5395
ExtProtoInfo getExtProtoInfo() const
Definition: Type.h:5266
ArrayRef< QualType > getParamTypes() const
Definition: Type.h:5262
unsigned getNumParams() const
Definition: TypeLoc.h:1500
SourceLocation getLocalRangeEnd() const
Definition: TypeLoc.h:1452
void setLocalRangeBegin(SourceLocation L)
Definition: TypeLoc.h:1448
void setLParenLoc(SourceLocation Loc)
Definition: TypeLoc.h:1464
SourceRange getExceptionSpecRange() const
Definition: TypeLoc.h:1480
void setParam(unsigned i, ParmVarDecl *VD)
Definition: TypeLoc.h:1507
ArrayRef< ParmVarDecl * > getParams() const
Definition: TypeLoc.h:1491
void setRParenLoc(SourceLocation Loc)
Definition: TypeLoc.h:1472
void setLocalRangeEnd(SourceLocation L)
Definition: TypeLoc.h:1456
void setExceptionSpecRange(SourceRange R)
Definition: TypeLoc.h:1486
TypeLoc getReturnLoc() const
Definition: TypeLoc.h:1509
SourceLocation getLocalRangeBegin() const
Definition: TypeLoc.h:1444
SourceLocation getLParenLoc() const
Definition: TypeLoc.h:1460
SourceLocation getRParenLoc() const
Definition: TypeLoc.h:1468
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
Definition: Type.h:4334
QualType getReturnType() const
Definition: Type.h:4630
AssociationTy< false > Association
Definition: Expr.h:6138
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition: Expr.h:3675
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5782
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:514
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Definition: Expr.cpp:977
Represents the declaration of a label.
Definition: Decl.h:499
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1954
const LambdaCapture * capture_iterator
An iterator that walks over the captures of the lambda, both implicit and explicit.
Definition: ExprCXX.h:2019
Represents the results of name lookup.
Definition: Lookup.h:46
@ FoundOverloaded
Name lookup found a set of overloaded functions that met the criteria.
Definition: Lookup.h:63
@ FoundUnresolvedValue
Name lookup found an unresolvable value declaration and cannot yet complete.
Definition: Lookup.h:68
@ Ambiguous
Name lookup results in an ambiguity; use getAmbiguityKind to figure out what kind of ambiguity we hav...
Definition: Lookup.h:73
@ NotFound
No entity found met the criteria.
Definition: Lookup.h:50
@ NotFoundInCurrentInstantiation
No entity found met the criteria within the current instantiation,, but there were dependent base cla...
Definition: Lookup.h:55
@ Found
Name lookup found a single declaration that met the criteria.
Definition: Lookup.h:59
LLVM_ATTRIBUTE_REINITIALIZES void clear()
Clears out any current state.
Definition: Lookup.h:605
void addDecl(NamedDecl *D)
Add a declaration to these results with its natural access.
Definition: Lookup.h:475
bool empty() const
Return true if no decls were found.
Definition: Lookup.h:362
void resolveKind()
Resolves the result kind of the lookup, possibly hiding decls.
Definition: SemaLookup.cpp:485
SourceLocation getNameLoc() const
Gets the location of the identifier.
Definition: Lookup.h:664
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Definition: Lookup.h:575
DeclarationName getLookupName() const
Gets the name to look up.
Definition: Lookup.h:265
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition: ExprCXX.h:4727
This represents a decl that may have a name.
Definition: Decl.h:249
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition: Decl.h:462
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
Represents a C++ namespace alias.
Definition: DeclCXX.h:3124
Represent a C++ namespace.
Definition: Decl.h:547
A C++ nested-name-specifier augmented with source location information.
SourceLocation getBeginLoc() const
Retrieve the location of the beginning of this nested-name-specifier.
SourceLocation getLocalEndLoc() const
Retrieve the location of the end of this component of the nested-name-specifier.
SourceLocation getEndLoc() const
Retrieve the location of the end of this nested-name-specifier.
TypeLoc getTypeLoc() const
For a nested-name-specifier that refers to a type, retrieve the type with source-location information...
void * getOpaqueData() const
Retrieve the opaque pointer that refers to source-location data.
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
SourceLocation getLocalBeginLoc() const
Retrieve the location of the beginning of this component of the nested-name-specifier.
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
@ NamespaceAlias
A namespace alias, stored as a NamespaceAliasDecl*.
@ TypeSpec
A type, stored as a Type*.
@ TypeSpecWithTemplate
A type that was preceded by the 'template' keyword, stored as a Type*.
@ Super
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Identifier
An identifier, stored as an IdentifierInfo*.
@ Global
The global specifier '::'. There is no stored value.
@ Namespace
A namespace, stored as a NamespaceDecl*.
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:55
This is a basic class for representing single OpenMP executable directive.
Definition: StmtOpenMP.h:266
This represents clauses with a list of expressions that are mappable.
This represents '#pragma omp metadirective' directive.
Definition: StmtOpenMP.h:6064
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1951
@ SuperInstance
The receiver is the instance of the superclass object.
Definition: ExprObjC.h:959
@ Instance
The receiver is an object instance.
Definition: ExprObjC.h:953
@ SuperClass
The receiver is a superclass.
Definition: ExprObjC.h:956
@ Class
The receiver is a class.
Definition: ExprObjC.h:950
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
bool isInstanceMethod() const
Definition: DeclObjC.h:426
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:730
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition: ExprObjC.h:617
Represents the declaration of an Objective-C type parameter.
Definition: DeclObjC.h:578
@ Array
An index into an array.
Definition: Expr.h:2374
@ Identifier
A field in a dependent type, known only by its name.
Definition: Expr.h:2378
@ Field
A field.
Definition: Expr.h:2376
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Definition: Expr.h:2381
Wrapper for void* pointer.
Definition: Ownership.h:50
PtrTy get() const
Definition: Ownership.h:80
static OpaquePtr make(QualType P)
Definition: Ownership.h:60
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition: Expr.h:1173
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition: Expr.h:1223
static OpenACCAsyncClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCAttachClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCAutoClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
This is the base type for all OpenACC Clauses.
Definition: OpenACCClause.h:24
static OpenACCCopyClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCopyInClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsReadOnly, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCopyOutClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCreateClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDefaultClause * Create(const ASTContext &C, OpenACCDefaultClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
static OpenACCDevicePtrClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDeviceTypeClause * Create(const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< DeviceTypeArgument > Archs, SourceLocation EndLoc)
static OpenACCFirstPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCIfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
static OpenACCIndependentClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCNoCreateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCNumGangsClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > IntExprs, SourceLocation EndLoc)
static OpenACCNumWorkersClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCPresentClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCReductionClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator Operator, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCSelfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
static OpenACCSeqClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCVectorLengthClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCWaitClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef< Expr * > QueueIdExprs, SourceLocation EndLoc)
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
Definition: ExprCXX.h:2982
bool hasExplicitTemplateArgs() const
Determines whether this expression had explicit template arguments.
Definition: ExprCXX.h:3134
SourceLocation getLAngleLoc() const
Retrieve the location of the left angle bracket starting the explicit template argument list followin...
Definition: ExprCXX.h:3116
SourceLocation getNameLoc() const
Gets the location of the name.
Definition: ExprCXX.h:3095
SourceLocation getTemplateKeywordLoc() const
Retrieve the location of the template keyword preceding this name, if any.
Definition: ExprCXX.h:3108
NestedNameSpecifierLoc getQualifierLoc() const
Fetches the nested-name qualifier with source-location information, if one was given.
Definition: ExprCXX.h:3104
TemplateArgumentLoc const * getTemplateArgs() const
Definition: ExprCXX.h:3136
llvm::iterator_range< decls_iterator > decls() const
Definition: ExprCXX.h:3081
unsigned getNumTemplateArgs() const
Definition: ExprCXX.h:3142
DeclarationName getName() const
Gets the name looked up.
Definition: ExprCXX.h:3092
SourceLocation getRAngleLoc() const
Retrieve the location of the right angle bracket ending the explicit template argument list following...
Definition: ExprCXX.h:3124
bool hasTemplateKeyword() const
Determines whether the name was preceded by the template keyword.
Definition: ExprCXX.h:3131
Represents a C++11 pack expansion that produces a sequence of expressions.
Definition: ExprCXX.h:4179
void setEllipsisLoc(SourceLocation Loc)
Definition: TypeLoc.h:2582
SourceLocation getEllipsisLoc() const
Definition: TypeLoc.h:2578
TypeLoc getPatternLoc() const
Definition: TypeLoc.h:2594
Represents a pack expansion of types.
Definition: Type.h:6960
std::optional< unsigned > getNumExpansions() const
Retrieve the number of expansions that this pack expansion will generate, if known.
Definition: Type.h:6985
ParenExpr - This represents a parenthesized expression, e.g.
Definition: Expr.h:2135
SourceLocation getLParen() const
Get the location of the left parentheses '('.
Definition: Expr.h:2158
SourceLocation getRParen() const
Get the location of the right parentheses ')'.
Definition: Expr.h:2162
Represents a parameter to a function.
Definition: Decl.h:1722
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
Definition: Decl.h:1782
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
Definition: Decl.h:1755
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Definition: Decl.cpp:2903
unsigned getFunctionScopeDepth() const
Definition: Decl.h:1772
void setSigilLoc(SourceLocation Loc)
Definition: TypeLoc.h:1278
TypeLoc getPointeeLoc() const
Definition: TypeLoc.h:1282
SourceLocation getSigilLoc() const
Definition: TypeLoc.h:1274
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3187
QualType getPointeeType() const
Definition: Type.h:3197
Stores the type being destroyed by a pseudo-destructor expression.
Definition: ExprCXX.h:2565
const IdentifierInfo * getIdentifier() const
Definition: ExprCXX.h:2585
SourceLocation getLocation() const
Definition: ExprCXX.h:2589
TypeSourceInfo * getTypeSourceInfo() const
Definition: ExprCXX.h:2581
A (possibly-)qualified type.
Definition: Type.h:941
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1008
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:7790
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:7844
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
Definition: Type.h:7782
Represents a template name as written in source code.
Definition: TemplateName.h:434
Wrapper of type source information for a type with non-trivial direct qualifiers.
Definition: TypeLoc.h:289
The collection of all-type qualifiers we support.
Definition: Type.h:319
void removeObjCLifetime()
Definition: Type.h:538
bool hasRestrict() const
Definition: Type.h:464
static Qualifiers fromCVRMask(unsigned CVR)
Definition: Type.h:422
bool hasObjCLifetime() const
Definition: Type.h:531
bool empty() const
Definition: Type.h:634
LangAS getAddressSpace() const
Definition: Type.h:558
Represents a struct/union/class.
Definition: Decl.h:4145
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5965
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3428
QualType getPointeeTypeAsWritten() const
Definition: Type.h:3444
Represents the body of a requires-expression.
Definition: DeclCXX.h:2033
static RequiresExprBodyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc)
Definition: DeclCXX.cpp:2212
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Definition: ExprConcepts.h:510
static RequiresExpr * Create(ASTContext &C, SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, SourceLocation LParenLoc, ArrayRef< ParmVarDecl * > LocalParameters, SourceLocation RParenLoc, ArrayRef< concepts::Requirement * > Requirements, SourceLocation RBraceLoc)
static SEHFinallyStmt * Create(const ASTContext &C, SourceLocation FinallyLoc, Stmt *Block)
Definition: Stmt.cpp:1275
Represents a __leave statement.
Definition: Stmt.h:3723
Smart pointer class that efficiently represents Objective-C method names.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:60
VarDecl * BuildObjCExceptionDecl(TypeSourceInfo *TInfo, QualType ExceptionType, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, bool Invalid=false)
Build a type-check a new Objective-C exception variable declaration.
StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, Expr *collection, SourceLocation RParenLoc)
Definition: SemaObjC.cpp:35
StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)
FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.
Definition: SemaObjC.cpp:197
ExprResult BuildObjCDictionaryLiteral(SourceRange SR, MutableArrayRef< ObjCDictionaryElement > Elements)
ExprResult BuildInstanceMessage(Expr *Receiver, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)
Build an Objective-C instance message expression.
QualType BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, SourceLocation ProtocolLAngleLoc, ArrayRef< ObjCProtocolDecl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc, bool FailOnError=false)
Build an Objective-C type parameter type.
Definition: SemaObjC.cpp:484
ExprResult BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, QualType ReceiverType, SourceLocation SuperLoc, Selector Sel, ObjCMethodDecl *Method, SourceLocation LBracLoc, ArrayRef< SourceLocation > SelectorLocs, SourceLocation RBracLoc, MultiExprArg Args, bool isImplicit=false)
Build an Objective-C class message expression.
StmtResult ActOnObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *SynchExpr, Stmt *SynchBody)
Definition: SemaObjC.cpp:324
ExprResult BuildObjCEncodeExpression(SourceLocation AtLoc, TypeSourceInfo *EncodedTypeInfo, SourceLocation RParenLoc)
ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements)
ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr)
BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the '@' prefixed parenthesized expression.
StmtResult ActOnObjCAtTryStmt(SourceLocation AtLoc, Stmt *Try, MultiStmtArg Catch, Stmt *Finally)
Definition: SemaObjC.cpp:222
StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body)
Definition: SemaObjC.cpp:217
StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw)
Definition: SemaObjC.cpp:242
QualType BuildObjCObjectType(QualType BaseType, SourceLocation Loc, SourceLocation TypeArgsLAngleLoc, ArrayRef< TypeSourceInfo * > TypeArgs, SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc, ArrayRef< ObjCProtocolDecl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc, bool FailOnError, bool Rebuilding)
Build an Objective-C object pointer type.
Definition: SemaObjC.cpp:711
ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand)
Definition: SemaObjC.cpp:286
ExprResult BuildObjCBridgedCast(SourceLocation LParenLoc, ObjCBridgeCastKind Kind, SourceLocation BridgeKeywordLoc, TypeSourceInfo *TSInfo, Expr *SubExpr)
StmtResult ActOnObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParen, Decl *Parm, Stmt *Body)
Definition: SemaObjC.cpp:206
StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body)
Definition: SemaObjC.cpp:333
ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr, Expr *IndexExpr, ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod)
Build an ObjC subscript pseudo-object expression, given that that's supported by the runtime.
ArrayRef< Expr * > getQueueIdExprs() const
Definition: SemaOpenACC.h:164
void setLParenLoc(SourceLocation EndLoc)
Definition: SemaOpenACC.h:250
void setConditionDetails(Expr *ConditionExpr)
Definition: SemaOpenACC.h:259
OpenACCClauseKind getClauseKind() const
Definition: SemaOpenACC.h:96
SourceLocation getLParenLoc() const
Definition: SemaOpenACC.h:100
SourceLocation getBeginLoc() const
Definition: SemaOpenACC.h:98
void setDefaultDetails(OpenACCDefaultClauseKind DefKind)
Definition: SemaOpenACC.h:253
SourceLocation getQueuesLoc() const
Definition: SemaOpenACC.h:144
void setVarListDetails(ArrayRef< Expr * > VarList, bool IsReadOnly, bool IsZero)
Definition: SemaOpenACC.h:290
void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc, llvm::SmallVector< Expr * > &&IntExprs)
Definition: SemaOpenACC.h:368
void setEndLoc(SourceLocation EndLoc)
Definition: SemaOpenACC.h:251
void setIntExprDetails(ArrayRef< Expr * > IntExprs)
Definition: SemaOpenACC.h:273
OpenACCDefaultClauseKind getDefaultClauseKind() const
Definition: SemaOpenACC.h:104
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLocFirst, Expr *Length, SourceLocation RBLoc)
Checks and creates an Array Section used in an OpenACC construct/clause.
OMPClause * ActOnOpenMPNocontextClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nocontext' clause.
OMPClause * ActOnOpenMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_dyn_cgroup_mem' clause.
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
OMPClause * ActOnOpenMPHoldsClause(Expr *E, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'holds' clause.
OMPClause * ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
OMPClause * ActOnOpenMPFilterClause(Expr *ThreadID, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'filter' clause.
OMPClause * ActOnOpenMPFullClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-form 'full' clauses.
OMPClause * ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'detach' clause.
OMPClause * ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'use' clause.
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed 'ordered' clause.
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr * > VarList, OpenMPReductionClauseModifier Modifier, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=std::nullopt)
Called on well-formed 'reduction' clause.
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'is_device_ptr' clause.
OMPClause * ActOnOpenMPHasDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'has_device_addr' clause.
OMPClause * ActOnOpenMPPartialClause(Expr *FactorExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'partial' clauses.
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr * > VarList, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'priority' clause.
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'dist_schedule' clause.
OMPClause * ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocate' clause.
OMPClause * ActOnOpenMPNontemporalClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nontemporal' clause.
OMPClause * ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'bind' clause.
OMPClause * ActOnOpenMPThreadLimitClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'thread_limit' clause.
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'shared' clause.
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyin' clause.
OMPClause * ActOnOpenMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'destroy' clause.
OMPClause * ActOnOpenMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef< Expr * > Locators)
Called on well-formed 'affinity' clause.
OMPClause * ActOnOpenMPNumTeamsClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
OMPClause * ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, Expr *DepModifier, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
OMPClause * ActOnOpenMPDoacrossClause(OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'doacross' clause.
OMPClause * ActOnOpenMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier, Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'grainsize' clause.
ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLocFirst, SourceLocation ColonLocSecond, Expr *Length, Expr *Stride, SourceLocation RBLoc)
OMPClause * ActOnOpenMPFromClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers=std::nullopt)
Called on well-formed 'from' clause.
OMPClause * ActOnOpenMPToClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers=std::nullopt)
Called on well-formed 'to' clause.
ExprResult ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc, ArrayRef< OMPIteratorData > Data)
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
OMPClause * ActOnOpenMPAllocatorClause(Expr *Allocator, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocator' clause.
OMPClause * ActOnOpenMPInclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'inclusive' clause.
OMPClause * ActOnOpenMPOrderClause(OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'order' clause.
OMPClause * ActOnOpenMPSizesClause(ArrayRef< Expr * > SizeExprs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'sizes' clause.
OMPClause * ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'device' clause.
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPMessageClause(Expr *MS, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'message' clause.
OMPClause * ActOnOpenMPMapClause(Expr *IteratorModifier, ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, bool NoDiagnose=false, ArrayRef< Expr * > UnresolvedMappers=std::nullopt)
Called on well-formed 'map' clause.
OMPClause * ActOnOpenMPTaskReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=std::nullopt)
Called on well-formed 'task_reduction' clause.
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'simdlen' clause.
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_ptr' clause.
OMPClause * ActOnOpenMPProcBindClause(llvm::omp::ProcBindKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
OMPClause * ActOnOpenMPXBareClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_bare' clause.
StmtResult ActOnOpenMPInformationalDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Process an OpenMP informational directive.
StmtResult ActOnOpenMPCanonicalLoop(Stmt *AStmt)
Called for syntactical loops (ForStmt or CXXForRangeStmt) associated to an OpenMP loop directive.
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
ExprResult ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, SourceLocation RParenLoc, ArrayRef< Expr * > Dims, ArrayRef< SourceRange > Brackets)
OMPClause * ActOnOpenMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'at' clause.
OMPClause * ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'init' clause.
OMPClause * ActOnOpenMPUseDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_addr' clause.
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
OMPClause * ActOnOpenMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'num_tasks' clause.
OMPClause * ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'severity' clause.
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr * > VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation StepModifierLoc, SourceLocation EndLoc)
Called on well-formed 'linear' clause.
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'defaultmap' clause.
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
OMPClause * ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depobj' pseudo clause.
OMPClause * ActOnOpenMPNovariantsClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'novariants' clause.
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'collapse' clause.
OMPClause * ActOnOpenMPAlignClause(Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'align' clause.
OMPClause * ActOnOpenMPXAttributeClause(ArrayRef< const Attr * > Attrs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_attribute' clause.
OMPClause * ActOnOpenMPInReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=std::nullopt)
Called on well-formed 'in_reduction' clause.
OMPClause * ActOnOpenMPExclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'exclusive' clause.
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
ExprResult checkAssignment(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opcode, Expr *LHS, Expr *RHS)
Expr * recreateSyntacticForm(PseudoObjectExpr *E)
Given a pseudo-object expression, recreate what it looks like syntactically without the attendant Opa...
ExprResult checkRValue(Expr *E)
ExprResult BuildUniqueStableNameExpr(SourceLocation OpLoc, SourceLocation LParen, SourceLocation RParen, TypeSourceInfo *TSI)
Definition: SemaSYCL.cpp:139
RAII object used to change the argument pack substitution index within a Sema object.
Definition: Sema.h:13247
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
Definition: Sema.h:8115
A RAII object to enter scope of a compound statement.
Definition: Sema.h:1011
A helper class for building up ExtParameterInfos.
Definition: Sema.h:12669
const FunctionProtoType::ExtParameterInfo * getPointerOrNull(unsigned numParams)
Return a pointer (suitable for setting in an ExtProtoInfo) to the ExtParameterInfo array we've built ...
Definition: Sema.h:12688
void set(unsigned index, FunctionProtoType::ExtParameterInfo info)
Set the ExtParameterInfo for the parameter at the given index,.
Definition: Sema.h:12676
Records and restores the CurFPFeatures state on entry/exit of compound statements.
Definition: Sema.h:13604
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:535
QualType BuildParenType(QualType T)
Build a paren type including T.
Definition: SemaType.cpp:1660
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
Definition: SemaType.cpp:6327
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
bool CheckSpecifiedExceptionType(QualType &T, SourceRange Range)
CheckSpecifiedExceptionType - Check if the given type is valid in an exception specification.
ExprResult BuildOperatorCoawaitCall(SourceLocation Loc, Expr *E, UnresolvedLookupExpr *Lookup)
Build a call to 'operator co_await' if there is a suitable operator for the given expression.
ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, const Scope *S, ActOnMemberAccessExtraArgs *ExtraArgs=nullptr)
StmtResult BuildMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, NestedNameSpecifierLoc QualifierLoc, DeclarationNameInfo NameInfo, Stmt *Nested)
Definition: SemaStmt.cpp:4385
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition: Sema.h:9057
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
Definition: Sema.h:9065
@ LookupTagName
Tag name lookup, which finds the names of enums, classes, structs, and unions.
Definition: Sema.h:9060
bool checkFinalSuspendNoThrow(const Stmt *FinalSuspend)
Check that the expression co_await promise.final_suspend() shall not be potentially-throwing.
QualType BuildAddressSpaceAttr(QualType &T, LangAS ASIdx, Expr *AddrSpace, SourceLocation AttrLoc)
BuildAddressSpaceAttr - Builds a DependentAddressSpaceType if an expression is uninstantiated.
Definition: SemaType.cpp:6430
ExprResult ActOnConstantExpression(ExprResult Res)
Definition: SemaExpr.cpp:19393
StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, ArrayRef< Token > AsmToks, StringRef AsmString, unsigned NumOutputs, unsigned NumInputs, ArrayRef< StringRef > Constraints, ArrayRef< StringRef > Clobbers, ArrayRef< Expr * > Exprs, SourceLocation EndLoc)
StmtResult BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs)
ExprResult BuildCoyieldExpr(SourceLocation KwLoc, Expr *E)
static std::enable_if_t< std::is_base_of_v< Attr, AttrInfo >, SourceLocation > getAttrLoc(const AttrInfo &AL)
A helper function to provide Attribute Location for the Attr types AND the ParsedAttr.
Definition: Sema.h:4465
QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc)
Definition: SemaType.cpp:2301
StmtResult BuildAttributedStmt(SourceLocation AttrsLoc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)
Definition: SemaStmt.cpp:606
SemaOpenMP & OpenMP()
Definition: Sema.h:1221
@ IER_DoesNotExist
The symbol does not exist.
Definition: Sema.h:8532
@ IER_Dependent
The name is a dependent name, so the results will differ from one instantiation to the next.
Definition: Sema.h:8536
@ IER_Error
An error occurred.
Definition: Sema.h:8539
@ IER_Exists
The symbol exists.
Definition: Sema.h:8529
void ActOnStartStmtExpr()
Definition: SemaExpr.cpp:15622
ExprResult BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, sema::LambdaScopeInfo *LSI)
Complete a lambda-expression having processed and attached the lambda body.
void ActOnStmtExprError()
Definition: SemaExpr.cpp:15628
std::optional< FunctionEffectMode > ActOnEffectExpression(Expr *CondExpr, StringRef AttributeName)
Try to parse the conditional expression attached to an effect attribute (e.g.
Definition: SemaType.cpp:7494
VarDecl * buildCoroutinePromise(SourceLocation Loc)
ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)
CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...
Definition: SemaExpr.cpp:20125
ConditionKind
Definition: Sema.h:7413
@ Boolean
A boolean condition, from 'if', 'while', 'for', or 'do'.
@ Switch
An integral condition for a 'switch' statement.
@ ConstexprIf
A constant boolean condition from 'if constexpr'.
bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC)
Require that the context specified by SS be complete.
ExprResult BuildBuiltinBitCastExpr(SourceLocation KWLoc, TypeSourceInfo *TSI, Expr *Operand, SourceLocation RParenLoc)
Definition: SemaCast.cpp:395
StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, LabelDecl *TheDecl)
Definition: SemaStmt.cpp:3126
ExprResult MaybeBindToTemporary(Expr *E)
MaybeBindToTemporary - If the passed in expression has a record type with a non-trivial destructor,...
StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E, bool IsImplicit=false)
ExprResult ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, ParsedType &ObjectType, bool &MayBePseudoDestructor)
ExprResult ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val)
Definition: SemaStmt.cpp:464
QualType BuildExtVectorType(QualType T, Expr *ArraySize, SourceLocation AttrLoc)
Build an ext-vector type.
Definition: SemaType.cpp:2372
ExprResult ActOnDesignatedInitializer(Designation &Desig, SourceLocation EqualOrColonLoc, bool GNUSyntax, ExprResult Init)
Definition: SemaInit.cpp:3478
void MarkDeclarationsReferencedInExpr(Expr *E, bool SkipLocalVariables=false, ArrayRef< const Expr * > StopAt=std::nullopt)
Mark any declarations that appear within this expression or any potentially-evaluated subexpressions ...
Definition: SemaExpr.cpp:19912
ExprResult BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, SourceLocation RPLoc, unsigned TemplateDepth)
Definition: SemaExpr.cpp:15641
ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, bool *NoArrowOperatorFound=nullptr)
BuildOverloadedArrowExpr - Build a call to an overloaded operator-> (if one exists),...
ExprResult BuildResolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand, Expr *Awaiter, bool IsImplicit=false)
SemaSYCL & SYCL()
Definition: Sema.h:1241
ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E, TypeSourceInfo *TInfo, SourceLocation RPLoc)
Definition: SemaExpr.cpp:16289
ExprResult ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, bool ArrayForm, Expr *Operand)
ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
ASTContext & Context
Definition: Sema.h:1004
ExprResult BuildCXXTypeId(QualType TypeInfoType, SourceLocation TypeidLoc, TypeSourceInfo *Operand, SourceLocation RParenLoc)
Build a C++ typeid expression with a type operand.
QualType BuildFunctionType(QualType T, MutableArrayRef< QualType > ParamTypes, SourceLocation Loc, DeclarationName Entity, const FunctionProtoType::ExtProtoInfo &EPI)
Build a function type.
Definition: SemaType.cpp:2611
ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow)
Perform conversions on the LHS of a member access expression.
DiagnosticsEngine & getDiagnostics() const
Definition: Sema.h:599
concepts::TypeRequirement * BuildTypeRequirement(TypeSourceInfo *Type)
TypeSourceInfo * CheckPackExpansion(TypeSourceInfo *Pattern, SourceLocation EllipsisLoc, std::optional< unsigned > NumExpansions)
Construct a pack expansion type from the pattern of the pack expansion.
bool diagnoseConflictingFunctionEffect(const FunctionEffectsRef &FX, const FunctionEffectWithCondition &EC, SourceLocation NewAttrLoc)
Warn and return true if adding an effect to a set would create a conflict.
Definition: SemaDecl.cpp:20303
SemaObjC & ObjC()
Definition: Sema.h:1206
ParsedType getDestructorName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec &SS, ParsedType ObjectType, bool EnteringContext)
ASTContext & getASTContext() const
Definition: Sema.h:602
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
Definition: SemaExpr.cpp:15559
ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, bool RequiresADL, const TemplateArgumentListInfo *TemplateArgs)
ExprResult CreateOverloadedBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *LHS, Expr *RHS, bool RequiresADL=true, bool AllowRewrittenCandidates=true, FunctionDecl *DefaultedFn=nullptr)
Create a binary operation that may resolve to an overloaded operator.
StmtResult ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
Definition: SemaStmt.cpp:4309
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
Definition: Sema.cpp:701
ExprResult BuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK)
Definition: SemaExpr.cpp:3470
ExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, SourceLocation RParenLoc, Expr *LiteralExpr)
Definition: SemaExpr.cpp:6974
ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc, LabelDecl *TheDecl)
ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
Definition: SemaExpr.cpp:15609
ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)
Definition: SemaExpr.cpp:7829
QualType BuildCountAttributedArrayOrPointerType(QualType WrappedTy, Expr *CountExpr, bool CountInBytes, bool OrNull)
Definition: SemaType.cpp:9400
ExprResult BuildCXXNew(SourceRange Range, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, SourceRange TypeIdParens, QualType AllocType, TypeSourceInfo *AllocTypeInfo, std::optional< Expr * > ArraySize, SourceRange DirectInitRange, Expr *Initializer)
bool isAcceptableTagRedeclaration(const TagDecl *Previous, TagTypeKind NewTag, bool isDefinition, SourceLocation NewTagLoc, const IdentifierInfo *Name)
Determine whether a tag with a given kind is acceptable as a redeclaration of the given tag declarati...
Definition: SemaDecl.cpp:16821
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
Definition: SemaExpr.cpp:2190
QualType BuildBitIntType(bool IsUnsigned, Expr *BitWidth, SourceLocation Loc)
Build a bit-precise integer type.
Definition: SemaType.cpp:1925
ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr, SourceLocation RPLoc)
Definition: SemaExpr.cpp:15897
ExprResult CreateGenericSelectionExpr(SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc, bool PredicateIsExpr, void *ControllingExprOrType, ArrayRef< TypeSourceInfo * > Types, ArrayRef< Expr * > Exprs)
ControllingExprOrType is either a TypeSourceInfo * or an Expr *.
Definition: SemaExpr.cpp:1657
QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs, const DeclSpec *DS=nullptr)
Definition: SemaType.cpp:1566
StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body)
Definition: SemaStmt.cpp:1245
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
Definition: Sema.cpp:83
const LangOptions & getLangOpts() const
Definition: Sema.h:595
StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, ConditionResult Cond, SourceLocation RParenLoc, Stmt *Body)
Definition: SemaStmt.cpp:1719
SemaOpenACC & OpenACC()
Definition: Sema.h:1211
@ ReuseLambdaContextDecl
Definition: Sema.h:6593
ExprResult BuildCXXFoldExpr(UnresolvedLookupExpr *Callee, SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Operator, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc, std::optional< unsigned > NumExpansions)
bool isPotentialImplicitMemberAccess(const CXXScopeSpec &SS, LookupResult &R, bool IsAddressOfOperand)
Check whether an expression might be an implicit class member access.
void collectUnexpandedParameterPacks(TemplateArgument Arg, SmallVectorImpl< UnexpandedParameterPack > &Unexpanded)
Collect the set of unexpanded parameter packs within the given template argument.
ExprResult BuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy, SourceLocation BuiltinLoc, SourceLocation RPLoc, DeclContext *ParentContext)
Definition: SemaExpr.cpp:16563
ExprResult BuildCXXTypeConstructExpr(TypeSourceInfo *Type, SourceLocation LParenLoc, MultiExprArg Exprs, SourceLocation RParenLoc, bool ListInitialization)
ExprResult BuildBuiltinOffsetOf(SourceLocation BuiltinLoc, TypeSourceInfo *TInfo, ArrayRef< OffsetOfComponent > Components, SourceLocation RParenLoc)
__builtin_offsetof(type, a.b[123][456].c)
Definition: SemaExpr.cpp:15711
sema::LambdaScopeInfo * getCurLambda(bool IgnoreNonLambdaCapturingScope=false)
Retrieve the current lambda scope info, if any.
Definition: Sema.cpp:2408
ExprResult TemporaryMaterializationConversion(Expr *E)
If E is a prvalue denoting an unmaterialized temporary, materialize it as an xvalue.
Definition: SemaInit.cpp:7484
ExprResult ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
ConvertVectorExpr - Handle __builtin_convertvector.
QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, SourceLocation KeywordLoc, NestedNameSpecifierLoc QualifierLoc, const IdentifierInfo &II, SourceLocation IILoc, TypeSourceInfo **TSI, bool DeducedTSTContext)
ExprResult BuildTypeTrait(TypeTrait Kind, SourceLocation KWLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc)
DeclContext * getCurLexicalContext() const
Definition: Sema.h:809
ExprResult BuildUnresolvedCoawaitExpr(SourceLocation KwLoc, Expr *Operand, UnresolvedLookupExpr *Lookup)
NonTagKind getNonTagTypeDeclKind(const Decl *D, TagTypeKind TTK)
Given a non-tag type declaration, returns an enum useful for indicating what kind of non-tag type thi...
Definition: SemaDecl.cpp:16796
ExprResult BuildExpressionTrait(ExpressionTrait OET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen)
bool buildCoroutineParameterMoves(SourceLocation Loc)
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
Definition: SemaCast.cpp:3341
ExprResult BuildCXXUuidof(QualType TypeInfoType, SourceLocation TypeidLoc, TypeSourceInfo *Operand, SourceLocation RParenLoc)
Build a Microsoft __uuidof expression with a type operand.
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:1035
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
Definition: SemaDecl.cpp:14794
Expr * BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit)
Build a CXXThisExpr and mark it referenced in the current context.
QualType BuildReferenceType(QualType T, bool LValueRef, SourceLocation Loc, DeclarationName Entity)
Build a reference type.
Definition: SemaType.cpp:1842
ExprResult CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, const UnresolvedSetImpl &Fns, Expr *input, bool RequiresADL=true)
Create a unary operation that may resolve to an overloaded operator.
int ArgumentPackSubstitutionIndex
The current index into pack expansion arguments that will be used for substitution of parameter packs...
Definition: Sema.h:13241
ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool NeedsADL, bool AcceptInvalidDecl=false)
Definition: SemaExpr.cpp:3167
sema::BlockScopeInfo * getCurBlock()
Retrieve the current block, if any.
Definition: Sema.cpp:2364
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:1139
VarDecl * BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id)
Perform semantic analysis for the variable declaration that occurs within a C++ catch clause,...
bool BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo, bool EnteringContext, CXXScopeSpec &SS, NamedDecl *ScopeLookupResult, bool ErrorRecoveryLookup, bool *IsCorrectedToColon=nullptr, bool OnlyNamespace=false)
Build a new nested-name-specifier for "identifier::", as described by ActOnCXXNestedNameSpecifier.
ExprResult BuildPackIndexingExpr(Expr *PackExpression, SourceLocation EllipsisLoc, Expr *IndexExpr, SourceLocation RSquareLoc, ArrayRef< Expr * > ExpandedExprs={}, bool EmptyPack=false)
void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base=nullptr)
Perform reference-marking and odr-use handling for a DeclRefExpr.
Definition: SemaExpr.cpp:19754
ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, SourceLocation RParen)
ExprResult BuildQualifiedDeclarationNameExpr(CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI=nullptr)
BuildQualifiedDeclarationNameExpr - Build a C++ qualified declaration name, generally during template...
Definition: SemaExpr.cpp:2874
StmtResult ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *First, ConditionResult Second, FullExprArg Third, SourceLocation RParenLoc, Stmt *Body)
Definition: SemaStmt.cpp:2164
StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, Expr *DestExp)
Definition: SemaStmt.cpp:3141
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Definition: SemaExpr.cpp:4085
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Definition: SemaExpr.cpp:20709
ExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, NamedDecl *FoundDecl, CXXConstructorDecl *Constructor, MultiExprArg Exprs, bool HadMultipleCandidates, bool IsListInitialization, bool IsStdInitListInitialization, bool RequiresZeroInit, CXXConstructionKind ConstructKind, SourceRange ParenRange)
BuildCXXConstructExpr - Creates a complete call to a constructor, including handling of its default a...
NonTagKind
Common ways to introduce type names without a tag for use in diagnostics.
Definition: Sema.h:3895
@ NTK_TypeAliasTemplate
Definition: Sema.h:3903
TryCaptureKind
Definition: Sema.h:6655
@ TryCapture_Implicit
Definition: Sema.h:6656
@ TryCapture_ExplicitByVal
Definition: Sema.h:6657
@ TryCapture_ExplicitByRef
Definition: Sema.h:6658
ExprResult BuildAsTypeExpr(Expr *E, QualType DestTy, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
Create a new AsTypeExpr node (bitcast) from the arguments.
Definition: SemaExpr.cpp:6629
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
bool CheckRebuiltStmtAttributes(ArrayRef< const Attr * > Attrs)
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
Definition: SemaExpr.cpp:8697
QualType BuildPackIndexingType(QualType Pattern, Expr *IndexExpr, SourceLocation Loc, SourceLocation EllipsisLoc, bool FullySubstituted=false, ArrayRef< QualType > Expansions={})
Definition: SemaType.cpp:9522
ExprResult BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs, const Scope *S)
Builds an expression which might be an implicit member expression.
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
concepts::ExprRequirement * BuildExprRequirement(Expr *E, bool IsSatisfied, SourceLocation NoexceptLoc, concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement)
QualType BuildAtomicType(QualType T, SourceLocation Loc)
Definition: SemaType.cpp:9805
QualType CheckTemplateIdType(TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs)
void ActOnInitializerError(Decl *Dcl)
ActOnInitializerError - Given that there was an error parsing an initializer for the given declaratio...
Definition: SemaDecl.cpp:13790
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
Definition: SemaExpr.cpp:215
StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, bool AllowRecovery=false)
Definition: SemaStmt.cpp:3789
ExprResult BuildPseudoDestructorExpr(Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, const CXXScopeSpec &SS, TypeSourceInfo *ScopeType, SourceLocation CCLoc, SourceLocation TildeLoc, PseudoDestructorTypeStorage DestroyedType)
QualType BuildPointerType(QualType T, SourceLocation Loc, DeclarationName Entity)
Build a pointer type.
Definition: SemaType.cpp:1790
StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt, SourceLocation ColonLoc, Stmt *RangeDecl, Stmt *Begin, Stmt *End, Expr *Cond, Expr *Inc, Stmt *LoopVarDecl, SourceLocation RParenLoc, BuildForRangeKind Kind, ArrayRef< MaterializeTemporaryExpr * > LifetimeExtendTemps={})
BuildCXXForRangeStmt - Build or instantiate a C++11 for-range statement.
Definition: SemaStmt.cpp:2592
StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation CondLParen, Expr *Cond, SourceLocation CondRParen)
Definition: SemaStmt.cpp:1740
StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc)
Definition: SemaStmt.cpp:1121
ExprResult BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, bool IsAddressOfOperand)
ExprResult BuiltinShuffleVector(CallExpr *TheCall)
BuiltinShuffleVector - Handle __builtin_shufflevector.
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
@ ImmediateFunctionContext
In addition of being constant evaluated, the current expression occurs in an immediate function conte...
QualType BuildDecltypeType(Expr *E, bool AsUnevaluated=true)
If AsUnevaluated is false, E is treated as though it were an evaluated context, such as when building...
Definition: SemaType.cpp:9490
QualType BuildUnaryTransformType(QualType BaseType, UTTKind UKind, SourceLocation Loc)
Definition: SemaType.cpp:9749
StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
Definition: SemaStmt.cpp:4347
ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo, SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, SourceRange R)
Build a sizeof or alignof expression given a type operand.
Definition: SemaExpr.cpp:4592
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
Definition: SemaStmt.cpp:79
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)
MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups,...
SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts
A stack of expression evaluation contexts.
Definition: Sema.h:7988
ExprResult BuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, BinaryOperatorKind Operator)
ExprResult BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, bool IsThrownVarInScope)
QualType BuildArrayType(QualType T, ArraySizeModifier ASM, Expr *ArraySize, unsigned Quals, SourceRange Brackets, DeclarationName Entity)
Build an array type.
Definition: SemaType.cpp:2033
ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field)
Definition: SemaExpr.cpp:5519
QualType BuildReadPipeType(QualType T, SourceLocation Loc)
Build a Read-only Pipe type.
Definition: SemaType.cpp:1917
concepts::NestedRequirement * BuildNestedRequirement(Expr *E)
QualType BuildWritePipeType(QualType T, SourceLocation Loc)
Build a Write-only Pipe type.
Definition: SemaType.cpp:1921
@ BFRK_Rebuild
Instantiation or recovery rebuild of a for-range statement.
Definition: Sema.h:10817
ExprResult CheckConceptTemplateId(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const DeclarationNameInfo &ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, const TemplateArgumentListInfo *TemplateArgs)
void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt)
ActOnCaseStmtBody - This installs a statement as the body of a case.
Definition: SemaStmt.cpp:547
ExprResult ActOnBlockStmtExpr(SourceLocation CaretLoc, Stmt *Body, Scope *CurScope)
ActOnBlockStmtExpr - This is called when the body of a block statement literal was successfully compl...
Definition: SemaExpr.cpp:16093
QualType BuildTypeofExprType(Expr *E, TypeOfKind Kind)
Definition: SemaType.cpp:9377
ExprResult BuildArrayTypeTrait(ArrayTypeTrait ATT, SourceLocation KWLoc, TypeSourceInfo *TSInfo, Expr *DimExpr, SourceLocation RParen)
void MarkMemberReferenced(MemberExpr *E)
Perform reference-marking and odr-use handling for a MemberExpr.
Definition: SemaExpr.cpp:19776
ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)
Definition: SemaCast.cpp:297
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
Definition: SemaExpr.cpp:17854
QualType BuildMatrixType(QualType T, Expr *NumRows, Expr *NumColumns, SourceLocation AttrLoc)
Definition: SemaType.cpp:2432
ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())
Attempts to produce a RecoveryExpr after some AST node cannot be created.
Definition: SemaExpr.cpp:20906
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
Definition: SemaExpr.cpp:15127
ExprResult PerformObjectMemberConversion(Expr *From, NestedNameSpecifier *Qualifier, NamedDecl *FoundDecl, NamedDecl *Member)
Cast a base object to a member's actual type.
Definition: SemaExpr.cpp:2947
StmtResult ActOnIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)
Definition: SemaStmt.cpp:908
ExprResult BuildInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList, SourceLocation RBraceLoc)
Definition: SemaExpr.cpp:7174
void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope)
ActOnBlockStart - This callback is invoked when a block literal is started.
Definition: SemaExpr.cpp:15935
ExprResult ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, MultiExprArg ArgExprs, SourceLocation RLoc)
Definition: SemaExpr.cpp:4804
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
CreateBuiltinBinOp - Creates a new built-in binary operation with operator Opc at location TokLoc.
Definition: SemaExpr.cpp:14592
ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, SourceLocation RParenLoc, MultiExprArg Args, AtomicExpr::AtomicOp Op, AtomicArgumentOrder ArgOrder=AtomicArgumentOrder::API)
ExprResult ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
ActOnCallExpr - Handle a call to Fn with the specified array of arguments.
Definition: SemaExpr.cpp:6362
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Definition: SemaType.cpp:2729
static ConditionResult ConditionError()
Definition: Sema.h:7400
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
Definition: SemaStmt.cpp:415
SemaPseudoObject & PseudoObject()
Definition: Sema.h:1231
StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt)
Definition: SemaStmt.cpp:572
StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef< Stmt * > Handlers)
ActOnCXXTryBlock - Takes a try compound-statement and a number of handlers and creates a try statemen...
Definition: SemaStmt.cpp:4196
StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope)
Definition: SemaStmt.cpp:552
ExprResult HandleExprEvaluationContextForTypeof(Expr *E)
Definition: SemaExpr.cpp:17681
StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHS, SourceLocation DotDotDotLoc, ExprResult RHS, SourceLocation ColonLoc)
Definition: SemaStmt.cpp:516
QualType BuildMemberPointerType(QualType T, QualType Class, SourceLocation Loc, DeclarationName Entity)
Build a member pointer type T Class::*.
Definition: SemaType.cpp:2660
QualType BuildBlockPointerType(QualType T, SourceLocation Loc, DeclarationName Entity)
Build a block pointer type.
Definition: SemaType.cpp:2712
StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body)
FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement.
Definition: SemaStmt.cpp:3108
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Definition: Sema.h:8335
ExprResult CreateBuiltinMatrixSubscriptExpr(Expr *Base, Expr *RowIdx, Expr *ColumnIdx, SourceLocation RBLoc)
Definition: SemaExpr.cpp:4979
StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, IdentifierInfo **Names, MultiExprArg Constraints, MultiExprArg Exprs, Expr *AsmString, MultiExprArg Clobbers, unsigned NumLabels, SourceLocation RParenLoc)
static SizeOfPackExpr * Create(ASTContext &Context, SourceLocation OperatorLoc, NamedDecl *Pack, SourceLocation PackLoc, SourceLocation RParenLoc, std::optional< unsigned > Length=std::nullopt, ArrayRef< TemplateArgument > PartialArgs=std::nullopt)
Definition: ExprCXX.cpp:1694
static bool MayBeDependent(SourceLocIdentKind Kind)
Definition: Expr.h:4811
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
bool isInvalid() const
SourceLocation getEnd() const
SourceLocation getBegin() const
Stmt - This represents one statement.
Definition: Stmt.h:84
SourceLocation getEndLoc() const LLVM_READONLY
Definition: Stmt.cpp:350
StmtClass
Definition: Stmt.h:86
@ NoStmtClass
Definition: Stmt.h:87
StmtClass getStmtClass() const
Definition: Stmt.h:1358
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:326
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:338
A structure for storing an already-substituted template template parameter pack.
Definition: TemplateName.h:141
Wrapper for substituted template type parameters.
Definition: TypeLoc.h:864
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3561
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
void setLAngleLoc(SourceLocation Loc)
Definition: TemplateBase.h:650
void setRAngleLoc(SourceLocation Loc)
Definition: TemplateBase.h:651
void addArgument(const TemplateArgumentLoc &Loc)
Definition: TemplateBase.h:667
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:659
const TemplateArgumentLoc * operator->() const
Simple iterator that traverses the template arguments in a container that provides a getArgLoc() memb...
TemplateArgumentLocContainerIterator operator++(int)
friend bool operator!=(const TemplateArgumentLocContainerIterator &X, const TemplateArgumentLocContainerIterator &Y)
TemplateArgumentLocContainerIterator(ArgLocContainer &Container, unsigned Index)
friend bool operator==(const TemplateArgumentLocContainerIterator &X, const TemplateArgumentLocContainerIterator &Y)
TemplateArgumentLocContainerIterator & operator++()
const TemplateArgumentLoc * operator->() const
Iterator adaptor that invents template argument location information for each of the template argumen...
TemplateArgumentLocInventIterator & operator++()
std::iterator_traits< InputIterator >::difference_type difference_type
TemplateArgumentLocInventIterator operator++(int)
friend bool operator==(const TemplateArgumentLocInventIterator &X, const TemplateArgumentLocInventIterator &Y)
TemplateArgumentLocInventIterator(TreeTransform< Derived > &Self, InputIterator Iter)
friend bool operator!=(const TemplateArgumentLocInventIterator &X, const TemplateArgumentLocInventIterator &Y)
std::input_iterator_tag iterator_category
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:574
SourceLocation getTemplateNameLoc() const
Definition: TemplateBase.h:616
TypeSourceInfo * getTypeSourceInfo() const
Definition: TemplateBase.h:578
SourceRange getSourceRange() const LLVM_READONLY
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Definition: TemplateBase.h:609
Expr * getSourceExpression() const
Definition: TemplateBase.h:584
Represents a template argument.
Definition: TemplateBase.h:61
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:408
QualType getNonTypeTemplateArgumentType() const
If this is a non-type template argument, get its type.
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:319
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:363
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
Definition: TemplateBase.h:343
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
Definition: TemplateBase.h:326
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
Definition: TemplateBase.h:74
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:93
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
Definition: TemplateBase.h:89
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:107
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:97
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
Definition: TemplateBase.h:78
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
Definition: TemplateBase.h:67
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:82
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:103
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:295
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
Definition: TemplateBase.h:396
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
Represents a C++ template name within the type system.
Definition: TemplateName.h:203
bool isNull() const
Determine whether this template name is NULL.
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI)
Definition: TypeLoc.h:1687
void setTemplateKeywordLoc(SourceLocation Loc)
Definition: TypeLoc.h:1663
void setTemplateNameLoc(SourceLocation Loc)
Definition: TypeLoc.h:1704
void setLAngleLoc(SourceLocation Loc)
Definition: TypeLoc.h:1671
SourceLocation getTemplateNameLoc() const
Definition: TypeLoc.h:1700
void setRAngleLoc(SourceLocation Loc)
Definition: TypeLoc.h:1679
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:6480
Wrapper for template type parameters.
Definition: TypeLoc.h:758
The top declaration context.
Definition: Decl.h:84
RAII object that temporarily sets the base location and entity used for reporting diagnostics in type...
TemporaryBase(TreeTransform &Self, SourceLocation Location, DeclarationName Entity)
A semantic tree transformation that allows one to transform one abstract syntax tree into another.
ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *object)
Rebuild the operand to an Objective-C @synchronized statement.
OMPClause * RebuildOMPNontemporalClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'nontemporal' clause.
ExprResult TransformInitializer(Expr *Init, bool NotCopyInit)
Transform the given initializer.
StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L, SourceLocation ColonLoc, Stmt *SubStmt)
Build a new label statement.
StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args)
StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body)
Build a new Objective-C @autoreleasepool statement.
OMPClause * RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Build a new OpenMP 'dist_schedule' clause.
ExprResult RebuildUnaryOperator(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *SubExpr)
Build a new unary operator expression.
OMPClause * RebuildOMPProcBindClause(ProcBindKind Kind, SourceLocation KindKwLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'proc_bind' clause.
StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind, DeclarationNameInfo DirName, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Build a new OpenMP informational directive.
ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field)
Build a new C++11 default-initialization expression.
OMPClause * RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'priority' clause.
ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc, TypeSourceInfo *EncodeTypeInfo, SourceLocation RParenLoc)
Build a new Objective-C @encode expression.
StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body)
Alternative implementation of TransformLambdaBody that skips transforming the body.
QualType TransformAttributedType(TypeLocBuilder &TLB, AttributedTypeLoc TL, Fn TransformModifiedType)
ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc, SourceLocation OpLoc, bool IsArrow)
Build a new Objective-C "isa" expression.
StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body)
Build a new Objective-C @finally statement.
SourceLocation getBaseLocation()
Returns the location of the entity being transformed, if that information was not available elsewhere...
ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
Build a new call expression.
ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar, SourceLocation IvarLoc, bool IsArrow, bool IsFreeIvar)
Build a new Objective-C ivar reference expression.
OMPClause * RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'at' clause.
StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result, bool IsImplicit)
Build a new co_return statement.
OMPClause * RebuildOMPInReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions)
Build a new OpenMP 'in_reduction' clause.
ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, SourceLocation RParenLoc, Expr *Init)
Build a new compound literal expression.
ExprResult TransformAddressOfOperand(Expr *E)
The operand of a unary address-of operator has special rules: it's allowed to refer to a non-static m...
ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc, QualType ThisType, bool isImplicit)
Build a new C++ "this" expression.
ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType, SourceLocation TypeidLoc, Expr *Operand, SourceLocation RParenLoc)
Build a new C++ typeid(expr) expression.
TreeTransform(Sema &SemaRef)
Initializes a new tree transformer.
QualType RebuildDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const IdentifierInfo *Name, SourceLocation NameLoc, TemplateArgumentListInfo &Args, bool AllowInjectedClassName)
Build a new typename type that refers to a template-id.
QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr, Expr *ColumnExpr, SourceLocation AttributeLoc)
Build a new matrix type given the type and dependently-defined dimensions.
QualType RebuildUnaryTransformType(QualType BaseType, UnaryTransformType::UTTKind UKind, SourceLocation Loc)
Build a new unary transform type.
ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg, ObjCPropertyDecl *Property, SourceLocation PropertyLoc)
Build a new Objective-C property reference expression.
void InventTemplateArgumentLoc(const TemplateArgument &Arg, TemplateArgumentLoc &ArgLoc)
Fakes up a TemplateArgumentLoc for a given TemplateArgument.
OMPClause * RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Build a new OpenMP 'use' clause.
QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL)
Transform the given type-with-location into a new type, collecting location information in the given ...
ExprResult RebuildCXXRewrittenBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opcode, const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS)
Build a new rewritten operator expression.
ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E, bool IsAddressOfOperand)
ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy, SourceLocation BuiltinLoc, SourceLocation RPLoc, DeclContext *ParentContext)
Build a new expression representing a call to a source location builtin.
QualType RebuildEnumType(EnumDecl *Enum)
Build a new Enum type.
TemplateName RebuildTemplateName(const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index, bool Final)
Build a new template name given a template template parameter pack and the.
ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, std::optional< unsigned > NumExpansions)
Build a new expression pack expansion.
QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL)
Transforms a reference type.
OMPClause * RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'message' clause.
ExprResult RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc, TypeSourceInfo *TInfo, SourceLocation RAngleLoc, SourceLocation LParenLoc, Expr *SubExpr, SourceLocation RParenLoc)
QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind)
Build a new typeof(type) type.
ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, Expr *SubExpr, TypeSourceInfo *TInfo, SourceLocation RParenLoc)
Build a new va_arg expression.
ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo, SourceLocation LParenLoc, SourceLocation RParenLoc)
Build a new C++ zero-initialization expression.
StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr)
OMPClause * RebuildOMPThreadLimitClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'thread_limit' clause.
StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block)
OMPClause * RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'simdlen' clause.
StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef< Stmt * > Handlers)
Build a new C++ try statement.
StmtDiscardKind
The reason why the value of a statement is not discarded, if any.
ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, UnresolvedLookupExpr *OpCoawaitLookup, bool IsImplicit)
Build a new co_await expression.
bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs, unsigned NumInputs, TemplateArgumentListInfo &Outputs, bool Uneval=false)
Transform the given set of template arguments.
ExprResult RebuildDesignatedInitExpr(Designation &Desig, MultiExprArg ArrayExprs, SourceLocation EqualOrColonLoc, bool GNUSyntax, Expr *Init)
Build a new designated initializer expression.
OMPClause * RebuildOMPSizesClause(ArrayRef< Expr * > Sizes, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK)
Build a new predefined expression.
QualType RebuildElaboratedType(SourceLocation KeywordLoc, ElaboratedTypeKeyword Keyword, NestedNameSpecifierLoc QualifierLoc, QualType Named)
Build a new qualified name type.
ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc, TypeSourceInfo *TInfo, SourceLocation RAngleLoc, SourceLocation LParenLoc, Expr *SubExpr, SourceLocation RParenLoc)
Build a new C++ static_cast expression.
StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *Init, Sema::ConditionResult Cond, Sema::FullExprArg Inc, SourceLocation RParenLoc, Stmt *Body)
Build a new for statement.
StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, NestedNameSpecifierLoc QualifierLoc, DeclarationNameInfo NameInfo, Stmt *Nested)
Build a new C++0x range-based for statement.
ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt, SourceLocation RParenLoc, unsigned TemplateDepth)
Build a new GNU statement expression.
QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword, SourceLocation KeywordLoc, NestedNameSpecifierLoc QualifierLoc, const IdentifierInfo *Id, SourceLocation IdLoc, bool DeducedTSTContext)
Build a new typename type that refers to an identifier.
QualType RebuildTemplateSpecializationType(TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &Args)
Build a new template specialization type.
bool TryExpandParameterPacks(SourceLocation EllipsisLoc, SourceRange PatternRange, ArrayRef< UnexpandedParameterPack > Unexpanded, bool &ShouldExpand, bool &RetainExpansion, std::optional< unsigned > &NumExpansions)
Determine whether we should expand a pack expansion with the given set of parameter packs into separa...
Sema & getSema() const
Retrieves a reference to the semantic analysis object used for this tree transform.
ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs, SourceLocation RParenLoc)
Build a new shuffle vector expression.
QualType TransformType(QualType T)
Transforms the given type into another type.
OMPClause * RebuildOMPOrderClause(OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc)
Build a new OpenMP 'order' clause.
QualType RebuildReferenceType(QualType ReferentType, bool LValue, SourceLocation Sigil)
Build a new reference type given the type it references.
ExprResult TransformRequiresTypeParams(SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE, RequiresExprBodyDecl *Body, ArrayRef< ParmVarDecl * > Params, SmallVectorImpl< QualType > &PTypes, SmallVectorImpl< ParmVarDecl * > &TransParams, Sema::ExtParameterInfoBuilder &PInfos)
Transforms the parameters of a requires expresison into the given vectors.
ExprResult RebuildInitList(SourceLocation LBraceLoc, MultiExprArg Inits, SourceLocation RBraceLoc)
Build a new initializer list expression.
QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, SourceLocation ProtocolLAngleLoc, ArrayRef< ObjCProtocolDecl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc)
StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Operand)
Build a new Objective-C @throw statement.
OMPClause * RebuildOMPTaskReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions)
Build a new OpenMP 'task_reduction' clause.
OMPClause * RebuildOMPCopyinClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'copyin' clause.
QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc, bool isReadPipe)
Build a new pipe type given its value type.
StmtResult RebuildCaseStmt(SourceLocation CaseLoc, Expr *LHS, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation ColonLoc)
Build a new case statement.
ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, bool RequiresADL, const TemplateArgumentListInfo *TemplateArgs)
Build a new template-id expression.
StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc, VarDecl *ExceptionDecl, Stmt *Handler)
Build a new C++ catch statement.
OMPClause * RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Build a new OpenMP 'destroy' clause.
ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, SourceRange R)
Build a new sizeof, alignof or vec step expression with an expression argument.
ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc, SourceLocation LabelLoc, LabelDecl *Label)
Build a new address-of-label expression.
ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc)
TemplateName TransformTemplateName(CXXScopeSpec &SS, TemplateName Name, SourceLocation NameLoc, QualType ObjectType=QualType(), NamedDecl *FirstQualifierInScope=nullptr, bool AllowInjectedClassName=false)
Transform the given template name.
OMPClause * RebuildOMPXBareClause(SourceLocation StartLoc, SourceLocation EndLoc)
Build a new OpenMP 'ompx_bare' clause.
const Attr * TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS, const Attr *A)
ExprResult RebuildConditionalOperator(Expr *Cond, SourceLocation QuestionLoc, Expr *LHS, SourceLocation ColonLoc, Expr *RHS)
Build a new conditional operator expression.
StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body)
Attach body to a C++0x range-based for statement.
StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *Object, Stmt *Body)
Build a new Objective-C @synchronized statement.
TemplateName RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW, TemplateDecl *Template)
Build a new template name given a nested name specifier, a flag indicating whether the "template" key...
OMPClause * RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Build a new OpenMP 'device' clause.
QualType TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL, TemplateName Template, CXXScopeSpec &SS)
OMPClause * RebuildOMPHasDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Build a new OpenMP 'has_device_addr' clause.
QualType RebuildDependentSizedExtVectorType(QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc)
Build a new potentially dependently-sized extended vector type given the element type and number of e...
void RememberPartiallySubstitutedPack(TemplateArgument Arg)
"Remember" the partially-substituted pack template argument after performing an instantiation that mu...
Decl * TransformDefinition(SourceLocation Loc, Decl *D)
Transform the definition of the given declaration.
OMPClause * RebuildOMPFromClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers)
Build a new OpenMP 'from' clause.
ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc, Expr *Result, UnresolvedLookupExpr *Lookup)
Build a new co_await expression.
QualType RebuildTypedefType(TypedefNameDecl *Typedef)
Build a new typedef type.
StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result)
Build a new return statement.
TemplateArgument ForgetPartiallySubstitutedPack()
"Forget" about the partially-substituted pack template argument, when performing an instantiation tha...
OMPClause * RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'nocontext' clause.
ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc, TypeSourceInfo *TInfo, SourceLocation RAngleLoc, SourceLocation LParenLoc, Expr *SubExpr, SourceLocation RParenLoc)
Build a new C++ reinterpret_cast expression.
QualType RebuildVectorType(QualType ElementType, unsigned NumElements, VectorKind VecKind)
Build a new vector type given the element type and number of elements.
ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc, TypeSourceInfo *Type, ArrayRef< Sema::OffsetOfComponent > Components, SourceLocation RParenLoc)
Build a new builtin offsetof expression.
QualType RebuildParenType(QualType InnerType)
Build a new parenthesized type.
QualType RebuildRecordType(RecordDecl *Record)
Build a new class/struct/union type.
static StmtResult Owned(Stmt *S)
OMPClause * RebuildOMPReductionClause(ArrayRef< Expr * > VarList, OpenMPReductionClauseModifier Modifier, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions)
Build a new OpenMP 'reduction' clause.
OMPClause * RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'partial' clause.
OMPClause * RebuildOMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Build a new OpenMP 'schedule' clause.
StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body)
Transform the body of a lambda-expression.
StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
OMPClause * RebuildOMPExclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'exclusive' clause.
QualType RebuildDependentAddressSpaceType(QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc)
Build a new DependentAddressSpaceType or return the pointee type variable with the correct address sp...
StmtResult RebuildAttributedStmt(SourceLocation AttrLoc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)
Build a new attributed statement.
ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, TemplateArgumentListInfo *TALI)
Build a new Objective-C boxed expression.
OMPClause * RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Build a new OpenMP 'defaultmap' clause.
StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult Loop)
ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param, Expr *RewrittenExpr)
Build a new C++ default-argument expression.
StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, Sema::ConditionResult Cond, SourceLocation RParenLoc, Stmt *Body)
Build a new while statement.
OMPClause * RebuildOMPNumTeamsClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'num_teams' clause.
ExprResult RebuildImplicitValueInitExpr(QualType T)
Build a new value-initialized expression.
bool TransformFunctionTypeParams(SourceLocation Loc, ArrayRef< ParmVarDecl * > Params, const QualType *ParamTypes, const FunctionProtoType::ExtParameterInfo *ParamInfos, SmallVectorImpl< QualType > &PTypes, SmallVectorImpl< ParmVarDecl * > *PVars, Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed)
Transforms the parameters of a function type into the given vectors.
StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, IdentifierInfo **Names, MultiExprArg Constraints, MultiExprArg Exprs, Expr *AsmString, MultiExprArg Clobbers, unsigned NumLabels, SourceLocation RParenLoc)
Build a new inline asm statement.
StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S)
ExprResult RebuildObjCMessageExpr(Expr *Receiver, Selector Sel, ArrayRef< SourceLocation > SelectorLocs, ObjCMethodDecl *Method, SourceLocation LBracLoc, MultiExprArg Args, SourceLocation RBracLoc)
Build a new Objective-C instance message.
QualType TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool SuppressObjCLifetime)
ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool RequiresADL)
Build a new expression that references a declaration.
bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall, SmallVectorImpl< Expr * > &Outputs, bool *ArgChanged=nullptr)
Transform the given list of expressions.
StmtResult TransformSEHHandler(Stmt *Handler)
NestedNameSpecifierLoc TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, QualType ObjectType=QualType(), NamedDecl *FirstQualifierInScope=nullptr)
Transform the given nested-name-specifier with source-location information.
TemplateName RebuildTemplateName(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, OverloadedOperatorKind Operator, SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName)
Build a new template name given a nested name specifier and the overloaded operator name that is refe...
QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc)
Build a new C++11 decltype type.
OMPClause * RebuildOMPUseDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Build a new OpenMP 'use_device_ptr' clause.
QualType TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL, NestedNameSpecifierLoc QualifierLoc)
void ExpandingFunctionParameterPack(ParmVarDecl *Pack)
Note to the derived class when a function parameter pack is being expanded.
void setBase(SourceLocation Loc, DeclarationName Entity)
Sets the "base" location and entity when that information is known based on another transformation.
concepts::TypeRequirement * TransformTypeRequirement(concepts::TypeRequirement *Req)
const Derived & getDerived() const
Retrieves a reference to the derived class.
OMPClause * RebuildOMPAllocateClause(Expr *Allocate, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Build a new OpenMP 'allocate' clause.
ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen, SourceLocation RParen)
Build a new expression in parentheses.
OMPClause * RebuildOMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'num_threads' clause.
QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil)
Build a new block pointer type given its pointee type.
ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc, bool isArrow, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &MemberNameInfo, ValueDecl *Member, NamedDecl *FoundDecl, const TemplateArgumentListInfo *ExplicitTemplateArgs, NamedDecl *FirstQualifierInScope)
Build a new member access expression.
OMPClause * RebuildOMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'shared' clause.
ExprResult RebuildCXXConstructExpr(QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor, bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates, bool ListInitialization, bool StdInitListInitialization, bool RequiresZeroInit, CXXConstructionKind ConstructKind, SourceRange ParenRange)
Build a new object-construction expression.
bool TransformFunctionTypeParams(SourceLocation Loc, ArrayRef< ParmVarDecl * > Params, const QualType *ParamTypes, const FunctionProtoType::ExtParameterInfo *ParamInfos, SmallVectorImpl< QualType > &PTypes, SmallVectorImpl< ParmVarDecl * > *PVars, Sema::ExtParameterInfoBuilder &PInfos)
OMPClause * RebuildOMPLinearClause(ArrayRef< Expr * > VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation StepModifierLoc, SourceLocation EndLoc)
Build a new OpenMP 'linear' clause.
VarDecl * RebuildExceptionDecl(VarDecl *ExceptionDecl, TypeSourceInfo *Declarator, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id)
Build a new C++ exception declaration.
ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg)
Build a new noexcept expression.
QualType RebuildFunctionProtoType(QualType T, MutableArrayRef< QualType > ParamTypes, const FunctionProtoType::ExtProtoInfo &EPI)
Build a new function type.
ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB, Expr *Base, Expr *Key, ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod)
ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc, ArrayRef< Expr * > SubExprs, QualType Type)
ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, LambdaScopeInfo *LSI)
QualType RebuildIncompleteArrayType(QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals, SourceRange BracketsRange)
Build a new incomplete array type given the element type, size modifier, and index type qualifiers.
TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern, SourceLocation EllipsisLoc, std::optional< unsigned > NumExpansions)
Build a new template argument pack expansion.
CXXRecordDecl::LambdaDependencyKind ComputeLambdaDependency(LambdaScopeInfo *LSI)
ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, SourceLocation LParenLoc, Expr *Sub, SourceLocation RParenLoc, bool ListInitialization)
Build a new C++ functional-style cast expression.
TypeSourceInfo * TransformType(TypeSourceInfo *DI)
Transforms the given type-with-location into a new type-with-location.
ExprResult RebuildObjCDictionaryLiteral(SourceRange Range, MutableArrayRef< ObjCDictionaryElement > Elements)
Build a new Objective-C dictionary literal.
StmtResult TransformStmt(Stmt *S, StmtDiscardKind SDK=SDK_Discarded)
Transform the given statement.
StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, Expr *Target)
Build a new indirect goto statement.
ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc, bool IsArrow, SourceLocation AccessorLoc, IdentifierInfo &Accessor)
Build a new extended vector element access expression.
ExprResult RebuildParenListExpr(SourceLocation LParenLoc, MultiExprArg SubExprs, SourceLocation RParenLoc)
Build a new expression list in parentheses.
OMPClause * RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'allocator' clause.
QualType RebuildDependentSizedArrayType(QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange)
Build a new dependent-sized array type given the element type, size modifier, size expression,...
NamedDecl * TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc)
Transform the given declaration, which was the first part of a nested-name-specifier in a member acce...
OMPClause * RebuildOMPInclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'inclusive' clause.
StmtResult TransformOMPInformationalDirective(OMPExecutableDirective *S)
This is mostly the same as above, but allows 'informational' class directives when rebuilding the stm...
concepts::ExprRequirement * RebuildExprRequirement(concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple, SourceLocation NoexceptLoc, concepts::ExprRequirement::ReturnTypeRequirement Ret)
OMPClause * TransformOMPClause(OMPClause *S)
Transform the given statement.
QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc)
Build a new atomic type given its value type.
ExprResult RebuildBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHS, Expr *RHS)
Build a new binary operator expression.
ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, SourceLocation RParenLoc, Expr *SubExpr)
Build a new C-style cast expression.
OMPClause * RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'default' clause.
QualType RebuildObjCObjectPointerType(QualType PointeeType, SourceLocation Star)
Build a new Objective-C object pointer type given the pointee type.
ExprResult TransformExpr(Expr *E)
Transform the given expression.
bool AlreadyTransformed(QualType T)
Determine whether the given type T has already been transformed.
concepts::TypeRequirement * RebuildTypeRequirement(TypeSourceInfo *T)
ExprResult RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc, ArrayRef< SemaOpenMP::OMPIteratorData > Data)
Build a new iterator expression.
ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc, SourceLocation LParen, SourceLocation RParen, TypeSourceInfo *TSI)
OMPClause * RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier, Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Build a new OpenMP 'grainsize' clause.
OMPClause * RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
bool TransformTemplateArguments(InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs, bool Uneval=false)
Transform the given set of template arguments.
OMPClause * RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'collapse' clause.
static ExprResult Owned(Expr *E)
ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc, Expr *Operand, SourceLocation RParenLoc)
Build a new C++ __uuidof(expr) expression.
OMPClause * RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Build a new OpenMP 'num_tasks' clause.
OMPClause * RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'depobj' pseudo clause.
ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc, Expr *Cond, Expr *LHS, Expr *RHS, SourceLocation RParenLoc)
Build a new __builtin_choose_expr expression.
OMPClause * RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'align' clause.
ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo, Selector Sel, ArrayRef< SourceLocation > SelectorLocs, ObjCMethodDecl *Method, SourceLocation LBracLoc, MultiExprArg Args, SourceLocation RBracLoc)
Build a new Objective-C class message.
bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL, LookupResult &R)
Transform the set of declarations in an OverloadExpr.
ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo, SourceLocation LParenOrBraceLoc, MultiExprArg Args, SourceLocation RParenOrBraceLoc, bool ListInitialization)
Build a new object-construction expression.
StmtResult RebuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init, SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond, Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc, ArrayRef< MaterializeTemporaryExpr * > LifetimeExtendTemps)
Build a new C++0x range-based for statement.
OMPClause * RebuildOMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc, Expr *Num)
Build a new OpenMP 'ordered' clause.
ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result)
Build a new co_yield expression.
QualType RebuildObjCObjectType(QualType BaseType, SourceLocation Loc, SourceLocation TypeArgsLAngleLoc, ArrayRef< TypeSourceInfo * > TypeArgs, SourceLocation TypeArgsRAngleLoc, SourceLocation ProtocolLAngleLoc, ArrayRef< ObjCProtocolDecl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc)
Build an Objective-C object type.
llvm::DenseMap< Decl *, Decl * > TransformedLocalDecls
The set of local declarations that have been transformed, for cases where we are forced to build new ...
OMPClause * RebuildOMPNovariantsClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'novariants' clause.
StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K, SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult StrBlock)
ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E)
ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, SourceRange TypeIdParens, QualType AllocatedType, TypeSourceInfo *AllocatedTypeInfo, std::optional< Expr * > ArraySize, SourceRange DirectInitRange, Expr *Initializer)
Build a new C++ "new" expression.
StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc, Stmt *Element, Expr *Collection, SourceLocation RParenLoc, Stmt *Body)
Build a new Objective-C fast enumeration statement.
ExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI)
Build a new (previously unresolved) declaration reference expression.
StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc, Stmt *TryBody, MultiStmtArg CatchStmts, Stmt *Finally)
Build a new Objective-C @try statement.
DeclarationName getBaseEntity()
Returns the name of the entity being transformed, if that information was not available elsewhere in ...
ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc, bool ListInitialization)
Build a new object-construction expression.
ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack, SourceLocation PackLoc, SourceLocation RParenLoc, std::optional< unsigned > Length, ArrayRef< TemplateArgument > PartialArgs)
Build a new expression to compute the length of a parameter pack.
ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc, bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First, Expr *Second)
Build a new overloaded operator call expression.
OMPClause * RebuildOMPUseDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Build a new OpenMP 'use_device_addr' clause.
QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc)
Build a dependent bit-precise int given its value type.
OMPClause * RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'hint' clause.
Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind)
Transform the specified condition.
TemplateName RebuildTemplateName(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name, SourceLocation NameLoc, QualType ObjectType, NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName)
Build a new template name given a nested name specifier and the name that is referred to as a templat...
OMPClause * RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind, SourceLocation KwLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'severity' clause.
OMPClause * RebuildOMPFirstprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'firstprivate' clause.
StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, ArrayRef< Token > AsmToks, StringRef AsmString, unsigned NumOutputs, unsigned NumInputs, ArrayRef< StringRef > Constraints, ArrayRef< StringRef > Clobbers, ArrayRef< Expr * > Exprs, SourceLocation EndLoc)
Build a new MS style inline asm statement.
QualType TransformTemplateSpecializationType(TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL, TemplateName Template)
VarDecl * RebuildObjCExceptionDecl(VarDecl *ExceptionDecl, TypeSourceInfo *TInfo, QualType T)
Rebuild an Objective-C exception declaration.
concepts::NestedRequirement * TransformNestedRequirement(concepts::NestedRequirement *Req)
QualType RebuildConstantArrayType(QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size, Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange)
Build a new constant array type given the element type, size modifier, (known) size of the array,...
ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, SourceLocation RParenLoc, ArrayRef< Expr * > Dims, ArrayRef< SourceRange > BracketsRanges)
Build a new array shaping expression.
ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc, bool IsGlobalDelete, bool IsArrayForm, Expr *Operand)
Build a new C++ "delete" expression.
bool TransformExceptionSpec(SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI, SmallVectorImpl< QualType > &Exceptions, bool &Changed)
QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D)
Rebuild an unresolved typename type, given the decl that the UnresolvedUsingTypenameDecl was transfor...
ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait, SourceLocation StartLoc, TypeSourceInfo *TSInfo, Expr *DimExpr, SourceLocation RParenLoc)
Build a new array type trait expression.
OMPClause * RebuildOMPIsDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Build a new OpenMP 'is_device_ptr' clause.
QualType RebuildMacroQualifiedType(QualType T, const IdentifierInfo *MacroII)
Build a new MacroDefined type.
concepts::NestedRequirement * RebuildNestedRequirement(Expr *Constraint)
ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx, Expr *ColumnIdx, SourceLocation RBracketLoc)
Build a new matrix subscript expression.
ExprResult TransformParenDependentScopeDeclRefExpr(ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI)
TemplateParameterList * TransformTemplateParameterList(TemplateParameterList *TPL)
QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType, SourceLocation Sigil)
Build a new member pointer type given the pointee type and the class type it refers into.
void transformAttrs(Decl *Old, Decl *New)
Transform the attributes associated with the given declaration and place them on the new declaration.
Decl * TransformDecl(SourceLocation Loc, Decl *D)
Transform the given declaration, which is referenced from a type or expression.
bool AlwaysRebuild()
Whether the transformation should always rebuild AST nodes, even if none of the children have changed...
ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc, Selector Sel, ArrayRef< SourceLocation > SelectorLocs, QualType SuperType, ObjCMethodDecl *Method, SourceLocation LBracLoc, MultiExprArg Args, SourceLocation RBracLoc)
Build a new Objective-C instance/class message to 'super'.
OMPClause * RebuildOMPLastprivateClause(ArrayRef< Expr * > VarList, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'lastprivate' clause.
QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc, VectorKind)
Build a new potentially dependently-sized extended vector type given the element type and number of e...
bool AllowSkippingCXXConstructExpr()
Wether CXXConstructExpr can be skipped when they are implicit.
OMPClause * RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'safelen' clause.
StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc, SourceLocation LParenLoc, Stmt *Init, Sema::ConditionResult Cond, SourceLocation RParenLoc)
Start building a new switch statement.
StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt)
Build a new default statement.
StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParenLoc, VarDecl *Var, Stmt *Body)
Build a new Objective-C @catch statement.
OMPClause * RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'filter' clause.
ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base, SourceLocation OperatorLoc, bool isArrow, CXXScopeSpec &SS, TypeSourceInfo *ScopeType, SourceLocation CCLoc, SourceLocation TildeLoc, PseudoDestructorTypeStorage Destroyed)
Build a new pseudo-destructor expression.
QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange, SourceLocation EllipsisLoc, std::optional< unsigned > NumExpansions)
Build a new pack expansion type.
QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits, SourceLocation Loc)
Build a bit-precise int given its value type.
ExprResult RebuildObjCArrayLiteral(SourceRange Range, Expr **Elements, unsigned NumElements)
Build a new Objective-C array literal.
ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc, TypeSourceInfo *Operand, SourceLocation RParenLoc)
Build a new C++ __uuidof(type) expression.
ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType, SourceLocation OperatorLoc, bool IsArrow, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs)
Build a new member reference expression.
OMPClause * RebuildOMPBindClause(OpenMPBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'bind' clause.
concepts::NestedRequirement * RebuildNestedRequirement(StringRef InvalidConstraintEntity, const ASTConstraintSatisfaction &Satisfaction)
OMPClause * RebuildOMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'copyprivate' clause.
QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword, ConceptDecl *TypeConstraintConcept, ArrayRef< TemplateArgument > TypeConstraintArgs)
Build a new C++11 auto type.
ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc, SourceLocation RSquareLoc, Expr *PackIdExpression, Expr *IndexExpr, ArrayRef< Expr * > ExpandedExprs, bool EmptyPack=false)
QualType RebuildVariableArrayType(QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange)
Build a new variable-length array type given the element type, size modifier, size expression,...
ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc, TypeSourceInfo *TInfo, SourceLocation RAngleLoc, SourceLocation LParenLoc, Expr *SubExpr, SourceLocation RParenLoc)
Build a new C++ dynamic_cast expression.
ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc, TypeSourceInfo *ControllingType, ArrayRef< TypeSourceInfo * > Types, ArrayRef< Expr * > Exprs)
Build a new generic selection expression with a type predicate.
QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil)
Build a new pointer type given its pointee type.
concepts::TypeRequirement * RebuildTypeRequirement(concepts::Requirement::SubstitutionDiagnostic *SubstDiag)
OMPClause * RebuildOMPUsesAllocatorsClause(ArrayRef< SemaOpenMP::UsesAllocatorsData > Data, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'uses_allocators' clause.
ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor, bool ConstructsVBase, bool InheritedFromVBase)
Build a new implicit construction via inherited constructor expression.
ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc, TypeSourceInfo *TInfo, SourceLocation RAngleLoc, SourceLocation LParenLoc, Expr *SubExpr, SourceLocation RParenLoc)
Build a new C++ const_cast expression.
ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs, AtomicExpr::AtomicOp Op, SourceLocation RParenLoc)
Build a new atomic operation expression.
DeclarationNameInfo TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo)
Transform the given declaration name.
OMPClause * RebuildOMPXAttributeClause(ArrayRef< const Attr * > Attrs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'ompx_attribute' clause.
ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE, SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Operator, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc, std::optional< unsigned > NumExpansions)
Build a new C++1z fold-expression.
OMPClause * RebuildOMPToClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers)
Build a new OpenMP 'to' clause.
StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation LParenLoc, Expr *Cond, SourceLocation RParenLoc)
Build a new do-while statement.
OMPClause * RebuildOMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Build a new OpenMP 'if' clause.
StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body)
Attach the body to a new case statement.
ExprResult RebuildTypeTrait(TypeTrait Trait, SourceLocation StartLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc)
Build a new type trait expression.
ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, BinaryOperatorKind Operator)
Build an empty C++1z fold-expression with the given operator.
QualType TransformTypeWithDeducedTST(QualType T)
Transform a type that is permitted to produce a DeducedTemplateSpecializationType.
OMPClause * RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Build a new OpenMP 'init' clause.
OMPClause * RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'detach' clause.
StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc, MultiStmtArg Statements, SourceLocation RBraceLoc, bool IsStmtExpr)
Build a new compound statement.
ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc, ValueDecl *VD, const DeclarationNameInfo &NameInfo, NamedDecl *Found, TemplateArgumentListInfo *TemplateArgs)
Build a new expression that references a declaration.
QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size, Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange)
Build a new array type given the element type, size modifier, size of the array (if known),...
StmtResult RebuildDeclStmt(MutableArrayRef< Decl * > Decls, SourceLocation StartLoc, SourceLocation EndLoc)
Build a new declaration statement.
QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying)
Build a new type found via an alias.
ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc, Expr *SrcExpr, TypeSourceInfo *DstTInfo, SourceLocation RParenLoc)
Build a new convert vector expression.
QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL)
Build a new qualified type given its unqualified type and type location.
OMPClause * RebuildOMPDependClause(OMPDependClause::DependDataTy Data, Expr *DepModifier, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'depend' pseudo clause.
OMPClause * RebuildOMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Build a new OpenMP 'aligned' clause.
unsigned TransformTemplateDepth(unsigned Depth)
Transform a template parameter depth level.
QualType RebuildFunctionNoProtoType(QualType ResultType)
Build a new unprototyped function type.
QualType TransformFunctionProtoType(TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, Qualifiers ThisTypeQuals, Fn TransformExceptionSpec)
const Attr * TransformAttr(const Attr *S)
Transform the given attribute.
QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows, unsigned NumColumns)
Build a new matrix type given the element type and dimensions.
OMPClause * RebuildOMPMapClause(Expr *IteratorModifier, ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers)
Build a new OpenMP 'map' clause.
ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc, TypeSourceInfo *TSI, Expr *Sub, SourceLocation RParenLoc)
Build a new C++ __builtin_bit_cast expression.
QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr, SourceLocation Loc, SourceLocation EllipsisLoc, bool FullySubstituted, ArrayRef< QualType > Expansions={})
StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt)
Build a new OpenMP Canonical loop.
StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind, DeclarationNameInfo DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Build a new OpenMP executable directive.
concepts::ExprRequirement * RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc, concepts::ExprRequirement::ReturnTypeRequirement Ret)
ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E, bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI)
OMPClause * RebuildOMPFullClause(SourceLocation StartLoc, SourceLocation EndLoc)
Build a new OpenMP 'full' clause.
StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
OMPClause * RebuildOMPAffinityClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, Expr *Modifier, ArrayRef< Expr * > Locators)
Build a new OpenMP 'affinity' clause.
ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType, SourceLocation TypeidLoc, TypeSourceInfo *Operand, SourceLocation RParenLoc)
Build a new C++ typeid(type) expression.
TypeSourceInfo * TransformTypeWithDeducedTST(TypeSourceInfo *DI)
ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs)
Build a new member reference expression.
ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc, Stmt::StmtClass Class, SourceLocation LAngleLoc, TypeSourceInfo *TInfo, SourceLocation RAngleLoc, SourceLocation LParenLoc, Expr *SubExpr, SourceLocation RParenLoc)
Build a new C++ "named" cast expression, such as static_cast or reinterpret_cast.
StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body)
Attach the body to the switch statement.
TypeSourceInfo * InventTypeSourceInfo(QualType T)
Fakes up a TypeSourceInfo for a type.
ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo, SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, SourceRange R)
Build a new sizeof, alignof or vec_step expression with a type argument.
ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc, Expr *ControllingExpr, ArrayRef< TypeSourceInfo * > Types, ArrayRef< Expr * > Exprs)
Build a new generic selection expression with an expression predicate.
QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool SuppressObjCLifetime)
Derived & getDerived()
Retrieves a reference to the derived class.
OMPClause * RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'holds' clause.
ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base, SourceLocation LBracketLoc, Expr *LowerBound, SourceLocation ColonLocFirst, SourceLocation ColonLocSecond, Expr *Length, Expr *Stride, SourceLocation RBracketLoc)
Build a new array section expression.
concepts::ExprRequirement * TransformExprRequirement(concepts::ExprRequirement *Req)
QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc, TypeOfKind Kind)
Build a new typeof(expr) type.
ParmVarDecl * TransformFunctionTypeParam(ParmVarDecl *OldParm, int indexAdjustment, std::optional< unsigned > NumExpansions, bool ExpectParameterPack)
Transforms a single function-type parameter.
bool ReplacingOriginal()
Whether the transformation is forming an expression or statement that replaces the original.
OMPClause * RebuildOMPFlushClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'flush' pseudo clause.
bool TransformTemplateArgument(const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output, bool Uneval=false)
Transform the given template argument.
QualType RebuildDeducedTemplateSpecializationType(TemplateName Template, QualType Deduced)
By default, builds a new DeducedTemplateSpecializationType with the given deduced type.
ExprResult RebuildArraySubscriptExpr(Expr *LHS, SourceLocation LBracketLoc, Expr *RHS, SourceLocation RBracketLoc)
Build a new array subscript expression.
QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements, SourceLocation AttributeLoc)
Build a new extended vector type given the element type and number of elements.
void transformedLocalDecl(Decl *Old, ArrayRef< Decl * > New)
Note that a local declaration has been transformed by this transformer.
ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr)
Build a new Objective-C boxed expression.
ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub, bool IsThrownVariableInScope)
Build a new C++ throw expression.
bool TransformRequiresExprRequirements(ArrayRef< concepts::Requirement * > Reqs, llvm::SmallVectorImpl< concepts::Requirement * > &Transformed)
bool DropCallArgument(Expr *E)
Determine whether the given call argument should be dropped, e.g., because it is a default argument.
StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, LabelDecl *Label)
Build a new goto statement.
OMPClause * RebuildOMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'private' clause.
ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T, ObjCMethodDecl *Getter, ObjCMethodDecl *Setter, SourceLocation PropertyLoc)
Build a new Objective-C property reference expression.
ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, SourceLocation LParenLoc, ArrayRef< ParmVarDecl * > LocalParameters, SourceLocation RParenLoc, ArrayRef< concepts::Requirement * > Requirements, SourceLocation ClosingBraceLoc)
Build a new requires expression.
ExprResult RebuildExpressionTrait(ExpressionTrait Trait, SourceLocation StartLoc, Expr *Queried, SourceLocation RParenLoc)
Build a new expression trait expression.
OMPClause * RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'doacross' clause.
OMPClause * RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'final' clause.
StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind, SourceLocation LParenLoc, Sema::ConditionResult Cond, SourceLocation RParenLoc, Stmt *Init, Stmt *Then, SourceLocation ElseLoc, Stmt *Else)
Build a new "if" statement.
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
void reserve(size_t Requested)
Ensures that this buffer has at least as much capacity as described.
void TypeWasModifiedSafely(QualType T)
Tell the TypeLocBuilder that the type it is storing has been modified in some safe way that doesn't a...
TypeSourceInfo * getTypeSourceInfo(ASTContext &Context, QualType T)
Creates a TypeSourceInfo for the given type.
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:59
UnqualTypeLoc getUnqualifiedLoc() const
Skips past any qualifiers, if this is qualified.
Definition: TypeLoc.h:338
QualType getType() const
Get the type for which this source info wrapper provides information.
Definition: TypeLoc.h:133
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition: TypeLoc.h:89
T castAs() const
Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.
Definition: TypeLoc.h:78
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
Definition: TypeLoc.h:153
unsigned getFullDataSize() const
Returns the size of the type source info data block.
Definition: TypeLoc.h:164
SourceLocation getTemplateKeywordLoc() const
Get the SourceLocation of the template keyword (if any).
Definition: TypeLoc.cpp:751
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition: TypeLoc.h:2684
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:192
A container of type source information.
Definition: Type.h:7721
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:256
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7732
static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword)
Converts an elaborated type keyword into a TagTypeKind.
Definition: Type.cpp:3168
ElaboratedTypeKeyword getKeyword() const
Definition: Type.h:6720
The base class of the type hierarchy.
Definition: Type.h:1829
bool isPointerType() const
Definition: Type.h:8003
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8607
bool isReferenceType() const
Definition: Type.h:8021
bool isEnumeralType() const
Definition: Type.h:8107
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:705
bool canHaveNullability(bool ResultIfUnknown=true) const
Determine whether the given type can have a nullability specifier applied to it, i....
Definition: Type.cpp:4706
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.h:2800
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2695
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:2354
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
Definition: Type.h:8460
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
Definition: Type.cpp:4970
bool isFunctionType() const
Definition: Type.h:7999
bool isObjCObjectPointerType() const
Definition: Type.h:8145
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8540
bool isRecordType() const
Definition: Type.h:8103
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3409
Wrapper for source info for typedefs.
Definition: TypeLoc.h:693
TypedefNameDecl * getTypedefNameDecl() const
Definition: TypeLoc.h:695
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2188
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO, bool Postfix)
Retrieve the unary opcode that corresponds to the given overloaded operator.
Definition: Expr.cpp:1414
Represents a C++ unqualified-id that has been parsed.
Definition: DeclSpec.h:1028
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition: ExprCXX.h:3202
CXXRecordDecl * getNamingClass()
Gets the 'naming class' (in the sense of C++0x [class.access.base]p5) of the lookup.
Definition: ExprCXX.h:3276
bool requiresADL() const
True if this declaration should be extended by argument-dependent lookup.
Definition: ExprCXX.h:3271
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent, bool KnownInstantiationDependent)
Definition: ExprCXX.cpp:420
A set of unresolved declarations.
Definition: UnresolvedSet.h:62
void addDecl(NamedDecl *D)
Definition: UnresolvedSet.h:92
A set of unresolved declarations.
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition: Type.h:5567
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition: DeclCXX.h:3324
NamedDecl * getTargetDecl() const
Gets the underlying declaration which has been brought into the local scope.
Definition: DeclCXX.h:3388
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:667
QualType getType() const
Definition: Decl.h:678
Represents a variable declaration or definition.
Definition: Decl.h:879
@ CInit
C-style initialization with assignment.
Definition: Decl.h:884
@ CallInit
Call-style initialization (C++98)
Definition: Decl.h:887
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition: Decl.h:1116
bool isParameterPack() const
Determine whether this variable is actually a function parameter pack or init-capture pack.
Definition: Decl.cpp:2651
A requires-expression requirement which queries the validity and properties of an expression ('simple...
Definition: ExprConcepts.h:280
SubstitutionDiagnostic * getExprSubstitutionDiagnostic() const
Definition: ExprConcepts.h:408
const ReturnTypeRequirement & getReturnTypeRequirement() const
Definition: ExprConcepts.h:398
SourceLocation getNoexceptLoc() const
Definition: ExprConcepts.h:390
A requires-expression requirement which is satisfied when a general constraint expression is satisfie...
Definition: ExprConcepts.h:429
const ASTConstraintSatisfaction & getConstraintSatisfaction() const
Definition: ExprConcepts.h:484
A static requirement that can be used in a requires-expression to check properties of types and expre...
Definition: ExprConcepts.h:168
A requires-expression requirement which queries the existence of a type name or type template special...
Definition: ExprConcepts.h:225
SubstitutionDiagnostic * getSubstitutionDiagnostic() const
Definition: ExprConcepts.h:260
TypeSourceInfo * getType() const
Definition: ExprConcepts.h:267
bool ContainsUnexpandedParameterPack
Whether the lambda contains an unexpanded parameter pack.
Definition: ScopeInfo.h:899
CXXRecordDecl * Lambda
The class that describes the lambda.
Definition: ScopeInfo.h:865
CXXMethodDecl * CallOperator
The lambda's compiler-generated operator().
Definition: ScopeInfo.h:868
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const AstTypeMatcher< FunctionType > functionType
Matches FunctionType nodes.
bool Inc(InterpState &S, CodePtr OpPC)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...
Definition: Interp.h:776
bool Comp(InterpState &S, CodePtr OpPC)
1) Pops the value from the stack.
Definition: Interp.h:876
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
Definition: Descriptor.h:28
CharSourceRange getSourceRange(const SourceRange &Range)
Returns the token CharSourceRange corresponding to Range.
Definition: FixIt.h:32
The JSON file list parser is used to communicate input to InstallAPI.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
@ OO_None
Not an overloaded operator.
Definition: OperatorKinds.h:22
@ NUM_OVERLOADED_OPERATORS
Definition: OperatorKinds.h:26
ArrayTypeTrait
Names for the array type traits.
Definition: TypeTraits.h:42
@ CPlusPlus23
Definition: LangStandard.h:61
AutoTypeKeyword
Which keyword(s) were used to create an AutoType.
Definition: Type.h:1788
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
Definition: OpenMPKinds.h:24
OpenMPDefaultmapClauseModifier
OpenMP modifiers for 'defaultmap' clause.
Definition: OpenMPKinds.h:118
OpenMPOrderClauseModifier
OpenMP modifiers for 'order' clause.
Definition: OpenMPKinds.h:171
IfStatementKind
In an if statement, this denotes whether the statement is a constexpr or consteval if statement.
Definition: Specifiers.h:39
CXXConstructionKind
Definition: ExprCXX.h:1538
@ OK_ObjCProperty
An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...
Definition: Specifiers.h:161
OpenMPAtClauseKind
OpenMP attributes for 'at' clause.
Definition: OpenMPKinds.h:135
@ LCK_ByCopy
Capturing by copy (a.k.a., by value)
Definition: Lambda.h:36
@ LCK_ByRef
Capturing by reference.
Definition: Lambda.h:37
@ LCK_StarThis
Capturing the *this object by copy.
Definition: Lambda.h:35
OpenMPReductionClauseModifier
OpenMP modifiers for 'reduction' clause.
Definition: OpenMPKinds.h:186
BinaryOperatorKind
TypeOfKind
The kind of 'typeof' expression we're after.
Definition: Type.h:922
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
Definition: OpenMPKinds.h:38
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
Definition: OpenMPKinds.h:103
OpenMPDoacrossClauseModifier
OpenMP dependence types for 'doacross' clause.
Definition: OpenMPKinds.h:219
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
Definition: TypeTraits.h:51
ExprResult ExprEmpty()
Definition: Ownership.h:271
StmtResult StmtError()
Definition: Ownership.h:265
@ Property
The type of a property.
@ Result
The result type of a method or function.
OpenMPBindClauseKind
OpenMP bindings for the 'bind' clause.
Definition: OpenMPKinds.h:200
ArraySizeModifier
Capture whether this is a normal array (e.g.
Definition: Type.h:3563
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
OpenMPLastprivateModifier
OpenMP 'lastprivate' clause modifier.
Definition: OpenMPKinds.h:157
OpenMPGrainsizeClauseModifier
Definition: OpenMPKinds.h:206
OpenMPNumTasksClauseModifier
Definition: OpenMPKinds.h:212
UnaryOperatorKind
ActionResult< Expr * > ExprResult
Definition: Ownership.h:248
TagTypeKind
The kind of a tag type.
Definition: Type.h:6690
bool transformOMPMappableExprListClause(TreeTransform< Derived > &TT, OMPMappableExprListClause< T > *C, llvm::SmallVectorImpl< Expr * > &Vars, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperIdInfo, llvm::SmallVectorImpl< Expr * > &UnresolvedMappers)
OpenACCDirectiveKind
Definition: OpenACCKinds.h:25
ExprResult ExprError()
Definition: Ownership.h:264
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
std::pair< NullabilityKind, bool > DiagNullabilityKind
A nullability kind paired with a bit indicating whether it used a context-sensitive keyword.
Definition: Diagnostic.h:1542
OpenMPSeverityClauseKind
OpenMP attributes for 'severity' clause.
Definition: OpenMPKinds.h:142
ActionResult< Stmt * > StmtResult
Definition: Ownership.h:249
OpenMPDefaultmapClauseKind
OpenMP attributes for 'defaultmap' clause.
Definition: OpenMPKinds.h:110
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Definition: OpenMPKinds.h:62
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:135
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:139
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Definition: Ownership.h:229
const FunctionProtoType * T
std::pair< llvm::PointerUnion< const TemplateTypeParmType *, NamedDecl * >, SourceLocation > UnexpandedParameterPack
Definition: Sema.h:258
VectorKind
Definition: Type.h:3980
OpenMPDeviceClauseModifier
OpenMP modifiers for 'device' clause.
Definition: OpenMPKinds.h:47
SourceLocIdentKind
Definition: Expr.h:4738
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
Definition: Type.h:6665
@ None
No keyword precedes the qualified type name.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
OpenMPOrderClauseKind
OpenMP attributes for 'order' clause.
Definition: OpenMPKinds.h:164
TypeTrait
Names for traits that operate specifically on types.
Definition: TypeTraits.h:21
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_DynamicNone
throw()
@ EST_Uninstantiated
not instantiated yet
@ EST_Unevaluated
not evaluated yet, for special member function
@ EST_Dynamic
throw(T1, T2)
PredefinedIdentKind
Definition: Expr.h:1975
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Definition: OpenMPKinds.h:30
static QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T)
MutableArrayRef< Expr * > MultiExprArg
Definition: Ownership.h:258
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
Definition: OpenMPKinds.h:70
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:89
static const ASTTemplateArgumentListInfo * Create(const ASTContext &C, const TemplateArgumentListInfo &List)
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
DeclarationName getName() const
getName - Returns the embedded declaration name.
void setNamedTypeInfo(TypeSourceInfo *TInfo)
setNamedTypeInfo - Sets the source type info associated to the name.
void setName(DeclarationName N)
setName - Sets the embedded declaration name.
TypeSourceInfo * getNamedTypeInfo() const
getNamedTypeInfo - Returns the source type info associated to the name.
A FunctionEffect plus a potential boolean expression determining whether the effect is declared (e....
Definition: Type.h:4820
EffectConditionExpr Cond
Definition: Type.h:4822
Holds information about the various types of exception specification.
Definition: Type.h:5059
FunctionDecl * SourceTemplate
The function template whose exception specification this is instantiated from, for EST_Uninstantiated...
Definition: Type.h:5075
ExceptionSpecificationType Type
The kind of exception specification this is.
Definition: Type.h:5061
ArrayRef< QualType > Exceptions
Explicitly-specified list of exception types.
Definition: Type.h:5064
Expr * NoexceptExpr
Noexcept expression, if this is a computed noexcept specification.
Definition: Type.h:5067
Extra information about a function prototype.
Definition: Type.h:5087
ExceptionSpecInfo ExceptionSpec
Definition: Type.h:5094
FunctionEffectsRef FunctionEffects
Definition: Type.h:5097
const ExtParameterInfo * ExtParameterInfos
Definition: Type.h:5095
This structure contains most locations needed for by an OMPVarListClause.
Definition: OpenMPClause.h:259
@ LambdaExpressionSubstitution
We are substituting into a lambda expression.
Definition: Sema.h:12746
Keeps information about an identifier in a nested-name-spec.
Definition: Sema.h:2865
Location information for a TemplateArgument.
Definition: TemplateBase.h:472