clang 21.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"
32#include "clang/AST/StmtSYCL.h"
37#include "clang/Sema/Lookup.h"
43#include "clang/Sema/SemaObjC.h"
47#include "clang/Sema/SemaSYCL.h"
48#include "llvm/ADT/ArrayRef.h"
49#include "llvm/Support/ErrorHandling.h"
50#include <algorithm>
51#include <optional>
52
53using namespace llvm::omp;
54
55namespace clang {
56using namespace sema;
57
58/// A semantic tree transformation that allows one to transform one
59/// abstract syntax tree into another.
60///
61/// A new tree transformation is defined by creating a new subclass \c X of
62/// \c TreeTransform<X> and then overriding certain operations to provide
63/// behavior specific to that transformation. For example, template
64/// instantiation is implemented as a tree transformation where the
65/// transformation of TemplateTypeParmType nodes involves substituting the
66/// template arguments for their corresponding template parameters; a similar
67/// transformation is performed for non-type template parameters and
68/// template template parameters.
69///
70/// This tree-transformation template uses static polymorphism to allow
71/// subclasses to customize any of its operations. Thus, a subclass can
72/// override any of the transformation or rebuild operators by providing an
73/// operation with the same signature as the default implementation. The
74/// overriding function should not be virtual.
75///
76/// Semantic tree transformations are split into two stages, either of which
77/// can be replaced by a subclass. The "transform" step transforms an AST node
78/// or the parts of an AST node using the various transformation functions,
79/// then passes the pieces on to the "rebuild" step, which constructs a new AST
80/// node of the appropriate kind from the pieces. The default transformation
81/// routines recursively transform the operands to composite AST nodes (e.g.,
82/// the pointee type of a PointerType node) and, if any of those operand nodes
83/// were changed by the transformation, invokes the rebuild operation to create
84/// a new AST node.
85///
86/// Subclasses can customize the transformation at various levels. The
87/// most coarse-grained transformations involve replacing TransformType(),
88/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
89/// TransformTemplateName(), or TransformTemplateArgument() with entirely
90/// new implementations.
91///
92/// For more fine-grained transformations, subclasses can replace any of the
93/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
94/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
95/// replacing TransformTemplateTypeParmType() allows template instantiation
96/// to substitute template arguments for their corresponding template
97/// parameters. Additionally, subclasses can override the \c RebuildXXX
98/// functions to control how AST nodes are rebuilt when their operands change.
99/// By default, \c TreeTransform will invoke semantic analysis to rebuild
100/// AST nodes. However, certain other tree transformations (e.g, cloning) may
101/// be able to use more efficient rebuild steps.
102///
103/// There are a handful of other functions that can be overridden, allowing one
104/// to avoid traversing nodes that don't need any transformation
105/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
106/// operands have not changed (\c AlwaysRebuild()), and customize the
107/// default locations and entity names used for type-checking
108/// (\c getBaseLocation(), \c getBaseEntity()).
109template<typename Derived>
111 /// Private RAII object that helps us forget and then re-remember
112 /// the template argument corresponding to a partially-substituted parameter
113 /// pack.
114 class ForgetPartiallySubstitutedPackRAII {
115 Derived &Self;
117 // Set the pack expansion index to -1 to avoid pack substitution and
118 // indicate that parameter packs should be instantiated as themselves.
119 Sema::ArgumentPackSubstitutionIndexRAII ResetPackSubstIndex;
120
121 public:
122 ForgetPartiallySubstitutedPackRAII(Derived &Self)
123 : Self(Self), ResetPackSubstIndex(Self.getSema(), -1) {
124 Old = Self.ForgetPartiallySubstitutedPack();
125 }
126
127 ~ForgetPartiallySubstitutedPackRAII() {
128 Self.RememberPartiallySubstitutedPack(Old);
129 }
130 };
131
132protected:
134
135 /// The set of local declarations that have been transformed, for
136 /// cases where we are forced to build new declarations within the transformer
137 /// rather than in the subclass (e.g., lambda closure types).
138 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
139
140public:
141 /// Initializes a new tree transformer.
143
144 /// Retrieves a reference to the derived class.
145 Derived &getDerived() { return static_cast<Derived&>(*this); }
146
147 /// Retrieves a reference to the derived class.
148 const Derived &getDerived() const {
149 return static_cast<const Derived&>(*this);
150 }
151
152 static inline ExprResult Owned(Expr *E) { return E; }
153 static inline StmtResult Owned(Stmt *S) { return S; }
154
155 /// Retrieves a reference to the semantic analysis object used for
156 /// this tree transform.
157 Sema &getSema() const { return SemaRef; }
158
159 /// Whether the transformation should always rebuild AST nodes, even
160 /// if none of the children have changed.
161 ///
162 /// Subclasses may override this function to specify when the transformation
163 /// should rebuild all AST nodes.
164 ///
165 /// We must always rebuild all AST nodes when performing variadic template
166 /// pack expansion, in order to avoid violating the AST invariant that each
167 /// statement node appears at most once in its containing declaration.
169
170 /// Whether the transformation is forming an expression or statement that
171 /// replaces the original. In this case, we'll reuse mangling numbers from
172 /// existing lambdas.
173 bool ReplacingOriginal() { return false; }
174
175 /// Wether CXXConstructExpr can be skipped when they are implicit.
176 /// They will be reconstructed when used if needed.
177 /// This is useful when the user that cause rebuilding of the
178 /// CXXConstructExpr is outside of the expression at which the TreeTransform
179 /// started.
180 bool AllowSkippingCXXConstructExpr() { return true; }
181
182 /// Returns the location of the entity being transformed, if that
183 /// information was not available elsewhere in the AST.
184 ///
185 /// By default, returns no source-location information. Subclasses can
186 /// provide an alternative implementation that provides better location
187 /// information.
189
190 /// Returns the name of the entity being transformed, if that
191 /// information was not available elsewhere in the AST.
192 ///
193 /// By default, returns an empty name. Subclasses can provide an alternative
194 /// implementation with a more precise name.
196
197 /// Sets the "base" location and entity when that
198 /// information is known based on another transformation.
199 ///
200 /// By default, the source location and entity are ignored. Subclasses can
201 /// override this function to provide a customized implementation.
203
204 /// RAII object that temporarily sets the base location and entity
205 /// used for reporting diagnostics in types.
207 TreeTransform &Self;
208 SourceLocation OldLocation;
209 DeclarationName OldEntity;
210
211 public:
213 DeclarationName Entity) : Self(Self) {
214 OldLocation = Self.getDerived().getBaseLocation();
215 OldEntity = Self.getDerived().getBaseEntity();
216
217 if (Location.isValid())
218 Self.getDerived().setBase(Location, Entity);
219 }
220
222 Self.getDerived().setBase(OldLocation, OldEntity);
223 }
224 };
225
226 /// Determine whether the given type \p T has already been
227 /// transformed.
228 ///
229 /// Subclasses can provide an alternative implementation of this routine
230 /// to short-circuit evaluation when it is known that a given type will
231 /// not change. For example, template instantiation need not traverse
232 /// non-dependent types.
234 return T.isNull();
235 }
236
237 /// Transform a template parameter depth level.
238 ///
239 /// During a transformation that transforms template parameters, this maps
240 /// an old template parameter depth to a new depth.
241 unsigned TransformTemplateDepth(unsigned Depth) {
242 return Depth;
243 }
244
245 /// Determine whether the given call argument should be dropped, e.g.,
246 /// because it is a default argument.
247 ///
248 /// Subclasses can provide an alternative implementation of this routine to
249 /// determine which kinds of call arguments get dropped. By default,
250 /// CXXDefaultArgument nodes are dropped (prior to transformation).
252 return E->isDefaultArgument();
253 }
254
255 /// Determine whether we should expand a pack expansion with the
256 /// given set of parameter packs into separate arguments by repeatedly
257 /// transforming the pattern.
258 ///
259 /// By default, the transformer never tries to expand pack expansions.
260 /// Subclasses can override this routine to provide different behavior.
261 ///
262 /// \param EllipsisLoc The location of the ellipsis that identifies the
263 /// pack expansion.
264 ///
265 /// \param PatternRange The source range that covers the entire pattern of
266 /// the pack expansion.
267 ///
268 /// \param Unexpanded The set of unexpanded parameter packs within the
269 /// pattern.
270 ///
271 /// \param ShouldExpand Will be set to \c true if the transformer should
272 /// expand the corresponding pack expansions into separate arguments. When
273 /// set, \c NumExpansions must also be set.
274 ///
275 /// \param RetainExpansion Whether the caller should add an unexpanded
276 /// pack expansion after all of the expanded arguments. This is used
277 /// when extending explicitly-specified template argument packs per
278 /// C++0x [temp.arg.explicit]p9.
279 ///
280 /// \param NumExpansions The number of separate arguments that will be in
281 /// the expanded form of the corresponding pack expansion. This is both an
282 /// input and an output parameter, which can be set by the caller if the
283 /// number of expansions is known a priori (e.g., due to a prior substitution)
284 /// and will be set by the callee when the number of expansions is known.
285 /// The callee must set this value when \c ShouldExpand is \c true; it may
286 /// set this value in other cases.
287 ///
288 /// \returns true if an error occurred (e.g., because the parameter packs
289 /// are to be instantiated with arguments of different lengths), false
290 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
291 /// must be set.
293 SourceRange PatternRange,
295 bool &ShouldExpand, bool &RetainExpansion,
296 std::optional<unsigned> &NumExpansions) {
297 ShouldExpand = false;
298 return false;
299 }
300
301 /// "Forget" about the partially-substituted pack template argument,
302 /// when performing an instantiation that must preserve the parameter pack
303 /// use.
304 ///
305 /// This routine is meant to be overridden by the template instantiator.
307 return TemplateArgument();
308 }
309
310 /// "Remember" the partially-substituted pack template argument
311 /// after performing an instantiation that must preserve the parameter pack
312 /// use.
313 ///
314 /// This routine is meant to be overridden by the template instantiator.
316
317 /// Note to the derived class when a function parameter pack is
318 /// being expanded.
320
321 /// Transforms the given type into another type.
322 ///
323 /// By default, this routine transforms a type by creating a
324 /// TypeSourceInfo for it and delegating to the appropriate
325 /// function. This is expensive, but we don't mind, because
326 /// this method is deprecated anyway; all users should be
327 /// switched to storing TypeSourceInfos.
328 ///
329 /// \returns the transformed type.
331
332 /// Transforms the given type-with-location into a new
333 /// type-with-location.
334 ///
335 /// By default, this routine transforms a type by delegating to the
336 /// appropriate TransformXXXType to build a new type. Subclasses
337 /// may override this function (to take over all type
338 /// transformations) or some set of the TransformXXXType functions
339 /// to alter the transformation.
341
342 /// Transform the given type-with-location into a new
343 /// type, collecting location information in the given builder
344 /// as necessary.
345 ///
347
348 /// Transform a type that is permitted to produce a
349 /// DeducedTemplateSpecializationType.
350 ///
351 /// This is used in the (relatively rare) contexts where it is acceptable
352 /// for transformation to produce a class template type with deduced
353 /// template arguments.
354 /// @{
357 /// @}
358
359 /// The reason why the value of a statement is not discarded, if any.
364 };
365
366 /// Transform the given statement.
367 ///
368 /// By default, this routine transforms a statement by delegating to the
369 /// appropriate TransformXXXStmt function to transform a specific kind of
370 /// statement or the TransformExpr() function to transform an expression.
371 /// Subclasses may override this function to transform statements using some
372 /// other mechanism.
373 ///
374 /// \returns the transformed statement.
376
377 /// Transform the given statement.
378 ///
379 /// By default, this routine transforms a statement by delegating to the
380 /// appropriate TransformOMPXXXClause function to transform a specific kind
381 /// of clause. Subclasses may override this function to transform statements
382 /// using some other mechanism.
383 ///
384 /// \returns the transformed OpenMP clause.
386
387 /// Transform the given attribute.
388 ///
389 /// By default, this routine transforms a statement by delegating to the
390 /// appropriate TransformXXXAttr function to transform a specific kind
391 /// of attribute. Subclasses may override this function to transform
392 /// attributed statements/types using some other mechanism.
393 ///
394 /// \returns the transformed attribute
395 const Attr *TransformAttr(const Attr *S);
396
397 // Transform the given statement attribute.
398 //
399 // Delegates to the appropriate TransformXXXAttr function to transform a
400 // specific kind of statement attribute. Unlike the non-statement taking
401 // version of this, this implements all attributes, not just pragmas.
402 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
403 const Attr *A);
404
405 // Transform the specified attribute.
406 //
407 // Subclasses should override the transformation of attributes with a pragma
408 // spelling to transform expressions stored within the attribute.
409 //
410 // \returns the transformed attribute.
411#define ATTR(X) \
412 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
413#include "clang/Basic/AttrList.inc"
414
415 // Transform the specified attribute.
416 //
417 // Subclasses should override the transformation of attributes to do
418 // transformation and checking of statement attributes. By default, this
419 // delegates to the non-statement taking version.
420 //
421 // \returns the transformed attribute.
422#define ATTR(X) \
423 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
424 const X##Attr *A) { \
425 return getDerived().Transform##X##Attr(A); \
426 }
427#include "clang/Basic/AttrList.inc"
428
429 /// Transform the given expression.
430 ///
431 /// By default, this routine transforms an expression by delegating to the
432 /// appropriate TransformXXXExpr function to build a new expression.
433 /// Subclasses may override this function to transform expressions using some
434 /// other mechanism.
435 ///
436 /// \returns the transformed expression.
438
439 /// Transform the given initializer.
440 ///
441 /// By default, this routine transforms an initializer by stripping off the
442 /// semantic nodes added by initialization, then passing the result to
443 /// TransformExpr or TransformExprs.
444 ///
445 /// \returns the transformed initializer.
447
448 /// Transform the given list of expressions.
449 ///
450 /// This routine transforms a list of expressions by invoking
451 /// \c TransformExpr() for each subexpression. However, it also provides
452 /// support for variadic templates by expanding any pack expansions (if the
453 /// derived class permits such expansion) along the way. When pack expansions
454 /// are present, the number of outputs may not equal the number of inputs.
455 ///
456 /// \param Inputs The set of expressions to be transformed.
457 ///
458 /// \param NumInputs The number of expressions in \c Inputs.
459 ///
460 /// \param IsCall If \c true, then this transform is being performed on
461 /// function-call arguments, and any arguments that should be dropped, will
462 /// be.
463 ///
464 /// \param Outputs The transformed input expressions will be added to this
465 /// vector.
466 ///
467 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
468 /// due to transformation.
469 ///
470 /// \returns true if an error occurred, false otherwise.
471 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
473 bool *ArgChanged = nullptr);
474
475 /// Transform the given declaration, which is referenced from a type
476 /// or expression.
477 ///
478 /// By default, acts as the identity function on declarations, unless the
479 /// transformer has had to transform the declaration itself. Subclasses
480 /// may override this function to provide alternate behavior.
482 llvm::DenseMap<Decl *, Decl *>::iterator Known
483 = TransformedLocalDecls.find(D);
484 if (Known != TransformedLocalDecls.end())
485 return Known->second;
486
487 return D;
488 }
489
490 /// Transform the specified condition.
491 ///
492 /// By default, this transforms the variable and expression and rebuilds
493 /// the condition.
495 Expr *Expr,
497
498 /// Transform the attributes associated with the given declaration and
499 /// place them on the new declaration.
500 ///
501 /// By default, this operation does nothing. Subclasses may override this
502 /// behavior to transform attributes.
503 void transformAttrs(Decl *Old, Decl *New) { }
504
505 /// Note that a local declaration has been transformed by this
506 /// transformer.
507 ///
508 /// Local declarations are typically transformed via a call to
509 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
510 /// the transformer itself has to transform the declarations. This routine
511 /// can be overridden by a subclass that keeps track of such mappings.
513 assert(New.size() == 1 &&
514 "must override transformedLocalDecl if performing pack expansion");
515 TransformedLocalDecls[Old] = New.front();
516 }
517
518 /// Transform the definition of the given declaration.
519 ///
520 /// By default, invokes TransformDecl() to transform the declaration.
521 /// Subclasses may override this function to provide alternate behavior.
523 return getDerived().TransformDecl(Loc, D);
524 }
525
526 /// Transform the given declaration, which was the first part of a
527 /// nested-name-specifier in a member access expression.
528 ///
529 /// This specific declaration transformation only applies to the first
530 /// identifier in a nested-name-specifier of a member access expression, e.g.,
531 /// the \c T in \c x->T::member
532 ///
533 /// By default, invokes TransformDecl() to transform the declaration.
534 /// Subclasses may override this function to provide alternate behavior.
536 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
537 }
538
539 /// Transform the set of declarations in an OverloadExpr.
540 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
541 LookupResult &R);
542
543 /// Transform the given nested-name-specifier with source-location
544 /// information.
545 ///
546 /// By default, transforms all of the types and declarations within the
547 /// nested-name-specifier. Subclasses may override this function to provide
548 /// alternate behavior.
551 QualType ObjectType = QualType(),
552 NamedDecl *FirstQualifierInScope = nullptr);
553
554 /// Transform the given declaration name.
555 ///
556 /// By default, transforms the types of conversion function, constructor,
557 /// and destructor names and then (if needed) rebuilds the declaration name.
558 /// Identifiers and selectors are returned unmodified. Subclasses may
559 /// override this function to provide alternate behavior.
562
572
573 /// Transform the given template name.
574 ///
575 /// \param SS The nested-name-specifier that qualifies the template
576 /// name. This nested-name-specifier must already have been transformed.
577 ///
578 /// \param Name The template name to transform.
579 ///
580 /// \param NameLoc The source location of the template name.
581 ///
582 /// \param ObjectType If we're translating a template name within a member
583 /// access expression, this is the type of the object whose member template
584 /// is being referenced.
585 ///
586 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
587 /// also refers to a name within the current (lexical) scope, this is the
588 /// declaration it refers to.
589 ///
590 /// By default, transforms the template name by transforming the declarations
591 /// and nested-name-specifiers that occur within the template name.
592 /// Subclasses may override this function to provide alternate behavior.
595 SourceLocation NameLoc,
596 QualType ObjectType = QualType(),
597 NamedDecl *FirstQualifierInScope = nullptr,
598 bool AllowInjectedClassName = false);
599
600 /// Transform the given template argument.
601 ///
602 /// By default, this operation transforms the type, expression, or
603 /// declaration stored within the template argument and constructs a
604 /// new template argument from the transformed result. Subclasses may
605 /// override this function to provide alternate behavior.
606 ///
607 /// Returns true if there was an error.
609 TemplateArgumentLoc &Output,
610 bool Uneval = false);
611
612 /// Transform the given set of template arguments.
613 ///
614 /// By default, this operation transforms all of the template arguments
615 /// in the input set using \c TransformTemplateArgument(), and appends
616 /// the transformed arguments to the output list.
617 ///
618 /// Note that this overload of \c TransformTemplateArguments() is merely
619 /// a convenience function. Subclasses that wish to override this behavior
620 /// should override the iterator-based member template version.
621 ///
622 /// \param Inputs The set of template arguments to be transformed.
623 ///
624 /// \param NumInputs The number of template arguments in \p Inputs.
625 ///
626 /// \param Outputs The set of transformed template arguments output by this
627 /// routine.
628 ///
629 /// Returns true if an error occurred.
631 unsigned NumInputs,
633 bool Uneval = false) {
634 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
635 Uneval);
636 }
637
638 /// Transform the given set of template arguments.
639 ///
640 /// By default, this operation transforms all of the template arguments
641 /// in the input set using \c TransformTemplateArgument(), and appends
642 /// the transformed arguments to the output list.
643 ///
644 /// \param First An iterator to the first template argument.
645 ///
646 /// \param Last An iterator one step past the last template argument.
647 ///
648 /// \param Outputs The set of transformed template arguments output by this
649 /// routine.
650 ///
651 /// Returns true if an error occurred.
652 template<typename InputIterator>
654 InputIterator Last,
656 bool Uneval = false);
657
658 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
660 TemplateArgumentLoc &ArgLoc);
661
662 /// Fakes up a TypeSourceInfo for a type.
666 }
667
668#define ABSTRACT_TYPELOC(CLASS, PARENT)
669#define TYPELOC(CLASS, PARENT) \
670 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
671#include "clang/AST/TypeLocNodes.def"
672
675 bool SuppressObjCLifetime);
679 bool SuppressObjCLifetime);
680
681 template<typename Fn>
684 CXXRecordDecl *ThisContext,
685 Qualifiers ThisTypeQuals,
687
690 SmallVectorImpl<QualType> &Exceptions,
691 bool &Changed);
692
694
698 TemplateName Template);
699
703 TemplateName Template,
704 CXXScopeSpec &SS);
705
708 NestedNameSpecifierLoc QualifierLoc);
709
710 /// Transforms the parameters of a function type into the
711 /// given vectors.
712 ///
713 /// The result vectors should be kept in sync; null entries in the
714 /// variables vector are acceptable.
715 ///
716 /// LastParamTransformed, if non-null, will be set to the index of the last
717 /// parameter on which transfromation was started. In the event of an error,
718 /// this will contain the parameter which failed to instantiate.
719 ///
720 /// Return true on error.
723 const QualType *ParamTypes,
724 const FunctionProtoType::ExtParameterInfo *ParamInfos,
726 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
727
730 const QualType *ParamTypes,
731 const FunctionProtoType::ExtParameterInfo *ParamInfos,
734 return getDerived().TransformFunctionTypeParams(
735 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
736 }
737
738 /// Transforms the parameters of a requires expresison into the given vectors.
739 ///
740 /// The result vectors should be kept in sync; null entries in the
741 /// variables vector are acceptable.
742 ///
743 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
744 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
745 /// which are cases where transformation shouldn't continue.
747 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
753 KWLoc, Params, /*ParamTypes=*/nullptr,
754 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
755 return ExprError();
756
757 return ExprResult{};
758 }
759
760 /// Transforms a single function-type parameter. Return null
761 /// on error.
762 ///
763 /// \param indexAdjustment - A number to add to the parameter's
764 /// scope index; can be negative
766 int indexAdjustment,
767 std::optional<unsigned> NumExpansions,
768 bool ExpectParameterPack);
769
770 /// Transform the body of a lambda-expression.
772 /// Alternative implementation of TransformLambdaBody that skips transforming
773 /// the body.
775
778 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
780 }
781
783
786
789 return TPL;
790 }
791
793
795 bool IsAddressOfOperand,
796 TypeSourceInfo **RecoveryTSI);
797
799 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
800 TypeSourceInfo **RecoveryTSI);
801
803 bool IsAddressOfOperand);
804
806
808
809// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
810// amount of stack usage with clang.
811#define STMT(Node, Parent) \
812 LLVM_ATTRIBUTE_NOINLINE \
813 StmtResult Transform##Node(Node *S);
814#define VALUESTMT(Node, Parent) \
815 LLVM_ATTRIBUTE_NOINLINE \
816 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
817#define EXPR(Node, Parent) \
818 LLVM_ATTRIBUTE_NOINLINE \
819 ExprResult Transform##Node(Node *E);
820#define ABSTRACT_STMT(Stmt)
821#include "clang/AST/StmtNodes.inc"
822
823#define GEN_CLANG_CLAUSE_CLASS
824#define CLAUSE_CLASS(Enum, Str, Class) \
825 LLVM_ATTRIBUTE_NOINLINE \
826 OMPClause *Transform##Class(Class *S);
827#include "llvm/Frontend/OpenMP/OMP.inc"
828
829 /// Build a new qualified type given its unqualified type and type location.
830 ///
831 /// By default, this routine adds type qualifiers only to types that can
832 /// have qualifiers, and silently suppresses those qualifiers that are not
833 /// permitted. Subclasses may override this routine to provide different
834 /// behavior.
836
837 /// Build a new pointer type given its pointee type.
838 ///
839 /// By default, performs semantic analysis when building the pointer type.
840 /// Subclasses may override this routine to provide different behavior.
842
843 /// Build a new block pointer type given its pointee type.
844 ///
845 /// By default, performs semantic analysis when building the block pointer
846 /// type. Subclasses may override this routine to provide different behavior.
848
849 /// Build a new reference type given the type it references.
850 ///
851 /// By default, performs semantic analysis when building the
852 /// reference type. Subclasses may override this routine to provide
853 /// different behavior.
854 ///
855 /// \param LValue whether the type was written with an lvalue sigil
856 /// or an rvalue sigil.
858 bool LValue,
859 SourceLocation Sigil);
860
861 /// Build a new member pointer type given the pointee type and the
862 /// class type it refers into.
863 ///
864 /// By default, performs semantic analysis when building the member pointer
865 /// type. Subclasses may override this routine to provide different behavior.
867 SourceLocation Sigil);
868
870 SourceLocation ProtocolLAngleLoc,
872 ArrayRef<SourceLocation> ProtocolLocs,
873 SourceLocation ProtocolRAngleLoc);
874
875 /// Build an Objective-C object type.
876 ///
877 /// By default, performs semantic analysis when building the object type.
878 /// Subclasses may override this routine to provide different behavior.
881 SourceLocation TypeArgsLAngleLoc,
883 SourceLocation TypeArgsRAngleLoc,
884 SourceLocation ProtocolLAngleLoc,
886 ArrayRef<SourceLocation> ProtocolLocs,
887 SourceLocation ProtocolRAngleLoc);
888
889 /// Build a new Objective-C object pointer type given the pointee type.
890 ///
891 /// By default, directly builds the pointer type, with no additional semantic
892 /// analysis.
895
896 /// Build a new array type given the element type, size
897 /// modifier, size of the array (if known), size expression, and index type
898 /// qualifiers.
899 ///
900 /// By default, performs semantic analysis when building the array type.
901 /// Subclasses may override this routine to provide different behavior.
902 /// Also by default, all of the other Rebuild*Array
904 const llvm::APInt *Size, Expr *SizeExpr,
905 unsigned IndexTypeQuals, SourceRange BracketsRange);
906
907 /// Build a new constant array type given the element type, size
908 /// modifier, (known) size of the array, and index type qualifiers.
909 ///
910 /// By default, performs semantic analysis when building the array type.
911 /// Subclasses may override this routine to provide different behavior.
913 ArraySizeModifier SizeMod,
914 const llvm::APInt &Size, Expr *SizeExpr,
915 unsigned IndexTypeQuals,
916 SourceRange BracketsRange);
917
918 /// Build a new incomplete array type given the element type, size
919 /// modifier, and index type qualifiers.
920 ///
921 /// By default, performs semantic analysis when building the array type.
922 /// Subclasses may override this routine to provide different behavior.
924 ArraySizeModifier SizeMod,
925 unsigned IndexTypeQuals,
926 SourceRange BracketsRange);
927
928 /// Build a new variable-length array type given the element type,
929 /// size modifier, size expression, and index type qualifiers.
930 ///
931 /// By default, performs semantic analysis when building the array type.
932 /// Subclasses may override this routine to provide different behavior.
934 ArraySizeModifier SizeMod, Expr *SizeExpr,
935 unsigned IndexTypeQuals,
936 SourceRange BracketsRange);
937
938 /// Build a new dependent-sized array type given the element type,
939 /// size modifier, size expression, and index type qualifiers.
940 ///
941 /// By default, performs semantic analysis when building the array type.
942 /// Subclasses may override this routine to provide different behavior.
944 ArraySizeModifier SizeMod,
945 Expr *SizeExpr,
946 unsigned IndexTypeQuals,
947 SourceRange BracketsRange);
948
949 /// Build a new vector type given the element type and
950 /// number of elements.
951 ///
952 /// By default, performs semantic analysis when building the vector type.
953 /// Subclasses may override this routine to provide different behavior.
954 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
955 VectorKind VecKind);
956
957 /// Build a new potentially dependently-sized extended vector type
958 /// given the element type and number of elements.
959 ///
960 /// By default, performs semantic analysis when building the vector type.
961 /// Subclasses may override this routine to provide different behavior.
963 SourceLocation AttributeLoc, VectorKind);
964
965 /// Build a new extended vector type given the element type and
966 /// number of elements.
967 ///
968 /// By default, performs semantic analysis when building the vector type.
969 /// Subclasses may override this routine to provide different behavior.
970 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
971 SourceLocation AttributeLoc);
972
973 /// Build a new potentially dependently-sized extended vector type
974 /// given the element type and number of elements.
975 ///
976 /// By default, performs semantic analysis when building the vector type.
977 /// Subclasses may override this routine to provide different behavior.
979 Expr *SizeExpr,
980 SourceLocation AttributeLoc);
981
982 /// Build a new matrix type given the element type and dimensions.
983 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
984 unsigned NumColumns);
985
986 /// Build a new matrix type given the type and dependently-defined
987 /// dimensions.
989 Expr *ColumnExpr,
990 SourceLocation AttributeLoc);
991
992 /// Build a new DependentAddressSpaceType or return the pointee
993 /// type variable with the correct address space (retrieved from
994 /// AddrSpaceExpr) applied to it. The former will be returned in cases
995 /// where the address space remains dependent.
996 ///
997 /// By default, performs semantic analysis when building the type with address
998 /// space applied. Subclasses may override this routine to provide different
999 /// behavior.
1001 Expr *AddrSpaceExpr,
1002 SourceLocation AttributeLoc);
1003
1004 /// Build a new function type.
1005 ///
1006 /// By default, performs semantic analysis when building the function type.
1007 /// Subclasses may override this routine to provide different behavior.
1009 MutableArrayRef<QualType> ParamTypes,
1011
1012 /// Build a new unprototyped function type.
1014
1015 /// Rebuild an unresolved typename type, given the decl that
1016 /// the UnresolvedUsingTypenameDecl was transformed to.
1018
1019 /// Build a new type found via an alias.
1021 return SemaRef.Context.getUsingType(Found, Underlying);
1022 }
1023
1024 /// Build a new typedef type.
1026 return SemaRef.Context.getTypeDeclType(Typedef);
1027 }
1028
1029 /// Build a new MacroDefined type.
1031 const IdentifierInfo *MacroII) {
1032 return SemaRef.Context.getMacroQualifiedType(T, MacroII);
1033 }
1034
1035 /// Build a new class/struct/union type.
1038 }
1039
1040 /// Build a new Enum type.
1043 }
1044
1045 /// Build a new typeof(expr) type.
1046 ///
1047 /// By default, performs semantic analysis when building the typeof type.
1048 /// Subclasses may override this routine to provide different behavior.
1050 TypeOfKind Kind);
1051
1052 /// Build a new typeof(type) type.
1053 ///
1054 /// By default, builds a new TypeOfType with the given underlying type.
1056
1057 /// Build a new unary transform type.
1061
1062 /// Build a new C++11 decltype type.
1063 ///
1064 /// By default, performs semantic analysis when building the decltype type.
1065 /// Subclasses may override this routine to provide different behavior.
1067
1070 SourceLocation EllipsisLoc,
1071 bool FullySubstituted,
1072 ArrayRef<QualType> Expansions = {});
1073
1074 /// Build a new C++11 auto type.
1075 ///
1076 /// By default, builds a new AutoType with the given deduced type.
1078 ConceptDecl *TypeConstraintConcept,
1079 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1080 // Note, IsDependent is always false here: we implicitly convert an 'auto'
1081 // which has been deduced to a dependent type into an undeduced 'auto', so
1082 // that we'll retry deduction after the transformation.
1083 return SemaRef.Context.getAutoType(Deduced, Keyword,
1084 /*IsDependent*/ false, /*IsPack=*/false,
1085 TypeConstraintConcept,
1086 TypeConstraintArgs);
1087 }
1088
1089 /// By default, builds a new DeducedTemplateSpecializationType with the given
1090 /// deduced type.
1092 QualType Deduced) {
1094 Template, Deduced, /*IsDependent*/ false);
1095 }
1096
1097 /// Build a new template specialization type.
1098 ///
1099 /// By default, performs semantic analysis when building the template
1100 /// specialization type. Subclasses may override this routine to provide
1101 /// different behavior.
1103 SourceLocation TemplateLoc,
1105
1106 /// Build a new parenthesized type.
1107 ///
1108 /// By default, builds a new ParenType type from the inner type.
1109 /// Subclasses may override this routine to provide different behavior.
1111 return SemaRef.BuildParenType(InnerType);
1112 }
1113
1114 /// Build a new qualified name type.
1115 ///
1116 /// By default, builds a new ElaboratedType type from the keyword,
1117 /// the nested-name-specifier and the named type.
1118 /// Subclasses may override this routine to provide different behavior.
1120 ElaboratedTypeKeyword Keyword,
1121 NestedNameSpecifierLoc QualifierLoc,
1122 QualType Named) {
1123 return SemaRef.Context.getElaboratedType(Keyword,
1124 QualifierLoc.getNestedNameSpecifier(),
1125 Named);
1126 }
1127
1128 /// Build a new typename type that refers to a template-id.
1129 ///
1130 /// By default, builds a new DependentNameType type from the
1131 /// nested-name-specifier and the given type. Subclasses may override
1132 /// this routine to provide different behavior.
1134 ElaboratedTypeKeyword Keyword,
1135 NestedNameSpecifierLoc QualifierLoc,
1136 SourceLocation TemplateKWLoc,
1137 const IdentifierInfo *Name,
1138 SourceLocation NameLoc,
1140 bool AllowInjectedClassName) {
1141 // Rebuild the template name.
1142 // TODO: avoid TemplateName abstraction
1143 CXXScopeSpec SS;
1144 SS.Adopt(QualifierLoc);
1145 TemplateName InstName = getDerived().RebuildTemplateName(
1146 SS, TemplateKWLoc, *Name, NameLoc, QualType(), nullptr,
1147 AllowInjectedClassName);
1148
1149 if (InstName.isNull())
1150 return QualType();
1151
1152 // If it's still dependent, make a dependent specialization.
1153 if (InstName.getAsDependentTemplateName())
1155 Keyword, QualifierLoc.getNestedNameSpecifier(), Name,
1156 Args.arguments());
1157
1158 // Otherwise, make an elaborated type wrapping a non-dependent
1159 // specialization.
1160 QualType T =
1161 getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
1162 if (T.isNull())
1163 return QualType();
1165 Keyword, QualifierLoc.getNestedNameSpecifier(), T);
1166 }
1167
1168 /// Build a new typename type that refers to an identifier.
1169 ///
1170 /// By default, performs semantic analysis when building the typename type
1171 /// (or elaborated type). Subclasses may override this routine to provide
1172 /// different behavior.
1174 SourceLocation KeywordLoc,
1175 NestedNameSpecifierLoc QualifierLoc,
1176 const IdentifierInfo *Id,
1177 SourceLocation IdLoc,
1178 bool DeducedTSTContext) {
1179 CXXScopeSpec SS;
1180 SS.Adopt(QualifierLoc);
1181
1182 if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
1183 // If the name is still dependent, just build a new dependent name type.
1184 if (!SemaRef.computeDeclContext(SS))
1185 return SemaRef.Context.getDependentNameType(Keyword,
1186 QualifierLoc.getNestedNameSpecifier(),
1187 Id);
1188 }
1189
1190 if (Keyword == ElaboratedTypeKeyword::None ||
1192 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1193 *Id, IdLoc, DeducedTSTContext);
1194 }
1195
1197
1198 // We had a dependent elaborated-type-specifier that has been transformed
1199 // into a non-dependent elaborated-type-specifier. Find the tag we're
1200 // referring to.
1202 DeclContext *DC = SemaRef.computeDeclContext(SS, false);
1203 if (!DC)
1204 return QualType();
1205
1207 return QualType();
1208
1209 TagDecl *Tag = nullptr;
1211 switch (Result.getResultKind()) {
1214 break;
1215
1217 Tag = Result.getAsSingle<TagDecl>();
1218 break;
1219
1222 llvm_unreachable("Tag lookup cannot find non-tags");
1223
1225 // Let the LookupResult structure handle ambiguities.
1226 return QualType();
1227 }
1228
1229 if (!Tag) {
1230 // Check where the name exists but isn't a tag type and use that to emit
1231 // better diagnostics.
1234 switch (Result.getResultKind()) {
1238 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1239 Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind);
1240 SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag)
1241 << SomeDecl << NTK << llvm::to_underlying(Kind);
1242 SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
1243 break;
1244 }
1245 default:
1246 SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
1247 << llvm::to_underlying(Kind) << Id << DC
1248 << QualifierLoc.getSourceRange();
1249 break;
1250 }
1251 return QualType();
1252 }
1253
1254 if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false,
1255 IdLoc, Id)) {
1256 SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
1257 SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
1258 return QualType();
1259 }
1260
1261 // Build the elaborated-type-specifier type.
1263 return SemaRef.Context.getElaboratedType(Keyword,
1264 QualifierLoc.getNestedNameSpecifier(),
1265 T);
1266 }
1267
1268 /// Build a new pack expansion type.
1269 ///
1270 /// By default, builds a new PackExpansionType type from the given pattern.
1271 /// Subclasses may override this routine to provide different behavior.
1273 SourceLocation EllipsisLoc,
1274 std::optional<unsigned> NumExpansions) {
1275 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1276 NumExpansions);
1277 }
1278
1279 /// Build a new atomic type given its value type.
1280 ///
1281 /// By default, performs semantic analysis when building the atomic type.
1282 /// Subclasses may override this routine to provide different behavior.
1284
1285 /// Build a new pipe type given its value type.
1287 bool isReadPipe);
1288
1289 /// Build a bit-precise int given its value type.
1290 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1292
1293 /// Build a dependent bit-precise int given its value type.
1294 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1296
1297 /// Build a new template name given a nested name specifier, a flag
1298 /// indicating whether the "template" keyword was provided, and the template
1299 /// that the template name refers to.
1300 ///
1301 /// By default, builds the new template name directly. Subclasses may override
1302 /// this routine to provide different behavior.
1304 bool TemplateKW,
1305 TemplateDecl *Template);
1306
1307 /// Build a new template name given a nested name specifier and the
1308 /// name that is referred to as a template.
1309 ///
1310 /// By default, performs semantic analysis to determine whether the name can
1311 /// be resolved to a specific template, then builds the appropriate kind of
1312 /// template name. Subclasses may override this routine to provide different
1313 /// behavior.
1315 SourceLocation TemplateKWLoc,
1316 const IdentifierInfo &Name,
1317 SourceLocation NameLoc, QualType ObjectType,
1318 NamedDecl *FirstQualifierInScope,
1319 bool AllowInjectedClassName);
1320
1321 /// Build a new template name given a nested name specifier and the
1322 /// overloaded operator name that is referred to as a template.
1323 ///
1324 /// By default, performs semantic analysis to determine whether the name can
1325 /// be resolved to a specific template, then builds the appropriate kind of
1326 /// template name. Subclasses may override this routine to provide different
1327 /// behavior.
1329 SourceLocation TemplateKWLoc,
1330 OverloadedOperatorKind Operator,
1331 SourceLocation NameLoc, QualType ObjectType,
1332 bool AllowInjectedClassName);
1333
1334 /// Build a new template name given a template template parameter pack
1335 /// and the
1336 ///
1337 /// By default, performs semantic analysis to determine whether the name can
1338 /// be resolved to a specific template, then builds the appropriate kind of
1339 /// template name. Subclasses may override this routine to provide different
1340 /// behavior.
1342 Decl *AssociatedDecl, unsigned Index,
1343 bool Final) {
1345 ArgPack, AssociatedDecl, Index, Final);
1346 }
1347
1348 /// Build a new compound statement.
1349 ///
1350 /// By default, performs semantic analysis to build the new statement.
1351 /// Subclasses may override this routine to provide different behavior.
1353 MultiStmtArg Statements,
1354 SourceLocation RBraceLoc,
1355 bool IsStmtExpr) {
1356 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1357 IsStmtExpr);
1358 }
1359
1360 /// Build a new case statement.
1361 ///
1362 /// By default, performs semantic analysis to build the new statement.
1363 /// Subclasses may override this routine to provide different behavior.
1365 Expr *LHS,
1366 SourceLocation EllipsisLoc,
1367 Expr *RHS,
1368 SourceLocation ColonLoc) {
1369 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1370 ColonLoc);
1371 }
1372
1373 /// Attach the body to a new case statement.
1374 ///
1375 /// By default, performs semantic analysis to build the new statement.
1376 /// Subclasses may override this routine to provide different behavior.
1378 getSema().ActOnCaseStmtBody(S, Body);
1379 return S;
1380 }
1381
1382 /// Build a new default statement.
1383 ///
1384 /// By default, performs semantic analysis to build the new statement.
1385 /// Subclasses may override this routine to provide different behavior.
1387 SourceLocation ColonLoc,
1388 Stmt *SubStmt) {
1389 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1390 /*CurScope=*/nullptr);
1391 }
1392
1393 /// Build a new label statement.
1394 ///
1395 /// By default, performs semantic analysis to build the new statement.
1396 /// Subclasses may override this routine to provide different behavior.
1398 SourceLocation ColonLoc, Stmt *SubStmt) {
1399 return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt);
1400 }
1401
1402 /// Build a new attributed statement.
1403 ///
1404 /// By default, performs semantic analysis to build the new statement.
1405 /// Subclasses may override this routine to provide different behavior.
1408 Stmt *SubStmt) {
1410 return StmtError();
1411 return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt);
1412 }
1413
1414 /// Build a new "if" statement.
1415 ///
1416 /// By default, performs semantic analysis to build the new statement.
1417 /// Subclasses may override this routine to provide different behavior.
1419 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1420 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1421 SourceLocation ElseLoc, Stmt *Else) {
1422 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1423 Then, ElseLoc, Else);
1424 }
1425
1426 /// Start building a new switch statement.
1427 ///
1428 /// By default, performs semantic analysis to build the new statement.
1429 /// Subclasses may override this routine to provide different behavior.
1431 SourceLocation LParenLoc, Stmt *Init,
1433 SourceLocation RParenLoc) {
1434 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1435 RParenLoc);
1436 }
1437
1438 /// Attach the body to the switch statement.
1439 ///
1440 /// By default, performs semantic analysis to build the new statement.
1441 /// Subclasses may override this routine to provide different behavior.
1443 Stmt *Switch, Stmt *Body) {
1444 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1445 }
1446
1447 /// Build a new while statement.
1448 ///
1449 /// By default, performs semantic analysis to build the new statement.
1450 /// Subclasses may override this routine to provide different behavior.
1453 SourceLocation RParenLoc, Stmt *Body) {
1454 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1455 }
1456
1457 /// Build a new do-while statement.
1458 ///
1459 /// By default, performs semantic analysis to build the new statement.
1460 /// Subclasses may override this routine to provide different behavior.
1462 SourceLocation WhileLoc, SourceLocation LParenLoc,
1463 Expr *Cond, SourceLocation RParenLoc) {
1464 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1465 Cond, RParenLoc);
1466 }
1467
1468 /// Build a new for statement.
1469 ///
1470 /// By default, performs semantic analysis to build the new statement.
1471 /// Subclasses may override this routine to provide different behavior.
1474 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1475 Stmt *Body) {
1476 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1477 Inc, RParenLoc, Body);
1478 }
1479
1480 /// Build a new goto statement.
1481 ///
1482 /// By default, performs semantic analysis to build the new statement.
1483 /// Subclasses may override this routine to provide different behavior.
1485 LabelDecl *Label) {
1486 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1487 }
1488
1489 /// Build a new indirect goto statement.
1490 ///
1491 /// By default, performs semantic analysis to build the new statement.
1492 /// Subclasses may override this routine to provide different behavior.
1494 SourceLocation StarLoc,
1495 Expr *Target) {
1496 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1497 }
1498
1499 /// Build a new return statement.
1500 ///
1501 /// By default, performs semantic analysis to build the new statement.
1502 /// Subclasses may override this routine to provide different behavior.
1504 return getSema().BuildReturnStmt(ReturnLoc, Result);
1505 }
1506
1507 /// Build a new declaration statement.
1508 ///
1509 /// By default, performs semantic analysis to build the new statement.
1510 /// Subclasses may override this routine to provide different behavior.
1512 SourceLocation StartLoc, SourceLocation EndLoc) {
1514 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1515 }
1516
1517 /// Build a new inline asm statement.
1518 ///
1519 /// By default, performs semantic analysis to build the new statement.
1520 /// Subclasses may override this routine to provide different behavior.
1522 bool IsVolatile, unsigned NumOutputs,
1523 unsigned NumInputs, IdentifierInfo **Names,
1524 MultiExprArg Constraints, MultiExprArg Exprs,
1525 Expr *AsmString, MultiExprArg Clobbers,
1526 unsigned NumLabels,
1527 SourceLocation RParenLoc) {
1528 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1529 NumInputs, Names, Constraints, Exprs,
1530 AsmString, Clobbers, NumLabels, RParenLoc);
1531 }
1532
1533 /// Build a new MS style inline asm statement.
1534 ///
1535 /// By default, performs semantic analysis to build the new statement.
1536 /// Subclasses may override this routine to provide different behavior.
1538 ArrayRef<Token> AsmToks,
1539 StringRef AsmString,
1540 unsigned NumOutputs, unsigned NumInputs,
1541 ArrayRef<StringRef> Constraints,
1542 ArrayRef<StringRef> Clobbers,
1543 ArrayRef<Expr*> Exprs,
1544 SourceLocation EndLoc) {
1545 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1546 NumOutputs, NumInputs,
1547 Constraints, Clobbers, Exprs, EndLoc);
1548 }
1549
1550 /// Build a new co_return statement.
1551 ///
1552 /// By default, performs semantic analysis to build the new statement.
1553 /// Subclasses may override this routine to provide different behavior.
1555 bool IsImplicit) {
1556 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1557 }
1558
1559 /// Build a new co_await expression.
1560 ///
1561 /// By default, performs semantic analysis to build the new expression.
1562 /// Subclasses may override this routine to provide different behavior.
1564 UnresolvedLookupExpr *OpCoawaitLookup,
1565 bool IsImplicit) {
1566 // This function rebuilds a coawait-expr given its operator.
1567 // For an explicit coawait-expr, the rebuild involves the full set
1568 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1569 // including calling await_transform().
1570 // For an implicit coawait-expr, we need to rebuild the "operator
1571 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1572 // This mirrors how the implicit CoawaitExpr is originally created
1573 // in Sema::ActOnCoroutineBodyStart().
1574 if (IsImplicit) {
1576 CoawaitLoc, Operand, OpCoawaitLookup);
1577 if (Suspend.isInvalid())
1578 return ExprError();
1579 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1580 Suspend.get(), true);
1581 }
1582
1583 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1584 OpCoawaitLookup);
1585 }
1586
1587 /// Build a new co_await expression.
1588 ///
1589 /// By default, performs semantic analysis to build the new expression.
1590 /// Subclasses may override this routine to provide different behavior.
1592 Expr *Result,
1593 UnresolvedLookupExpr *Lookup) {
1594 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1595 }
1596
1597 /// Build a new co_yield expression.
1598 ///
1599 /// By default, performs semantic analysis to build the new expression.
1600 /// Subclasses may override this routine to provide different behavior.
1602 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1603 }
1604
1606 return getSema().BuildCoroutineBodyStmt(Args);
1607 }
1608
1609 /// Build a new Objective-C \@try statement.
1610 ///
1611 /// By default, performs semantic analysis to build the new statement.
1612 /// Subclasses may override this routine to provide different behavior.
1614 Stmt *TryBody,
1615 MultiStmtArg CatchStmts,
1616 Stmt *Finally) {
1617 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1618 Finally);
1619 }
1620
1621 /// Rebuild an Objective-C exception declaration.
1622 ///
1623 /// By default, performs semantic analysis to build the new declaration.
1624 /// Subclasses may override this routine to provide different behavior.
1626 TypeSourceInfo *TInfo, QualType T) {
1628 TInfo, T, ExceptionDecl->getInnerLocStart(),
1629 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1630 }
1631
1632 /// Build a new Objective-C \@catch statement.
1633 ///
1634 /// By default, performs semantic analysis to build the new statement.
1635 /// Subclasses may override this routine to provide different behavior.
1637 SourceLocation RParenLoc,
1638 VarDecl *Var,
1639 Stmt *Body) {
1640 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1641 }
1642
1643 /// Build a new Objective-C \@finally statement.
1644 ///
1645 /// By default, performs semantic analysis to build the new statement.
1646 /// Subclasses may override this routine to provide different behavior.
1648 Stmt *Body) {
1649 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1650 }
1651
1652 /// Build a new Objective-C \@throw statement.
1653 ///
1654 /// By default, performs semantic analysis to build the new statement.
1655 /// Subclasses may override this routine to provide different behavior.
1657 Expr *Operand) {
1658 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1659 }
1660
1661 /// Build a new OpenMP Canonical loop.
1662 ///
1663 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1664 /// OMPCanonicalLoop.
1666 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1667 }
1668
1669 /// Build a new OpenMP executable directive.
1670 ///
1671 /// By default, performs semantic analysis to build the new statement.
1672 /// Subclasses may override this routine to provide different behavior.
1674 DeclarationNameInfo DirName,
1675 OpenMPDirectiveKind CancelRegion,
1676 ArrayRef<OMPClause *> Clauses,
1677 Stmt *AStmt, SourceLocation StartLoc,
1678 SourceLocation EndLoc) {
1679
1681 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1682 }
1683
1684 /// Build a new OpenMP informational directive.
1686 DeclarationNameInfo DirName,
1687 ArrayRef<OMPClause *> Clauses,
1688 Stmt *AStmt,
1689 SourceLocation StartLoc,
1690 SourceLocation EndLoc) {
1691
1693 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1694 }
1695
1696 /// Build a new OpenMP 'if' clause.
1697 ///
1698 /// By default, performs semantic analysis to build the new OpenMP clause.
1699 /// Subclasses may override this routine to provide different behavior.
1701 Expr *Condition, SourceLocation StartLoc,
1702 SourceLocation LParenLoc,
1703 SourceLocation NameModifierLoc,
1704 SourceLocation ColonLoc,
1705 SourceLocation EndLoc) {
1707 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1708 EndLoc);
1709 }
1710
1711 /// Build a new OpenMP 'final' clause.
1712 ///
1713 /// By default, performs semantic analysis to build the new OpenMP clause.
1714 /// Subclasses may override this routine to provide different behavior.
1716 SourceLocation LParenLoc,
1717 SourceLocation EndLoc) {
1718 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1719 LParenLoc, EndLoc);
1720 }
1721
1722 /// Build a new OpenMP 'num_threads' clause.
1723 ///
1724 /// By default, performs semantic analysis to build the new OpenMP clause.
1725 /// Subclasses may override this routine to provide different behavior.
1727 SourceLocation StartLoc,
1728 SourceLocation LParenLoc,
1729 SourceLocation EndLoc) {
1730 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc,
1731 LParenLoc, EndLoc);
1732 }
1733
1734 /// Build a new OpenMP 'safelen' clause.
1735 ///
1736 /// By default, performs semantic analysis to build the new OpenMP clause.
1737 /// Subclasses may override this routine to provide different behavior.
1739 SourceLocation LParenLoc,
1740 SourceLocation EndLoc) {
1741 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1742 EndLoc);
1743 }
1744
1745 /// Build a new OpenMP 'simdlen' clause.
1746 ///
1747 /// By default, performs semantic analysis to build the new OpenMP clause.
1748 /// Subclasses may override this routine to provide different behavior.
1750 SourceLocation LParenLoc,
1751 SourceLocation EndLoc) {
1752 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1753 EndLoc);
1754 }
1755
1757 SourceLocation StartLoc,
1758 SourceLocation LParenLoc,
1759 SourceLocation EndLoc) {
1760 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1761 EndLoc);
1762 }
1763
1764 /// Build a new OpenMP 'permutation' clause.
1766 SourceLocation StartLoc,
1767 SourceLocation LParenLoc,
1768 SourceLocation EndLoc) {
1769 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1770 LParenLoc, EndLoc);
1771 }
1772
1773 /// Build a new OpenMP 'full' clause.
1775 SourceLocation EndLoc) {
1776 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1777 }
1778
1779 /// Build a new OpenMP 'partial' clause.
1781 SourceLocation LParenLoc,
1782 SourceLocation EndLoc) {
1783 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1784 LParenLoc, EndLoc);
1785 }
1786
1787 /// Build a new OpenMP 'allocator' clause.
1788 ///
1789 /// By default, performs semantic analysis to build the new OpenMP clause.
1790 /// Subclasses may override this routine to provide different behavior.
1792 SourceLocation LParenLoc,
1793 SourceLocation EndLoc) {
1794 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1795 EndLoc);
1796 }
1797
1798 /// Build a new OpenMP 'collapse' clause.
1799 ///
1800 /// By default, performs semantic analysis to build the new OpenMP clause.
1801 /// Subclasses may override this routine to provide different behavior.
1803 SourceLocation LParenLoc,
1804 SourceLocation EndLoc) {
1805 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1806 LParenLoc, EndLoc);
1807 }
1808
1809 /// Build a new OpenMP 'default' clause.
1810 ///
1811 /// By default, performs semantic analysis to build the new OpenMP clause.
1812 /// Subclasses may override this routine to provide different behavior.
1814 SourceLocation StartLoc,
1815 SourceLocation LParenLoc,
1816 SourceLocation EndLoc) {
1818 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1819 }
1820
1821 /// Build a new OpenMP 'proc_bind' clause.
1822 ///
1823 /// By default, performs semantic analysis to build the new OpenMP clause.
1824 /// Subclasses may override this routine to provide different behavior.
1826 SourceLocation KindKwLoc,
1827 SourceLocation StartLoc,
1828 SourceLocation LParenLoc,
1829 SourceLocation EndLoc) {
1831 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1832 }
1833
1834 /// Build a new OpenMP 'schedule' clause.
1835 ///
1836 /// By default, performs semantic analysis to build the new OpenMP clause.
1837 /// Subclasses may override this routine to provide different behavior.
1840 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1841 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1842 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1844 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1845 CommaLoc, EndLoc);
1846 }
1847
1848 /// Build a new OpenMP 'ordered' clause.
1849 ///
1850 /// By default, performs semantic analysis to build the new OpenMP clause.
1851 /// Subclasses may override this routine to provide different behavior.
1853 SourceLocation EndLoc,
1854 SourceLocation LParenLoc, Expr *Num) {
1855 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1856 LParenLoc, Num);
1857 }
1858
1859 /// Build a new OpenMP 'private' clause.
1860 ///
1861 /// By default, performs semantic analysis to build the new OpenMP clause.
1862 /// Subclasses may override this routine to provide different behavior.
1864 SourceLocation StartLoc,
1865 SourceLocation LParenLoc,
1866 SourceLocation EndLoc) {
1867 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1868 LParenLoc, EndLoc);
1869 }
1870
1871 /// Build a new OpenMP 'firstprivate' clause.
1872 ///
1873 /// By default, performs semantic analysis to build the new OpenMP clause.
1874 /// Subclasses may override this routine to provide different behavior.
1876 SourceLocation StartLoc,
1877 SourceLocation LParenLoc,
1878 SourceLocation EndLoc) {
1879 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1880 LParenLoc, EndLoc);
1881 }
1882
1883 /// Build a new OpenMP 'lastprivate' clause.
1884 ///
1885 /// By default, performs semantic analysis to build the new OpenMP clause.
1886 /// Subclasses may override this routine to provide different behavior.
1889 SourceLocation LPKindLoc,
1890 SourceLocation ColonLoc,
1891 SourceLocation StartLoc,
1892 SourceLocation LParenLoc,
1893 SourceLocation EndLoc) {
1895 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1896 }
1897
1898 /// Build a new OpenMP 'shared' clause.
1899 ///
1900 /// By default, performs semantic analysis to build the new OpenMP clause.
1901 /// Subclasses may override this routine to provide different behavior.
1903 SourceLocation StartLoc,
1904 SourceLocation LParenLoc,
1905 SourceLocation EndLoc) {
1906 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1907 LParenLoc, EndLoc);
1908 }
1909
1910 /// Build a new OpenMP 'reduction' clause.
1911 ///
1912 /// By default, performs semantic analysis to build the new statement.
1913 /// Subclasses may override this routine to provide different behavior.
1916 SourceLocation StartLoc, SourceLocation LParenLoc,
1917 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1918 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1919 const DeclarationNameInfo &ReductionId,
1920 ArrayRef<Expr *> UnresolvedReductions) {
1922 VarList, Modifier, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
1923 ReductionIdScopeSpec, ReductionId, UnresolvedReductions);
1924 }
1925
1926 /// Build a new OpenMP 'task_reduction' clause.
1927 ///
1928 /// By default, performs semantic analysis to build the new statement.
1929 /// Subclasses may override this routine to provide different behavior.
1931 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1932 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1933 CXXScopeSpec &ReductionIdScopeSpec,
1934 const DeclarationNameInfo &ReductionId,
1935 ArrayRef<Expr *> UnresolvedReductions) {
1937 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1938 ReductionId, UnresolvedReductions);
1939 }
1940
1941 /// Build a new OpenMP 'in_reduction' clause.
1942 ///
1943 /// By default, performs semantic analysis to build the new statement.
1944 /// Subclasses may override this routine to provide different behavior.
1945 OMPClause *
1947 SourceLocation LParenLoc, SourceLocation ColonLoc,
1948 SourceLocation EndLoc,
1949 CXXScopeSpec &ReductionIdScopeSpec,
1950 const DeclarationNameInfo &ReductionId,
1951 ArrayRef<Expr *> UnresolvedReductions) {
1953 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1954 ReductionId, UnresolvedReductions);
1955 }
1956
1957 /// Build a new OpenMP 'linear' clause.
1958 ///
1959 /// By default, performs semantic analysis to build the new OpenMP clause.
1960 /// Subclasses may override this routine to provide different behavior.
1962 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1963 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1964 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1965 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
1967 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
1968 StepModifierLoc, EndLoc);
1969 }
1970
1971 /// Build a new OpenMP 'aligned' clause.
1972 ///
1973 /// By default, performs semantic analysis to build the new OpenMP clause.
1974 /// Subclasses may override this routine to provide different behavior.
1976 SourceLocation StartLoc,
1977 SourceLocation LParenLoc,
1978 SourceLocation ColonLoc,
1979 SourceLocation EndLoc) {
1981 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
1982 }
1983
1984 /// Build a new OpenMP 'copyin' clause.
1985 ///
1986 /// By default, performs semantic analysis to build the new OpenMP clause.
1987 /// Subclasses may override this routine to provide different behavior.
1989 SourceLocation StartLoc,
1990 SourceLocation LParenLoc,
1991 SourceLocation EndLoc) {
1992 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
1993 LParenLoc, EndLoc);
1994 }
1995
1996 /// Build a new OpenMP 'copyprivate' clause.
1997 ///
1998 /// By default, performs semantic analysis to build the new OpenMP clause.
1999 /// Subclasses may override this routine to provide different behavior.
2001 SourceLocation StartLoc,
2002 SourceLocation LParenLoc,
2003 SourceLocation EndLoc) {
2004 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
2005 LParenLoc, EndLoc);
2006 }
2007
2008 /// Build a new OpenMP 'flush' pseudo clause.
2009 ///
2010 /// By default, performs semantic analysis to build the new OpenMP clause.
2011 /// Subclasses may override this routine to provide different behavior.
2013 SourceLocation StartLoc,
2014 SourceLocation LParenLoc,
2015 SourceLocation EndLoc) {
2016 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2017 LParenLoc, EndLoc);
2018 }
2019
2020 /// Build a new OpenMP 'depobj' pseudo clause.
2021 ///
2022 /// By default, performs semantic analysis to build the new OpenMP clause.
2023 /// Subclasses may override this routine to provide different behavior.
2025 SourceLocation LParenLoc,
2026 SourceLocation EndLoc) {
2027 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2028 LParenLoc, EndLoc);
2029 }
2030
2031 /// Build a new OpenMP 'depend' pseudo clause.
2032 ///
2033 /// By default, performs semantic analysis to build the new OpenMP clause.
2034 /// Subclasses may override this routine to provide different behavior.
2036 Expr *DepModifier, ArrayRef<Expr *> VarList,
2037 SourceLocation StartLoc,
2038 SourceLocation LParenLoc,
2039 SourceLocation EndLoc) {
2041 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2042 }
2043
2044 /// Build a new OpenMP 'device' clause.
2045 ///
2046 /// By default, performs semantic analysis to build the new statement.
2047 /// Subclasses may override this routine to provide different behavior.
2049 Expr *Device, SourceLocation StartLoc,
2050 SourceLocation LParenLoc,
2051 SourceLocation ModifierLoc,
2052 SourceLocation EndLoc) {
2054 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2055 }
2056
2057 /// Build a new OpenMP 'map' clause.
2058 ///
2059 /// By default, performs semantic analysis to build the new OpenMP clause.
2060 /// Subclasses may override this routine to provide different behavior.
2062 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2063 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2064 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2065 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2066 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2067 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2069 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2070 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2071 ColonLoc, VarList, Locs,
2072 /*NoDiagnose=*/false, UnresolvedMappers);
2073 }
2074
2075 /// Build a new OpenMP 'allocate' clause.
2076 ///
2077 /// By default, performs semantic analysis to build the new OpenMP clause.
2078 /// Subclasses may override this routine to provide different behavior.
2079 OMPClause *
2080 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,
2081 OpenMPAllocateClauseModifier FirstModifier,
2082 SourceLocation FirstModifierLoc,
2083 OpenMPAllocateClauseModifier SecondModifier,
2084 SourceLocation SecondModifierLoc,
2085 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2086 SourceLocation LParenLoc, SourceLocation ColonLoc,
2087 SourceLocation EndLoc) {
2089 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,
2090 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2091 }
2092
2093 /// Build a new OpenMP 'num_teams' clause.
2094 ///
2095 /// By default, performs semantic analysis to build the new statement.
2096 /// Subclasses may override this routine to provide different behavior.
2098 SourceLocation StartLoc,
2099 SourceLocation LParenLoc,
2100 SourceLocation EndLoc) {
2101 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(VarList, StartLoc,
2102 LParenLoc, EndLoc);
2103 }
2104
2105 /// Build a new OpenMP 'thread_limit' clause.
2106 ///
2107 /// By default, performs semantic analysis to build the new statement.
2108 /// Subclasses may override this routine to provide different behavior.
2110 SourceLocation StartLoc,
2111 SourceLocation LParenLoc,
2112 SourceLocation EndLoc) {
2113 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(VarList, StartLoc,
2114 LParenLoc, EndLoc);
2115 }
2116
2117 /// Build a new OpenMP 'priority' clause.
2118 ///
2119 /// By default, performs semantic analysis to build the new statement.
2120 /// Subclasses may override this routine to provide different behavior.
2122 SourceLocation LParenLoc,
2123 SourceLocation EndLoc) {
2124 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2125 LParenLoc, EndLoc);
2126 }
2127
2128 /// Build a new OpenMP 'grainsize' clause.
2129 ///
2130 /// By default, performs semantic analysis to build the new statement.
2131 /// Subclasses may override this routine to provide different behavior.
2133 Expr *Device, SourceLocation StartLoc,
2134 SourceLocation LParenLoc,
2135 SourceLocation ModifierLoc,
2136 SourceLocation EndLoc) {
2138 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2139 }
2140
2141 /// Build a new OpenMP 'num_tasks' clause.
2142 ///
2143 /// By default, performs semantic analysis to build the new statement.
2144 /// Subclasses may override this routine to provide different behavior.
2146 Expr *NumTasks, SourceLocation StartLoc,
2147 SourceLocation LParenLoc,
2148 SourceLocation ModifierLoc,
2149 SourceLocation EndLoc) {
2151 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2152 }
2153
2154 /// Build a new OpenMP 'hint' clause.
2155 ///
2156 /// By default, performs semantic analysis to build the new statement.
2157 /// Subclasses may override this routine to provide different behavior.
2159 SourceLocation LParenLoc,
2160 SourceLocation EndLoc) {
2161 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2162 EndLoc);
2163 }
2164
2165 /// Build a new OpenMP 'detach' clause.
2166 ///
2167 /// By default, performs semantic analysis to build the new statement.
2168 /// Subclasses may override this routine to provide different behavior.
2170 SourceLocation LParenLoc,
2171 SourceLocation EndLoc) {
2172 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2173 EndLoc);
2174 }
2175
2176 /// Build a new OpenMP 'dist_schedule' clause.
2177 ///
2178 /// By default, performs semantic analysis to build the new OpenMP clause.
2179 /// Subclasses may override this routine to provide different behavior.
2180 OMPClause *
2182 Expr *ChunkSize, SourceLocation StartLoc,
2183 SourceLocation LParenLoc, SourceLocation KindLoc,
2184 SourceLocation CommaLoc, SourceLocation EndLoc) {
2186 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2187 }
2188
2189 /// Build a new OpenMP 'to' clause.
2190 ///
2191 /// By default, performs semantic analysis to build the new statement.
2192 /// Subclasses may override this routine to provide different behavior.
2193 OMPClause *
2195 ArrayRef<SourceLocation> MotionModifiersLoc,
2196 CXXScopeSpec &MapperIdScopeSpec,
2197 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2198 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2199 ArrayRef<Expr *> UnresolvedMappers) {
2201 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2202 ColonLoc, VarList, Locs, UnresolvedMappers);
2203 }
2204
2205 /// Build a new OpenMP 'from' clause.
2206 ///
2207 /// By default, performs semantic analysis to build the new statement.
2208 /// Subclasses may override this routine to provide different behavior.
2209 OMPClause *
2211 ArrayRef<SourceLocation> MotionModifiersLoc,
2212 CXXScopeSpec &MapperIdScopeSpec,
2213 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2214 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2215 ArrayRef<Expr *> UnresolvedMappers) {
2217 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2218 ColonLoc, VarList, Locs, UnresolvedMappers);
2219 }
2220
2221 /// Build a new OpenMP 'use_device_ptr' clause.
2222 ///
2223 /// By default, performs semantic analysis to build the new OpenMP clause.
2224 /// Subclasses may override this routine to provide different behavior.
2226 const OMPVarListLocTy &Locs) {
2227 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2228 }
2229
2230 /// Build a new OpenMP 'use_device_addr' clause.
2231 ///
2232 /// By default, performs semantic analysis to build the new OpenMP clause.
2233 /// Subclasses may override this routine to provide different behavior.
2235 const OMPVarListLocTy &Locs) {
2236 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2237 }
2238
2239 /// Build a new OpenMP 'is_device_ptr' clause.
2240 ///
2241 /// By default, performs semantic analysis to build the new OpenMP clause.
2242 /// Subclasses may override this routine to provide different behavior.
2244 const OMPVarListLocTy &Locs) {
2245 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2246 }
2247
2248 /// Build a new OpenMP 'has_device_addr' clause.
2249 ///
2250 /// By default, performs semantic analysis to build the new OpenMP clause.
2251 /// Subclasses may override this routine to provide different behavior.
2253 const OMPVarListLocTy &Locs) {
2254 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2255 }
2256
2257 /// Build a new OpenMP 'defaultmap' clause.
2258 ///
2259 /// By default, performs semantic analysis to build the new OpenMP clause.
2260 /// Subclasses may override this routine to provide different behavior.
2263 SourceLocation StartLoc,
2264 SourceLocation LParenLoc,
2265 SourceLocation MLoc,
2266 SourceLocation KindLoc,
2267 SourceLocation EndLoc) {
2269 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2270 }
2271
2272 /// Build a new OpenMP 'nontemporal' clause.
2273 ///
2274 /// By default, performs semantic analysis to build the new OpenMP clause.
2275 /// Subclasses may override this routine to provide different behavior.
2277 SourceLocation StartLoc,
2278 SourceLocation LParenLoc,
2279 SourceLocation EndLoc) {
2280 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2281 LParenLoc, EndLoc);
2282 }
2283
2284 /// Build a new OpenMP 'inclusive' clause.
2285 ///
2286 /// By default, performs semantic analysis to build the new OpenMP clause.
2287 /// Subclasses may override this routine to provide different behavior.
2289 SourceLocation StartLoc,
2290 SourceLocation LParenLoc,
2291 SourceLocation EndLoc) {
2292 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2293 LParenLoc, EndLoc);
2294 }
2295
2296 /// Build a new OpenMP 'exclusive' clause.
2297 ///
2298 /// By default, performs semantic analysis to build the new OpenMP clause.
2299 /// Subclasses may override this routine to provide different behavior.
2301 SourceLocation StartLoc,
2302 SourceLocation LParenLoc,
2303 SourceLocation EndLoc) {
2304 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2305 LParenLoc, EndLoc);
2306 }
2307
2308 /// Build a new OpenMP 'uses_allocators' clause.
2309 ///
2310 /// By default, performs semantic analysis to build the new OpenMP clause.
2311 /// Subclasses may override this routine to provide different behavior.
2314 SourceLocation LParenLoc, SourceLocation EndLoc) {
2316 StartLoc, LParenLoc, EndLoc, Data);
2317 }
2318
2319 /// Build a new OpenMP 'affinity' clause.
2320 ///
2321 /// By default, performs semantic analysis to build the new OpenMP clause.
2322 /// Subclasses may override this routine to provide different behavior.
2324 SourceLocation LParenLoc,
2325 SourceLocation ColonLoc,
2326 SourceLocation EndLoc, Expr *Modifier,
2327 ArrayRef<Expr *> Locators) {
2329 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2330 }
2331
2332 /// Build a new OpenMP 'order' clause.
2333 ///
2334 /// By default, performs semantic analysis to build the new OpenMP clause.
2335 /// Subclasses may override this routine to provide different behavior.
2337 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2338 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2339 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2341 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2342 }
2343
2344 /// Build a new OpenMP 'init' clause.
2345 ///
2346 /// By default, performs semantic analysis to build the new OpenMP clause.
2347 /// Subclasses may override this routine to provide different behavior.
2349 SourceLocation StartLoc,
2350 SourceLocation LParenLoc,
2351 SourceLocation VarLoc,
2352 SourceLocation EndLoc) {
2354 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2355 }
2356
2357 /// Build a new OpenMP 'use' clause.
2358 ///
2359 /// By default, performs semantic analysis to build the new OpenMP clause.
2360 /// Subclasses may override this routine to provide different behavior.
2362 SourceLocation LParenLoc,
2363 SourceLocation VarLoc, SourceLocation EndLoc) {
2364 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2365 LParenLoc, VarLoc, EndLoc);
2366 }
2367
2368 /// Build a new OpenMP 'destroy' clause.
2369 ///
2370 /// By default, performs semantic analysis to build the new OpenMP clause.
2371 /// Subclasses may override this routine to provide different behavior.
2373 SourceLocation LParenLoc,
2374 SourceLocation VarLoc,
2375 SourceLocation EndLoc) {
2377 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2378 }
2379
2380 /// Build a new OpenMP 'novariants' clause.
2381 ///
2382 /// By default, performs semantic analysis to build the new OpenMP clause.
2383 /// Subclasses may override this routine to provide different behavior.
2385 SourceLocation StartLoc,
2386 SourceLocation LParenLoc,
2387 SourceLocation EndLoc) {
2389 LParenLoc, EndLoc);
2390 }
2391
2392 /// Build a new OpenMP 'nocontext' clause.
2393 ///
2394 /// By default, performs semantic analysis to build the new OpenMP clause.
2395 /// Subclasses may override this routine to provide different behavior.
2397 SourceLocation LParenLoc,
2398 SourceLocation EndLoc) {
2400 LParenLoc, EndLoc);
2401 }
2402
2403 /// Build a new OpenMP 'filter' clause.
2404 ///
2405 /// By default, performs semantic analysis to build the new OpenMP clause.
2406 /// Subclasses may override this routine to provide different behavior.
2408 SourceLocation LParenLoc,
2409 SourceLocation EndLoc) {
2410 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2411 LParenLoc, EndLoc);
2412 }
2413
2414 /// Build a new OpenMP 'bind' clause.
2415 ///
2416 /// By default, performs semantic analysis to build the new OpenMP clause.
2417 /// Subclasses may override this routine to provide different behavior.
2419 SourceLocation KindLoc,
2420 SourceLocation StartLoc,
2421 SourceLocation LParenLoc,
2422 SourceLocation EndLoc) {
2423 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2424 LParenLoc, EndLoc);
2425 }
2426
2427 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2428 ///
2429 /// By default, performs semantic analysis to build the new OpenMP clause.
2430 /// Subclasses may override this routine to provide different behavior.
2432 SourceLocation LParenLoc,
2433 SourceLocation EndLoc) {
2434 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2435 LParenLoc, EndLoc);
2436 }
2437
2438 /// Build a new OpenMP 'ompx_attribute' clause.
2439 ///
2440 /// By default, performs semantic analysis to build the new OpenMP clause.
2441 /// Subclasses may override this routine to provide different behavior.
2443 SourceLocation StartLoc,
2444 SourceLocation LParenLoc,
2445 SourceLocation EndLoc) {
2446 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2447 LParenLoc, EndLoc);
2448 }
2449
2450 /// Build a new OpenMP 'ompx_bare' clause.
2451 ///
2452 /// By default, performs semantic analysis to build the new OpenMP clause.
2453 /// Subclasses may override this routine to provide different behavior.
2455 SourceLocation EndLoc) {
2456 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2457 }
2458
2459 /// Build a new OpenMP 'align' clause.
2460 ///
2461 /// By default, performs semantic analysis to build the new OpenMP clause.
2462 /// Subclasses may override this routine to provide different behavior.
2464 SourceLocation LParenLoc,
2465 SourceLocation EndLoc) {
2466 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2467 EndLoc);
2468 }
2469
2470 /// Build a new OpenMP 'at' clause.
2471 ///
2472 /// By default, performs semantic analysis to build the new OpenMP clause.
2473 /// Subclasses may override this routine to provide different behavior.
2475 SourceLocation StartLoc,
2476 SourceLocation LParenLoc,
2477 SourceLocation EndLoc) {
2478 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2479 LParenLoc, EndLoc);
2480 }
2481
2482 /// Build a new OpenMP 'severity' clause.
2483 ///
2484 /// By default, performs semantic analysis to build the new OpenMP clause.
2485 /// Subclasses may override this routine to provide different behavior.
2487 SourceLocation KwLoc,
2488 SourceLocation StartLoc,
2489 SourceLocation LParenLoc,
2490 SourceLocation EndLoc) {
2491 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2492 LParenLoc, EndLoc);
2493 }
2494
2495 /// Build a new OpenMP 'message' clause.
2496 ///
2497 /// By default, performs semantic analysis to build the new OpenMP clause.
2498 /// Subclasses may override this routine to provide different behavior.
2500 SourceLocation LParenLoc,
2501 SourceLocation EndLoc) {
2502 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2503 EndLoc);
2504 }
2505
2506 /// Build a new OpenMP 'doacross' clause.
2507 ///
2508 /// By default, performs semantic analysis to build the new OpenMP clause.
2509 /// Subclasses may override this routine to provide different behavior.
2510 OMPClause *
2512 SourceLocation DepLoc, SourceLocation ColonLoc,
2513 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2514 SourceLocation LParenLoc, SourceLocation EndLoc) {
2516 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2517 }
2518
2519 /// Build a new OpenMP 'holds' clause.
2521 SourceLocation LParenLoc,
2522 SourceLocation EndLoc) {
2523 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2524 EndLoc);
2525 }
2526
2527 /// Rebuild the operand to an Objective-C \@synchronized statement.
2528 ///
2529 /// By default, performs semantic analysis to build the new statement.
2530 /// Subclasses may override this routine to provide different behavior.
2532 Expr *object) {
2533 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2534 }
2535
2536 /// Build a new Objective-C \@synchronized statement.
2537 ///
2538 /// By default, performs semantic analysis to build the new statement.
2539 /// Subclasses may override this routine to provide different behavior.
2541 Expr *Object, Stmt *Body) {
2542 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2543 }
2544
2545 /// Build a new Objective-C \@autoreleasepool statement.
2546 ///
2547 /// By default, performs semantic analysis to build the new statement.
2548 /// Subclasses may override this routine to provide different behavior.
2550 Stmt *Body) {
2551 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2552 }
2553
2554 /// Build a new Objective-C fast enumeration statement.
2555 ///
2556 /// By default, performs semantic analysis to build the new statement.
2557 /// Subclasses may override this routine to provide different behavior.
2559 Stmt *Element,
2560 Expr *Collection,
2561 SourceLocation RParenLoc,
2562 Stmt *Body) {
2564 ForLoc, Element, Collection, RParenLoc);
2565 if (ForEachStmt.isInvalid())
2566 return StmtError();
2567
2568 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2569 Body);
2570 }
2571
2572 /// Build a new C++ exception declaration.
2573 ///
2574 /// By default, performs semantic analysis to build the new decaration.
2575 /// Subclasses may override this routine to provide different behavior.
2578 SourceLocation StartLoc,
2579 SourceLocation IdLoc,
2580 IdentifierInfo *Id) {
2582 StartLoc, IdLoc, Id);
2583 if (Var)
2584 getSema().CurContext->addDecl(Var);
2585 return Var;
2586 }
2587
2588 /// Build a new C++ catch statement.
2589 ///
2590 /// By default, performs semantic analysis to build the new statement.
2591 /// Subclasses may override this routine to provide different behavior.
2593 VarDecl *ExceptionDecl,
2594 Stmt *Handler) {
2595 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2596 Handler));
2597 }
2598
2599 /// Build a new C++ try statement.
2600 ///
2601 /// By default, performs semantic analysis to build the new statement.
2602 /// Subclasses may override this routine to provide different behavior.
2604 ArrayRef<Stmt *> Handlers) {
2605 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2606 }
2607
2608 /// Build a new C++0x range-based for statement.
2609 ///
2610 /// By default, performs semantic analysis to build the new statement.
2611 /// Subclasses may override this routine to provide different behavior.
2613 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2614 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2615 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2616 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2617 // If we've just learned that the range is actually an Objective-C
2618 // collection, treat this as an Objective-C fast enumeration loop.
2619 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
2620 if (RangeStmt->isSingleDecl()) {
2621 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
2622 if (RangeVar->isInvalidDecl())
2623 return StmtError();
2624
2625 Expr *RangeExpr = RangeVar->getInit();
2626 if (!RangeExpr->isTypeDependent() &&
2627 RangeExpr->getType()->isObjCObjectPointerType()) {
2628 // FIXME: Support init-statements in Objective-C++20 ranged for
2629 // statement.
2630 if (Init) {
2631 return SemaRef.Diag(Init->getBeginLoc(),
2632 diag::err_objc_for_range_init_stmt)
2633 << Init->getSourceRange();
2634 }
2636 ForLoc, LoopVar, RangeExpr, RParenLoc);
2637 }
2638 }
2639 }
2640 }
2641
2643 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2644 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2645 }
2646
2647 /// Build a new C++0x range-based for statement.
2648 ///
2649 /// By default, performs semantic analysis to build the new statement.
2650 /// Subclasses may override this routine to provide different behavior.
2652 bool IsIfExists,
2653 NestedNameSpecifierLoc QualifierLoc,
2654 DeclarationNameInfo NameInfo,
2655 Stmt *Nested) {
2656 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2657 QualifierLoc, NameInfo, Nested);
2658 }
2659
2660 /// Attach body to a C++0x range-based for statement.
2661 ///
2662 /// By default, performs semantic analysis to finish the new statement.
2663 /// Subclasses may override this routine to provide different behavior.
2665 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2666 }
2667
2669 Stmt *TryBlock, Stmt *Handler) {
2670 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2671 }
2672
2674 Stmt *Block) {
2675 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2676 }
2677
2679 return SEHFinallyStmt::Create(getSema().getASTContext(), Loc, Block);
2680 }
2681
2683 SourceLocation LParen,
2684 SourceLocation RParen,
2685 TypeSourceInfo *TSI) {
2686 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2687 TSI);
2688 }
2689
2690 /// Build a new predefined expression.
2691 ///
2692 /// By default, performs semantic analysis to build the new expression.
2693 /// Subclasses may override this routine to provide different behavior.
2695 return getSema().BuildPredefinedExpr(Loc, IK);
2696 }
2697
2698 /// Build a new expression that references a declaration.
2699 ///
2700 /// By default, performs semantic analysis to build the new expression.
2701 /// Subclasses may override this routine to provide different behavior.
2703 LookupResult &R,
2704 bool RequiresADL) {
2705 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2706 }
2707
2708
2709 /// Build a new expression that references a declaration.
2710 ///
2711 /// By default, performs semantic analysis to build the new expression.
2712 /// Subclasses may override this routine to provide different behavior.
2714 ValueDecl *VD,
2715 const DeclarationNameInfo &NameInfo,
2717 TemplateArgumentListInfo *TemplateArgs) {
2718 CXXScopeSpec SS;
2719 SS.Adopt(QualifierLoc);
2720 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2721 TemplateArgs);
2722 }
2723
2724 /// Build a new expression in parentheses.
2725 ///
2726 /// By default, performs semantic analysis to build the new expression.
2727 /// Subclasses may override this routine to provide different behavior.
2729 SourceLocation RParen) {
2730 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2731 }
2732
2733 /// Build a new pseudo-destructor expression.
2734 ///
2735 /// By default, performs semantic analysis to build the new expression.
2736 /// Subclasses may override this routine to provide different behavior.
2738 SourceLocation OperatorLoc,
2739 bool isArrow,
2740 CXXScopeSpec &SS,
2741 TypeSourceInfo *ScopeType,
2742 SourceLocation CCLoc,
2743 SourceLocation TildeLoc,
2744 PseudoDestructorTypeStorage Destroyed);
2745
2746 /// Build a new unary operator expression.
2747 ///
2748 /// By default, performs semantic analysis to build the new expression.
2749 /// Subclasses may override this routine to provide different behavior.
2752 Expr *SubExpr) {
2753 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2754 }
2755
2756 /// Build a new builtin offsetof expression.
2757 ///
2758 /// By default, performs semantic analysis to build the new expression.
2759 /// Subclasses may override this routine to provide different behavior.
2763 SourceLocation RParenLoc) {
2764 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2765 RParenLoc);
2766 }
2767
2768 /// Build a new sizeof, alignof or vec_step expression with a
2769 /// type argument.
2770 ///
2771 /// By default, performs semantic analysis to build the new expression.
2772 /// Subclasses may override this routine to provide different behavior.
2774 SourceLocation OpLoc,
2775 UnaryExprOrTypeTrait ExprKind,
2776 SourceRange R) {
2777 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2778 }
2779
2780 /// Build a new sizeof, alignof or vec step expression with an
2781 /// expression argument.
2782 ///
2783 /// By default, performs semantic analysis to build the new expression.
2784 /// Subclasses may override this routine to provide different behavior.
2786 UnaryExprOrTypeTrait ExprKind,
2787 SourceRange R) {
2789 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2790 if (Result.isInvalid())
2791 return ExprError();
2792
2793 return Result;
2794 }
2795
2796 /// Build a new array subscript expression.
2797 ///
2798 /// By default, performs semantic analysis to build the new expression.
2799 /// Subclasses may override this routine to provide different behavior.
2801 SourceLocation LBracketLoc,
2802 Expr *RHS,
2803 SourceLocation RBracketLoc) {
2804 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2805 LBracketLoc, RHS,
2806 RBracketLoc);
2807 }
2808
2809 /// Build a new matrix subscript expression.
2810 ///
2811 /// By default, performs semantic analysis to build the new expression.
2812 /// Subclasses may override this routine to provide different behavior.
2814 Expr *ColumnIdx,
2815 SourceLocation RBracketLoc) {
2816 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2817 RBracketLoc);
2818 }
2819
2820 /// Build a new array section expression.
2821 ///
2822 /// By default, performs semantic analysis to build the new expression.
2823 /// Subclasses may override this routine to provide different behavior.
2825 SourceLocation LBracketLoc,
2826 Expr *LowerBound,
2827 SourceLocation ColonLocFirst,
2828 SourceLocation ColonLocSecond,
2829 Expr *Length, Expr *Stride,
2830 SourceLocation RBracketLoc) {
2831 if (IsOMPArraySection)
2833 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2834 Stride, RBracketLoc);
2835
2836 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2837 "Stride/second colon not allowed for OpenACC");
2838
2840 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2841 }
2842
2843 /// Build a new array shaping expression.
2844 ///
2845 /// By default, performs semantic analysis to build the new expression.
2846 /// Subclasses may override this routine to provide different behavior.
2848 SourceLocation RParenLoc,
2849 ArrayRef<Expr *> Dims,
2850 ArrayRef<SourceRange> BracketsRanges) {
2852 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2853 }
2854
2855 /// Build a new iterator expression.
2856 ///
2857 /// By default, performs semantic analysis to build the new expression.
2858 /// Subclasses may override this routine to provide different behavior.
2861 SourceLocation RLoc,
2864 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2865 }
2866
2867 /// Build a new call expression.
2868 ///
2869 /// By default, performs semantic analysis to build the new expression.
2870 /// Subclasses may override this routine to provide different behavior.
2872 MultiExprArg Args,
2873 SourceLocation RParenLoc,
2874 Expr *ExecConfig = nullptr) {
2875 return getSema().ActOnCallExpr(
2876 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2877 }
2878
2880 MultiExprArg Args,
2881 SourceLocation RParenLoc) {
2883 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2884 }
2885
2886 /// Build a new member access expression.
2887 ///
2888 /// By default, performs semantic analysis to build the new expression.
2889 /// Subclasses may override this routine to provide different behavior.
2891 bool isArrow,
2892 NestedNameSpecifierLoc QualifierLoc,
2893 SourceLocation TemplateKWLoc,
2894 const DeclarationNameInfo &MemberNameInfo,
2896 NamedDecl *FoundDecl,
2897 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2898 NamedDecl *FirstQualifierInScope) {
2900 isArrow);
2901 if (!Member->getDeclName()) {
2902 // We have a reference to an unnamed field. This is always the
2903 // base of an anonymous struct/union member access, i.e. the
2904 // field is always of record type.
2905 assert(Member->getType()->isRecordType() &&
2906 "unnamed member not of record type?");
2907
2908 BaseResult =
2910 QualifierLoc.getNestedNameSpecifier(),
2911 FoundDecl, Member);
2912 if (BaseResult.isInvalid())
2913 return ExprError();
2914 Base = BaseResult.get();
2915
2916 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
2917 // from the AST, so we need to re-insert them if needed (since
2918 // `BuildFieldRefereneExpr()` doesn't do this).
2919 if (!isArrow && Base->isPRValue()) {
2921 if (BaseResult.isInvalid())
2922 return ExprError();
2923 Base = BaseResult.get();
2924 }
2925
2926 CXXScopeSpec EmptySS;
2928 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
2929 DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()),
2930 MemberNameInfo);
2931 }
2932
2933 CXXScopeSpec SS;
2934 SS.Adopt(QualifierLoc);
2935
2936 Base = BaseResult.get();
2937 if (Base->containsErrors())
2938 return ExprError();
2939
2940 QualType BaseType = Base->getType();
2941
2942 if (isArrow && !BaseType->isPointerType())
2943 return ExprError();
2944
2945 // FIXME: this involves duplicating earlier analysis in a lot of
2946 // cases; we should avoid this when possible.
2947 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2948 R.addDecl(FoundDecl);
2949 R.resolveKind();
2950
2951 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2952 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {
2953 if (auto *ThisClass = cast<CXXThisExpr>(Base)
2954 ->getType()
2955 ->getPointeeType()
2956 ->getAsCXXRecordDecl()) {
2957 auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());
2958 // In unevaluated contexts, an expression supposed to be a member access
2959 // might reference a member in an unrelated class.
2960 if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))
2961 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2962 VK_LValue, Member->getLocation());
2963 }
2964 }
2965
2966 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2967 SS, TemplateKWLoc,
2968 FirstQualifierInScope,
2969 R, ExplicitTemplateArgs,
2970 /*S*/nullptr);
2971 }
2972
2973 /// Build a new binary operator expression.
2974 ///
2975 /// By default, performs semantic analysis to build the new expression.
2976 /// Subclasses may override this routine to provide different behavior.
2979 Expr *LHS, Expr *RHS) {
2980 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS);
2981 }
2982
2983 /// Build a new rewritten operator expression.
2984 ///
2985 /// By default, performs semantic analysis to build the new expression.
2986 /// Subclasses may override this routine to provide different behavior.
2988 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2989 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2990 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2991 RHS, /*RequiresADL*/false);
2992 }
2993
2994 /// Build a new conditional operator expression.
2995 ///
2996 /// By default, performs semantic analysis to build the new expression.
2997 /// Subclasses may override this routine to provide different behavior.
2999 SourceLocation QuestionLoc,
3000 Expr *LHS,
3001 SourceLocation ColonLoc,
3002 Expr *RHS) {
3003 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
3004 LHS, RHS);
3005 }
3006
3007 /// Build a new C-style cast expression.
3008 ///
3009 /// By default, performs semantic analysis to build the new expression.
3010 /// Subclasses may override this routine to provide different behavior.
3012 TypeSourceInfo *TInfo,
3013 SourceLocation RParenLoc,
3014 Expr *SubExpr) {
3015 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3016 SubExpr);
3017 }
3018
3019 /// Build a new compound literal expression.
3020 ///
3021 /// By default, performs semantic analysis to build the new expression.
3022 /// Subclasses may override this routine to provide different behavior.
3024 TypeSourceInfo *TInfo,
3025 SourceLocation RParenLoc,
3026 Expr *Init) {
3027 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3028 Init);
3029 }
3030
3031 /// Build a new extended vector element access expression.
3032 ///
3033 /// By default, performs semantic analysis to build the new expression.
3034 /// Subclasses may override this routine to provide different behavior.
3036 bool IsArrow,
3037 SourceLocation AccessorLoc,
3038 IdentifierInfo &Accessor) {
3039
3040 CXXScopeSpec SS;
3041 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3043 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3044 /*FirstQualifierInScope*/ nullptr, NameInfo,
3045 /* TemplateArgs */ nullptr,
3046 /*S*/ nullptr);
3047 }
3048
3049 /// Build a new initializer list expression.
3050 ///
3051 /// By default, performs semantic analysis to build the new expression.
3052 /// Subclasses may override this routine to provide different behavior.
3054 MultiExprArg Inits,
3055 SourceLocation RBraceLoc) {
3056 return SemaRef.BuildInitList(LBraceLoc, Inits, RBraceLoc);
3057 }
3058
3059 /// Build a new designated initializer expression.
3060 ///
3061 /// By default, performs semantic analysis to build the new expression.
3062 /// Subclasses may override this routine to provide different behavior.
3064 MultiExprArg ArrayExprs,
3065 SourceLocation EqualOrColonLoc,
3066 bool GNUSyntax,
3067 Expr *Init) {
3069 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3070 Init);
3071 if (Result.isInvalid())
3072 return ExprError();
3073
3074 return Result;
3075 }
3076
3077 /// Build a new value-initialized expression.
3078 ///
3079 /// By default, builds the implicit value initialization without performing
3080 /// any semantic analysis. Subclasses may override this routine to provide
3081 /// different behavior.
3083 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3084 }
3085
3086 /// Build a new \c va_arg expression.
3087 ///
3088 /// By default, performs semantic analysis to build the new expression.
3089 /// Subclasses may override this routine to provide different behavior.
3091 Expr *SubExpr, TypeSourceInfo *TInfo,
3092 SourceLocation RParenLoc) {
3093 return getSema().BuildVAArgExpr(BuiltinLoc,
3094 SubExpr, TInfo,
3095 RParenLoc);
3096 }
3097
3098 /// Build a new expression list in parentheses.
3099 ///
3100 /// By default, performs semantic analysis to build the new expression.
3101 /// Subclasses may override this routine to provide different behavior.
3103 MultiExprArg SubExprs,
3104 SourceLocation RParenLoc) {
3105 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3106 }
3107
3108 /// Build a new address-of-label expression.
3109 ///
3110 /// By default, performs semantic analysis, using the name of the label
3111 /// rather than attempting to map the label statement itself.
3112 /// Subclasses may override this routine to provide different behavior.
3114 SourceLocation LabelLoc, LabelDecl *Label) {
3115 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3116 }
3117
3118 /// Build a new GNU statement expression.
3119 ///
3120 /// By default, performs semantic analysis to build the new expression.
3121 /// Subclasses may override this routine to provide different behavior.
3123 SourceLocation RParenLoc, unsigned TemplateDepth) {
3124 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3125 TemplateDepth);
3126 }
3127
3128 /// Build a new __builtin_choose_expr expression.
3129 ///
3130 /// By default, performs semantic analysis to build the new expression.
3131 /// Subclasses may override this routine to provide different behavior.
3133 Expr *Cond, Expr *LHS, Expr *RHS,
3134 SourceLocation RParenLoc) {
3135 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3136 Cond, LHS, RHS,
3137 RParenLoc);
3138 }
3139
3140 /// Build a new generic selection expression with an expression 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 Expr *ControllingExpr,
3149 ArrayRef<Expr *> Exprs) {
3150 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3151 /*PredicateIsExpr=*/true,
3152 ControllingExpr, Types, Exprs);
3153 }
3154
3155 /// Build a new generic selection expression with a type predicate.
3156 ///
3157 /// By default, performs semantic analysis to build the new expression.
3158 /// Subclasses may override this routine to provide different behavior.
3160 SourceLocation DefaultLoc,
3161 SourceLocation RParenLoc,
3162 TypeSourceInfo *ControllingType,
3164 ArrayRef<Expr *> Exprs) {
3165 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3166 /*PredicateIsExpr=*/false,
3167 ControllingType, Types, Exprs);
3168 }
3169
3170 /// Build a new overloaded operator call expression.
3171 ///
3172 /// By default, performs semantic analysis to build the new expression.
3173 /// The semantic analysis provides the behavior of template instantiation,
3174 /// copying with transformations that turn what looks like an overloaded
3175 /// operator call into a use of a builtin operator, performing
3176 /// argument-dependent lookup, etc. Subclasses may override this routine to
3177 /// provide different behavior.
3179 SourceLocation OpLoc,
3180 SourceLocation CalleeLoc,
3181 bool RequiresADL,
3182 const UnresolvedSetImpl &Functions,
3183 Expr *First, Expr *Second);
3184
3185 /// Build a new C++ "named" cast expression, such as static_cast or
3186 /// reinterpret_cast.
3187 ///
3188 /// By default, this routine dispatches to one of the more-specific routines
3189 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3190 /// Subclasses may override this routine to provide different behavior.
3193 SourceLocation LAngleLoc,
3194 TypeSourceInfo *TInfo,
3195 SourceLocation RAngleLoc,
3196 SourceLocation LParenLoc,
3197 Expr *SubExpr,
3198 SourceLocation RParenLoc) {
3199 switch (Class) {
3200 case Stmt::CXXStaticCastExprClass:
3201 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3202 RAngleLoc, LParenLoc,
3203 SubExpr, RParenLoc);
3204
3205 case Stmt::CXXDynamicCastExprClass:
3206 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3207 RAngleLoc, LParenLoc,
3208 SubExpr, RParenLoc);
3209
3210 case Stmt::CXXReinterpretCastExprClass:
3211 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3212 RAngleLoc, LParenLoc,
3213 SubExpr,
3214 RParenLoc);
3215
3216 case Stmt::CXXConstCastExprClass:
3217 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3218 RAngleLoc, LParenLoc,
3219 SubExpr, RParenLoc);
3220
3221 case Stmt::CXXAddrspaceCastExprClass:
3222 return getDerived().RebuildCXXAddrspaceCastExpr(
3223 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3224
3225 default:
3226 llvm_unreachable("Invalid C++ named cast");
3227 }
3228 }
3229
3230 /// Build a new C++ static_cast expression.
3231 ///
3232 /// By default, performs semantic analysis to build the new expression.
3233 /// Subclasses may override this routine to provide different behavior.
3235 SourceLocation LAngleLoc,
3236 TypeSourceInfo *TInfo,
3237 SourceLocation RAngleLoc,
3238 SourceLocation LParenLoc,
3239 Expr *SubExpr,
3240 SourceLocation RParenLoc) {
3241 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3242 TInfo, SubExpr,
3243 SourceRange(LAngleLoc, RAngleLoc),
3244 SourceRange(LParenLoc, RParenLoc));
3245 }
3246
3247 /// Build a new C++ dynamic_cast expression.
3248 ///
3249 /// By default, performs semantic analysis to build the new expression.
3250 /// Subclasses may override this routine to provide different behavior.
3252 SourceLocation LAngleLoc,
3253 TypeSourceInfo *TInfo,
3254 SourceLocation RAngleLoc,
3255 SourceLocation LParenLoc,
3256 Expr *SubExpr,
3257 SourceLocation RParenLoc) {
3258 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3259 TInfo, SubExpr,
3260 SourceRange(LAngleLoc, RAngleLoc),
3261 SourceRange(LParenLoc, RParenLoc));
3262 }
3263
3264 /// Build a new C++ reinterpret_cast expression.
3265 ///
3266 /// By default, performs semantic analysis to build the new expression.
3267 /// Subclasses may override this routine to provide different behavior.
3269 SourceLocation LAngleLoc,
3270 TypeSourceInfo *TInfo,
3271 SourceLocation RAngleLoc,
3272 SourceLocation LParenLoc,
3273 Expr *SubExpr,
3274 SourceLocation RParenLoc) {
3275 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3276 TInfo, SubExpr,
3277 SourceRange(LAngleLoc, RAngleLoc),
3278 SourceRange(LParenLoc, RParenLoc));
3279 }
3280
3281 /// Build a new C++ const_cast expression.
3282 ///
3283 /// By default, performs semantic analysis to build the new expression.
3284 /// Subclasses may override this routine to provide different behavior.
3286 SourceLocation LAngleLoc,
3287 TypeSourceInfo *TInfo,
3288 SourceLocation RAngleLoc,
3289 SourceLocation LParenLoc,
3290 Expr *SubExpr,
3291 SourceLocation RParenLoc) {
3292 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3293 TInfo, SubExpr,
3294 SourceRange(LAngleLoc, RAngleLoc),
3295 SourceRange(LParenLoc, RParenLoc));
3296 }
3297
3300 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3301 SourceLocation LParenLoc, Expr *SubExpr,
3302 SourceLocation RParenLoc) {
3303 return getSema().BuildCXXNamedCast(
3304 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3305 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3306 }
3307
3308 /// Build a new C++ functional-style cast expression.
3309 ///
3310 /// By default, performs semantic analysis to build the new expression.
3311 /// Subclasses may override this routine to provide different behavior.
3313 SourceLocation LParenLoc,
3314 Expr *Sub,
3315 SourceLocation RParenLoc,
3316 bool ListInitialization) {
3317 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3318 // CXXParenListInitExpr. Pass its expanded arguments so that the
3319 // CXXParenListInitExpr can be rebuilt.
3320 if (auto *PLE = dyn_cast<ParenListExpr>(Sub))
3322 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3323 RParenLoc, ListInitialization);
3324 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3325 MultiExprArg(&Sub, 1), RParenLoc,
3326 ListInitialization);
3327 }
3328
3329 /// Build a new C++ __builtin_bit_cast expression.
3330 ///
3331 /// By default, performs semantic analysis to build the new expression.
3332 /// Subclasses may override this routine to provide different behavior.
3334 TypeSourceInfo *TSI, Expr *Sub,
3335 SourceLocation RParenLoc) {
3336 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3337 }
3338
3339 /// Build a new C++ typeid(type) expression.
3340 ///
3341 /// By default, performs semantic analysis to build the new expression.
3342 /// Subclasses may override this routine to provide different behavior.
3344 SourceLocation TypeidLoc,
3345 TypeSourceInfo *Operand,
3346 SourceLocation RParenLoc) {
3347 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3348 RParenLoc);
3349 }
3350
3351
3352 /// Build a new C++ typeid(expr) expression.
3353 ///
3354 /// By default, performs semantic analysis to build the new expression.
3355 /// Subclasses may override this routine to provide different behavior.
3357 SourceLocation TypeidLoc,
3358 Expr *Operand,
3359 SourceLocation RParenLoc) {
3360 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3361 RParenLoc);
3362 }
3363
3364 /// Build a new C++ __uuidof(type) expression.
3365 ///
3366 /// By default, performs semantic analysis to build the new expression.
3367 /// Subclasses may override this routine to provide different behavior.
3369 TypeSourceInfo *Operand,
3370 SourceLocation RParenLoc) {
3371 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3372 }
3373
3374 /// Build a new C++ __uuidof(expr) expression.
3375 ///
3376 /// By default, performs semantic analysis to build the new expression.
3377 /// Subclasses may override this routine to provide different behavior.
3379 Expr *Operand, SourceLocation RParenLoc) {
3380 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3381 }
3382
3383 /// Build a new C++ "this" expression.
3384 ///
3385 /// By default, performs semantic analysis to build a new "this" expression.
3386 /// Subclasses may override this routine to provide different behavior.
3388 QualType ThisType,
3389 bool isImplicit) {
3390 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3391 return ExprError();
3392 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3393 }
3394
3395 /// Build a new C++ throw expression.
3396 ///
3397 /// By default, performs semantic analysis to build the new expression.
3398 /// Subclasses may override this routine to provide different behavior.
3400 bool IsThrownVariableInScope) {
3401 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3402 }
3403
3404 /// Build a new C++ default-argument expression.
3405 ///
3406 /// By default, builds a new default-argument expression, which does not
3407 /// require any semantic analysis. Subclasses may override this routine to
3408 /// provide different behavior.
3410 Expr *RewrittenExpr) {
3411 return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param,
3412 RewrittenExpr, getSema().CurContext);
3413 }
3414
3415 /// Build a new C++11 default-initialization expression.
3416 ///
3417 /// By default, builds a new default field initialization expression, which
3418 /// does not require any semantic analysis. Subclasses may override this
3419 /// routine to provide different behavior.
3421 FieldDecl *Field) {
3422 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3423 }
3424
3425 /// Build a new C++ zero-initialization expression.
3426 ///
3427 /// By default, performs semantic analysis to build the new expression.
3428 /// Subclasses may override this routine to provide different behavior.
3430 SourceLocation LParenLoc,
3431 SourceLocation RParenLoc) {
3432 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3433 /*ListInitialization=*/false);
3434 }
3435
3436 /// Build a new C++ "new" expression.
3437 ///
3438 /// By default, performs semantic analysis to build the new expression.
3439 /// Subclasses may override this routine to provide different behavior.
3441 SourceLocation PlacementLParen,
3442 MultiExprArg PlacementArgs,
3443 SourceLocation PlacementRParen,
3444 SourceRange TypeIdParens, QualType AllocatedType,
3445 TypeSourceInfo *AllocatedTypeInfo,
3446 std::optional<Expr *> ArraySize,
3447 SourceRange DirectInitRange, Expr *Initializer) {
3448 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3449 PlacementLParen,
3450 PlacementArgs,
3451 PlacementRParen,
3452 TypeIdParens,
3453 AllocatedType,
3454 AllocatedTypeInfo,
3455 ArraySize,
3456 DirectInitRange,
3457 Initializer);
3458 }
3459
3460 /// Build a new C++ "delete" expression.
3461 ///
3462 /// By default, performs semantic analysis to build the new expression.
3463 /// Subclasses may override this routine to provide different behavior.
3465 bool IsGlobalDelete,
3466 bool IsArrayForm,
3467 Expr *Operand) {
3468 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3469 Operand);
3470 }
3471
3472 /// Build a new type trait expression.
3473 ///
3474 /// By default, performs semantic analysis to build the new expression.
3475 /// Subclasses may override this routine to provide different behavior.
3477 SourceLocation StartLoc,
3479 SourceLocation RParenLoc) {
3480 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3481 }
3482
3483 /// Build a new array type trait expression.
3484 ///
3485 /// By default, performs semantic analysis to build the new expression.
3486 /// Subclasses may override this routine to provide different behavior.
3488 SourceLocation StartLoc,
3489 TypeSourceInfo *TSInfo,
3490 Expr *DimExpr,
3491 SourceLocation RParenLoc) {
3492 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3493 }
3494
3495 /// Build a new expression trait expression.
3496 ///
3497 /// By default, performs semantic analysis to build the new expression.
3498 /// Subclasses may override this routine to provide different behavior.
3500 SourceLocation StartLoc,
3501 Expr *Queried,
3502 SourceLocation RParenLoc) {
3503 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3504 }
3505
3506 /// Build a new (previously unresolved) declaration reference
3507 /// expression.
3508 ///
3509 /// By default, performs semantic analysis to build the new expression.
3510 /// Subclasses may override this routine to provide different behavior.
3512 NestedNameSpecifierLoc QualifierLoc,
3513 SourceLocation TemplateKWLoc,
3514 const DeclarationNameInfo &NameInfo,
3515 const TemplateArgumentListInfo *TemplateArgs,
3516 bool IsAddressOfOperand,
3517 TypeSourceInfo **RecoveryTSI) {
3518 CXXScopeSpec SS;
3519 SS.Adopt(QualifierLoc);
3520
3521 if (TemplateArgs || TemplateKWLoc.isValid())
3523 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3524
3526 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3527 }
3528
3529 /// Build a new template-id expression.
3530 ///
3531 /// By default, performs semantic analysis to build the new expression.
3532 /// Subclasses may override this routine to provide different behavior.
3534 SourceLocation TemplateKWLoc,
3535 LookupResult &R,
3536 bool RequiresADL,
3537 const TemplateArgumentListInfo *TemplateArgs) {
3538 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3539 TemplateArgs);
3540 }
3541
3542 /// Build a new object-construction expression.
3543 ///
3544 /// By default, performs semantic analysis to build the new expression.
3545 /// Subclasses may override this routine to provide different behavior.
3548 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3549 bool ListInitialization, bool StdInitListInitialization,
3550 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3551 SourceRange ParenRange) {
3552 // Reconstruct the constructor we originally found, which might be
3553 // different if this is a call to an inherited constructor.
3554 CXXConstructorDecl *FoundCtor = Constructor;
3555 if (Constructor->isInheritingConstructor())
3556 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3557
3558 SmallVector<Expr *, 8> ConvertedArgs;
3559 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3560 ConvertedArgs))
3561 return ExprError();
3562
3563 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3564 IsElidable,
3565 ConvertedArgs,
3566 HadMultipleCandidates,
3567 ListInitialization,
3568 StdInitListInitialization,
3569 RequiresZeroInit, ConstructKind,
3570 ParenRange);
3571 }
3572
3573 /// Build a new implicit construction via inherited constructor
3574 /// expression.
3576 CXXConstructorDecl *Constructor,
3577 bool ConstructsVBase,
3578 bool InheritedFromVBase) {
3580 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3581 }
3582
3583 /// Build a new object-construction expression.
3584 ///
3585 /// By default, performs semantic analysis to build the new expression.
3586 /// Subclasses may override this routine to provide different behavior.
3588 SourceLocation LParenOrBraceLoc,
3589 MultiExprArg Args,
3590 SourceLocation RParenOrBraceLoc,
3591 bool ListInitialization) {
3593 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3594 }
3595
3596 /// Build a new object-construction expression.
3597 ///
3598 /// By default, performs semantic analysis to build the new expression.
3599 /// Subclasses may override this routine to provide different behavior.
3601 SourceLocation LParenLoc,
3602 MultiExprArg Args,
3603 SourceLocation RParenLoc,
3604 bool ListInitialization) {
3605 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3606 RParenLoc, ListInitialization);
3607 }
3608
3609 /// Build a new member reference expression.
3610 ///
3611 /// By default, performs semantic analysis to build the new expression.
3612 /// Subclasses may override this routine to provide different behavior.
3614 QualType BaseType,
3615 bool IsArrow,
3616 SourceLocation OperatorLoc,
3617 NestedNameSpecifierLoc QualifierLoc,
3618 SourceLocation TemplateKWLoc,
3619 NamedDecl *FirstQualifierInScope,
3620 const DeclarationNameInfo &MemberNameInfo,
3621 const TemplateArgumentListInfo *TemplateArgs) {
3622 CXXScopeSpec SS;
3623 SS.Adopt(QualifierLoc);
3624
3625 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3626 OperatorLoc, IsArrow,
3627 SS, TemplateKWLoc,
3628 FirstQualifierInScope,
3629 MemberNameInfo,
3630 TemplateArgs, /*S*/nullptr);
3631 }
3632
3633 /// Build a new member reference expression.
3634 ///
3635 /// By default, performs semantic analysis to build the new expression.
3636 /// Subclasses may override this routine to provide different behavior.
3638 SourceLocation OperatorLoc,
3639 bool IsArrow,
3640 NestedNameSpecifierLoc QualifierLoc,
3641 SourceLocation TemplateKWLoc,
3642 NamedDecl *FirstQualifierInScope,
3643 LookupResult &R,
3644 const TemplateArgumentListInfo *TemplateArgs) {
3645 CXXScopeSpec SS;
3646 SS.Adopt(QualifierLoc);
3647
3648 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3649 OperatorLoc, IsArrow,
3650 SS, TemplateKWLoc,
3651 FirstQualifierInScope,
3652 R, TemplateArgs, /*S*/nullptr);
3653 }
3654
3655 /// Build a new noexcept expression.
3656 ///
3657 /// By default, performs semantic analysis to build the new expression.
3658 /// Subclasses may override this routine to provide different behavior.
3660 return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd());
3661 }
3662
3663 /// Build a new expression to compute the length of a parameter pack.
3665 SourceLocation PackLoc,
3666 SourceLocation RParenLoc,
3667 std::optional<unsigned> Length,
3668 ArrayRef<TemplateArgument> PartialArgs) {
3669 return SizeOfPackExpr::Create(SemaRef.Context, OperatorLoc, Pack, PackLoc,
3670 RParenLoc, Length, PartialArgs);
3671 }
3672
3674 SourceLocation RSquareLoc,
3675 Expr *PackIdExpression, Expr *IndexExpr,
3676 ArrayRef<Expr *> ExpandedExprs,
3677 bool FullySubstituted = false) {
3678 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3679 IndexExpr, RSquareLoc, ExpandedExprs,
3680 FullySubstituted);
3681 }
3682
3684 QualType T,
3685 ArrayRef<Expr *> Exprs) {
3687 Exprs);
3688 }
3689
3690 /// Build a new expression representing a call to a source location
3691 /// builtin.
3692 ///
3693 /// By default, performs semantic analysis to build the new expression.
3694 /// Subclasses may override this routine to provide different behavior.
3696 SourceLocation BuiltinLoc,
3697 SourceLocation RPLoc,
3698 DeclContext *ParentContext) {
3699 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3700 ParentContext);
3701 }
3702
3703 /// Build a new Objective-C boxed expression.
3704 ///
3705 /// By default, performs semantic analysis to build the new expression.
3706 /// Subclasses may override this routine to provide different behavior.
3708 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3709 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3711 CXXScopeSpec SS;
3712 SS.Adopt(NNS);
3713 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3714 ConceptNameInfo,
3715 FoundDecl,
3716 NamedConcept, TALI);
3717 if (Result.isInvalid())
3718 return ExprError();
3719 return Result;
3720 }
3721
3722 /// \brief Build a new requires expression.
3723 ///
3724 /// By default, performs semantic analysis to build the new expression.
3725 /// Subclasses may override this routine to provide different behavior.
3728 SourceLocation LParenLoc,
3729 ArrayRef<ParmVarDecl *> LocalParameters,
3730 SourceLocation RParenLoc,
3732 SourceLocation ClosingBraceLoc) {
3733 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3734 LocalParameters, RParenLoc, Requirements,
3735 ClosingBraceLoc);
3736 }
3737
3741 return SemaRef.BuildTypeRequirement(SubstDiag);
3742 }
3743
3746 }
3747
3750 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3751 SourceLocation NoexceptLoc,
3753 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
3754 std::move(Ret));
3755 }
3756
3758 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3760 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
3761 std::move(Ret));
3762 }
3763
3765 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3766 const ASTConstraintSatisfaction &Satisfaction) {
3767 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3768 Satisfaction);
3769 }
3770
3772 return SemaRef.BuildNestedRequirement(Constraint);
3773 }
3774
3775 /// \brief Build a new Objective-C boxed expression.
3776 ///
3777 /// By default, performs semantic analysis to build the new expression.
3778 /// Subclasses may override this routine to provide different behavior.
3780 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3781 }
3782
3783 /// Build a new Objective-C array literal.
3784 ///
3785 /// By default, performs semantic analysis to build the new expression.
3786 /// Subclasses may override this routine to provide different behavior.
3788 Expr **Elements, unsigned NumElements) {
3790 Range, MultiExprArg(Elements, NumElements));
3791 }
3792
3794 Expr *Base, Expr *Key,
3795 ObjCMethodDecl *getterMethod,
3796 ObjCMethodDecl *setterMethod) {
3798 RB, Base, Key, getterMethod, setterMethod);
3799 }
3800
3801 /// Build a new Objective-C dictionary literal.
3802 ///
3803 /// By default, performs semantic analysis to build the new expression.
3804 /// Subclasses may override this routine to provide different behavior.
3807 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3808 }
3809
3810 /// Build a new Objective-C \@encode expression.
3811 ///
3812 /// By default, performs semantic analysis to build the new expression.
3813 /// Subclasses may override this routine to provide different behavior.
3815 TypeSourceInfo *EncodeTypeInfo,
3816 SourceLocation RParenLoc) {
3817 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
3818 RParenLoc);
3819 }
3820
3821 /// Build a new Objective-C class message.
3823 Selector Sel,
3824 ArrayRef<SourceLocation> SelectorLocs,
3825 ObjCMethodDecl *Method,
3826 SourceLocation LBracLoc,
3827 MultiExprArg Args,
3828 SourceLocation RBracLoc) {
3830 ReceiverTypeInfo, ReceiverTypeInfo->getType(),
3831 /*SuperLoc=*/SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3832 RBracLoc, Args);
3833 }
3834
3835 /// Build a new Objective-C instance message.
3837 Selector Sel,
3838 ArrayRef<SourceLocation> SelectorLocs,
3839 ObjCMethodDecl *Method,
3840 SourceLocation LBracLoc,
3841 MultiExprArg Args,
3842 SourceLocation RBracLoc) {
3843 return SemaRef.ObjC().BuildInstanceMessage(Receiver, Receiver->getType(),
3844 /*SuperLoc=*/SourceLocation(),
3845 Sel, Method, LBracLoc,
3846 SelectorLocs, RBracLoc, Args);
3847 }
3848
3849 /// Build a new Objective-C instance/class message to 'super'.
3851 Selector Sel,
3852 ArrayRef<SourceLocation> SelectorLocs,
3853 QualType SuperType,
3854 ObjCMethodDecl *Method,
3855 SourceLocation LBracLoc,
3856 MultiExprArg Args,
3857 SourceLocation RBracLoc) {
3858 return Method->isInstanceMethod()
3860 nullptr, SuperType, SuperLoc, Sel, Method, LBracLoc,
3861 SelectorLocs, RBracLoc, Args)
3862 : SemaRef.ObjC().BuildClassMessage(nullptr, SuperType, SuperLoc,
3863 Sel, Method, LBracLoc,
3864 SelectorLocs, RBracLoc, Args);
3865 }
3866
3867 /// Build a new Objective-C ivar reference expression.
3868 ///
3869 /// By default, performs semantic analysis to build the new expression.
3870 /// Subclasses may override this routine to provide different behavior.
3872 SourceLocation IvarLoc,
3873 bool IsArrow, bool IsFreeIvar) {
3874 CXXScopeSpec SS;
3875 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3877 BaseArg, BaseArg->getType(),
3878 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3879 /*FirstQualifierInScope=*/nullptr, NameInfo,
3880 /*TemplateArgs=*/nullptr,
3881 /*S=*/nullptr);
3882 if (IsFreeIvar && Result.isUsable())
3883 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
3884 return Result;
3885 }
3886
3887 /// Build a new Objective-C property reference expression.
3888 ///
3889 /// By default, performs semantic analysis to build the new expression.
3890 /// Subclasses may override this routine to provide different behavior.
3893 SourceLocation PropertyLoc) {
3894 CXXScopeSpec SS;
3895 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3896 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3897 /*FIXME:*/PropertyLoc,
3898 /*IsArrow=*/false,
3899 SS, SourceLocation(),
3900 /*FirstQualifierInScope=*/nullptr,
3901 NameInfo,
3902 /*TemplateArgs=*/nullptr,
3903 /*S=*/nullptr);
3904 }
3905
3906 /// Build a new Objective-C property reference expression.
3907 ///
3908 /// By default, performs semantic analysis to build the new expression.
3909 /// Subclasses may override this routine to provide different behavior.
3911 ObjCMethodDecl *Getter,
3912 ObjCMethodDecl *Setter,
3913 SourceLocation PropertyLoc) {
3914 // Since these expressions can only be value-dependent, we do not
3915 // need to perform semantic analysis again.
3916 return Owned(
3917 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3919 PropertyLoc, Base));
3920 }
3921
3922 /// Build a new Objective-C "isa" expression.
3923 ///
3924 /// By default, performs semantic analysis to build the new expression.
3925 /// Subclasses may override this routine to provide different behavior.
3927 SourceLocation OpLoc, bool IsArrow) {
3928 CXXScopeSpec SS;
3929 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3930 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3931 OpLoc, IsArrow,
3932 SS, SourceLocation(),
3933 /*FirstQualifierInScope=*/nullptr,
3934 NameInfo,
3935 /*TemplateArgs=*/nullptr,
3936 /*S=*/nullptr);
3937 }
3938
3939 /// Build a new shuffle vector expression.
3940 ///
3941 /// By default, performs semantic analysis to build the new expression.
3942 /// Subclasses may override this routine to provide different behavior.
3944 MultiExprArg SubExprs,
3945 SourceLocation RParenLoc) {
3946 // Find the declaration for __builtin_shufflevector
3947 const IdentifierInfo &Name
3948 = SemaRef.Context.Idents.get("__builtin_shufflevector");
3950 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
3951 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3952
3953 // Build a reference to the __builtin_shufflevector builtin
3954 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
3955 Expr *Callee = new (SemaRef.Context)
3956 DeclRefExpr(SemaRef.Context, Builtin, false,
3957 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3958 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
3959 Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
3960 CK_BuiltinFnToFnPtr).get();
3961
3962 // Build the CallExpr
3963 ExprResult TheCall = CallExpr::Create(
3964 SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
3965 Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc,
3967
3968 // Type-check the __builtin_shufflevector expression.
3969 return SemaRef.BuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
3970 }
3971
3972 /// Build a new convert vector expression.
3974 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3975 SourceLocation RParenLoc) {
3976 return SemaRef.ConvertVectorExpr(SrcExpr, DstTInfo, BuiltinLoc, RParenLoc);
3977 }
3978
3979 /// Build a new template argument pack expansion.
3980 ///
3981 /// By default, performs semantic analysis to build a new pack expansion
3982 /// for a template argument. Subclasses may override this routine to provide
3983 /// different behavior.
3986 std::optional<unsigned> NumExpansions) {
3987 switch (Pattern.getArgument().getKind()) {
3991 EllipsisLoc, NumExpansions);
3992 if (Result.isInvalid())
3993 return TemplateArgumentLoc();
3994
3995 return TemplateArgumentLoc(Result.get(), Result.get());
3996 }
3997
3999 return TemplateArgumentLoc(
4002 NumExpansions),
4003 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
4004 EllipsisLoc);
4005
4013 llvm_unreachable("Pack expansion pattern has no parameter packs");
4014
4016 if (TypeSourceInfo *Expansion
4017 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4018 EllipsisLoc,
4019 NumExpansions))
4020 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4021 Expansion);
4022 break;
4023 }
4024
4025 return TemplateArgumentLoc();
4026 }
4027
4028 /// Build a new expression pack expansion.
4029 ///
4030 /// By default, performs semantic analysis to build a new pack expansion
4031 /// for an expression. Subclasses may override this routine to provide
4032 /// different behavior.
4034 std::optional<unsigned> NumExpansions) {
4035 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4036 }
4037
4038 /// Build a new C++1z fold-expression.
4039 ///
4040 /// By default, performs semantic analysis in order to build a new fold
4041 /// expression.
4043 SourceLocation LParenLoc, Expr *LHS,
4044 BinaryOperatorKind Operator,
4045 SourceLocation EllipsisLoc, Expr *RHS,
4046 SourceLocation RParenLoc,
4047 std::optional<unsigned> NumExpansions) {
4048 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4049 EllipsisLoc, RHS, RParenLoc,
4050 NumExpansions);
4051 }
4052
4054 LambdaScopeInfo *LSI) {
4055 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4056 if (Expr *Init = PVD->getInit())
4058 Init->containsUnexpandedParameterPack();
4059 else if (PVD->hasUninstantiatedDefaultArg())
4061 PVD->getUninstantiatedDefaultArg()
4062 ->containsUnexpandedParameterPack();
4063 }
4064 return getSema().BuildLambdaExpr(StartLoc, EndLoc, LSI);
4065 }
4066
4067 /// Build an empty C++1z fold-expression with the given operator.
4068 ///
4069 /// By default, produces the fallback value for the fold-expression, or
4070 /// produce an error if there is no fallback value.
4072 BinaryOperatorKind Operator) {
4073 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4074 }
4075
4076 /// Build a new atomic operation expression.
4077 ///
4078 /// By default, performs semantic analysis to build the new expression.
4079 /// Subclasses may override this routine to provide different behavior.
4082 SourceLocation RParenLoc) {
4083 // Use this for all of the locations, since we don't know the difference
4084 // between the call and the expr at this point.
4085 SourceRange Range{BuiltinLoc, RParenLoc};
4086 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4088 }
4089
4091 ArrayRef<Expr *> SubExprs, QualType Type) {
4092 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4093 }
4094
4096 SourceLocation BeginLoc,
4097 SourceLocation DirLoc,
4098 SourceLocation EndLoc,
4100 StmtResult StrBlock) {
4102 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4103 SourceLocation{}, EndLoc, Clauses, StrBlock);
4104 }
4105
4107 SourceLocation DirLoc,
4108 SourceLocation EndLoc,
4110 StmtResult Loop) {
4112 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4113 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, Loop);
4114 }
4115
4117 SourceLocation BeginLoc,
4118 SourceLocation DirLoc,
4119 SourceLocation EndLoc,
4121 StmtResult Loop) {
4123 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4124 SourceLocation{}, EndLoc, Clauses, Loop);
4125 }
4126
4128 SourceLocation DirLoc,
4129 SourceLocation EndLoc,
4131 StmtResult StrBlock) {
4133 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4134 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, StrBlock);
4135 }
4136
4139 SourceLocation DirLoc, SourceLocation EndLoc,
4140 ArrayRef<OpenACCClause *> Clauses) {
4143 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
4144 }
4145
4148 SourceLocation DirLoc, SourceLocation EndLoc,
4149 ArrayRef<OpenACCClause *> Clauses) {
4152 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
4153 }
4154
4156 SourceLocation DirLoc,
4157 SourceLocation EndLoc,
4159 StmtResult StrBlock) {
4162 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, StrBlock);
4163 }
4164
4166 SourceLocation DirLoc,
4167 SourceLocation EndLoc,
4168 ArrayRef<OpenACCClause *> Clauses) {
4170 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4171 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
4172 }
4173
4176 SourceLocation DirLoc, SourceLocation EndLoc,
4177 ArrayRef<OpenACCClause *> Clauses) {
4180 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
4181 }
4182
4184 SourceLocation DirLoc,
4185 SourceLocation EndLoc,
4186 ArrayRef<OpenACCClause *> Clauses) {
4188 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4189 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
4190 }
4191
4193 SourceLocation DirLoc,
4194 SourceLocation EndLoc,
4195 ArrayRef<OpenACCClause *> Clauses) {
4197 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4198 SourceLocation{}, {}, SourceLocation{}, EndLoc, Clauses, {});
4199 }
4200
4202 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4203 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4204 SourceLocation RParenLoc, SourceLocation EndLoc,
4205 ArrayRef<OpenACCClause *> Clauses) {
4207 Exprs.push_back(DevNumExpr);
4208 Exprs.insert(Exprs.end(), QueueIdExprs.begin(), QueueIdExprs.end());
4210 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4211 Exprs, RParenLoc, EndLoc, Clauses, {});
4212 }
4213
4215 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4216 }
4217
4218private:
4219 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
4220 QualType ObjectType,
4221 NamedDecl *FirstQualifierInScope,
4222 CXXScopeSpec &SS);
4223
4224 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4225 QualType ObjectType,
4226 NamedDecl *FirstQualifierInScope,
4227 CXXScopeSpec &SS);
4228
4229 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
4230 NamedDecl *FirstQualifierInScope,
4231 CXXScopeSpec &SS);
4232
4233 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4235 bool DeducibleTSTContext);
4236
4238 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4240
4242 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4243 OpenACCDirectiveKind DirKind,
4244 const OpenACCClause *OldClause);
4245};
4246
4247template <typename Derived>
4249 if (!S)
4250 return S;
4251
4252 switch (S->getStmtClass()) {
4253 case Stmt::NoStmtClass: break;
4254
4255 // Transform individual statement nodes
4256 // Pass SDK into statements that can produce a value
4257#define STMT(Node, Parent) \
4258 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4259#define VALUESTMT(Node, Parent) \
4260 case Stmt::Node##Class: \
4261 return getDerived().Transform##Node(cast<Node>(S), SDK);
4262#define ABSTRACT_STMT(Node)
4263#define EXPR(Node, Parent)
4264#include "clang/AST/StmtNodes.inc"
4265
4266 // Transform expressions by calling TransformExpr.
4267#define STMT(Node, Parent)
4268#define ABSTRACT_STMT(Stmt)
4269#define EXPR(Node, Parent) case Stmt::Node##Class:
4270#include "clang/AST/StmtNodes.inc"
4271 {
4272 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
4273
4274 if (SDK == SDK_StmtExprResult)
4275 E = getSema().ActOnStmtExprResult(E);
4276 return getSema().ActOnExprStmt(E, SDK == SDK_Discarded);
4277 }
4278 }
4279
4280 return S;
4281}
4282
4283template<typename Derived>
4285 if (!S)
4286 return S;
4287
4288 switch (S->getClauseKind()) {
4289 default: break;
4290 // Transform individual clause nodes
4291#define GEN_CLANG_CLAUSE_CLASS
4292#define CLAUSE_CLASS(Enum, Str, Class) \
4293 case Enum: \
4294 return getDerived().Transform##Class(cast<Class>(S));
4295#include "llvm/Frontend/OpenMP/OMP.inc"
4296 }
4297
4298 return S;
4299}
4300
4301
4302template<typename Derived>
4304 if (!E)
4305 return E;
4306
4307 switch (E->getStmtClass()) {
4308 case Stmt::NoStmtClass: break;
4309#define STMT(Node, Parent) case Stmt::Node##Class: break;
4310#define ABSTRACT_STMT(Stmt)
4311#define EXPR(Node, Parent) \
4312 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4313#include "clang/AST/StmtNodes.inc"
4314 }
4315
4316 return E;
4317}
4318
4319template<typename Derived>
4321 bool NotCopyInit) {
4322 // Initializers are instantiated like expressions, except that various outer
4323 // layers are stripped.
4324 if (!Init)
4325 return Init;
4326
4327 if (auto *FE = dyn_cast<FullExpr>(Init))
4328 Init = FE->getSubExpr();
4329
4330 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {
4331 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4332 Init = OVE->getSourceExpr();
4333 }
4334
4335 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
4336 Init = MTE->getSubExpr();
4337
4338 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
4339 Init = Binder->getSubExpr();
4340
4341 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
4342 Init = ICE->getSubExprAsWritten();
4343
4344 if (CXXStdInitializerListExpr *ILE =
4345 dyn_cast<CXXStdInitializerListExpr>(Init))
4346 return TransformInitializer(ILE->getSubExpr(), NotCopyInit);
4347
4348 // If this is copy-initialization, we only need to reconstruct
4349 // InitListExprs. Other forms of copy-initialization will be a no-op if
4350 // the initializer is already the right type.
4351 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
4352 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4353 return getDerived().TransformExpr(Init);
4354
4355 // Revert value-initialization back to empty parens.
4356 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
4357 SourceRange Parens = VIE->getSourceRange();
4358 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4359 Parens.getEnd());
4360 }
4361
4362 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4363 if (isa<ImplicitValueInitExpr>(Init))
4364 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4365 SourceLocation());
4366
4367 // Revert initialization by constructor back to a parenthesized or braced list
4368 // of expressions. Any other form of initializer can just be reused directly.
4369 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
4370 return getDerived().TransformExpr(Init);
4371
4372 // If the initialization implicitly converted an initializer list to a
4373 // std::initializer_list object, unwrap the std::initializer_list too.
4374 if (Construct && Construct->isStdInitListInitialization())
4375 return TransformInitializer(Construct->getArg(0), NotCopyInit);
4376
4377 // Enter a list-init context if this was list initialization.
4380 Construct->isListInitialization());
4381
4382 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4383 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4384 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4385 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4386 SmallVector<Expr*, 8> NewArgs;
4387 bool ArgChanged = false;
4388 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4389 /*IsCall*/true, NewArgs, &ArgChanged))
4390 return ExprError();
4391
4392 // If this was list initialization, revert to syntactic list form.
4393 if (Construct->isListInitialization())
4394 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4395 Construct->getEndLoc());
4396
4397 // Build a ParenListExpr to represent anything else.
4399 if (Parens.isInvalid()) {
4400 // This was a variable declaration's initialization for which no initializer
4401 // was specified.
4402 assert(NewArgs.empty() &&
4403 "no parens or braces but have direct init with arguments?");
4404 return ExprEmpty();
4405 }
4406 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4407 Parens.getEnd());
4408}
4409
4410template<typename Derived>
4412 unsigned NumInputs,
4413 bool IsCall,
4414 SmallVectorImpl<Expr *> &Outputs,
4415 bool *ArgChanged) {
4416 for (unsigned I = 0; I != NumInputs; ++I) {
4417 // If requested, drop call arguments that need to be dropped.
4418 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4419 if (ArgChanged)
4420 *ArgChanged = true;
4421
4422 break;
4423 }
4424
4425 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
4426 Expr *Pattern = Expansion->getPattern();
4427
4429 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4430 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4431
4432 // Determine whether the set of unexpanded parameter packs can and should
4433 // be expanded.
4434 bool Expand = true;
4435 bool RetainExpansion = false;
4436 std::optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions();
4437 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4438 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4439 Pattern->getSourceRange(),
4440 Unexpanded,
4441 Expand, RetainExpansion,
4442 NumExpansions))
4443 return true;
4444
4445 if (!Expand) {
4446 // The transform has determined that we should perform a simple
4447 // transformation on the pack expansion, producing another pack
4448 // expansion.
4449 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4450 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4451 if (OutPattern.isInvalid())
4452 return true;
4453
4454 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4455 Expansion->getEllipsisLoc(),
4456 NumExpansions);
4457 if (Out.isInvalid())
4458 return true;
4459
4460 if (ArgChanged)
4461 *ArgChanged = true;
4462 Outputs.push_back(Out.get());
4463 continue;
4464 }
4465
4466 // Record right away that the argument was changed. This needs
4467 // to happen even if the array expands to nothing.
4468 if (ArgChanged) *ArgChanged = true;
4469
4470 // The transform has determined that we should perform an elementwise
4471 // expansion of the pattern. Do so.
4472 for (unsigned I = 0; I != *NumExpansions; ++I) {
4473 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4474 ExprResult Out = getDerived().TransformExpr(Pattern);
4475 if (Out.isInvalid())
4476 return true;
4477
4478 if (Out.get()->containsUnexpandedParameterPack()) {
4479 Out = getDerived().RebuildPackExpansion(
4480 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4481 if (Out.isInvalid())
4482 return true;
4483 }
4484
4485 Outputs.push_back(Out.get());
4486 }
4487
4488 // If we're supposed to retain a pack expansion, do so by temporarily
4489 // forgetting the partially-substituted parameter pack.
4490 if (RetainExpansion) {
4491 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4492
4493 ExprResult Out = getDerived().TransformExpr(Pattern);
4494 if (Out.isInvalid())
4495 return true;
4496
4497 Out = getDerived().RebuildPackExpansion(
4498 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4499 if (Out.isInvalid())
4500 return true;
4501
4502 Outputs.push_back(Out.get());
4503 }
4504
4505 continue;
4506 }
4507
4509 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4510 : getDerived().TransformExpr(Inputs[I]);
4511 if (Result.isInvalid())
4512 return true;
4513
4514 if (Result.get() != Inputs[I] && ArgChanged)
4515 *ArgChanged = true;
4516
4517 Outputs.push_back(Result.get());
4518 }
4519
4520 return false;
4521}
4522
4523template <typename Derived>
4526 if (Var) {
4527 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4528 getDerived().TransformDefinition(Var->getLocation(), Var));
4529
4530 if (!ConditionVar)
4531 return Sema::ConditionError();
4532
4533 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4534 }
4535
4536 if (Expr) {
4537 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4538
4539 if (CondExpr.isInvalid())
4540 return Sema::ConditionError();
4541
4542 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4543 /*MissingOK=*/true);
4544 }
4545
4546 return Sema::ConditionResult();
4547}
4548
4549template <typename Derived>
4551 NestedNameSpecifierLoc NNS, QualType ObjectType,
4552 NamedDecl *FirstQualifierInScope) {
4554
4555 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4556 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4557 Qualifier = Qualifier.getPrefix())
4558 Qualifiers.push_back(Qualifier);
4559 };
4560 insertNNS(NNS);
4561
4562 CXXScopeSpec SS;
4563 while (!Qualifiers.empty()) {
4564 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4566
4567 switch (QNNS->getKind()) {
4571 ObjectType);
4572 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false,
4573 SS, FirstQualifierInScope, false))
4574 return NestedNameSpecifierLoc();
4575 break;
4576 }
4577
4579 NamespaceDecl *NS =
4580 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4581 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4582 SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
4583 break;
4584 }
4585
4587 NamespaceAliasDecl *Alias =
4588 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4590 SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
4591 Q.getLocalEndLoc());
4592 break;
4593 }
4594
4596 // There is no meaningful transformation that one could perform on the
4597 // global scope.
4598 SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
4599 break;
4600
4602 CXXRecordDecl *RD =
4603 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4604 SourceLocation(), QNNS->getAsRecordDecl()));
4605 SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc());
4606 break;
4607 }
4608
4611 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4612 FirstQualifierInScope, SS);
4613
4614 if (!TL)
4615 return NestedNameSpecifierLoc();
4616
4617 QualType T = TL.getType();
4618 if (T->isDependentType() || T->isRecordType() ||
4619 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4620 if (T->isEnumeralType())
4621 SemaRef.Diag(TL.getBeginLoc(),
4622 diag::warn_cxx98_compat_enum_nested_name_spec);
4623
4624 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4625 SS.Adopt(ETL.getQualifierLoc());
4626 TL = ETL.getNamedTypeLoc();
4627 }
4628
4629 SS.Extend(SemaRef.Context, TL.getTemplateKeywordLoc(), TL,
4630 Q.getLocalEndLoc());
4631 break;
4632 }
4633 // If the nested-name-specifier is an invalid type def, don't emit an
4634 // error because a previous error should have already been emitted.
4636 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4637 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
4638 << T << SS.getRange();
4639 }
4640 return NestedNameSpecifierLoc();
4641 }
4642 }
4643
4644 // The qualifier-in-scope and object type only apply to the leftmost entity.
4645 FirstQualifierInScope = nullptr;
4646 ObjectType = QualType();
4647 }
4648
4649 // Don't rebuild the nested-name-specifier if we don't have to.
4650 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4651 !getDerived().AlwaysRebuild())
4652 return NNS;
4653
4654 // If we can re-use the source-location data from the original
4655 // nested-name-specifier, do so.
4656 if (SS.location_size() == NNS.getDataLength() &&
4657 memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)
4659
4660 // Allocate new nested-name-specifier location information.
4661 return SS.getWithLocInContext(SemaRef.Context);
4662}
4663
4664template<typename Derived>
4668 DeclarationName Name = NameInfo.getName();
4669 if (!Name)
4670 return DeclarationNameInfo();
4671
4672 switch (Name.getNameKind()) {
4680 return NameInfo;
4681
4683 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4684 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4685 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4686 if (!NewTemplate)
4687 return DeclarationNameInfo();
4688
4689 DeclarationNameInfo NewNameInfo(NameInfo);
4690 NewNameInfo.setName(
4692 return NewNameInfo;
4693 }
4694
4698 TypeSourceInfo *NewTInfo;
4699 CanQualType NewCanTy;
4700 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4701 NewTInfo = getDerived().TransformType(OldTInfo);
4702 if (!NewTInfo)
4703 return DeclarationNameInfo();
4704 NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
4705 }
4706 else {
4707 NewTInfo = nullptr;
4708 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4709 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4710 if (NewT.isNull())
4711 return DeclarationNameInfo();
4712 NewCanTy = SemaRef.Context.getCanonicalType(NewT);
4713 }
4714
4715 DeclarationName NewName
4716 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
4717 NewCanTy);
4718 DeclarationNameInfo NewNameInfo(NameInfo);
4719 NewNameInfo.setName(NewName);
4720 NewNameInfo.setNamedTypeInfo(NewTInfo);
4721 return NewNameInfo;
4722 }
4723 }
4724
4725 llvm_unreachable("Unknown name kind.");
4726}
4727
4728template<typename Derived>
4731 TemplateName Name,
4732 SourceLocation NameLoc,
4733 QualType ObjectType,
4734 NamedDecl *FirstQualifierInScope,
4735 bool AllowInjectedClassName) {
4736 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4737 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4738 assert(Template && "qualified template name must refer to a template");
4739
4740 TemplateDecl *TransTemplate
4741 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4742 Template));
4743 if (!TransTemplate)
4744 return TemplateName();
4745
4746 if (!getDerived().AlwaysRebuild() &&
4747 SS.getScopeRep() == QTN->getQualifier() &&
4748 TransTemplate == Template)
4749 return Name;
4750
4751 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4752 TransTemplate);
4753 }
4754
4755 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4756 if (SS.getScopeRep()) {
4757 // These apply to the scope specifier, not the template.
4758 ObjectType = QualType();
4759 FirstQualifierInScope = nullptr;
4760 }
4761
4762 if (!getDerived().AlwaysRebuild() &&
4763 SS.getScopeRep() == DTN->getQualifier() &&
4764 ObjectType.isNull())
4765 return Name;
4766
4767 // FIXME: Preserve the location of the "template" keyword.
4768 SourceLocation TemplateKWLoc = NameLoc;
4769
4770 if (DTN->isIdentifier()) {
4771 return getDerived().RebuildTemplateName(SS,
4772 TemplateKWLoc,
4773 *DTN->getIdentifier(),
4774 NameLoc,
4775 ObjectType,
4776 FirstQualifierInScope,
4777 AllowInjectedClassName);
4778 }
4779
4780 return getDerived().RebuildTemplateName(SS, TemplateKWLoc,
4781 DTN->getOperator(), NameLoc,
4782 ObjectType, AllowInjectedClassName);
4783 }
4784
4785 // FIXME: Try to preserve more of the TemplateName.
4786 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4787 TemplateDecl *TransTemplate
4788 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4789 Template));
4790 if (!TransTemplate)
4791 return TemplateName();
4792
4793 return getDerived().RebuildTemplateName(SS, /*TemplateKeyword=*/false,
4794 TransTemplate);
4795 }
4796
4798 = Name.getAsSubstTemplateTemplateParmPack()) {
4799 return getDerived().RebuildTemplateName(
4800 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4801 SubstPack->getIndex(), SubstPack->getFinal());
4802 }
4803
4804 // These should be getting filtered out before they reach the AST.
4805 llvm_unreachable("overloaded function decl survived to here");
4806}
4807
4808template<typename Derived>
4810 const TemplateArgument &Arg,
4811 TemplateArgumentLoc &Output) {
4812 Output = getSema().getTrivialTemplateArgumentLoc(
4813 Arg, QualType(), getDerived().getBaseLocation());
4814}
4815
4816template <typename Derived>
4818 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4819 bool Uneval) {
4820 const TemplateArgument &Arg = Input.getArgument();
4821 switch (Arg.getKind()) {
4824 llvm_unreachable("Unexpected TemplateArgument");
4825
4830 // Transform a resolved template argument straight to a resolved template
4831 // argument. We get here when substituting into an already-substituted
4832 // template type argument during concept satisfaction checking.
4834 QualType NewT = getDerived().TransformType(T);
4835 if (NewT.isNull())
4836 return true;
4837
4839 ? Arg.getAsDecl()
4840 : nullptr;
4841 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4842 getDerived().getBaseLocation(), D))
4843 : nullptr;
4844 if (D && !NewD)
4845 return true;
4846
4847 if (NewT == T && D == NewD)
4848 Output = Input;
4849 else if (Arg.getKind() == TemplateArgument::Integral)
4850 Output = TemplateArgumentLoc(
4851 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4853 else if (Arg.getKind() == TemplateArgument::NullPtr)
4854 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4856 else if (Arg.getKind() == TemplateArgument::Declaration)
4857 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4860 Output = TemplateArgumentLoc(
4861 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
4863 else
4864 llvm_unreachable("unexpected template argument kind");
4865
4866 return false;
4867 }
4868
4870 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4871 if (!DI)
4872 DI = InventTypeSourceInfo(Input.getArgument().getAsType());
4873
4874 DI = getDerived().TransformType(DI);
4875 if (!DI)
4876 return true;
4877
4878 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4879 return false;
4880 }
4881
4883 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4884 if (QualifierLoc) {
4885 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4886 if (!QualifierLoc)
4887 return true;
4888 }
4889
4890 CXXScopeSpec SS;
4891 SS.Adopt(QualifierLoc);
4892 TemplateName Template = getDerived().TransformTemplateName(
4893 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4894 if (Template.isNull())
4895 return true;
4896
4897 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4898 QualifierLoc, Input.getTemplateNameLoc());
4899 return false;
4900 }
4901
4903 llvm_unreachable("Caller should expand pack expansions");
4904
4906 // Template argument expressions are constant expressions.
4908 getSema(),
4911 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4913
4914 Expr *InputExpr = Input.getSourceExpression();
4915 if (!InputExpr)
4916 InputExpr = Input.getArgument().getAsExpr();
4917
4918 ExprResult E = getDerived().TransformExpr(InputExpr);
4919 E = SemaRef.ActOnConstantExpression(E);
4920 if (E.isInvalid())
4921 return true;
4922 Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
4923 return false;
4924 }
4925 }
4926
4927 // Work around bogus GCC warning
4928 return true;
4929}
4930
4931/// Iterator adaptor that invents template argument location information
4932/// for each of the template arguments in its underlying iterator.
4933template<typename Derived, typename InputIterator>
4936 InputIterator Iter;
4937
4938public:
4941 typedef typename std::iterator_traits<InputIterator>::difference_type
4943 typedef std::input_iterator_tag iterator_category;
4944
4945 class pointer {
4947
4948 public:
4949 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4950
4951 const TemplateArgumentLoc *operator->() const { return &Arg; }
4952 };
4953
4955 InputIterator Iter)
4956 : Self(Self), Iter(Iter) { }
4957
4959 ++Iter;
4960 return *this;
4961 }
4962
4965 ++(*this);
4966 return Old;
4967 }
4968
4971 Self.InventTemplateArgumentLoc(*Iter, Result);
4972 return Result;
4973 }
4974
4975 pointer operator->() const { return pointer(**this); }
4976
4979 return X.Iter == Y.Iter;
4980 }
4981
4984 return X.Iter != Y.Iter;
4985 }
4986};
4987
4988template<typename Derived>
4989template<typename InputIterator>
4991 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
4992 bool Uneval) {
4993 for (; First != Last; ++First) {
4996
4997 if (In.getArgument().getKind() == TemplateArgument::Pack) {
4998 // Unpack argument packs, which we translate them into separate
4999 // arguments.
5000 // FIXME: We could do much better if we could guarantee that the
5001 // TemplateArgumentLocInfo for the pack expansion would be usable for
5002 // all of the template arguments in the argument pack.
5003 typedef TemplateArgumentLocInventIterator<Derived,
5005 PackLocIterator;
5006 if (TransformTemplateArguments(PackLocIterator(*this,
5007 In.getArgument().pack_begin()),
5008 PackLocIterator(*this,
5009 In.getArgument().pack_end()),
5010 Outputs, Uneval))
5011 return true;
5012
5013 continue;
5014 }
5015
5016 if (In.getArgument().isPackExpansion()) {
5017 // We have a pack expansion, for which we will be substituting into
5018 // the pattern.
5019 SourceLocation Ellipsis;
5020 std::optional<unsigned> OrigNumExpansions;
5021 TemplateArgumentLoc Pattern
5022 = getSema().getTemplateArgumentPackExpansionPattern(
5023 In, Ellipsis, OrigNumExpansions);
5024
5026 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5027 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5028
5029 // Determine whether the set of unexpanded parameter packs can and should
5030 // be expanded.
5031 bool Expand = true;
5032 bool RetainExpansion = false;
5033 std::optional<unsigned> NumExpansions = OrigNumExpansions;
5034 if (getDerived().TryExpandParameterPacks(Ellipsis,
5035 Pattern.getSourceRange(),
5036 Unexpanded,
5037 Expand,
5038 RetainExpansion,
5039 NumExpansions))
5040 return true;
5041
5042 if (!Expand) {
5043 // The transform has determined that we should perform a simple
5044 // transformation on the pack expansion, producing another pack
5045 // expansion.
5046 TemplateArgumentLoc OutPattern;
5047 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
5048 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5049 return true;
5050
5051 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
5052 NumExpansions);
5053 if (Out.getArgument().isNull())
5054 return true;
5055
5056 Outputs.addArgument(Out);
5057 continue;
5058 }
5059
5060 // The transform has determined that we should perform an elementwise
5061 // expansion of the pattern. Do so.
5062 for (unsigned I = 0; I != *NumExpansions; ++I) {
5063 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
5064
5065 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
5066 return true;
5067
5068 if (Out.getArgument().containsUnexpandedParameterPack()) {
5069 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
5070 OrigNumExpansions);
5071 if (Out.getArgument().isNull())
5072 return true;
5073 }
5074
5075 Outputs.addArgument(Out);
5076 }
5077
5078 // If we're supposed to retain a pack expansion, do so by temporarily
5079 // forgetting the partially-substituted parameter pack.
5080 if (RetainExpansion) {
5081 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5082
5083 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
5084 return true;
5085
5086 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
5087 OrigNumExpansions);
5088 if (Out.getArgument().isNull())
5089 return true;
5090
5091 Outputs.addArgument(Out);
5092 }
5093
5094 continue;
5095 }
5096
5097 // The simple case:
5098 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5099 return true;
5100
5101 Outputs.addArgument(Out);
5102 }
5103
5104 return false;
5105
5106}
5107
5108//===----------------------------------------------------------------------===//
5109// Type transformation
5110//===----------------------------------------------------------------------===//
5111
5112template<typename Derived>
5114 if (getDerived().AlreadyTransformed(T))
5115 return T;
5116
5117 // Temporary workaround. All of these transformations should
5118 // eventually turn into transformations on TypeLocs.
5119 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5120 getDerived().getBaseLocation());
5121
5122 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
5123
5124 if (!NewDI)
5125 return QualType();
5126
5127 return NewDI->getType();
5128}
5129
5130template<typename Derived>
5132 // Refine the base location to the type's location.
5133 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5134 getDerived().getBaseEntity());
5135 if (getDerived().AlreadyTransformed(DI->getType()))
5136 return DI;
5137
5138 TypeLocBuilder TLB;
5139
5140 TypeLoc TL = DI->getTypeLoc();
5141 TLB.reserve(TL.getFullDataSize());
5142
5143 QualType Result = getDerived().TransformType(TLB, TL);
5144 if (Result.isNull())
5145 return nullptr;
5146
5147 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5148}
5149
5150template<typename Derived>
5153 switch (T.getTypeLocClass()) {
5154#define ABSTRACT_TYPELOC(CLASS, PARENT)
5155#define TYPELOC(CLASS, PARENT) \
5156 case TypeLoc::CLASS: \
5157 return getDerived().Transform##CLASS##Type(TLB, \
5158 T.castAs<CLASS##TypeLoc>());
5159#include "clang/AST/TypeLocNodes.def"
5160 }
5161
5162 llvm_unreachable("unhandled type loc!");
5163}
5164
5165template<typename Derived>
5167 if (!isa<DependentNameType>(T))
5168 return TransformType(T);
5169
5170 if (getDerived().AlreadyTransformed(T))
5171 return T;
5172 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5173 getDerived().getBaseLocation());
5174 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
5175 return NewDI ? NewDI->getType() : QualType();
5176}
5177
5178template<typename Derived>
5181 if (!isa<DependentNameType>(DI->getType()))
5182 return TransformType(DI);
5183
5184 // Refine the base location to the type's location.
5185 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5186 getDerived().getBaseEntity());
5187 if (getDerived().AlreadyTransformed(DI->getType()))
5188 return DI;
5189
5190 TypeLocBuilder TLB;
5191
5192 TypeLoc TL = DI->getTypeLoc();
5193 TLB.reserve(TL.getFullDataSize());
5194
5195 auto QTL = TL.getAs<QualifiedTypeLoc>();
5196 if (QTL)
5197 TL = QTL.getUnqualifiedLoc();
5198
5199 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5200
5201 QualType Result = getDerived().TransformDependentNameType(
5202 TLB, DNTL, /*DeducedTSTContext*/true);
5203 if (Result.isNull())
5204 return nullptr;
5205
5206 if (QTL) {
5207 Result = getDerived().RebuildQualifiedType(Result, QTL);
5208 if (Result.isNull())
5209 return nullptr;
5211 }
5212
5213 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5214}
5215
5216template<typename Derived>
5221 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5222 auto SuppressObjCLifetime =
5223 T.getType().getLocalQualifiers().hasObjCLifetime();
5224 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5225 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5226 SuppressObjCLifetime);
5227 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5228 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5229 TLB, STTP, SuppressObjCLifetime);
5230 } else {
5231 Result = getDerived().TransformType(TLB, UnqualTL);
5232 }
5233
5234 if (Result.isNull())
5235 return QualType();
5236
5237 Result = getDerived().RebuildQualifiedType(Result, T);
5238
5239 if (Result.isNull())
5240 return QualType();
5241
5242 // RebuildQualifiedType might have updated the type, but not in a way
5243 // that invalidates the TypeLoc. (There's no location information for
5244 // qualifiers.)
5246
5247 return Result;
5248}
5249
5250template <typename Derived>
5252 QualifiedTypeLoc TL) {
5253
5255 Qualifiers Quals = TL.getType().getLocalQualifiers();
5256
5257 if ((T.getAddressSpace() != LangAS::Default &&
5258 Quals.getAddressSpace() != LangAS::Default) &&
5259 T.getAddressSpace() != Quals.getAddressSpace()) {
5260 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)
5261 << TL.getType() << T;
5262 return QualType();
5263 }
5264
5265 // C++ [dcl.fct]p7:
5266 // [When] adding cv-qualifications on top of the function type [...] the
5267 // cv-qualifiers are ignored.
5268 if (T->isFunctionType()) {
5270 Quals.getAddressSpace());
5271 return T;
5272 }
5273
5274 // C++ [dcl.ref]p1:
5275 // when the cv-qualifiers are introduced through the use of a typedef-name
5276 // or decltype-specifier [...] the cv-qualifiers are ignored.
5277 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5278 // applied to a reference type.
5279 if (T->isReferenceType()) {
5280 // The only qualifier that applies to a reference type is restrict.
5281 if (!Quals.hasRestrict())
5282 return T;
5284 }
5285
5286 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5287 // resulting type.
5288 if (Quals.hasObjCLifetime()) {
5289 if (!T->isObjCLifetimeType() && !T->isDependentType())
5290 Quals.removeObjCLifetime();
5291 else if (T.getObjCLifetime()) {
5292 // Objective-C ARC:
5293 // A lifetime qualifier applied to a substituted template parameter
5294 // overrides the lifetime qualifier from the template argument.
5295 const AutoType *AutoTy;
5296 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
5297 // 'auto' types behave the same way as template parameters.
5298 QualType Deduced = AutoTy->getDeducedType();
5299 Qualifiers Qs = Deduced.getQualifiers();
5300 Qs.removeObjCLifetime();
5301 Deduced =
5302 SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);
5303 T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),
5304 AutoTy->isDependentType(),
5305 /*isPack=*/false,
5306 AutoTy->getTypeConstraintConcept(),
5307 AutoTy->getTypeConstraintArguments());
5308 } else {
5309 // Otherwise, complain about the addition of a qualifier to an
5310 // already-qualified type.
5311 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5312 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
5313 Quals.removeObjCLifetime();
5314 }
5315 }
5316 }
5317
5318 return SemaRef.BuildQualifiedType(T, Loc, Quals);
5319}
5320
5321template<typename Derived>
5322TypeLoc
5324 QualType ObjectType,
5325 NamedDecl *UnqualLookup,
5326 CXXScopeSpec &SS) {
5327 if (getDerived().AlreadyTransformed(TL.getType()))
5328 return TL;
5329
5330 TypeSourceInfo *TSI =
5331 TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS);
5332 if (TSI)
5333 return TSI->getTypeLoc();
5334 return TypeLoc();
5335}
5336
5337template<typename Derived>
5338TypeSourceInfo *
5339TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5340 QualType ObjectType,
5341 NamedDecl *UnqualLookup,
5342 CXXScopeSpec &SS) {
5343 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5344 return TSInfo;
5345
5346 return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType,
5347 UnqualLookup, SS);
5348}
5349
5350template <typename Derived>
5351TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5352 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5353 CXXScopeSpec &SS) {
5354 QualType T = TL.getType();
5355 assert(!getDerived().AlreadyTransformed(T));
5356
5357 TypeLocBuilder TLB;
5358 QualType Result;
5359
5360 if (isa<TemplateSpecializationType>(T)) {
5361 TemplateSpecializationTypeLoc SpecTL =
5362 TL.castAs<TemplateSpecializationTypeLoc>();
5363
5364 TemplateName Template = getDerived().TransformTemplateName(
5365 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5366 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5367 if (Template.isNull())
5368 return nullptr;
5369
5370 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5371 Template);
5372 } else if (isa<DependentTemplateSpecializationType>(T)) {
5373 DependentTemplateSpecializationTypeLoc SpecTL =
5374 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5375
5376 TemplateName Template
5377 = getDerived().RebuildTemplateName(SS,
5378 SpecTL.getTemplateKeywordLoc(),
5379 *SpecTL.getTypePtr()->getIdentifier(),
5380 SpecTL.getTemplateNameLoc(),
5381 ObjectType, UnqualLookup,
5382 /*AllowInjectedClassName*/true);
5383 if (Template.isNull())
5384 return nullptr;
5385
5386 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5387 SpecTL,
5388 Template,
5389 SS);
5390 } else {
5391 // Nothing special needs to be done for these.
5392 Result = getDerived().TransformType(TLB, TL);
5393 }
5394
5395 if (Result.isNull())
5396 return nullptr;
5397
5398 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5399}
5400
5401template <class TyLoc> static inline
5403 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5404 NewT.setNameLoc(T.getNameLoc());
5405 return T.getType();
5406}
5407
5408template<typename Derived>
5409QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5410 BuiltinTypeLoc T) {
5411 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
5412 NewT.setBuiltinLoc(T.getBuiltinLoc());
5413 if (T.needsExtraLocalData())
5414 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5415 return T.getType();
5416}
5417
5418template<typename Derived>
5419QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5420 ComplexTypeLoc T) {
5421 // FIXME: recurse?
5422 return TransformTypeSpecType(TLB, T);
5423}
5424
5425template <typename Derived>
5426QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5427 AdjustedTypeLoc TL) {
5428 // Adjustments applied during transformation are handled elsewhere.
5429 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5430}
5431
5432template<typename Derived>
5433QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5434 DecayedTypeLoc TL) {
5435 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5436 if (OriginalType.isNull())
5437 return QualType();
5438
5439 QualType Result = TL.getType();
5440 if (getDerived().AlwaysRebuild() ||
5441 OriginalType != TL.getOriginalLoc().getType())
5442 Result = SemaRef.Context.getDecayedType(OriginalType);
5443 TLB.push<DecayedTypeLoc>(Result);
5444 // Nothing to set for DecayedTypeLoc.
5445 return Result;
5446}
5447
5448template <typename Derived>
5449QualType
5450TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5451 ArrayParameterTypeLoc TL) {
5452 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5453 if (OriginalType.isNull())
5454 return QualType();
5455
5456 QualType Result = TL.getType();
5457 if (getDerived().AlwaysRebuild() ||
5458 OriginalType != TL.getElementLoc().getType())
5459 Result = SemaRef.Context.getArrayParameterType(OriginalType);
5460 TLB.push<ArrayParameterTypeLoc>(Result);
5461 // Nothing to set for ArrayParameterTypeLoc.
5462 return Result;
5463}
5464
5465template<typename Derived>
5466QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5467 PointerTypeLoc TL) {
5468 QualType PointeeType
5469 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5470 if (PointeeType.isNull())
5471 return QualType();
5472
5473 QualType Result = TL.getType();
5474 if (PointeeType->getAs<ObjCObjectType>()) {
5475 // A dependent pointer type 'T *' has is being transformed such
5476 // that an Objective-C class type is being replaced for 'T'. The
5477 // resulting pointer type is an ObjCObjectPointerType, not a
5478 // PointerType.
5479 Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
5480
5481 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
5482 NewT.setStarLoc(TL.getStarLoc());
5483 return Result;
5484 }
5485
5486 if (getDerived().AlwaysRebuild() ||
5487 PointeeType != TL.getPointeeLoc().getType()) {
5488 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5489 if (Result.isNull())
5490 return QualType();
5491 }
5492
5493 // Objective-C ARC can add lifetime qualifiers to the type that we're
5494 // pointing to.
5495 TLB.TypeWasModifiedSafely(Result->getPointeeType());
5496
5497 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
5498 NewT.setSigilLoc(TL.getSigilLoc());
5499 return Result;
5500}
5501
5502template<typename Derived>
5503QualType
5504TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5505 BlockPointerTypeLoc TL) {
5506 QualType PointeeType
5507 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5508 if (PointeeType.isNull())
5509 return QualType();
5510
5511 QualType Result = TL.getType();
5512 if (getDerived().AlwaysRebuild() ||
5513 PointeeType != TL.getPointeeLoc().getType()) {
5514 Result = getDerived().RebuildBlockPointerType(PointeeType,
5515 TL.getSigilLoc());
5516 if (Result.isNull())
5517 return QualType();
5518 }
5519
5520 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
5521 NewT.setSigilLoc(TL.getSigilLoc());
5522 return Result;
5523}
5524
5525/// Transforms a reference type. Note that somewhat paradoxically we
5526/// don't care whether the type itself is an l-value type or an r-value
5527/// type; we only care if the type was *written* as an l-value type
5528/// or an r-value type.
5529template<typename Derived>
5530QualType
5532 ReferenceTypeLoc TL) {
5533 const ReferenceType *T = TL.getTypePtr();
5534
5535 // Note that this works with the pointee-as-written.
5536 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5537 if (PointeeType.isNull())
5538 return QualType();
5539
5540 QualType Result = TL.getType();
5541 if (getDerived().AlwaysRebuild() ||
5542 PointeeType != T->getPointeeTypeAsWritten()) {
5543 Result = getDerived().RebuildReferenceType(PointeeType,
5544 T->isSpelledAsLValue(),
5545 TL.getSigilLoc());
5546 if (Result.isNull())
5547 return QualType();
5548 }
5549
5550 // Objective-C ARC can add lifetime qualifiers to the type that we're
5551 // referring to.
5554
5555 // r-value references can be rebuilt as l-value references.
5556 ReferenceTypeLoc NewTL;
5557 if (isa<LValueReferenceType>(Result))
5558 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
5559 else
5560 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
5561 NewTL.setSigilLoc(TL.getSigilLoc());
5562
5563 return Result;
5564}
5565
5566template<typename Derived>
5570 return TransformReferenceType(TLB, TL);
5571}
5572
5573template<typename Derived>
5574QualType
5575TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5576 RValueReferenceTypeLoc TL) {
5577 return TransformReferenceType(TLB, TL);
5578}
5579
5580template<typename Derived>
5581QualType
5582TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5583 MemberPointerTypeLoc TL) {
5584 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5585 if (PointeeType.isNull())
5586 return QualType();
5587
5588 TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
5589 TypeSourceInfo *NewClsTInfo = nullptr;
5590 if (OldClsTInfo) {
5591 NewClsTInfo = getDerived().TransformType(OldClsTInfo);
5592 if (!NewClsTInfo)
5593 return QualType();
5594 }
5595
5596 const MemberPointerType *T = TL.getTypePtr();
5597 QualType OldClsType = QualType(T->getClass(), 0);
5598 QualType NewClsType;
5599 if (NewClsTInfo)
5600 NewClsType = NewClsTInfo->getType();
5601 else {
5602 NewClsType = getDerived().TransformType(OldClsType);
5603 if (NewClsType.isNull())
5604 return QualType();
5605 }
5606
5607 QualType Result = TL.getType();
5608 if (getDerived().AlwaysRebuild() ||
5609 PointeeType != T->getPointeeType() ||
5610 NewClsType != OldClsType) {
5611 Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
5612 TL.getStarLoc());
5613 if (Result.isNull())
5614 return QualType();
5615 }
5616
5617 // If we had to adjust the pointee type when building a member pointer, make
5618 // sure to push TypeLoc info for it.
5619 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5620 if (MPT && PointeeType != MPT->getPointeeType()) {
5621 assert(isa<AdjustedType>(MPT->getPointeeType()));
5622 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
5623 }
5624
5625 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
5626 NewTL.setSigilLoc(TL.getSigilLoc());
5627 NewTL.setClassTInfo(NewClsTInfo);
5628
5629 return Result;
5630}
5631
5632template<typename Derived>
5633QualType
5634TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5635 ConstantArrayTypeLoc TL) {
5636 const ConstantArrayType *T = TL.getTypePtr();
5637 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5638 if (ElementType.isNull())
5639 return QualType();
5640
5641 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5642 Expr *OldSize = TL.getSizeExpr();
5643 if (!OldSize)
5644 OldSize = const_cast<Expr*>(T->getSizeExpr());
5645 Expr *NewSize = nullptr;
5646 if (OldSize) {
5647 EnterExpressionEvaluationContext Unevaluated(
5649 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5650 NewSize = SemaRef.ActOnConstantExpression(NewSize).get();
5651 }
5652
5653 QualType Result = TL.getType();
5654 if (getDerived().AlwaysRebuild() ||
5655 ElementType != T->getElementType() ||
5656 (T->getSizeExpr() && NewSize != OldSize)) {
5657 Result = getDerived().RebuildConstantArrayType(ElementType,
5658 T->getSizeModifier(),
5659 T->getSize(), NewSize,
5660 T->getIndexTypeCVRQualifiers(),
5661 TL.getBracketsRange());
5662 if (Result.isNull())
5663 return QualType();
5664 }
5665
5666 // We might have either a ConstantArrayType or a VariableArrayType now:
5667 // a ConstantArrayType is allowed to have an element type which is a
5668 // VariableArrayType if the type is dependent. Fortunately, all array
5669 // types have the same location layout.
5670 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5671 NewTL.setLBracketLoc(TL.getLBracketLoc());
5672 NewTL.setRBracketLoc(TL.getRBracketLoc());
5673 NewTL.setSizeExpr(NewSize);
5674
5675 return Result;
5676}
5677
5678template<typename Derived>
5679QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5680 TypeLocBuilder &TLB,
5681 IncompleteArrayTypeLoc TL) {
5682 const IncompleteArrayType *T = TL.getTypePtr();
5683 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5684 if (ElementType.isNull())
5685 return QualType();
5686
5687 QualType Result = TL.getType();
5688 if (getDerived().AlwaysRebuild() ||
5689 ElementType != T->getElementType()) {
5690 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5691 T->getSizeModifier(),
5692 T->getIndexTypeCVRQualifiers(),
5693 TL.getBracketsRange());
5694 if (Result.isNull())
5695 return QualType();
5696 }
5697
5698 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
5699 NewTL.setLBracketLoc(TL.getLBracketLoc());
5700 NewTL.setRBracketLoc(TL.getRBracketLoc());
5701 NewTL.setSizeExpr(nullptr);
5702
5703 return Result;
5704}
5705
5706template<typename Derived>
5707QualType
5708TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5709 VariableArrayTypeLoc TL) {
5710 const VariableArrayType *T = TL.getTypePtr();
5711 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5712 if (ElementType.isNull())
5713 return QualType();
5714
5715 ExprResult SizeResult;
5716 {
5717 EnterExpressionEvaluationContext Context(
5719 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5720 }
5721 if (SizeResult.isInvalid())
5722 return QualType();
5723 SizeResult =
5724 SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);
5725 if (SizeResult.isInvalid())
5726 return QualType();
5727
5728 Expr *Size = SizeResult.get();
5729
5730 QualType Result = TL.getType();
5731 if (getDerived().AlwaysRebuild() ||
5732 ElementType != T->getElementType() ||
5733 Size != T->getSizeExpr()) {
5734 Result = getDerived().RebuildVariableArrayType(ElementType,
5735 T->getSizeModifier(),
5736 Size,
5737 T->getIndexTypeCVRQualifiers(),
5738 TL.getBracketsRange());
5739 if (Result.isNull())
5740 return QualType();
5741 }
5742
5743 // We might have constant size array now, but fortunately it has the same
5744 // location layout.
5745 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5746 NewTL.setLBracketLoc(TL.getLBracketLoc());
5747 NewTL.setRBracketLoc(TL.getRBracketLoc());
5748 NewTL.setSizeExpr(Size);
5749
5750 return Result;
5751}
5752
5753template<typename Derived>
5754QualType
5755TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5756 DependentSizedArrayTypeLoc TL) {
5757 const DependentSizedArrayType *T = TL.getTypePtr();
5758 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5759 if (ElementType.isNull())
5760 return QualType();
5761
5762 // Array bounds are constant expressions.
5763 EnterExpressionEvaluationContext Unevaluated(
5765
5766 // If we have a VLA then it won't be a constant.
5767 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5768
5769 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5770 Expr *origSize = TL.getSizeExpr();
5771 if (!origSize) origSize = T->getSizeExpr();
5772
5773 ExprResult sizeResult
5774 = getDerived().TransformExpr(origSize);
5775 sizeResult = SemaRef.ActOnConstantExpression(sizeResult);
5776 if (sizeResult.isInvalid())
5777 return QualType();
5778
5779 Expr *size = sizeResult.get();
5780
5781 QualType Result = TL.getType();
5782 if (getDerived().AlwaysRebuild() ||
5783 ElementType != T->getElementType() ||
5784 size != origSize) {
5785 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5786 T->getSizeModifier(),
5787 size,
5788 T->getIndexTypeCVRQualifiers(),
5789 TL.getBracketsRange());
5790 if (Result.isNull())
5791 return QualType();
5792 }
5793
5794 // We might have any sort of array type now, but fortunately they
5795 // all have the same location layout.
5796 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5797 NewTL.setLBracketLoc(TL.getLBracketLoc());
5798 NewTL.setRBracketLoc(TL.getRBracketLoc());
5799 NewTL.setSizeExpr(size);
5800
5801 return Result;
5802}
5803
5804template <typename Derived>
5805QualType TreeTransform<Derived>::TransformDependentVectorType(
5806 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5807 const DependentVectorType *T = TL.getTypePtr();
5808 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5809 if (ElementType.isNull())
5810 return QualType();
5811
5812 EnterExpressionEvaluationContext Unevaluated(
5814
5815 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5816 Size = SemaRef.ActOnConstantExpression(Size);
5817 if (Size.isInvalid())
5818 return QualType();
5819
5820 QualType Result = TL.getType();
5821 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5822 Size.get() != T->getSizeExpr()) {
5823 Result = getDerived().RebuildDependentVectorType(
5824 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5825 if (Result.isNull())
5826 return QualType();
5827 }
5828
5829 // Result might be dependent or not.
5830 if (isa<DependentVectorType>(Result)) {
5831 DependentVectorTypeLoc NewTL =
5832 TLB.push<DependentVectorTypeLoc>(Result);
5833 NewTL.setNameLoc(TL.getNameLoc());
5834 } else {
5835 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5836 NewTL.setNameLoc(TL.getNameLoc());
5837 }
5838
5839 return Result;
5840}
5841
5842template<typename Derived>
5843QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5844 TypeLocBuilder &TLB,
5845 DependentSizedExtVectorTypeLoc TL) {
5846 const DependentSizedExtVectorType *T = TL.getTypePtr();
5847
5848 // FIXME: ext vector locs should be nested
5849 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5850 if (ElementType.isNull())
5851 return QualType();
5852
5853 // Vector sizes are constant expressions.
5854 EnterExpressionEvaluationContext Unevaluated(
5856
5857 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5858 Size = SemaRef.ActOnConstantExpression(Size);
5859 if (Size.isInvalid())
5860 return QualType();
5861
5862 QualType Result = TL.getType();
5863 if (getDerived().AlwaysRebuild() ||
5864 ElementType != T->getElementType() ||
5865 Size.get() != T->getSizeExpr()) {
5866 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5867 Size.get(),
5868 T->getAttributeLoc());
5869 if (Result.isNull())
5870 return QualType();
5871 }
5872
5873 // Result might be dependent or not.
5874 if (isa<DependentSizedExtVectorType>(Result)) {
5875 DependentSizedExtVectorTypeLoc NewTL
5876 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
5877 NewTL.setNameLoc(TL.getNameLoc());
5878 } else {
5879 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5880 NewTL.setNameLoc(TL.getNameLoc());
5881 }
5882
5883 return Result;
5884}
5885
5886template <typename Derived>
5887QualType
5888TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5889 ConstantMatrixTypeLoc TL) {
5890 const ConstantMatrixType *T = TL.getTypePtr();
5891 QualType ElementType = getDerived().TransformType(T->getElementType());
5892 if (ElementType.isNull())
5893 return QualType();
5894
5895 QualType Result = TL.getType();
5896 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5897 Result = getDerived().RebuildConstantMatrixType(
5898 ElementType, T->getNumRows(), T->getNumColumns());
5899 if (Result.isNull())
5900 return QualType();
5901 }
5902
5903 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);
5904 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5905 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5906 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5907 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5908
5909 return Result;
5910}
5911
5912template <typename Derived>
5913QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5914 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5915 const DependentSizedMatrixType *T = TL.getTypePtr();
5916
5917 QualType ElementType = getDerived().TransformType(T->getElementType());
5918 if (ElementType.isNull()) {
5919 return QualType();
5920 }
5921
5922 // Matrix dimensions are constant expressions.
5923 EnterExpressionEvaluationContext Unevaluated(
5925
5926 Expr *origRows = TL.getAttrRowOperand();
5927 if (!origRows)
5928 origRows = T->getRowExpr();
5929 Expr *origColumns = TL.getAttrColumnOperand();
5930 if (!origColumns)
5931 origColumns = T->getColumnExpr();
5932
5933 ExprResult rowResult = getDerived().TransformExpr(origRows);
5934 rowResult = SemaRef.ActOnConstantExpression(rowResult);
5935 if (rowResult.isInvalid())
5936 return QualType();
5937
5938 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5939 columnResult = SemaRef.ActOnConstantExpression(columnResult);
5940 if (columnResult.isInvalid())
5941 return QualType();
5942
5943 Expr *rows = rowResult.get();
5944 Expr *columns = columnResult.get();
5945
5946 QualType Result = TL.getType();
5947 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5948 rows != origRows || columns != origColumns) {
5949 Result = getDerived().RebuildDependentSizedMatrixType(
5950 ElementType, rows, columns, T->getAttributeLoc());
5951
5952 if (Result.isNull())
5953 return QualType();
5954 }
5955
5956 // We might have any sort of matrix type now, but fortunately they
5957 // all have the same location layout.
5958 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);
5959 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5960 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5961 NewTL.setAttrRowOperand(rows);
5962 NewTL.setAttrColumnOperand(columns);
5963 return Result;
5964}
5965
5966template <typename Derived>
5967QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
5968 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
5969 const DependentAddressSpaceType *T = TL.getTypePtr();
5970
5971 QualType pointeeType =
5972 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
5973
5974 if (pointeeType.isNull())
5975 return QualType();
5976
5977 // Address spaces are constant expressions.
5978 EnterExpressionEvaluationContext Unevaluated(
5980
5981 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
5982 AddrSpace = SemaRef.ActOnConstantExpression(AddrSpace);
5983 if (AddrSpace.isInvalid())
5984 return QualType();
5985
5986 QualType Result = TL.getType();
5987 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
5988 AddrSpace.get() != T->getAddrSpaceExpr()) {
5989 Result = getDerived().RebuildDependentAddressSpaceType(
5990 pointeeType, AddrSpace.get(), T->getAttributeLoc());
5991 if (Result.isNull())
5992 return QualType();
5993 }
5994
5995 // Result might be dependent or not.
5996 if (isa<DependentAddressSpaceType>(Result)) {
5997 DependentAddressSpaceTypeLoc NewTL =
5998 TLB.push<DependentAddressSpaceTypeLoc>(Result);
5999
6000 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6001 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6002 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6003
6004 } else {
6005 TLB.TypeWasModifiedSafely(Result);
6006 }
6007
6008 return Result;
6009}
6010
6011template <typename Derived>
6012QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6013 VectorTypeLoc TL) {
6014 const VectorType *T = TL.getTypePtr();
6015 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6016 if (ElementType.isNull())
6017 return QualType();
6018
6019 QualType Result = TL.getType();
6020 if (getDerived().AlwaysRebuild() ||
6021 ElementType != T->getElementType()) {
6022 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6023 T->getVectorKind());
6024 if (Result.isNull())
6025 return QualType();
6026 }
6027
6028 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
6029 NewTL.setNameLoc(TL.getNameLoc());
6030
6031 return Result;
6032}
6033
6034template<typename Derived>
6035QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6036 ExtVectorTypeLoc TL) {
6037 const VectorType *T = TL.getTypePtr();
6038 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6039 if (ElementType.isNull())
6040 return QualType();
6041
6042 QualType Result = TL.getType();
6043 if (getDerived().AlwaysRebuild() ||
6044 ElementType != T->getElementType()) {
6045 Result = getDerived().RebuildExtVectorType(ElementType,
6046 T->getNumElements(),
6047 /*FIXME*/ SourceLocation());
6048 if (Result.isNull())
6049 return QualType();
6050 }
6051
6052 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
6053 NewTL.setNameLoc(TL.getNameLoc());
6054
6055 return Result;
6056}
6057
6058template <typename Derived>
6060 ParmVarDecl *OldParm, int indexAdjustment,
6061 std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
6062 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
6063 TypeSourceInfo *NewDI = nullptr;
6064
6065 if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
6066 // If we're substituting into a pack expansion type and we know the
6067 // length we want to expand to, just substitute for the pattern.
6068 TypeLoc OldTL = OldDI->getTypeLoc();
6069 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6070
6071 TypeLocBuilder TLB;
6072 TypeLoc NewTL = OldDI->getTypeLoc();
6073 TLB.reserve(NewTL.getFullDataSize());
6074
6075 QualType Result = getDerived().TransformType(TLB,
6076 OldExpansionTL.getPatternLoc());
6077 if (Result.isNull())
6078 return nullptr;
6079
6080 Result = RebuildPackExpansionType(Result,
6081 OldExpansionTL.getPatternLoc().getSourceRange(),
6082 OldExpansionTL.getEllipsisLoc(),
6083 NumExpansions);
6084 if (Result.isNull())
6085 return nullptr;
6086
6087 PackExpansionTypeLoc NewExpansionTL
6088 = TLB.push<PackExpansionTypeLoc>(Result);
6089 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6090 NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result);
6091 } else
6092 NewDI = getDerived().TransformType(OldDI);
6093 if (!NewDI)
6094 return nullptr;
6095
6096 if (NewDI == OldDI && indexAdjustment == 0)
6097 return OldParm;
6098
6099 ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context,
6100 OldParm->getDeclContext(),
6101 OldParm->getInnerLocStart(),
6102 OldParm->getLocation(),
6103 OldParm->getIdentifier(),
6104 NewDI->getType(),
6105 NewDI,
6106 OldParm->getStorageClass(),
6107 /* DefArg */ nullptr);
6108 newParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
6109 OldParm->getFunctionScopeIndex() + indexAdjustment);
6110 transformedLocalDecl(OldParm, {newParm});
6111 return newParm;
6112}
6113
6114template <typename Derived>
6117 const QualType *ParamTypes,
6118 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6119 SmallVectorImpl<QualType> &OutParamTypes,
6122 unsigned *LastParamTransformed) {
6123 int indexAdjustment = 0;
6124
6125 unsigned NumParams = Params.size();
6126 for (unsigned i = 0; i != NumParams; ++i) {
6127 if (LastParamTransformed)
6128 *LastParamTransformed = i;
6129 if (ParmVarDecl *OldParm = Params[i]) {
6130 assert(OldParm->getFunctionScopeIndex() == i);
6131
6132 std::optional<unsigned> NumExpansions;
6133 ParmVarDecl *NewParm = nullptr;
6134 if (OldParm->isParameterPack()) {
6135 // We have a function parameter pack that may need to be expanded.
6137
6138 // Find the parameter packs that could be expanded.
6139 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6141 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6142 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
6143
6144 // Determine whether we should expand the parameter packs.
6145 bool ShouldExpand = false;
6146 bool RetainExpansion = false;
6147 std::optional<unsigned> OrigNumExpansions;
6148 if (Unexpanded.size() > 0) {
6149 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6150 NumExpansions = OrigNumExpansions;
6151 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
6152 Pattern.getSourceRange(),
6153 Unexpanded,
6154 ShouldExpand,
6155 RetainExpansion,
6156 NumExpansions)) {
6157 return true;
6158 }
6159 } else {
6160#ifndef NDEBUG
6161 const AutoType *AT =
6162 Pattern.getType().getTypePtr()->getContainedAutoType();
6163 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6164 "Could not find parameter packs or undeduced auto type!");
6165#endif
6166 }
6167
6168 if (ShouldExpand) {
6169 // Expand the function parameter pack into multiple, separate
6170 // parameters.
6171 getDerived().ExpandingFunctionParameterPack(OldParm);
6172 for (unsigned I = 0; I != *NumExpansions; ++I) {
6173 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6174 ParmVarDecl *NewParm
6175 = getDerived().TransformFunctionTypeParam(OldParm,
6176 indexAdjustment++,
6177 OrigNumExpansions,
6178 /*ExpectParameterPack=*/false);
6179 if (!NewParm)
6180 return true;
6181
6182 if (ParamInfos)
6183 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6184 OutParamTypes.push_back(NewParm->getType());
6185 if (PVars)
6186 PVars->push_back(NewParm);
6187 }
6188
6189 // If we're supposed to retain a pack expansion, do so by temporarily
6190 // forgetting the partially-substituted parameter pack.
6191 if (RetainExpansion) {
6192 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6193 ParmVarDecl *NewParm
6194 = getDerived().TransformFunctionTypeParam(OldParm,
6195 indexAdjustment++,
6196 OrigNumExpansions,
6197 /*ExpectParameterPack=*/false);
6198 if (!NewParm)
6199 return true;
6200
6201 if (ParamInfos)
6202 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6203 OutParamTypes.push_back(NewParm->getType());
6204 if (PVars)
6205 PVars->push_back(NewParm);
6206 }
6207
6208 // The next parameter should have the same adjustment as the
6209 // last thing we pushed, but we post-incremented indexAdjustment
6210 // on every push. Also, if we push nothing, the adjustment should
6211 // go down by one.
6212 indexAdjustment--;
6213
6214 // We're done with the pack expansion.
6215 continue;
6216 }
6217
6218 // We'll substitute the parameter now without expanding the pack
6219 // expansion.
6220 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6221 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6222 indexAdjustment,
6223 NumExpansions,
6224 /*ExpectParameterPack=*/true);
6225 assert(NewParm->isParameterPack() &&
6226 "Parameter pack no longer a parameter pack after "
6227 "transformation.");
6228 } else {
6229 NewParm = getDerived().TransformFunctionTypeParam(
6230 OldParm, indexAdjustment, std::nullopt,
6231 /*ExpectParameterPack=*/false);
6232 }
6233
6234 if (!NewParm)
6235 return true;
6236
6237 if (ParamInfos)
6238 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6239 OutParamTypes.push_back(NewParm->getType());
6240 if (PVars)
6241 PVars->push_back(NewParm);
6242 continue;
6243 }
6244
6245 // Deal with the possibility that we don't have a parameter
6246 // declaration for this parameter.
6247 assert(ParamTypes);
6248 QualType OldType = ParamTypes[i];
6249 bool IsPackExpansion = false;
6250 std::optional<unsigned> NumExpansions;
6251 QualType NewType;
6252 if (const PackExpansionType *Expansion
6253 = dyn_cast<PackExpansionType>(OldType)) {
6254 // We have a function parameter pack that may need to be expanded.
6255 QualType Pattern = Expansion->getPattern();
6257 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6258
6259 // Determine whether we should expand the parameter packs.
6260 bool ShouldExpand = false;
6261 bool RetainExpansion = false;
6262 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
6263 Unexpanded,
6264 ShouldExpand,
6265 RetainExpansion,
6266 NumExpansions)) {
6267 return true;
6268 }
6269
6270 if (ShouldExpand) {
6271 // Expand the function parameter pack into multiple, separate
6272 // parameters.
6273 for (unsigned I = 0; I != *NumExpansions; ++I) {
6274 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6275 QualType NewType = getDerived().TransformType(Pattern);
6276 if (NewType.isNull())
6277 return true;
6278
6279 if (NewType->containsUnexpandedParameterPack()) {
6280 NewType = getSema().getASTContext().getPackExpansionType(
6281 NewType, std::nullopt);
6282
6283 if (NewType.isNull())
6284 return true;
6285 }
6286
6287 if (ParamInfos)
6288 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6289 OutParamTypes.push_back(NewType);
6290 if (PVars)
6291 PVars->push_back(nullptr);
6292 }
6293
6294 // We're done with the pack expansion.
6295 continue;
6296 }
6297
6298 // If we're supposed to retain a pack expansion, do so by temporarily
6299 // forgetting the partially-substituted parameter pack.
6300 if (RetainExpansion) {
6301 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6302 QualType NewType = getDerived().TransformType(Pattern);
6303 if (NewType.isNull())
6304 return true;
6305
6306 if (ParamInfos)
6307 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6308 OutParamTypes.push_back(NewType);
6309 if (PVars)
6310 PVars->push_back(nullptr);
6311 }
6312
6313 // We'll substitute the parameter now without expanding the pack
6314 // expansion.
6315 OldType = Expansion->getPattern();
6316 IsPackExpansion = true;
6317 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6318 NewType = getDerived().TransformType(OldType);
6319 } else {
6320 NewType = getDerived().TransformType(OldType);
6321 }
6322
6323 if (NewType.isNull())
6324 return true;
6325
6326 if (IsPackExpansion)
6327 NewType = getSema().Context.getPackExpansionType(NewType,
6328 NumExpansions);
6329
6330 if (ParamInfos)
6331 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6332 OutParamTypes.push_back(NewType);
6333 if (PVars)
6334 PVars->push_back(nullptr);
6335 }
6336
6337#ifndef NDEBUG
6338 if (PVars) {
6339 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6340 if (ParmVarDecl *parm = (*PVars)[i])
6341 assert(parm->getFunctionScopeIndex() == i);
6342 }
6343#endif
6344
6345 return false;
6346}
6347
6348template<typename Derived>
6352 SmallVector<QualType, 4> ExceptionStorage;
6353 return getDerived().TransformFunctionProtoType(
6354 TLB, TL, nullptr, Qualifiers(),
6355 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6356 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6357 ExceptionStorage, Changed);
6358 });
6359}
6360
6361template<typename Derived> template<typename Fn>
6363 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6364 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6365
6366 // Transform the parameters and return type.
6367 //
6368 // We are required to instantiate the params and return type in source order.
6369 // When the function has a trailing return type, we instantiate the
6370 // parameters before the return type, since the return type can then refer
6371 // to the parameters themselves (via decltype, sizeof, etc.).
6372 //
6373 SmallVector<QualType, 4> ParamTypes;
6375 Sema::ExtParameterInfoBuilder ExtParamInfos;
6376 const FunctionProtoType *T = TL.getTypePtr();
6377
6378 QualType ResultType;
6379
6380 if (T->hasTrailingReturn()) {
6381 if (getDerived().TransformFunctionTypeParams(
6382 TL.getBeginLoc(), TL.getParams(),
6385 ParamTypes, &ParamDecls, ExtParamInfos))
6386 return QualType();
6387
6388 {
6389 // C++11 [expr.prim.general]p3:
6390 // If a declaration declares a member function or member function
6391 // template of a class X, the expression this is a prvalue of type
6392 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6393 // and the end of the function-definition, member-declarator, or
6394 // declarator.
6395 auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.getCurLexicalContext());
6396 Sema::CXXThisScopeRAII ThisScope(
6397 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6398
6399 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6400 if (ResultType.isNull())
6401 return QualType();
6402 }
6403 }
6404 else {
6405 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6406 if (ResultType.isNull())
6407 return QualType();
6408
6409 if (getDerived().TransformFunctionTypeParams(
6410 TL.getBeginLoc(), TL.getParams(),
6413 ParamTypes, &ParamDecls, ExtParamInfos))
6414 return QualType();
6415 }
6416
6418
6419 bool EPIChanged = false;
6420 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6421 return QualType();
6422
6423 // Handle extended parameter information.
6424 if (auto NewExtParamInfos =
6425 ExtParamInfos.getPointerOrNull(ParamTypes.size())) {
6426 if (!EPI.ExtParameterInfos ||
6428 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6429 EPIChanged = true;
6430 }
6431 EPI.ExtParameterInfos = NewExtParamInfos;
6432 } else if (EPI.ExtParameterInfos) {
6433 EPIChanged = true;
6434 EPI.ExtParameterInfos = nullptr;
6435 }
6436
6437 // Transform any function effects with unevaluated conditions.
6438 // Hold this set in a local for the rest of this function, since EPI
6439 // may need to hold a FunctionEffectsRef pointing into it.
6440 std::optional<FunctionEffectSet> NewFX;
6441 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6442 NewFX.emplace();
6445
6446 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6447 FunctionEffectWithCondition NewEC = PrevEC;
6448 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6449 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6450 if (NewExpr.isInvalid())
6451 return QualType();
6452 std::optional<FunctionEffectMode> Mode =
6453 SemaRef.ActOnEffectExpression(NewExpr.get(), PrevEC.Effect.name());
6454 if (!Mode)
6455 return QualType();
6456
6457 // The condition expression has been transformed, and re-evaluated.
6458 // It may or may not have become constant.
6459 switch (*Mode) {
6461 NewEC.Cond = {};
6462 break;
6464 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6465 NewEC.Cond = {};
6466 break;
6468 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6469 break;
6471 llvm_unreachable(
6472 "FunctionEffectMode::None shouldn't be possible here");
6473 }
6474 }
6475 if (!SemaRef.diagnoseConflictingFunctionEffect(*NewFX, NewEC,
6476 TL.getBeginLoc())) {
6478 NewFX->insert(NewEC, Errs);
6479 assert(Errs.empty());
6480 }
6481 }
6482 EPI.FunctionEffects = *NewFX;
6483 EPIChanged = true;
6484 }
6485
6486 QualType Result = TL.getType();
6487 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6488 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6489 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6490 if (Result.isNull())
6491 return QualType();
6492 }
6493
6496 NewTL.setLParenLoc(TL.getLParenLoc());
6497 NewTL.setRParenLoc(TL.getRParenLoc());
6500 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6501 NewTL.setParam(i, ParamDecls[i]);
6502
6503 return Result;
6504}
6505
6506template<typename Derived>
6509 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6510 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6511
6512 // Instantiate a dynamic noexcept expression, if any.
6513 if (isComputedNoexcept(ESI.Type)) {
6514 // Update this scrope because ContextDecl in Sema will be used in
6515 // TransformExpr.
6516 auto *Method = dyn_cast_if_present<CXXMethodDecl>(ESI.SourceTemplate);
6517 Sema::CXXThisScopeRAII ThisScope(
6518 SemaRef, Method ? Method->getParent() : nullptr,
6519 Method ? Method->getMethodQualifiers() : Qualifiers{},
6520 Method != nullptr);
6523 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6524 if (NoexceptExpr.isInvalid())
6525 return true;
6526
6528 NoexceptExpr =
6529 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6530 if (NoexceptExpr.isInvalid())
6531 return true;
6532
6533 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6534 Changed = true;
6535 ESI.NoexceptExpr = NoexceptExpr.get();
6536 ESI.Type = EST;
6537 }
6538
6539 if (ESI.Type != EST_Dynamic)
6540 return false;
6541
6542 // Instantiate a dynamic exception specification's type.
6543 for (QualType T : ESI.Exceptions) {
6544 if (const PackExpansionType *PackExpansion =
6546 Changed = true;
6547
6548 // We have a pack expansion. Instantiate it.
6550 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
6551 Unexpanded);
6552 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6553
6554 // Determine whether the set of unexpanded parameter packs can and
6555 // should
6556 // be expanded.
6557 bool Expand = false;
6558 bool RetainExpansion = false;
6559 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
6560 // FIXME: Track the location of the ellipsis (and track source location
6561 // information for the types in the exception specification in general).
6562 if (getDerived().TryExpandParameterPacks(
6563 Loc, SourceRange(), Unexpanded, Expand,
6564 RetainExpansion, NumExpansions))
6565 return true;
6566
6567 if (!Expand) {
6568 // We can't expand this pack expansion into separate arguments yet;
6569 // just substitute into the pattern and create a new pack expansion
6570 // type.
6571 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6572 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6573 if (U.isNull())
6574 return true;
6575
6576 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
6577 Exceptions.push_back(U);
6578 continue;
6579 }
6580
6581 // Substitute into the pack expansion pattern for each slice of the
6582 // pack.
6583 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6584 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
6585
6586 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6587 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6588 return true;
6589
6590 Exceptions.push_back(U);
6591 }
6592 } else {
6593 QualType U = getDerived().TransformType(T);
6594 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6595 return true;
6596 if (T != U)
6597 Changed = true;
6598
6599 Exceptions.push_back(U);
6600 }
6601 }
6602
6603 ESI.Exceptions = Exceptions;
6604 if (ESI.Exceptions.empty())
6605 ESI.Type = EST_DynamicNone;
6606 return false;
6607}
6608
6609template<typename Derived>
6611 TypeLocBuilder &TLB,
6613 const FunctionNoProtoType *T = TL.getTypePtr();
6614 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6615 if (ResultType.isNull())
6616 return QualType();
6617
6618 QualType Result = TL.getType();
6619 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6620 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6621
6624 NewTL.setLParenLoc(TL.getLParenLoc());
6625 NewTL.setRParenLoc(TL.getRParenLoc());
6627
6628 return Result;
6629}
6630
6631template <typename Derived>
6632QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6633 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6634 const UnresolvedUsingType *T = TL.getTypePtr();
6635 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6636 if (!D)
6637 return QualType();
6638
6639 QualType Result = TL.getType();
6640 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6641 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6642 if (Result.isNull())
6643 return QualType();
6644 }
6645
6646 // We might get an arbitrary type spec type back. We should at
6647 // least always get a type spec type, though.
6648 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result);
6649 NewTL.setNameLoc(TL.getNameLoc());
6650
6651 return Result;
6652}
6653
6654template <typename Derived>
6655QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6656 UsingTypeLoc TL) {
6657 const UsingType *T = TL.getTypePtr();
6658
6659 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6660 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6661 if (!Found)
6662 return QualType();
6663
6664 QualType Underlying = getDerived().TransformType(T->desugar());
6665 if (Underlying.isNull())
6666 return QualType();
6667
6668 QualType Result = TL.getType();
6669 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6670 Underlying != T->getUnderlyingType()) {
6671 Result = getDerived().RebuildUsingType(Found, Underlying);
6672 if (Result.isNull())
6673 return QualType();
6674 }
6675
6676 TLB.pushTypeSpec(Result).setNameLoc(TL.getNameLoc());
6677 return Result;
6678}
6679
6680template<typename Derived>
6681QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6682 TypedefTypeLoc TL) {
6683 const TypedefType *T = TL.getTypePtr();
6684 TypedefNameDecl *Typedef
6685 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6686 T->getDecl()));
6687 if (!Typedef)
6688 return QualType();
6689
6690 QualType Result = TL.getType();
6691 if (getDerived().AlwaysRebuild() ||
6692 Typedef != T->getDecl()) {
6693 Result = getDerived().RebuildTypedefType(Typedef);
6694 if (Result.isNull())
6695 return QualType();
6696 }
6697
6698 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
6699 NewTL.setNameLoc(TL.getNameLoc());
6700
6701 return Result;
6702}
6703
6704template<typename Derived>
6705QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6706 TypeOfExprTypeLoc TL) {
6707 // typeof expressions are not potentially evaluated contexts
6708 EnterExpressionEvaluationContext Unevaluated(
6711
6712 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6713 if (E.isInvalid())
6714 return QualType();
6715
6716 E = SemaRef.HandleExprEvaluationContextForTypeof(E.get());
6717 if (E.isInvalid())
6718 return QualType();
6719
6720 QualType Result = TL.getType();
6721 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
6722 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6723 Result =
6724 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6725 if (Result.isNull())
6726 return QualType();
6727 }
6728
6729 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
6730 NewTL.setTypeofLoc(TL.getTypeofLoc());
6731 NewTL.setLParenLoc(TL.getLParenLoc());
6732 NewTL.setRParenLoc(TL.getRParenLoc());
6733
6734 return Result;
6735}
6736
6737template<typename Derived>
6738QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6739 TypeOfTypeLoc TL) {
6740 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6741 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6742 if (!New_Under_TI)
6743 return QualType();
6744
6745 QualType Result = TL.getType();
6746 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
6747 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6748 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6749 if (Result.isNull())
6750 return QualType();
6751 }
6752
6753 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
6754 NewTL.setTypeofLoc(TL.getTypeofLoc());
6755 NewTL.setLParenLoc(TL.getLParenLoc());
6756 NewTL.setRParenLoc(TL.getRParenLoc());
6757 NewTL.setUnmodifiedTInfo(New_Under_TI);
6758
6759 return Result;
6760}
6761
6762template<typename Derived>
6763QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6764 DecltypeTypeLoc TL) {
6765 const DecltypeType *T = TL.getTypePtr();
6766
6767 // decltype expressions are not potentially evaluated contexts
6768 EnterExpressionEvaluationContext Unevaluated(
6771
6772 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6773 if (E.isInvalid())
6774 return QualType();
6775
6776 E = getSema().ActOnDecltypeExpression(E.get());
6777 if (E.isInvalid())
6778 return QualType();
6779
6780 QualType Result = TL.getType();
6781 if (getDerived().AlwaysRebuild() ||
6782 E.get() != T->getUnderlyingExpr()) {
6783 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6784 if (Result.isNull())
6785 return QualType();
6786 }
6787 else E.get();
6788
6789 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
6790 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6791 NewTL.setRParenLoc(TL.getRParenLoc());
6792 return Result;
6793}
6794
6795template <typename Derived>
6796QualType
6797TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
6798 PackIndexingTypeLoc TL) {
6799 // Transform the index
6800 ExprResult IndexExpr;
6801 {
6802 EnterExpressionEvaluationContext ConstantContext(
6804
6805 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
6806 if (IndexExpr.isInvalid())
6807 return QualType();
6808 }
6809 QualType Pattern = TL.getPattern();
6810
6811 const PackIndexingType *PIT = TL.getTypePtr();
6812 SmallVector<QualType, 5> SubtitutedTypes;
6813 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
6814
6815 bool NotYetExpanded = Types.empty();
6816 bool FullySubstituted = true;
6817
6818 if (Types.empty() && !PIT->expandsToEmptyPack())
6819 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
6820
6821 for (QualType T : Types) {
6823 QualType Transformed = getDerived().TransformType(T);
6824 if (Transformed.isNull())
6825 return QualType();
6826 SubtitutedTypes.push_back(Transformed);
6827 continue;
6828 }
6829
6831 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
6832 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6833 // Determine whether the set of unexpanded parameter packs can and should
6834 // be expanded.
6835 bool ShouldExpand = true;
6836 bool RetainExpansion = false;
6837 std::optional<unsigned> OrigNumExpansions;
6838 std::optional<unsigned> NumExpansions = OrigNumExpansions;
6839 if (getDerived().TryExpandParameterPacks(TL.getEllipsisLoc(), SourceRange(),
6840 Unexpanded, ShouldExpand,
6841 RetainExpansion, NumExpansions))
6842 return QualType();
6843 if (!ShouldExpand) {
6844 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6845 // FIXME: should we keep TypeLoc for individual expansions in
6846 // PackIndexingTypeLoc?
6847 TypeSourceInfo *TI =
6848 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, TL.getBeginLoc());
6849 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
6850 if (Pack.isNull())
6851 return QualType();
6852 if (NotYetExpanded) {
6853 FullySubstituted = false;
6854 QualType Out = getDerived().RebuildPackIndexingType(
6855 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6856 FullySubstituted);
6857 if (Out.isNull())
6858 return QualType();
6859
6860 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6861 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6862 return Out;
6863 }
6864 SubtitutedTypes.push_back(Pack);
6865 continue;
6866 }
6867 for (unsigned I = 0; I != *NumExpansions; ++I) {
6868 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6869 QualType Out = getDerived().TransformType(T);
6870 if (Out.isNull())
6871 return QualType();
6872 SubtitutedTypes.push_back(Out);
6873 FullySubstituted &= !Out->containsUnexpandedParameterPack();
6874 }
6875 // If we're supposed to retain a pack expansion, do so by temporarily
6876 // forgetting the partially-substituted parameter pack.
6877 if (RetainExpansion) {
6878 FullySubstituted = false;
6879 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6880 QualType Out = getDerived().TransformType(T);
6881 if (Out.isNull())
6882 return QualType();
6883 SubtitutedTypes.push_back(Out);
6884 }
6885 }
6886
6887 // A pack indexing type can appear in a larger pack expansion,
6888 // e.g. `Pack...[pack_of_indexes]...`
6889 // so we need to temporarily disable substitution of pack elements
6890 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6891 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
6892
6893 QualType Out = getDerived().RebuildPackIndexingType(
6894 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6895 FullySubstituted, SubtitutedTypes);
6896 if (Out.isNull())
6897 return Out;
6898
6899 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6900 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6901 return Out;
6902}
6903
6904template<typename Derived>
6905QualType TreeTransform<Derived>::TransformUnaryTransformType(
6906 TypeLocBuilder &TLB,
6907 UnaryTransformTypeLoc TL) {
6908 QualType Result = TL.getType();
6909 if (Result->isDependentType()) {
6910 const UnaryTransformType *T = TL.getTypePtr();
6911
6912 TypeSourceInfo *NewBaseTSI =
6913 getDerived().TransformType(TL.getUnderlyingTInfo());
6914 if (!NewBaseTSI)
6915 return QualType();
6916 QualType NewBase = NewBaseTSI->getType();
6917
6918 Result = getDerived().RebuildUnaryTransformType(NewBase,
6919 T->getUTTKind(),
6920 TL.getKWLoc());
6921 if (Result.isNull())
6922 return QualType();
6923 }
6924
6925 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
6926 NewTL.setKWLoc(TL.getKWLoc());
6927 NewTL.setParensRange(TL.getParensRange());
6928 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6929 return Result;
6930}
6931
6932template<typename Derived>
6933QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6934 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6935 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6936
6937 CXXScopeSpec SS;
6938 TemplateName TemplateName = getDerived().TransformTemplateName(
6939 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6940 if (TemplateName.isNull())
6941 return QualType();
6942
6943 QualType OldDeduced = T->getDeducedType();
6944 QualType NewDeduced;
6945 if (!OldDeduced.isNull()) {
6946 NewDeduced = getDerived().TransformType(OldDeduced);
6947 if (NewDeduced.isNull())
6948 return QualType();
6949 }
6950
6951 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
6952 TemplateName, NewDeduced);
6953 if (Result.isNull())
6954 return QualType();
6955
6956 DeducedTemplateSpecializationTypeLoc NewTL =
6957 TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
6958 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6959
6960 return Result;
6961}
6962
6963template<typename Derived>
6964QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
6965 RecordTypeLoc TL) {
6966 const RecordType *T = TL.getTypePtr();
6967 RecordDecl *Record
6968 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6969 T->getDecl()));
6970 if (!Record)
6971 return QualType();
6972
6973 QualType Result = TL.getType();
6974 if (getDerived().AlwaysRebuild() ||
6975 Record != T->getDecl()) {
6976 Result = getDerived().RebuildRecordType(Record);
6977 if (Result.isNull())
6978 return QualType();
6979 }
6980
6981 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
6982 NewTL.setNameLoc(TL.getNameLoc());
6983
6984 return Result;
6985}
6986
6987template<typename Derived>
6988QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
6989 EnumTypeLoc TL) {
6990 const EnumType *T = TL.getTypePtr();
6991 EnumDecl *Enum
6992 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6993 T->getDecl()));
6994 if (!Enum)
6995 return QualType();
6996
6997 QualType Result = TL.getType();
6998 if (getDerived().AlwaysRebuild() ||
6999 Enum != T->getDecl()) {
7000 Result = getDerived().RebuildEnumType(Enum);
7001 if (Result.isNull())
7002 return QualType();
7003 }
7004
7005 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
7006 NewTL.setNameLoc(TL.getNameLoc());
7007
7008 return Result;
7009}
7010
7011template<typename Derived>
7012QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7013 TypeLocBuilder &TLB,
7014 InjectedClassNameTypeLoc TL) {
7015 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
7016 TL.getTypePtr()->getDecl());
7017 if (!D) return QualType();
7018
7019 QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
7020 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
7021 return T;
7022}
7023
7024template<typename Derived>
7026 TypeLocBuilder &TLB,
7028 return getDerived().TransformTemplateTypeParmType(
7029 TLB, TL,
7030 /*SuppressObjCLifetime=*/false);
7031}
7032
7033template <typename Derived>
7035 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7036 return TransformTypeSpecType(TLB, TL);
7037}
7038
7039template<typename Derived>
7040QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7041 TypeLocBuilder &TLB,
7042 SubstTemplateTypeParmTypeLoc TL) {
7043 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7044
7045 Decl *NewReplaced =
7046 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7047
7048 // Substitute into the replacement type, which itself might involve something
7049 // that needs to be transformed. This only tends to occur with default
7050 // template arguments of template template parameters.
7051 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7052 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7053 if (Replacement.isNull())
7054 return QualType();
7055
7056 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7057 Replacement, NewReplaced, T->getIndex(), T->getPackIndex());
7058
7059 // Propagate type-source information.
7060 SubstTemplateTypeParmTypeLoc NewTL
7061 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
7062 NewTL.setNameLoc(TL.getNameLoc());
7063 return Result;
7064
7065}
7066
7067template<typename Derived>
7069 TypeLocBuilder &TLB,
7071 return getDerived().TransformSubstTemplateTypeParmPackType(
7072 TLB, TL, /*SuppressObjCLifetime=*/false);
7073}
7074
7075template <typename Derived>
7078 return TransformTypeSpecType(TLB, TL);
7079}
7080
7081template<typename Derived>
7083 TypeLocBuilder &TLB,
7086
7087 // The nested-name-specifier never matters in a TemplateSpecializationType,
7088 // because we can't have a dependent nested-name-specifier anyway.
7089 CXXScopeSpec SS;
7090 TemplateName Template
7091 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
7092 TL.getTemplateNameLoc());
7093 if (Template.isNull())
7094 return QualType();
7095
7096 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
7097}
7098
7099template<typename Derived>
7101 AtomicTypeLoc TL) {
7102 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7103 if (ValueType.isNull())
7104 return QualType();
7105
7106 QualType Result = TL.getType();
7107 if (getDerived().AlwaysRebuild() ||
7108 ValueType != TL.getValueLoc().getType()) {
7109 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7110 if (Result.isNull())
7111 return QualType();
7112 }
7113
7114 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
7115 NewTL.setKWLoc(TL.getKWLoc());
7116 NewTL.setLParenLoc(TL.getLParenLoc());
7117 NewTL.setRParenLoc(TL.getRParenLoc());
7118
7119 return Result;
7120}
7121
7122template <typename Derived>
7123QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7124 PipeTypeLoc TL) {
7125 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7126 if (ValueType.isNull())
7127 return QualType();
7128
7129 QualType Result = TL.getType();
7130 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7131 const PipeType *PT = Result->castAs<PipeType>();
7132 bool isReadPipe = PT->isReadOnly();
7133 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7134 if (Result.isNull())
7135 return QualType();
7136 }
7137
7138 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);
7139 NewTL.setKWLoc(TL.getKWLoc());
7140
7141 return Result;
7142}
7143
7144template <typename Derived>
7145QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7146 BitIntTypeLoc TL) {
7147 const BitIntType *EIT = TL.getTypePtr();
7148 QualType Result = TL.getType();
7149
7150 if (getDerived().AlwaysRebuild()) {
7151 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7152 EIT->getNumBits(), TL.getNameLoc());
7153 if (Result.isNull())
7154 return QualType();
7155 }
7156
7157 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
7158 NewTL.setNameLoc(TL.getNameLoc());
7159 return Result;
7160}
7161
7162template <typename Derived>
7163QualType TreeTransform<Derived>::TransformDependentBitIntType(
7164 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7165 const DependentBitIntType *EIT = TL.getTypePtr();
7166
7167 EnterExpressionEvaluationContext Unevaluated(
7169 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7170 BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr);
7171
7172 if (BitsExpr.isInvalid())
7173 return QualType();
7174
7175 QualType Result = TL.getType();
7176
7177 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7178 Result = getDerived().RebuildDependentBitIntType(
7179 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7180
7181 if (Result.isNull())
7182 return QualType();
7183 }
7184
7185 if (isa<DependentBitIntType>(Result)) {
7186 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);
7187 NewTL.setNameLoc(TL.getNameLoc());
7188 } else {
7189 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
7190 NewTL.setNameLoc(TL.getNameLoc());
7191 }
7192 return Result;
7193}
7194
7195 /// Simple iterator that traverses the template arguments in a
7196 /// container that provides a \c getArgLoc() member function.
7197 ///
7198 /// This iterator is intended to be used with the iterator form of
7199 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7200 template<typename ArgLocContainer>
7202 ArgLocContainer *Container;
7203 unsigned Index;
7204
7205 public:
7208 typedef int difference_type;
7209 typedef std::input_iterator_tag iterator_category;
7210
7211 class pointer {
7213
7214 public:
7215 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7216
7218 return &Arg;
7219 }
7220 };
7221
7222
7224
7225 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7226 unsigned Index)
7227 : Container(&Container), Index(Index) { }
7228
7230 ++Index;
7231 return *this;
7232 }
7233
7236 ++(*this);
7237 return Old;
7238 }
7239
7241 return Container->getArgLoc(Index);
7242 }
7243
7245 return pointer(Container->getArgLoc(Index));
7246 }
7247
7250 return X.Container == Y.Container && X.Index == Y.Index;
7251 }
7252
7255 return !(X == Y);
7256 }
7257 };
7258
7259template<typename Derived>
7260QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7261 AutoTypeLoc TL) {
7262 const AutoType *T = TL.getTypePtr();
7263 QualType OldDeduced = T->getDeducedType();
7264 QualType NewDeduced;
7265 if (!OldDeduced.isNull()) {
7266 NewDeduced = getDerived().TransformType(OldDeduced);
7267 if (NewDeduced.isNull())
7268 return QualType();
7269 }
7270
7271 ConceptDecl *NewCD = nullptr;
7272 TemplateArgumentListInfo NewTemplateArgs;
7273 NestedNameSpecifierLoc NewNestedNameSpec;
7274 if (T->isConstrained()) {
7275 assert(TL.getConceptReference());
7276 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7277 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7278
7279 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7280 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7281 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7282 if (getDerived().TransformTemplateArguments(
7283 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7284 NewTemplateArgs))
7285 return QualType();
7286
7287 if (TL.getNestedNameSpecifierLoc()) {
7288 NewNestedNameSpec
7289 = getDerived().TransformNestedNameSpecifierLoc(
7290 TL.getNestedNameSpecifierLoc());
7291 if (!NewNestedNameSpec)
7292 return QualType();
7293 }
7294 }
7295
7296 QualType Result = TL.getType();
7297 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7298 T->isDependentType() || T->isConstrained()) {
7299 // FIXME: Maybe don't rebuild if all template arguments are the same.
7301 NewArgList.reserve(NewTemplateArgs.size());
7302 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7303 NewArgList.push_back(ArgLoc.getArgument());
7304 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7305 NewArgList);
7306 if (Result.isNull())
7307 return QualType();
7308 }
7309
7310 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
7311 NewTL.setNameLoc(TL.getNameLoc());
7312 NewTL.setRParenLoc(TL.getRParenLoc());
7313 NewTL.setConceptReference(nullptr);
7314
7315 if (T->isConstrained()) {
7316 DeclarationNameInfo DNI = DeclarationNameInfo(
7317 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7318 TL.getConceptNameLoc(),
7319 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7320 auto *CR = ConceptReference::Create(
7321 SemaRef.Context, NewNestedNameSpec, TL.getTemplateKWLoc(), DNI,
7322 TL.getFoundDecl(), TL.getTypePtr()->getTypeConstraintConcept(),
7323 ASTTemplateArgumentListInfo::Create(SemaRef.Context, NewTemplateArgs));
7324 NewTL.setConceptReference(CR);
7325 }
7326
7327 return Result;
7328}
7329
7330template <typename Derived>
7332 TypeLocBuilder &TLB,
7333 TemplateSpecializationTypeLoc TL,
7334 TemplateName Template) {
7335 TemplateArgumentListInfo NewTemplateArgs;
7336 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7337 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7338 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7339 ArgIterator;
7340 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7341 ArgIterator(TL, TL.getNumArgs()),
7342 NewTemplateArgs))
7343 return QualType();
7344
7345 // This needs to be rebuilt if either the arguments changed, or if the
7346 // original template changed. If the template changed, and even if the
7347 // arguments didn't change, these arguments might not correspond to their
7348 // respective parameters, therefore needing conversions.
7349 QualType Result =
7350 getDerived().RebuildTemplateSpecializationType(Template,
7351 TL.getTemplateNameLoc(),
7352 NewTemplateArgs);
7353
7354 if (!Result.isNull()) {
7355 // Specializations of template template parameters are represented as
7356 // TemplateSpecializationTypes, and substitution of type alias templates
7357 // within a dependent context can transform them into
7358 // DependentTemplateSpecializationTypes.
7359 if (isa<DependentTemplateSpecializationType>(Result)) {
7360 DependentTemplateSpecializationTypeLoc NewTL
7361 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7362 NewTL.setElaboratedKeywordLoc(SourceLocation());
7363 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
7364 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7365 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7366 NewTL.setLAngleLoc(TL.getLAngleLoc());
7367 NewTL.setRAngleLoc(TL.getRAngleLoc());
7368 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7369 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7370 return Result;
7371 }
7372
7373 TemplateSpecializationTypeLoc NewTL
7374 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7375 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7376 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7377 NewTL.setLAngleLoc(TL.getLAngleLoc());
7378 NewTL.setRAngleLoc(TL.getRAngleLoc());
7379 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7380 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7381 }
7382
7383 return Result;
7384}
7385
7386template <typename Derived>
7388 TypeLocBuilder &TLB,
7390 TemplateName Template,
7391 CXXScopeSpec &SS) {
7392 TemplateArgumentListInfo NewTemplateArgs;
7393 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7394 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7397 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7398 ArgIterator(TL, TL.getNumArgs()),
7399 NewTemplateArgs))
7400 return QualType();
7401
7402 // FIXME: maybe don't rebuild if all the template arguments are the same.
7403
7404 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
7405 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
7406 TL.getTypePtr()->getKeyword(), DTN->getQualifier(),
7407 DTN->getIdentifier(), NewTemplateArgs.arguments());
7408
7412 NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
7415 NewTL.setLAngleLoc(TL.getLAngleLoc());
7416 NewTL.setRAngleLoc(TL.getRAngleLoc());
7417 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7418 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7419 return Result;
7420 }
7421
7423 = getDerived().RebuildTemplateSpecializationType(Template,
7424 TL.getTemplateNameLoc(),
7425 NewTemplateArgs);
7426
7427 if (!Result.isNull()) {
7428 /// FIXME: Wrap this in an elaborated-type-specifier?
7433 NewTL.setLAngleLoc(TL.getLAngleLoc());
7434 NewTL.setRAngleLoc(TL.getRAngleLoc());
7435 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7436 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7437 }
7438
7439 return Result;
7440}
7441
7442template<typename Derived>
7445 ElaboratedTypeLoc TL) {
7446 const ElaboratedType *T = TL.getTypePtr();
7447
7448 NestedNameSpecifierLoc QualifierLoc;
7449 // NOTE: the qualifier in an ElaboratedType is optional.
7450 if (TL.getQualifierLoc()) {
7451 QualifierLoc
7452 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7453 if (!QualifierLoc)
7454 return QualType();
7455 }
7456
7457 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7458 if (NamedT.isNull())
7459 return QualType();
7460
7461 // C++0x [dcl.type.elab]p2:
7462 // If the identifier resolves to a typedef-name or the simple-template-id
7463 // resolves to an alias template specialization, the
7464 // elaborated-type-specifier is ill-formed.
7465 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7466 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7467 if (const TemplateSpecializationType *TST =
7468 NamedT->getAs<TemplateSpecializationType>()) {
7469 TemplateName Template = TST->getTemplateName();
7470 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7471 Template.getAsTemplateDecl())) {
7472 SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
7473 diag::err_tag_reference_non_tag)
7475 << llvm::to_underlying(
7477 SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
7478 }
7479 }
7480 }
7481
7482 QualType Result = TL.getType();
7483 if (getDerived().AlwaysRebuild() ||
7484 QualifierLoc != TL.getQualifierLoc() ||
7485 NamedT != T->getNamedType()) {
7486 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7487 T->getKeyword(),
7488 QualifierLoc, NamedT);
7489 if (Result.isNull())
7490 return QualType();
7491 }
7492
7493 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7494 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7495 NewTL.setQualifierLoc(QualifierLoc);
7496 return Result;
7497}
7498
7499template <typename Derived>
7500QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7501 AttributedTypeLoc TL) {
7502 const AttributedType *oldType = TL.getTypePtr();
7503 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7504 if (modifiedType.isNull())
7505 return QualType();
7506
7507 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7508 const Attr *oldAttr = TL.getAttr();
7509 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7510 if (oldAttr && !newAttr)
7511 return QualType();
7512
7513 QualType result = TL.getType();
7514
7515 // FIXME: dependent operand expressions?
7516 if (getDerived().AlwaysRebuild() ||
7517 modifiedType != oldType->getModifiedType()) {
7518 // If the equivalent type is equal to the modified type, we don't want to
7519 // transform it as well because:
7520 //
7521 // 1. The transformation would yield the same result and is therefore
7522 // superfluous, and
7523 //
7524 // 2. Transforming the same type twice can cause problems, e.g. if it
7525 // is a FunctionProtoType, we may end up instantiating the function
7526 // parameters twice, which causes an assertion since the parameters
7527 // are already bound to their counterparts in the template for this
7528 // instantiation.
7529 //
7530 QualType equivalentType = modifiedType;
7531 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7532 TypeLocBuilder AuxiliaryTLB;
7533 AuxiliaryTLB.reserve(TL.getFullDataSize());
7534 equivalentType =
7535 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7536 if (equivalentType.isNull())
7537 return QualType();
7538 }
7539
7540 // Check whether we can add nullability; it is only represented as
7541 // type sugar, and therefore cannot be diagnosed in any other way.
7542 if (auto nullability = oldType->getImmediateNullability()) {
7543 if (!modifiedType->canHaveNullability()) {
7544 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
7545 : TL.getModifiedLoc().getBeginLoc()),
7546 diag::err_nullability_nonpointer)
7547 << DiagNullabilityKind(*nullability, false) << modifiedType;
7548 return QualType();
7549 }
7550 }
7551
7552 result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
7553 modifiedType,
7554 equivalentType,
7555 TL.getAttr());
7556 }
7557
7558 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
7559 newTL.setAttr(newAttr);
7560 return result;
7561}
7562
7563template <typename Derived>
7564QualType TreeTransform<Derived>::TransformCountAttributedType(
7565 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7566 const CountAttributedType *OldTy = TL.getTypePtr();
7567 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7568 if (InnerTy.isNull())
7569 return QualType();
7570
7571 Expr *OldCount = TL.getCountExpr();
7572 Expr *NewCount = nullptr;
7573 if (OldCount) {
7574 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7575 if (CountResult.isInvalid())
7576 return QualType();
7577 NewCount = CountResult.get();
7578 }
7579
7580 QualType Result = TL.getType();
7581 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7582 OldCount != NewCount) {
7583 // Currently, CountAttributedType can only wrap incomplete array types.
7585 InnerTy, NewCount, OldTy->isCountInBytes(), OldTy->isOrNull());
7586 }
7587
7588 TLB.push<CountAttributedTypeLoc>(Result);
7589 return Result;
7590}
7591
7592template <typename Derived>
7593QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7594 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7595 // The BTFTagAttributedType is available for C only.
7596 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7597}
7598
7599template <typename Derived>
7600QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7601 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7602
7603 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7604
7605 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7606 if (WrappedTy.isNull())
7607 return QualType();
7608
7609 QualType ContainedTy = QualType();
7610 QualType OldContainedTy = oldType->getContainedType();
7611 if (!OldContainedTy.isNull()) {
7612 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7613 if (!oldContainedTSI)
7614 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7615 OldContainedTy, SourceLocation());
7616 TypeSourceInfo *ContainedTSI = getDerived().TransformType(oldContainedTSI);
7617 if (!ContainedTSI)
7618 return QualType();
7619 ContainedTy = ContainedTSI->getType();
7620 }
7621
7622 QualType Result = TL.getType();
7623 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7624 ContainedTy != oldType->getContainedType()) {
7626 WrappedTy, ContainedTy, oldType->getAttrs());
7627 }
7628
7629 TLB.push<HLSLAttributedResourceTypeLoc>(Result);
7630 return Result;
7631}
7632
7633template<typename Derived>
7634QualType
7635TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7636 ParenTypeLoc TL) {
7637 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7638 if (Inner.isNull())
7639 return QualType();
7640
7641 QualType Result = TL.getType();
7642 if (getDerived().AlwaysRebuild() ||
7643 Inner != TL.getInnerLoc().getType()) {
7644 Result = getDerived().RebuildParenType(Inner);
7645 if (Result.isNull())
7646 return QualType();
7647 }
7648
7649 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
7650 NewTL.setLParenLoc(TL.getLParenLoc());
7651 NewTL.setRParenLoc(TL.getRParenLoc());
7652 return Result;
7653}
7654
7655template <typename Derived>
7656QualType
7657TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7658 MacroQualifiedTypeLoc TL) {
7659 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7660 if (Inner.isNull())
7661 return QualType();
7662
7663 QualType Result = TL.getType();
7664 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7665 Result =
7666 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7667 if (Result.isNull())
7668 return QualType();
7669 }
7670
7671 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
7672 NewTL.setExpansionLoc(TL.getExpansionLoc());
7673 return Result;
7674}
7675
7676template<typename Derived>
7677QualType TreeTransform<Derived>::TransformDependentNameType(
7678 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7679 return TransformDependentNameType(TLB, TL, false);
7680}
7681
7682template<typename Derived>
7683QualType TreeTransform<Derived>::TransformDependentNameType(
7684 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7685 const DependentNameType *T = TL.getTypePtr();
7686
7687 NestedNameSpecifierLoc QualifierLoc
7688 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7689 if (!QualifierLoc)
7690 return QualType();
7691
7692 QualType Result
7693 = getDerived().RebuildDependentNameType(T->getKeyword(),
7694 TL.getElaboratedKeywordLoc(),
7695 QualifierLoc,
7696 T->getIdentifier(),
7697 TL.getNameLoc(),
7698 DeducedTSTContext);
7699 if (Result.isNull())
7700 return QualType();
7701
7702 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7703 QualType NamedT = ElabT->getNamedType();
7704 TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
7705
7706 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7707 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7708 NewTL.setQualifierLoc(QualifierLoc);
7709 } else {
7710 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
7711 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7712 NewTL.setQualifierLoc(QualifierLoc);
7713 NewTL.setNameLoc(TL.getNameLoc());
7714 }
7715 return Result;
7716}
7717
7718template<typename Derived>
7721 DependentTemplateSpecializationTypeLoc TL) {
7722 NestedNameSpecifierLoc QualifierLoc;
7723 if (TL.getQualifierLoc()) {
7724 QualifierLoc
7725 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7726 if (!QualifierLoc)
7727 return QualType();
7728 }
7729
7730 return getDerived()
7731 .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
7732}
7733
7734template<typename Derived>
7738 NestedNameSpecifierLoc QualifierLoc) {
7740
7741 TemplateArgumentListInfo NewTemplateArgs;
7742 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7743 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7744
7747 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7748 ArgIterator(TL, TL.getNumArgs()),
7749 NewTemplateArgs))
7750 return QualType();
7751
7752 QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
7753 T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(),
7754 T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs,
7755 /*AllowInjectedClassName*/ false);
7756 if (Result.isNull())
7757 return QualType();
7758
7759 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
7760 QualType NamedT = ElabT->getNamedType();
7761
7762 // Copy information relevant to the template specialization.
7764 = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
7767 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7768 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7769 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7770 NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7771
7772 // Copy information relevant to the elaborated type.
7775 NewTL.setQualifierLoc(QualifierLoc);
7776 } else if (isa<DependentTemplateSpecializationType>(Result)) {
7780 SpecTL.setQualifierLoc(QualifierLoc);
7783 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7784 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7785 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7786 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7787 } else {
7792 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7793 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7794 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7795 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7796 }
7797 return Result;
7798}
7799
7800template<typename Derived>
7803 QualType Pattern
7804 = getDerived().TransformType(TLB, TL.getPatternLoc());
7805 if (Pattern.isNull())
7806 return QualType();
7807
7808 QualType Result = TL.getType();
7809 if (getDerived().AlwaysRebuild() ||
7810 Pattern != TL.getPatternLoc().getType()) {
7811 Result = getDerived().RebuildPackExpansionType(Pattern,
7813 TL.getEllipsisLoc(),
7815 if (Result.isNull())
7816 return QualType();
7817 }
7818
7819 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
7820 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7821 return Result;
7822}
7823
7824template<typename Derived>
7825QualType
7826TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7827 ObjCInterfaceTypeLoc TL) {
7828 // ObjCInterfaceType is never dependent.
7829 TLB.pushFullCopy(TL);
7830 return TL.getType();
7831}
7832
7833template<typename Derived>
7834QualType
7835TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7836 ObjCTypeParamTypeLoc TL) {
7837 const ObjCTypeParamType *T = TL.getTypePtr();
7838 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7839 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7840 if (!OTP)
7841 return QualType();
7842
7843 QualType Result = TL.getType();
7844 if (getDerived().AlwaysRebuild() ||
7845 OTP != T->getDecl()) {
7846 Result = getDerived().RebuildObjCTypeParamType(
7847 OTP, TL.getProtocolLAngleLoc(),
7848 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7849 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7850 if (Result.isNull())
7851 return QualType();
7852 }
7853
7854 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
7855 if (TL.getNumProtocols()) {
7856 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7857 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7858 NewTL.setProtocolLoc(i, TL.getProtocolLoc(i));
7859 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7860 }
7861 return Result;
7862}
7863
7864template<typename Derived>
7865QualType
7866TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7867 ObjCObjectTypeLoc TL) {
7868 // Transform base type.
7869 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7870 if (BaseType.isNull())
7871 return QualType();
7872
7873 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7874
7875 // Transform type arguments.
7876 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7877 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7878 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7879 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7880 QualType TypeArg = TypeArgInfo->getType();
7881 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7882 AnyChanged = true;
7883
7884 // We have a pack expansion. Instantiate it.
7885 const auto *PackExpansion = PackExpansionLoc.getType()
7886 ->castAs<PackExpansionType>();
7888 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
7889 Unexpanded);
7890 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7891
7892 // Determine whether the set of unexpanded parameter packs can
7893 // and should be expanded.
7894 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7895 bool Expand = false;
7896 bool RetainExpansion = false;
7897 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
7898 if (getDerived().TryExpandParameterPacks(
7899 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7900 Unexpanded, Expand, RetainExpansion, NumExpansions))
7901 return QualType();
7902
7903 if (!Expand) {
7904 // We can't expand this pack expansion into separate arguments yet;
7905 // just substitute into the pattern and create a new pack expansion
7906 // type.
7907 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
7908
7909 TypeLocBuilder TypeArgBuilder;
7910 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7911 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7912 PatternLoc);
7913 if (NewPatternType.isNull())
7914 return QualType();
7915
7916 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7917 NewPatternType, NumExpansions);
7918 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);
7919 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7920 NewTypeArgInfos.push_back(
7921 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewExpansionType));
7922 continue;
7923 }
7924
7925 // Substitute into the pack expansion pattern for each slice of the
7926 // pack.
7927 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
7928 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
7929
7930 TypeLocBuilder TypeArgBuilder;
7931 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7932
7933 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
7934 PatternLoc);
7935 if (NewTypeArg.isNull())
7936 return QualType();
7937
7938 NewTypeArgInfos.push_back(
7939 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7940 }
7941
7942 continue;
7943 }
7944
7945 TypeLocBuilder TypeArgBuilder;
7946 TypeArgBuilder.reserve(TypeArgLoc.getFullDataSize());
7947 QualType NewTypeArg =
7948 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
7949 if (NewTypeArg.isNull())
7950 return QualType();
7951
7952 // If nothing changed, just keep the old TypeSourceInfo.
7953 if (NewTypeArg == TypeArg) {
7954 NewTypeArgInfos.push_back(TypeArgInfo);
7955 continue;
7956 }
7957
7958 NewTypeArgInfos.push_back(
7959 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7960 AnyChanged = true;
7961 }
7962
7963 QualType Result = TL.getType();
7964 if (getDerived().AlwaysRebuild() || AnyChanged) {
7965 // Rebuild the type.
7966 Result = getDerived().RebuildObjCObjectType(
7967 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
7968 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
7969 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7970 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7971
7972 if (Result.isNull())
7973 return QualType();
7974 }
7975
7976 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);
7977 NewT.setHasBaseTypeAsWritten(true);
7978 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
7979 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
7980 NewT.setTypeArgTInfo(i, NewTypeArgInfos[i]);
7981 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
7982 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7983 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7984 NewT.setProtocolLoc(i, TL.getProtocolLoc(i));
7985 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7986 return Result;
7987}
7988
7989template<typename Derived>
7990QualType
7991TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
7992 ObjCObjectPointerTypeLoc TL) {
7993 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
7994 if (PointeeType.isNull())
7995 return QualType();
7996
7997 QualType Result = TL.getType();
7998 if (getDerived().AlwaysRebuild() ||
7999 PointeeType != TL.getPointeeLoc().getType()) {
8000 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8001 TL.getStarLoc());
8002 if (Result.isNull())
8003 return QualType();
8004 }
8005
8006 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
8007 NewT.setStarLoc(TL.getStarLoc());
8008 return Result;
8009}
8010
8011//===----------------------------------------------------------------------===//
8012// Statement transformation
8013//===----------------------------------------------------------------------===//
8014template<typename Derived>
8016TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8017 return S;
8018}
8019
8020template<typename Derived>
8023 return getDerived().TransformCompoundStmt(S, false);
8024}
8025
8026template<typename Derived>
8029 bool IsStmtExpr) {
8030 Sema::CompoundScopeRAII CompoundScope(getSema());
8031 Sema::FPFeaturesStateRAII FPSave(getSema());
8032 if (S->hasStoredFPFeatures())
8033 getSema().resetFPOptions(
8034 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8035
8036 const Stmt *ExprResult = S->getStmtExprResult();
8037 bool SubStmtInvalid = false;
8038 bool SubStmtChanged = false;
8039 SmallVector<Stmt*, 8> Statements;
8040 for (auto *B : S->body()) {
8041 StmtResult Result = getDerived().TransformStmt(
8042 B, IsStmtExpr && B == ExprResult ? SDK_StmtExprResult : SDK_Discarded);
8043
8044 if (Result.isInvalid()) {
8045 // Immediately fail if this was a DeclStmt, since it's very
8046 // likely that this will cause problems for future statements.
8047 if (isa<DeclStmt>(B))
8048 return StmtError();
8049
8050 // Otherwise, just keep processing substatements and fail later.
8051 SubStmtInvalid = true;
8052 continue;
8053 }
8054
8055 SubStmtChanged = SubStmtChanged || Result.get() != B;
8056 Statements.push_back(Result.getAs<Stmt>());
8057 }
8058
8059 if (SubStmtInvalid)
8060 return StmtError();
8061
8062 if (!getDerived().AlwaysRebuild() &&
8063 !SubStmtChanged)
8064 return S;
8065
8066 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8067 Statements,
8068 S->getRBracLoc(),
8069 IsStmtExpr);
8070}
8071
8072template<typename Derived>
8074TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8075 ExprResult LHS, RHS;
8076 {
8077 EnterExpressionEvaluationContext Unevaluated(
8079
8080 // Transform the left-hand case value.
8081 LHS = getDerived().TransformExpr(S->getLHS());
8082 LHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), LHS);
8083 if (LHS.isInvalid())
8084 return StmtError();
8085
8086 // Transform the right-hand case value (for the GNU case-range extension).
8087 RHS = getDerived().TransformExpr(S->getRHS());
8088 RHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), RHS);
8089 if (RHS.isInvalid())
8090 return StmtError();
8091 }
8092
8093 // Build the case statement.
8094 // Case statements are always rebuilt so that they will attached to their
8095 // transformed switch statement.
8096 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8097 LHS.get(),
8098 S->getEllipsisLoc(),
8099 RHS.get(),
8100 S->getColonLoc());
8101 if (Case.isInvalid())
8102 return StmtError();
8103
8104 // Transform the statement following the case
8105 StmtResult SubStmt =
8106 getDerived().TransformStmt(S->getSubStmt());
8107 if (SubStmt.isInvalid())
8108 return StmtError();
8109
8110 // Attach the body to the case statement
8111 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8112}
8113
8114template <typename Derived>
8115StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8116 // Transform the statement following the default case
8117 StmtResult SubStmt =
8118 getDerived().TransformStmt(S->getSubStmt());
8119 if (SubStmt.isInvalid())
8120 return StmtError();
8121
8122 // Default statements are always rebuilt
8123 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8124 SubStmt.get());
8125}
8126
8127template<typename Derived>
8129TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8130 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8131 if (SubStmt.isInvalid())
8132 return StmtError();
8133
8134 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8135 S->getDecl());
8136 if (!LD)
8137 return StmtError();
8138
8139 // If we're transforming "in-place" (we're not creating new local
8140 // declarations), assume we're replacing the old label statement
8141 // and clear out the reference to it.
8142 if (LD == S->getDecl())
8143 S->getDecl()->setStmt(nullptr);
8144
8145 // FIXME: Pass the real colon location in.
8146 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8147 cast<LabelDecl>(LD), SourceLocation(),
8148 SubStmt.get());
8149}
8150
8151template <typename Derived>
8153 if (!R)
8154 return R;
8155
8156 switch (R->getKind()) {
8157// Transform attributes by calling TransformXXXAttr.
8158#define ATTR(X) \
8159 case attr::X: \
8160 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8161#include "clang/Basic/AttrList.inc"
8162 }
8163 return R;
8164}
8165
8166template <typename Derived>
8168 const Stmt *InstS,
8169 const Attr *R) {
8170 if (!R)
8171 return R;
8172
8173 switch (R->getKind()) {
8174// Transform attributes by calling TransformStmtXXXAttr.
8175#define ATTR(X) \
8176 case attr::X: \
8177 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8178#include "clang/Basic/AttrList.inc"
8179 }
8180 return TransformAttr(R);
8181}
8182
8183template <typename Derived>
8186 StmtDiscardKind SDK) {
8187 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8188 if (SubStmt.isInvalid())
8189 return StmtError();
8190
8191 bool AttrsChanged = false;
8193
8194 // Visit attributes and keep track if any are transformed.
8195 for (const auto *I : S->getAttrs()) {
8196 const Attr *R =
8197 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8198 AttrsChanged |= (I != R);
8199 if (R)
8200 Attrs.push_back(R);
8201 }
8202
8203 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8204 return S;
8205
8206 // If transforming the attributes failed for all of the attributes in the
8207 // statement, don't make an AttributedStmt without attributes.
8208 if (Attrs.empty())
8209 return SubStmt;
8210
8211 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8212 SubStmt.get());
8213}
8214
8215template<typename Derived>
8217TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8218 // Transform the initialization statement
8219 StmtResult Init = getDerived().TransformStmt(S->getInit());
8220 if (Init.isInvalid())
8221 return StmtError();
8222
8223 Sema::ConditionResult Cond;
8224 if (!S->isConsteval()) {
8225 // Transform the condition
8226 Cond = getDerived().TransformCondition(
8227 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8228 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8230 if (Cond.isInvalid())
8231 return StmtError();
8232 }
8233
8234 // If this is a constexpr if, determine which arm we should instantiate.
8235 std::optional<bool> ConstexprConditionValue;
8236 if (S->isConstexpr())
8237 ConstexprConditionValue = Cond.getKnownValue();
8238
8239 // Transform the "then" branch.
8240 StmtResult Then;
8241 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8242 EnterExpressionEvaluationContext Ctx(
8245 S->isNonNegatedConsteval());
8246
8247 Then = getDerived().TransformStmt(S->getThen());
8248 if (Then.isInvalid())
8249 return StmtError();
8250 } else {
8251 // Discarded branch is replaced with empty CompoundStmt so we can keep
8252 // proper source location for start and end of original branch, so
8253 // subsequent transformations like CoverageMapping work properly
8254 Then = new (getSema().Context)
8255 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8256 }
8257
8258 // Transform the "else" branch.
8259 StmtResult Else;
8260 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8261 EnterExpressionEvaluationContext Ctx(
8264 S->isNegatedConsteval());
8265
8266 Else = getDerived().TransformStmt(S->getElse());
8267 if (Else.isInvalid())
8268 return StmtError();
8269 } else if (S->getElse() && ConstexprConditionValue &&
8270 *ConstexprConditionValue) {
8271 // Same thing here as with <then> branch, we are discarding it, we can't
8272 // replace it with NULL nor NullStmt as we need to keep for source location
8273 // range, for CoverageMapping
8274 Else = new (getSema().Context)
8275 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8276 }
8277
8278 if (!getDerived().AlwaysRebuild() &&
8279 Init.get() == S->getInit() &&
8280 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8281 Then.get() == S->getThen() &&
8282 Else.get() == S->getElse())
8283 return S;
8284
8285 return getDerived().RebuildIfStmt(
8286 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8287 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8288}
8289
8290template<typename Derived>
8292TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8293 // Transform the initialization statement
8294 StmtResult Init = getDerived().TransformStmt(S->getInit());
8295 if (Init.isInvalid())
8296 return StmtError();
8297
8298 // Transform the condition.
8299 Sema::ConditionResult Cond = getDerived().TransformCondition(
8300 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8302 if (Cond.isInvalid())
8303 return StmtError();
8304
8305 // Rebuild the switch statement.
8307 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8308 Init.get(), Cond, S->getRParenLoc());
8309 if (Switch.isInvalid())
8310 return StmtError();
8311
8312 // Transform the body of the switch statement.
8313 StmtResult Body = getDerived().TransformStmt(S->getBody());
8314 if (Body.isInvalid())
8315 return StmtError();
8316
8317 // Complete the switch statement.
8318 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8319 Body.get());
8320}
8321
8322template<typename Derived>
8324TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8325 // Transform the condition
8326 Sema::ConditionResult Cond = getDerived().TransformCondition(
8327 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8329 if (Cond.isInvalid())
8330 return StmtError();
8331
8332 // OpenACC Restricts a while-loop inside of certain construct/clause
8333 // combinations, so diagnose that here in OpenACC mode.
8334 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8335 SemaRef.OpenACC().ActOnWhileStmt(S->getBeginLoc());
8336
8337 // Transform the body
8338 StmtResult Body = getDerived().TransformStmt(S->getBody());
8339 if (Body.isInvalid())
8340 return StmtError();
8341
8342 if (!getDerived().AlwaysRebuild() &&
8343 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8344 Body.get() == S->getBody())
8345 return Owned(S);
8346
8347 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8348 Cond, S->getRParenLoc(), Body.get());
8349}
8350
8351template<typename Derived>
8353TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8354 // OpenACC Restricts a do-loop inside of certain construct/clause
8355 // combinations, so diagnose that here in OpenACC mode.
8356 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8357 SemaRef.OpenACC().ActOnDoStmt(S->getBeginLoc());
8358
8359 // Transform the body
8360 StmtResult Body = getDerived().TransformStmt(S->getBody());
8361 if (Body.isInvalid())
8362 return StmtError();
8363
8364 // Transform the condition
8365 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8366 if (Cond.isInvalid())
8367 return StmtError();
8368
8369 if (!getDerived().AlwaysRebuild() &&
8370 Cond.get() == S->getCond() &&
8371 Body.get() == S->getBody())
8372 return S;
8373
8374 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8375 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8376 S->getRParenLoc());
8377}
8378
8379template<typename Derived>
8381TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8382 if (getSema().getLangOpts().OpenMP)
8383 getSema().OpenMP().startOpenMPLoop();
8384
8385 // Transform the initialization statement
8386 StmtResult Init = getDerived().TransformStmt(S->getInit());
8387 if (Init.isInvalid())
8388 return StmtError();
8389
8390 // In OpenMP loop region loop control variable must be captured and be
8391 // private. Perform analysis of first part (if any).
8392 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8393 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8394 Init.get());
8395
8396 // Transform the condition
8397 Sema::ConditionResult Cond = getDerived().TransformCondition(
8398 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8400 if (Cond.isInvalid())
8401 return StmtError();
8402
8403 // Transform the increment
8404 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8405 if (Inc.isInvalid())
8406 return StmtError();
8407
8408 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8409 if (S->getInc() && !FullInc.get())
8410 return StmtError();
8411
8412 // OpenACC Restricts a for-loop inside of certain construct/clause
8413 // combinations, so diagnose that here in OpenACC mode.
8414 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8415 SemaRef.OpenACC().ActOnForStmtBegin(
8416 S->getBeginLoc(), S->getInit(), Init.get(), S->getCond(),
8417 Cond.get().second, S->getInc(), Inc.get());
8418
8419 // Transform the body
8420 StmtResult Body = getDerived().TransformStmt(S->getBody());
8421 if (Body.isInvalid())
8422 return StmtError();
8423
8424 SemaRef.OpenACC().ActOnForStmtEnd(S->getBeginLoc(), Body);
8425
8426 if (!getDerived().AlwaysRebuild() &&
8427 Init.get() == S->getInit() &&
8428 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8429 Inc.get() == S->getInc() &&
8430 Body.get() == S->getBody())
8431 return S;
8432
8433 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8434 Init.get(), Cond, FullInc,
8435 S->getRParenLoc(), Body.get());
8436}
8437
8438template<typename Derived>
8440TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8441 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8442 S->getLabel());
8443 if (!LD)
8444 return StmtError();
8445
8446 // Goto statements must always be rebuilt, to resolve the label.
8447 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8448 cast<LabelDecl>(LD));
8449}
8450
8451template<typename Derived>
8453TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8454 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8455 if (Target.isInvalid())
8456 return StmtError();
8457 Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());
8458
8459 if (!getDerived().AlwaysRebuild() &&
8460 Target.get() == S->getTarget())
8461 return S;
8462
8463 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8464 Target.get());
8465}
8466
8467template<typename Derived>
8469TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8470 return S;
8471}
8472
8473template<typename Derived>
8475TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8476 return S;
8477}
8478
8479template<typename Derived>
8481TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8482 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8483 /*NotCopyInit*/false);
8484 if (Result.isInvalid())
8485 return StmtError();
8486
8487 // FIXME: We always rebuild the return statement because there is no way
8488 // to tell whether the return type of the function has changed.
8489 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8490}
8491
8492template<typename Derived>
8494TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8495 bool DeclChanged = false;
8497 LambdaScopeInfo *LSI = getSema().getCurLambda();
8498 for (auto *D : S->decls()) {
8499 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8500 if (!Transformed)
8501 return StmtError();
8502
8503 if (Transformed != D)
8504 DeclChanged = true;
8505
8506 if (LSI) {
8507 if (auto *TD = dyn_cast<TypeDecl>(Transformed))
8508 LSI->ContainsUnexpandedParameterPack |=
8509 getSema()
8510 .getASTContext()
8511 .getTypeDeclType(TD)
8512 .getSingleStepDesugaredType(getSema().getASTContext())
8513 ->containsUnexpandedParameterPack();
8514
8515 if (auto *VD = dyn_cast<VarDecl>(Transformed))
8516 LSI->ContainsUnexpandedParameterPack |=
8517 VD->getType()->containsUnexpandedParameterPack();
8518 }
8519
8520 Decls.push_back(Transformed);
8521 }
8522
8523 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8524 return S;
8525
8526 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8527}
8528
8529template<typename Derived>
8531TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8532
8533 SmallVector<Expr*, 8> Constraints;
8536
8537 ExprResult AsmString;
8538 SmallVector<Expr*, 8> Clobbers;
8539
8540 bool ExprsChanged = false;
8541
8542 // Go through the outputs.
8543 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8544 Names.push_back(S->getOutputIdentifier(I));
8545
8546 // No need to transform the constraint literal.
8547 Constraints.push_back(S->getOutputConstraintLiteral(I));
8548
8549 // Transform the output expr.
8550 Expr *OutputExpr = S->getOutputExpr(I);
8551 ExprResult Result = getDerived().TransformExpr(OutputExpr);
8552 if (Result.isInvalid())
8553 return StmtError();
8554
8555 ExprsChanged |= Result.get() != OutputExpr;
8556
8557 Exprs.push_back(Result.get());
8558 }
8559
8560 // Go through the inputs.
8561 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8562 Names.push_back(S->getInputIdentifier(I));
8563
8564 // No need to transform the constraint literal.
8565 Constraints.push_back(S->getInputConstraintLiteral(I));
8566
8567 // Transform the input expr.
8568 Expr *InputExpr = S->getInputExpr(I);
8569 ExprResult Result = getDerived().TransformExpr(InputExpr);
8570 if (Result.isInvalid())
8571 return StmtError();
8572
8573 ExprsChanged |= Result.get() != InputExpr;
8574
8575 Exprs.push_back(Result.get());
8576 }
8577
8578 // Go through the Labels.
8579 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8580 Names.push_back(S->getLabelIdentifier(I));
8581
8582 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(I));
8583 if (Result.isInvalid())
8584 return StmtError();
8585 ExprsChanged |= Result.get() != S->getLabelExpr(I);
8586 Exprs.push_back(Result.get());
8587 }
8588 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8589 return S;
8590
8591 // Go through the clobbers.
8592 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
8593 Clobbers.push_back(S->getClobberStringLiteral(I));
8594
8595 // No need to transform the asm string literal.
8596 AsmString = S->getAsmString();
8597 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8598 S->isVolatile(), S->getNumOutputs(),
8599 S->getNumInputs(), Names.data(),
8600 Constraints, Exprs, AsmString.get(),
8601 Clobbers, S->getNumLabels(),
8602 S->getRParenLoc());
8603}
8604
8605template<typename Derived>
8607TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8608 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8609
8610 bool HadError = false, HadChange = false;
8611
8612 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8613 SmallVector<Expr*, 8> TransformedExprs;
8614 TransformedExprs.reserve(SrcExprs.size());
8615 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8616 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8617 if (!Result.isUsable()) {
8618 HadError = true;
8619 } else {
8620 HadChange |= (Result.get() != SrcExprs[i]);
8621 TransformedExprs.push_back(Result.get());
8622 }
8623 }
8624
8625 if (HadError) return StmtError();
8626 if (!HadChange && !getDerived().AlwaysRebuild())
8627 return Owned(S);
8628
8629 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8630 AsmToks, S->getAsmString(),
8631 S->getNumOutputs(), S->getNumInputs(),
8632 S->getAllConstraints(), S->getClobbers(),
8633 TransformedExprs, S->getEndLoc());
8634}
8635
8636// C++ Coroutines
8637template<typename Derived>
8639TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8640 auto *ScopeInfo = SemaRef.getCurFunction();
8641 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
8642 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8643 ScopeInfo->NeedsCoroutineSuspends &&
8644 ScopeInfo->CoroutineSuspends.first == nullptr &&
8645 ScopeInfo->CoroutineSuspends.second == nullptr &&
8646 "expected clean scope info");
8647
8648 // Set that we have (possibly-invalid) suspend points before we do anything
8649 // that may fail.
8650 ScopeInfo->setNeedsCoroutineSuspends(false);
8651
8652 // We re-build the coroutine promise object (and the coroutine parameters its
8653 // type and constructor depend on) based on the types used in our current
8654 // function. We must do so, and set it on the current FunctionScopeInfo,
8655 // before attempting to transform the other parts of the coroutine body
8656 // statement, such as the implicit suspend statements (because those
8657 // statements reference the FunctionScopeInfo::CoroutinePromise).
8658 if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation()))
8659 return StmtError();
8660 auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());
8661 if (!Promise)
8662 return StmtError();
8663 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8664 ScopeInfo->CoroutinePromise = Promise;
8665
8666 // Transform the implicit coroutine statements constructed using dependent
8667 // types during the previous parse: initial and final suspensions, the return
8668 // object, and others. We also transform the coroutine function's body.
8669 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8670 if (InitSuspend.isInvalid())
8671 return StmtError();
8672 StmtResult FinalSuspend =
8673 getDerived().TransformStmt(S->getFinalSuspendStmt());
8674 if (FinalSuspend.isInvalid() ||
8675 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get()))
8676 return StmtError();
8677 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
8678 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8679
8680 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8681 if (BodyRes.isInvalid())
8682 return StmtError();
8683
8684 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8685 if (Builder.isInvalid())
8686 return StmtError();
8687
8688 Expr *ReturnObject = S->getReturnValueInit();
8689 assert(ReturnObject && "the return object is expected to be valid");
8690 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8691 /*NoCopyInit*/ false);
8692 if (Res.isInvalid())
8693 return StmtError();
8694 Builder.ReturnValue = Res.get();
8695
8696 // If during the previous parse the coroutine still had a dependent promise
8697 // statement, we may need to build some implicit coroutine statements
8698 // (such as exception and fallthrough handlers) for the first time.
8699 if (S->hasDependentPromiseType()) {
8700 // We can only build these statements, however, if the current promise type
8701 // is not dependent.
8702 if (!Promise->getType()->isDependentType()) {
8703 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8704 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8705 "these nodes should not have been built yet");
8706 if (!Builder.buildDependentStatements())
8707 return StmtError();
8708 }
8709 } else {
8710 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8711 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8712 if (Res.isInvalid())
8713 return StmtError();
8714 Builder.OnFallthrough = Res.get();
8715 }
8716
8717 if (auto *OnException = S->getExceptionHandler()) {
8718 StmtResult Res = getDerived().TransformStmt(OnException);
8719 if (Res.isInvalid())
8720 return StmtError();
8721 Builder.OnException = Res.get();
8722 }
8723
8724 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8725 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8726 if (Res.isInvalid())
8727 return StmtError();
8728 Builder.ReturnStmtOnAllocFailure = Res.get();
8729 }
8730
8731 // Transform any additional statements we may have already built
8732 assert(S->getAllocate() && S->getDeallocate() &&
8733 "allocation and deallocation calls must already be built");
8734 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8735 if (AllocRes.isInvalid())
8736 return StmtError();
8737 Builder.Allocate = AllocRes.get();
8738
8739 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8740 if (DeallocRes.isInvalid())
8741 return StmtError();
8742 Builder.Deallocate = DeallocRes.get();
8743
8744 if (auto *ResultDecl = S->getResultDecl()) {
8745 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8746 if (Res.isInvalid())
8747 return StmtError();
8748 Builder.ResultDecl = Res.get();
8749 }
8750
8751 if (auto *ReturnStmt = S->getReturnStmt()) {
8752 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8753 if (Res.isInvalid())
8754 return StmtError();
8755 Builder.ReturnStmt = Res.get();
8756 }
8757 }
8758
8759 return getDerived().RebuildCoroutineBodyStmt(Builder);
8760}
8761
8762template<typename Derived>
8764TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8765 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8766 /*NotCopyInit*/false);
8767 if (Result.isInvalid())
8768 return StmtError();
8769
8770 // Always rebuild; we don't know if this needs to be injected into a new
8771 // context or if the promise type has changed.
8772 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8773 S->isImplicit());
8774}
8775
8776template <typename Derived>
8777ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8778 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8779 /*NotCopyInit*/ false);
8780 if (Operand.isInvalid())
8781 return ExprError();
8782
8783 // Rebuild the common-expr from the operand rather than transforming it
8784 // separately.
8785
8786 // FIXME: getCurScope() should not be used during template instantiation.
8787 // We should pick up the set of unqualified lookup results for operator
8788 // co_await during the initial parse.
8789 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8790 getSema().getCurScope(), E->getKeywordLoc());
8791
8792 // Always rebuild; we don't know if this needs to be injected into a new
8793 // context or if the promise type has changed.
8794 return getDerived().RebuildCoawaitExpr(
8795 E->getKeywordLoc(), Operand.get(),
8796 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());
8797}
8798
8799template <typename Derived>
8801TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8802 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8803 /*NotCopyInit*/ false);
8804 if (OperandResult.isInvalid())
8805 return ExprError();
8806
8807 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8808 E->getOperatorCoawaitLookup());
8809
8810 if (LookupResult.isInvalid())
8811 return ExprError();
8812
8813 // Always rebuild; we don't know if this needs to be injected into a new
8814 // context or if the promise type has changed.
8815 return getDerived().RebuildDependentCoawaitExpr(
8816 E->getKeywordLoc(), OperandResult.get(),
8817 cast<UnresolvedLookupExpr>(LookupResult.get()));
8818}
8819
8820template<typename Derived>
8822TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8823 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8824 /*NotCopyInit*/false);
8825 if (Result.isInvalid())
8826 return ExprError();
8827
8828 // Always rebuild; we don't know if this needs to be injected into a new
8829 // context or if the promise type has changed.
8830 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8831}
8832
8833// Objective-C Statements.
8834
8835template<typename Derived>
8837TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8838 // Transform the body of the @try.
8839 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8840 if (TryBody.isInvalid())
8841 return StmtError();
8842
8843 // Transform the @catch statements (if present).
8844 bool AnyCatchChanged = false;
8845 SmallVector<Stmt*, 8> CatchStmts;
8846 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8847 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8848 if (Catch.isInvalid())
8849 return StmtError();
8850 if (Catch.get() != S->getCatchStmt(I))
8851 AnyCatchChanged = true;
8852 CatchStmts.push_back(Catch.get());
8853 }
8854
8855 // Transform the @finally statement (if present).
8856 StmtResult Finally;
8857 if (S->getFinallyStmt()) {
8858 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8859 if (Finally.isInvalid())
8860 return StmtError();
8861 }
8862
8863 // If nothing changed, just retain this statement.
8864 if (!getDerived().AlwaysRebuild() &&
8865 TryBody.get() == S->getTryBody() &&
8866 !AnyCatchChanged &&
8867 Finally.get() == S->getFinallyStmt())
8868 return S;
8869
8870 // Build a new statement.
8871 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8872 CatchStmts, Finally.get());
8873}
8874
8875template<typename Derived>
8877TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8878 // Transform the @catch parameter, if there is one.
8879 VarDecl *Var = nullptr;
8880 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8881 TypeSourceInfo *TSInfo = nullptr;
8882 if (FromVar->getTypeSourceInfo()) {
8883 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8884 if (!TSInfo)
8885 return StmtError();
8886 }
8887
8888 QualType T;
8889 if (TSInfo)
8890 T = TSInfo->getType();
8891 else {
8892 T = getDerived().TransformType(FromVar->getType());
8893 if (T.isNull())
8894 return StmtError();
8895 }
8896
8897 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8898 if (!Var)
8899 return StmtError();
8900 }
8901
8902 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8903 if (Body.isInvalid())
8904 return StmtError();
8905
8906 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
8907 S->getRParenLoc(),
8908 Var, Body.get());
8909}
8910
8911template<typename Derived>
8913TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
8914 // Transform the body.
8915 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
8916 if (Body.isInvalid())
8917 return StmtError();
8918
8919 // If nothing changed, just retain this statement.
8920 if (!getDerived().AlwaysRebuild() &&
8921 Body.get() == S->getFinallyBody())
8922 return S;
8923
8924 // Build a new statement.
8925 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
8926 Body.get());
8927}
8928
8929template<typename Derived>
8931TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
8933 if (S->getThrowExpr()) {
8934 Operand = getDerived().TransformExpr(S->getThrowExpr());
8935 if (Operand.isInvalid())
8936 return StmtError();
8937 }
8938
8939 if (!getDerived().AlwaysRebuild() &&
8940 Operand.get() == S->getThrowExpr())
8941 return S;
8942
8943 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
8944}
8945
8946template<typename Derived>
8948TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
8949 ObjCAtSynchronizedStmt *S) {
8950 // Transform the object we are locking.
8951 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
8952 if (Object.isInvalid())
8953 return StmtError();
8954 Object =
8955 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
8956 Object.get());
8957 if (Object.isInvalid())
8958 return StmtError();
8959
8960 // Transform the body.
8961 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
8962 if (Body.isInvalid())
8963 return StmtError();
8964
8965 // If nothing change, just retain the current statement.
8966 if (!getDerived().AlwaysRebuild() &&
8967 Object.get() == S->getSynchExpr() &&
8968 Body.get() == S->getSynchBody())
8969 return S;
8970
8971 // Build a new statement.
8972 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
8973 Object.get(), Body.get());
8974}
8975
8976template<typename Derived>
8978TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
8979 ObjCAutoreleasePoolStmt *S) {
8980 // Transform the body.
8981 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
8982 if (Body.isInvalid())
8983 return StmtError();
8984
8985 // If nothing changed, just retain this statement.
8986 if (!getDerived().AlwaysRebuild() &&
8987 Body.get() == S->getSubStmt())
8988 return S;
8989
8990 // Build a new statement.
8991 return getDerived().RebuildObjCAutoreleasePoolStmt(
8992 S->getAtLoc(), Body.get());
8993}
8994
8995template<typename Derived>
8997TreeTransform<Derived>::TransformObjCForCollectionStmt(
8998 ObjCForCollectionStmt *S) {
8999 // Transform the element statement.
9000 StmtResult Element =
9001 getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded);
9002 if (Element.isInvalid())
9003 return StmtError();
9004
9005 // Transform the collection expression.
9006 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9007 if (Collection.isInvalid())
9008 return StmtError();
9009
9010 // Transform the body.
9011 StmtResult Body = getDerived().TransformStmt(S->getBody());
9012 if (Body.isInvalid())
9013 return StmtError();
9014
9015 // If nothing changed, just retain this statement.
9016 if (!getDerived().AlwaysRebuild() &&
9017 Element.get() == S->getElement() &&
9018 Collection.get() == S->getCollection() &&
9019 Body.get() == S->getBody())
9020 return S;
9021
9022 // Build a new statement.
9023 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9024 Element.get(),
9025 Collection.get(),
9026 S->getRParenLoc(),
9027 Body.get());
9028}
9029
9030template <typename Derived>
9031StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9032 // Transform the exception declaration, if any.
9033 VarDecl *Var = nullptr;
9034 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9035 TypeSourceInfo *T =
9036 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9037 if (!T)
9038 return StmtError();
9039
9040 Var = getDerived().RebuildExceptionDecl(
9041 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9042 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9043 if (!Var || Var->isInvalidDecl())
9044 return StmtError();
9045 }
9046
9047 // Transform the actual exception handler.
9048 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9049 if (Handler.isInvalid())
9050 return StmtError();
9051
9052 if (!getDerived().AlwaysRebuild() && !Var &&
9053 Handler.get() == S->getHandlerBlock())
9054 return S;
9055
9056 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9057}
9058
9059template <typename Derived>
9060StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9061 // Transform the try block itself.
9062 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9063 if (TryBlock.isInvalid())
9064 return StmtError();
9065
9066 // Transform the handlers.
9067 bool HandlerChanged = false;
9068 SmallVector<Stmt *, 8> Handlers;
9069 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9070 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I));
9071 if (Handler.isInvalid())
9072 return StmtError();
9073
9074 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
9075 Handlers.push_back(Handler.getAs<Stmt>());
9076 }
9077
9078 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9079 !HandlerChanged)
9080 return S;
9081
9082 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9083 Handlers);
9084}
9085
9086template<typename Derived>
9088TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9089 EnterExpressionEvaluationContext ForRangeInitContext(
9091 /*LambdaContextDecl=*/nullptr,
9093 getSema().getLangOpts().CPlusPlus23);
9094
9095 // P2718R0 - Lifetime extension in range-based for loops.
9096 if (getSema().getLangOpts().CPlusPlus23) {
9097 auto &LastRecord = getSema().currentEvaluationContext();
9098 LastRecord.InLifetimeExtendingContext = true;
9099 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9100 }
9102 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9103 if (Init.isInvalid())
9104 return StmtError();
9105
9106 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9107 if (Range.isInvalid())
9108 return StmtError();
9109
9110 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9111 assert(getSema().getLangOpts().CPlusPlus23 ||
9112 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9113 auto ForRangeLifetimeExtendTemps =
9114 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9115
9116 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9117 if (Begin.isInvalid())
9118 return StmtError();
9119 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9120 if (End.isInvalid())
9121 return StmtError();
9122
9123 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9124 if (Cond.isInvalid())
9125 return StmtError();
9126 if (Cond.get())
9127 Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());
9128 if (Cond.isInvalid())
9129 return StmtError();
9130 if (Cond.get())
9131 Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());
9132
9133 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9134 if (Inc.isInvalid())
9135 return StmtError();
9136 if (Inc.get())
9137 Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());
9138
9139 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9140 if (LoopVar.isInvalid())
9141 return StmtError();
9142
9143 StmtResult NewStmt = S;
9144 if (getDerived().AlwaysRebuild() ||
9145 Init.get() != S->getInit() ||
9146 Range.get() != S->getRangeStmt() ||
9147 Begin.get() != S->getBeginStmt() ||
9148 End.get() != S->getEndStmt() ||
9149 Cond.get() != S->getCond() ||
9150 Inc.get() != S->getInc() ||
9151 LoopVar.get() != S->getLoopVarStmt()) {
9152 NewStmt = getDerived().RebuildCXXForRangeStmt(
9153 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9154 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9155 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9156 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9157 // Might not have attached any initializer to the loop variable.
9158 getSema().ActOnInitializerError(
9159 cast<DeclStmt>(LoopVar.get())->getSingleDecl());
9160 return StmtError();
9161 }
9162 }
9163
9164 // OpenACC Restricts a while-loop inside of certain construct/clause
9165 // combinations, so diagnose that here in OpenACC mode.
9166 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9167 SemaRef.OpenACC().ActOnRangeForStmtBegin(S->getBeginLoc(), S, NewStmt.get());
9168
9169 StmtResult Body = getDerived().TransformStmt(S->getBody());
9170 if (Body.isInvalid())
9171 return StmtError();
9172
9173 SemaRef.OpenACC().ActOnForStmtEnd(S->getBeginLoc(), Body);
9174
9175 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9176 // it now so we have a new statement to attach the body to.
9177 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9178 NewStmt = getDerived().RebuildCXXForRangeStmt(
9179 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9180 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9181 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9182 if (NewStmt.isInvalid())
9183 return StmtError();
9184 }
9185
9186 if (NewStmt.get() == S)
9187 return S;
9188
9189 return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
9190}
9191
9192template<typename Derived>
9194TreeTransform<Derived>::TransformMSDependentExistsStmt(
9195 MSDependentExistsStmt *S) {
9196 // Transform the nested-name-specifier, if any.
9197 NestedNameSpecifierLoc QualifierLoc;
9198 if (S->getQualifierLoc()) {
9199 QualifierLoc
9200 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9201 if (!QualifierLoc)
9202 return StmtError();
9203 }
9204
9205 // Transform the declaration name.
9206 DeclarationNameInfo NameInfo = S->getNameInfo();
9207 if (NameInfo.getName()) {
9208 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9209 if (!NameInfo.getName())
9210 return StmtError();
9211 }
9212
9213 // Check whether anything changed.
9214 if (!getDerived().AlwaysRebuild() &&
9215 QualifierLoc == S->getQualifierLoc() &&
9216 NameInfo.getName() == S->getNameInfo().getName())
9217 return S;
9218
9219 // Determine whether this name exists, if we can.
9220 CXXScopeSpec SS;
9221 SS.Adopt(QualifierLoc);
9222 bool Dependent = false;
9223 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9224 case Sema::IER_Exists:
9225 if (S->isIfExists())
9226 break;
9227
9228 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9229
9231 if (S->isIfNotExists())
9232 break;
9233
9234 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9235
9237 Dependent = true;
9238 break;
9239
9240 case Sema::IER_Error:
9241 return StmtError();
9242 }
9243
9244 // We need to continue with the instantiation, so do so now.
9245 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9246 if (SubStmt.isInvalid())
9247 return StmtError();
9248
9249 // If we have resolved the name, just transform to the substatement.
9250 if (!Dependent)
9251 return SubStmt;
9252
9253 // The name is still dependent, so build a dependent expression again.
9254 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9255 S->isIfExists(),
9256 QualifierLoc,
9257 NameInfo,
9258 SubStmt.get());
9259}
9260
9261template<typename Derived>
9263TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9264 NestedNameSpecifierLoc QualifierLoc;
9265 if (E->getQualifierLoc()) {
9266 QualifierLoc
9267 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9268 if (!QualifierLoc)
9269 return ExprError();
9270 }
9271
9272 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9273 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9274 if (!PD)
9275 return ExprError();
9276
9277 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9278 if (Base.isInvalid())
9279 return ExprError();
9280
9281 return new (SemaRef.getASTContext())
9282 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9284 QualifierLoc, E->getMemberLoc());
9285}
9286
9287template <typename Derived>
9288ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9289 MSPropertySubscriptExpr *E) {
9290 auto BaseRes = getDerived().TransformExpr(E->getBase());
9291 if (BaseRes.isInvalid())
9292 return ExprError();
9293 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9294 if (IdxRes.isInvalid())
9295 return ExprError();
9296
9297 if (!getDerived().AlwaysRebuild() &&
9298 BaseRes.get() == E->getBase() &&
9299 IdxRes.get() == E->getIdx())
9300 return E;
9301
9302 return getDerived().RebuildArraySubscriptExpr(
9303 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9304}
9305
9306template <typename Derived>
9307StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9308 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9309 if (TryBlock.isInvalid())
9310 return StmtError();
9311
9312 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9313 if (Handler.isInvalid())
9314 return StmtError();
9315
9316 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9317 Handler.get() == S->getHandler())
9318 return S;
9319
9320 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9321 TryBlock.get(), Handler.get());
9322}
9323
9324template <typename Derived>
9325StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9326 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9327 if (Block.isInvalid())
9328 return StmtError();
9329
9330 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9331}
9332
9333template <typename Derived>
9334StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9335 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9336 if (FilterExpr.isInvalid())
9337 return StmtError();
9338
9339 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9340 if (Block.isInvalid())
9341 return StmtError();
9342
9343 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9344 Block.get());
9345}
9346
9347template <typename Derived>
9349 if (isa<SEHFinallyStmt>(Handler))
9350 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
9351 else
9352 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
9353}
9354
9355template<typename Derived>
9358 return S;
9359}
9360
9361//===----------------------------------------------------------------------===//
9362// OpenMP directive transformation
9363//===----------------------------------------------------------------------===//
9364
9365template <typename Derived>
9367TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9368 // OMPCanonicalLoops are eliminated during transformation, since they will be
9369 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9370 // after transformation.
9371 return getDerived().TransformStmt(L->getLoopStmt());
9372}
9373
9374template <typename Derived>
9377
9378 // Transform the clauses
9380 ArrayRef<OMPClause *> Clauses = D->clauses();
9381 TClauses.reserve(Clauses.size());
9382 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9383 I != E; ++I) {
9384 if (*I) {
9385 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9386 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9387 getDerived().getSema().OpenMP().EndOpenMPClause();
9388 if (Clause)
9389 TClauses.push_back(Clause);
9390 } else {
9391 TClauses.push_back(nullptr);
9392 }
9393 }
9394 StmtResult AssociatedStmt;
9395 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9396 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9397 D->getDirectiveKind(),
9398 /*CurScope=*/nullptr);
9399 StmtResult Body;
9400 {
9401 Sema::CompoundScopeRAII CompoundScope(getSema());
9402 Stmt *CS;
9403 if (D->getDirectiveKind() == OMPD_atomic ||
9404 D->getDirectiveKind() == OMPD_critical ||
9405 D->getDirectiveKind() == OMPD_section ||
9406 D->getDirectiveKind() == OMPD_master)
9407 CS = D->getAssociatedStmt();
9408 else
9409 CS = D->getRawStmt();
9410 Body = getDerived().TransformStmt(CS);
9411 if (Body.isUsable() && isOpenMPLoopDirective(D->getDirectiveKind()) &&
9412 getSema().getLangOpts().OpenMPIRBuilder)
9413 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9414 }
9415 AssociatedStmt =
9416 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9417 if (AssociatedStmt.isInvalid()) {
9418 return StmtError();
9419 }
9420 }
9421 if (TClauses.size() != Clauses.size()) {
9422 return StmtError();
9423 }
9424
9425 // Transform directive name for 'omp critical' directive.
9426 DeclarationNameInfo DirName;
9427 if (D->getDirectiveKind() == OMPD_critical) {
9428 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
9429 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9430 }
9431 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9432 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9433 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();
9434 } else if (D->getDirectiveKind() == OMPD_cancel) {
9435 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();
9436 }
9437
9438 return getDerived().RebuildOMPExecutableDirective(
9439 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9440 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
9441}
9442
9443/// This is mostly the same as above, but allows 'informational' class
9444/// directives when rebuilding the stmt. It still takes an
9445/// OMPExecutableDirective-type argument because we're reusing that as the
9446/// superclass for the 'assume' directive at present, instead of defining a
9447/// mostly-identical OMPInformationalDirective parent class.
9448template <typename Derived>
9451
9452 // Transform the clauses
9454 ArrayRef<OMPClause *> Clauses = D->clauses();
9455 TClauses.reserve(Clauses.size());
9456 for (OMPClause *C : Clauses) {
9457 if (C) {
9458 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
9459 OMPClause *Clause = getDerived().TransformOMPClause(C);
9460 getDerived().getSema().OpenMP().EndOpenMPClause();
9461 if (Clause)
9462 TClauses.push_back(Clause);
9463 } else {
9464 TClauses.push_back(nullptr);
9465 }
9466 }
9467 StmtResult AssociatedStmt;
9468 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9469 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9470 D->getDirectiveKind(),
9471 /*CurScope=*/nullptr);
9472 StmtResult Body;
9473 {
9474 Sema::CompoundScopeRAII CompoundScope(getSema());
9475 assert(D->getDirectiveKind() == OMPD_assume &&
9476 "Unexpected informational directive");
9477 Stmt *CS = D->getAssociatedStmt();
9478 Body = getDerived().TransformStmt(CS);
9479 }
9480 AssociatedStmt =
9481 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9482 if (AssociatedStmt.isInvalid())
9483 return StmtError();
9484 }
9485 if (TClauses.size() != Clauses.size())
9486 return StmtError();
9487
9488 DeclarationNameInfo DirName;
9489
9490 return getDerived().RebuildOMPInformationalDirective(
9491 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
9492 D->getBeginLoc(), D->getEndLoc());
9493}
9494
9495template <typename Derived>
9498 // TODO: Fix This
9499 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)
9500 << getOpenMPDirectiveName(D->getDirectiveKind());
9501 return StmtError();
9502}
9503
9504template <typename Derived>
9506TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9507 DeclarationNameInfo DirName;
9508 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9509 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9510 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9511 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9512 return Res;
9513}
9514
9515template <typename Derived>
9517TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9518 DeclarationNameInfo DirName;
9519 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9520 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9521 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9522 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9523 return Res;
9524}
9525
9526template <typename Derived>
9528TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9529 DeclarationNameInfo DirName;
9530 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9531 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9532 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9533 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9534 return Res;
9535}
9536
9537template <typename Derived>
9539TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9540 DeclarationNameInfo DirName;
9541 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9542 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9543 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9544 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9545 return Res;
9546}
9547
9548template <typename Derived>
9550TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
9551 DeclarationNameInfo DirName;
9552 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9553 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9554 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9555 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9556 return Res;
9557}
9558
9559template <typename Derived>
9560StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
9561 OMPInterchangeDirective *D) {
9562 DeclarationNameInfo DirName;
9563 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9564 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9565 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9566 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9567 return Res;
9568}
9569
9570template <typename Derived>
9572TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9573 DeclarationNameInfo DirName;
9574 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9575 OMPD_for, DirName, nullptr, D->getBeginLoc());
9576 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9577 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9578 return Res;
9579}
9580
9581template <typename Derived>
9583TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9584 DeclarationNameInfo DirName;
9585 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9586 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9587 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9588 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9589 return Res;
9590}
9591
9592template <typename Derived>
9594TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9595 DeclarationNameInfo DirName;
9596 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9597 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9598 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9599 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9600 return Res;
9601}
9602
9603template <typename Derived>
9605TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9606 DeclarationNameInfo DirName;
9607 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9608 OMPD_section, DirName, nullptr, D->getBeginLoc());
9609 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9610 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9611 return Res;
9612}
9613
9614template <typename Derived>
9616TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9617 DeclarationNameInfo DirName;
9618 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9619 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9620 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9621 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9622 return Res;
9623}
9624
9625template <typename Derived>
9627TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9628 DeclarationNameInfo DirName;
9629 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9630 OMPD_single, DirName, nullptr, D->getBeginLoc());
9631 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9632 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9633 return Res;
9634}
9635
9636template <typename Derived>
9638TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9639 DeclarationNameInfo DirName;
9640 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9641 OMPD_master, DirName, nullptr, D->getBeginLoc());
9642 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9643 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9644 return Res;
9645}
9646
9647template <typename Derived>
9649TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9650 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9651 OMPD_critical, D->getDirectiveName(), 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>::TransformOMPParallelForDirective(
9659 OMPParallelForDirective *D) {
9660 DeclarationNameInfo DirName;
9661 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9662 OMPD_parallel_for, 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>::TransformOMPParallelForSimdDirective(
9670 OMPParallelForSimdDirective *D) {
9671 DeclarationNameInfo DirName;
9672 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9673 OMPD_parallel_for_simd, 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>::TransformOMPParallelMasterDirective(
9681 OMPParallelMasterDirective *D) {
9682 DeclarationNameInfo DirName;
9683 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9684 OMPD_parallel_master, 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>::TransformOMPParallelMaskedDirective(
9692 OMPParallelMaskedDirective *D) {
9693 DeclarationNameInfo DirName;
9694 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9695 OMPD_parallel_masked, 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>::TransformOMPParallelSectionsDirective(
9703 OMPParallelSectionsDirective *D) {
9704 DeclarationNameInfo DirName;
9705 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9706 OMPD_parallel_sections, 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>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9715 DeclarationNameInfo DirName;
9716 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9717 OMPD_task, 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>::TransformOMPTaskyieldDirective(
9725 OMPTaskyieldDirective *D) {
9726 DeclarationNameInfo DirName;
9727 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9728 OMPD_taskyield, 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>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9737 DeclarationNameInfo DirName;
9738 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9739 OMPD_barrier, 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>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9748 DeclarationNameInfo DirName;
9749 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9750 OMPD_taskwait, 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>
9758TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
9759 DeclarationNameInfo DirName;
9760 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9761 OMPD_assume, DirName, nullptr, D->getBeginLoc());
9762 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
9763 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9764 return Res;
9765}
9766
9767template <typename Derived>
9769TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9770 DeclarationNameInfo DirName;
9771 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9772 OMPD_error, 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>::TransformOMPTaskgroupDirective(
9780 OMPTaskgroupDirective *D) {
9781 DeclarationNameInfo DirName;
9782 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9783 OMPD_taskgroup, 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>
9791TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9792 DeclarationNameInfo DirName;
9793 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9794 OMPD_flush, 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>
9802TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9803 DeclarationNameInfo DirName;
9804 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9805 OMPD_depobj, 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>
9813TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9814 DeclarationNameInfo DirName;
9815 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9816 OMPD_scan, 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>
9824TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9825 DeclarationNameInfo DirName;
9826 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9827 OMPD_ordered, 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>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9836 DeclarationNameInfo DirName;
9837 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9838 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
9839 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9840 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9841 return Res;
9842}
9843
9844template <typename Derived>
9846TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9847 DeclarationNameInfo DirName;
9848 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9849 OMPD_target, DirName, nullptr, D->getBeginLoc());
9850 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9851 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9852 return Res;
9853}
9854
9855template <typename Derived>
9856StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9857 OMPTargetDataDirective *D) {
9858 DeclarationNameInfo DirName;
9859 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9860 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
9861 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9862 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9863 return Res;
9864}
9865
9866template <typename Derived>
9867StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9868 OMPTargetEnterDataDirective *D) {
9869 DeclarationNameInfo DirName;
9870 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9871 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
9872 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9873 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9874 return Res;
9875}
9876
9877template <typename Derived>
9878StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9879 OMPTargetExitDataDirective *D) {
9880 DeclarationNameInfo DirName;
9881 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9882 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
9883 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9884 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9885 return Res;
9886}
9887
9888template <typename Derived>
9889StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
9890 OMPTargetParallelDirective *D) {
9891 DeclarationNameInfo DirName;
9892 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9893 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
9894 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9895 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9896 return Res;
9897}
9898
9899template <typename Derived>
9900StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
9901 OMPTargetParallelForDirective *D) {
9902 DeclarationNameInfo DirName;
9903 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9904 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
9905 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9906 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9907 return Res;
9908}
9909
9910template <typename Derived>
9911StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
9912 OMPTargetUpdateDirective *D) {
9913 DeclarationNameInfo DirName;
9914 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9915 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
9916 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9917 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9918 return Res;
9919}
9920
9921template <typename Derived>
9923TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
9924 DeclarationNameInfo DirName;
9925 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9926 OMPD_teams, DirName, nullptr, D->getBeginLoc());
9927 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9928 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9929 return Res;
9930}
9931
9932template <typename Derived>
9933StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
9934 OMPCancellationPointDirective *D) {
9935 DeclarationNameInfo DirName;
9936 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9937 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
9938 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9939 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9940 return Res;
9941}
9942
9943template <typename Derived>
9945TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
9946 DeclarationNameInfo DirName;
9947 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9948 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
9949 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9950 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9951 return Res;
9952}
9953
9954template <typename Derived>
9956TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
9957 DeclarationNameInfo DirName;
9958 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9959 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
9960 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9961 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9962 return Res;
9963}
9964
9965template <typename Derived>
9966StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
9967 OMPTaskLoopSimdDirective *D) {
9968 DeclarationNameInfo DirName;
9969 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9970 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9971 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9972 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9973 return Res;
9974}
9975
9976template <typename Derived>
9977StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
9978 OMPMasterTaskLoopDirective *D) {
9979 DeclarationNameInfo DirName;
9980 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9981 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
9982 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9983 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9984 return Res;
9985}
9986
9987template <typename Derived>
9988StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
9989 OMPMaskedTaskLoopDirective *D) {
9990 DeclarationNameInfo DirName;
9991 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9992 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
9993 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9994 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9995 return Res;
9996}
9997
9998template <typename Derived>
9999StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10000 OMPMasterTaskLoopSimdDirective *D) {
10001 DeclarationNameInfo DirName;
10002 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10003 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10004 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10005 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10006 return Res;
10007}
10008
10009template <typename Derived>
10010StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10011 OMPMaskedTaskLoopSimdDirective *D) {
10012 DeclarationNameInfo DirName;
10013 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10014 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10015 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10016 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10017 return Res;
10018}
10019
10020template <typename Derived>
10021StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10022 OMPParallelMasterTaskLoopDirective *D) {
10023 DeclarationNameInfo DirName;
10024 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10025 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10026 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10027 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10028 return Res;
10029}
10030
10031template <typename Derived>
10032StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10033 OMPParallelMaskedTaskLoopDirective *D) {
10034 DeclarationNameInfo DirName;
10035 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10036 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10037 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10038 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10039 return Res;
10040}
10041
10042template <typename Derived>
10044TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10045 OMPParallelMasterTaskLoopSimdDirective *D) {
10046 DeclarationNameInfo DirName;
10047 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10048 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10049 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10050 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10051 return Res;
10052}
10053
10054template <typename Derived>
10056TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10057 OMPParallelMaskedTaskLoopSimdDirective *D) {
10058 DeclarationNameInfo DirName;
10059 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10060 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10061 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10062 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10063 return Res;
10064}
10065
10066template <typename Derived>
10067StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10068 OMPDistributeDirective *D) {
10069 DeclarationNameInfo DirName;
10070 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10071 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10072 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10073 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10074 return Res;
10075}
10076
10077template <typename Derived>
10078StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10079 OMPDistributeParallelForDirective *D) {
10080 DeclarationNameInfo DirName;
10081 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10082 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10083 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10084 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10085 return Res;
10086}
10087
10088template <typename Derived>
10090TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10091 OMPDistributeParallelForSimdDirective *D) {
10092 DeclarationNameInfo DirName;
10093 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10094 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10095 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10096 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10097 return Res;
10098}
10099
10100template <typename Derived>
10101StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10102 OMPDistributeSimdDirective *D) {
10103 DeclarationNameInfo DirName;
10104 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10105 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10106 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10107 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10108 return Res;
10109}
10110
10111template <typename Derived>
10112StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10113 OMPTargetParallelForSimdDirective *D) {
10114 DeclarationNameInfo DirName;
10115 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10116 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10117 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10118 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10119 return Res;
10120}
10121
10122template <typename Derived>
10123StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10124 OMPTargetSimdDirective *D) {
10125 DeclarationNameInfo DirName;
10126 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10127 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10128 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10129 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10130 return Res;
10131}
10132
10133template <typename Derived>
10134StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10135 OMPTeamsDistributeDirective *D) {
10136 DeclarationNameInfo DirName;
10137 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10138 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10139 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10140 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10141 return Res;
10142}
10143
10144template <typename Derived>
10145StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10146 OMPTeamsDistributeSimdDirective *D) {
10147 DeclarationNameInfo DirName;
10148 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10149 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10150 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10151 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10152 return Res;
10153}
10154
10155template <typename Derived>
10156StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10157 OMPTeamsDistributeParallelForSimdDirective *D) {
10158 DeclarationNameInfo DirName;
10159 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10160 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10161 D->getBeginLoc());
10162 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10163 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10164 return Res;
10165}
10166
10167template <typename Derived>
10168StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10169 OMPTeamsDistributeParallelForDirective *D) {
10170 DeclarationNameInfo DirName;
10171 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10172 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10173 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10174 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10175 return Res;
10176}
10177
10178template <typename Derived>
10179StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10180 OMPTargetTeamsDirective *D) {
10181 DeclarationNameInfo DirName;
10182 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10183 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10184 auto Res = getDerived().TransformOMPExecutableDirective(D);
10185 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10186 return Res;
10187}
10188
10189template <typename Derived>
10190StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10191 OMPTargetTeamsDistributeDirective *D) {
10192 DeclarationNameInfo DirName;
10193 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10194 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10195 auto Res = getDerived().TransformOMPExecutableDirective(D);
10196 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10197 return Res;
10198}
10199
10200template <typename Derived>
10202TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10203 OMPTargetTeamsDistributeParallelForDirective *D) {
10204 DeclarationNameInfo DirName;
10205 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10206 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10207 D->getBeginLoc());
10208 auto Res = getDerived().TransformOMPExecutableDirective(D);
10209 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10210 return Res;
10211}
10212
10213template <typename Derived>
10214StmtResult TreeTransform<Derived>::
10215 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10216 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10217 DeclarationNameInfo DirName;
10218 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10219 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10220 D->getBeginLoc());
10221 auto Res = getDerived().TransformOMPExecutableDirective(D);
10222 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10223 return Res;
10224}
10225
10226template <typename Derived>
10228TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10229 OMPTargetTeamsDistributeSimdDirective *D) {
10230 DeclarationNameInfo DirName;
10231 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10232 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10233 auto Res = getDerived().TransformOMPExecutableDirective(D);
10234 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10235 return Res;
10236}
10237
10238template <typename Derived>
10240TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10241 DeclarationNameInfo DirName;
10242 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10243 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10244 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10245 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10246 return Res;
10247}
10248
10249template <typename Derived>
10251TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10252 DeclarationNameInfo DirName;
10253 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10254 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10255 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10256 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10257 return Res;
10258}
10259
10260template <typename Derived>
10262TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10263 DeclarationNameInfo DirName;
10264 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10265 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10266 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10267 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10268 return Res;
10269}
10270
10271template <typename Derived>
10272StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10273 OMPGenericLoopDirective *D) {
10274 DeclarationNameInfo DirName;
10275 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10276 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10277 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10278 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10279 return Res;
10280}
10281
10282template <typename Derived>
10283StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10284 OMPTeamsGenericLoopDirective *D) {
10285 DeclarationNameInfo DirName;
10286 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10287 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10288 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10289 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10290 return Res;
10291}
10292
10293template <typename Derived>
10294StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10295 OMPTargetTeamsGenericLoopDirective *D) {
10296 DeclarationNameInfo DirName;
10297 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10298 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10299 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10300 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10301 return Res;
10302}
10303
10304template <typename Derived>
10305StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10306 OMPParallelGenericLoopDirective *D) {
10307 DeclarationNameInfo DirName;
10308 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10309 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10310 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10311 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10312 return Res;
10313}
10314
10315template <typename Derived>
10317TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10318 OMPTargetParallelGenericLoopDirective *D) {
10319 DeclarationNameInfo DirName;
10320 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10321 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10322 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10323 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10324 return Res;
10325}
10326
10327//===----------------------------------------------------------------------===//
10328// OpenMP clause transformation
10329//===----------------------------------------------------------------------===//
10330template <typename Derived>
10331OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10332 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10333 if (Cond.isInvalid())
10334 return nullptr;
10335 return getDerived().RebuildOMPIfClause(
10336 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10337 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10338}
10339
10340template <typename Derived>
10341OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10342 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10343 if (Cond.isInvalid())
10344 return nullptr;
10345 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10346 C->getLParenLoc(), C->getEndLoc());
10347}
10348
10349template <typename Derived>
10350OMPClause *
10351TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10352 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10353 if (NumThreads.isInvalid())
10354 return nullptr;
10355 return getDerived().RebuildOMPNumThreadsClause(
10356 NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10357}
10358
10359template <typename Derived>
10360OMPClause *
10361TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10362 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10363 if (E.isInvalid())
10364 return nullptr;
10365 return getDerived().RebuildOMPSafelenClause(
10366 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10367}
10368
10369template <typename Derived>
10370OMPClause *
10371TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10372 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10373 if (E.isInvalid())
10374 return nullptr;
10375 return getDerived().RebuildOMPAllocatorClause(
10376 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10377}
10378
10379template <typename Derived>
10380OMPClause *
10381TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10382 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10383 if (E.isInvalid())
10384 return nullptr;
10385 return getDerived().RebuildOMPSimdlenClause(
10386 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10387}
10388
10389template <typename Derived>
10390OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10391 SmallVector<Expr *, 4> TransformedSizes;
10392 TransformedSizes.reserve(C->getNumSizes());
10393 bool Changed = false;
10394 for (Expr *E : C->getSizesRefs()) {
10395 if (!E) {
10396 TransformedSizes.push_back(nullptr);
10397 continue;
10398 }
10399
10400 ExprResult T = getDerived().TransformExpr(E);
10401 if (T.isInvalid())
10402 return nullptr;
10403 if (E != T.get())
10404 Changed = true;
10405 TransformedSizes.push_back(T.get());
10406 }
10407
10408 if (!Changed && !getDerived().AlwaysRebuild())
10409 return C;
10410 return RebuildOMPSizesClause(TransformedSizes, C->getBeginLoc(),
10411 C->getLParenLoc(), C->getEndLoc());
10412}
10413
10414template <typename Derived>
10415OMPClause *
10416TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
10417 SmallVector<Expr *> TransformedArgs;
10418 TransformedArgs.reserve(C->getNumLoops());
10419 bool Changed = false;
10420 for (Expr *E : C->getArgsRefs()) {
10421 if (!E) {
10422 TransformedArgs.push_back(nullptr);
10423 continue;
10424 }
10425
10426 ExprResult T = getDerived().TransformExpr(E);
10427 if (T.isInvalid())
10428 return nullptr;
10429 if (E != T.get())
10430 Changed = true;
10431 TransformedArgs.push_back(T.get());
10432 }
10433
10434 if (!Changed && !getDerived().AlwaysRebuild())
10435 return C;
10436 return RebuildOMPPermutationClause(TransformedArgs, C->getBeginLoc(),
10437 C->getLParenLoc(), C->getEndLoc());
10438}
10439
10440template <typename Derived>
10441OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10442 if (!getDerived().AlwaysRebuild())
10443 return C;
10444 return RebuildOMPFullClause(C->getBeginLoc(), C->getEndLoc());
10445}
10446
10447template <typename Derived>
10448OMPClause *
10449TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10450 ExprResult T = getDerived().TransformExpr(C->getFactor());
10451 if (T.isInvalid())
10452 return nullptr;
10453 Expr *Factor = T.get();
10454 bool Changed = Factor != C->getFactor();
10455
10456 if (!Changed && !getDerived().AlwaysRebuild())
10457 return C;
10458 return RebuildOMPPartialClause(Factor, C->getBeginLoc(), C->getLParenLoc(),
10459 C->getEndLoc());
10460}
10461
10462template <typename Derived>
10463OMPClause *
10464TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10465 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10466 if (E.isInvalid())
10467 return nullptr;
10468 return getDerived().RebuildOMPCollapseClause(
10469 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10470}
10471
10472template <typename Derived>
10473OMPClause *
10474TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10475 return getDerived().RebuildOMPDefaultClause(
10476 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
10477 C->getLParenLoc(), C->getEndLoc());
10478}
10479
10480template <typename Derived>
10481OMPClause *
10482TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10483 return getDerived().RebuildOMPProcBindClause(
10484 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10485 C->getLParenLoc(), C->getEndLoc());
10486}
10487
10488template <typename Derived>
10489OMPClause *
10490TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10491 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10492 if (E.isInvalid())
10493 return nullptr;
10494 return getDerived().RebuildOMPScheduleClause(
10495 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10496 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10497 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10498 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10499}
10500
10501template <typename Derived>
10502OMPClause *
10503TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10504 ExprResult E;
10505 if (auto *Num = C->getNumForLoops()) {
10506 E = getDerived().TransformExpr(Num);
10507 if (E.isInvalid())
10508 return nullptr;
10509 }
10510 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10511 C->getLParenLoc(), E.get());
10512}
10513
10514template <typename Derived>
10515OMPClause *
10516TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10517 ExprResult E;
10518 if (Expr *Evt = C->getEventHandler()) {
10519 E = getDerived().TransformExpr(Evt);
10520 if (E.isInvalid())
10521 return nullptr;
10522 }
10523 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10524 C->getLParenLoc(), C->getEndLoc());
10525}
10526
10527template <typename Derived>
10528OMPClause *
10529TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10530 // No need to rebuild this clause, no template-dependent parameters.
10531 return C;
10532}
10533
10534template <typename Derived>
10535OMPClause *
10536TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10537 // No need to rebuild this clause, no template-dependent parameters.
10538 return C;
10539}
10540
10541template <typename Derived>
10542OMPClause *
10543TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10544 // No need to rebuild this clause, no template-dependent parameters.
10545 return C;
10546}
10547
10548template <typename Derived>
10549OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10550 // No need to rebuild this clause, no template-dependent parameters.
10551 return C;
10552}
10553
10554template <typename Derived>
10555OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10556 // No need to rebuild this clause, no template-dependent parameters.
10557 return C;
10558}
10559
10560template <typename Derived>
10561OMPClause *
10562TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10563 // No need to rebuild this clause, no template-dependent parameters.
10564 return C;
10565}
10566
10567template <typename Derived>
10568OMPClause *
10569TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10570 // No need to rebuild this clause, no template-dependent parameters.
10571 return C;
10572}
10573
10574template <typename Derived>
10575OMPClause *
10576TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10577 // No need to rebuild this clause, no template-dependent parameters.
10578 return C;
10579}
10580
10581template <typename Derived>
10582OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10583 // No need to rebuild this clause, no template-dependent parameters.
10584 return C;
10585}
10586
10587template <typename Derived>
10588OMPClause *
10589TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
10590 return C;
10591}
10592
10593template <typename Derived>
10594OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
10595 ExprResult E = getDerived().TransformExpr(C->getExpr());
10596 if (E.isInvalid())
10597 return nullptr;
10598 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
10599 C->getLParenLoc(), C->getEndLoc());
10600}
10601
10602template <typename Derived>
10603OMPClause *
10604TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
10605 return C;
10606}
10607
10608template <typename Derived>
10609OMPClause *
10610TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
10611 return C;
10612}
10613template <typename Derived>
10614OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
10615 OMPNoOpenMPRoutinesClause *C) {
10616 return C;
10617}
10618template <typename Derived>
10619OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
10620 OMPNoParallelismClause *C) {
10621 return C;
10622}
10623
10624template <typename Derived>
10625OMPClause *
10626TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10627 // No need to rebuild this clause, no template-dependent parameters.
10628 return C;
10629}
10630
10631template <typename Derived>
10632OMPClause *
10633TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10634 // No need to rebuild this clause, no template-dependent parameters.
10635 return C;
10636}
10637
10638template <typename Derived>
10639OMPClause *
10640TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10641 // No need to rebuild this clause, no template-dependent parameters.
10642 return C;
10643}
10644
10645template <typename Derived>
10646OMPClause *
10647TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10648 // No need to rebuild this clause, no template-dependent parameters.
10649 return C;
10650}
10651
10652template <typename Derived>
10653OMPClause *
10654TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10655 // No need to rebuild this clause, no template-dependent parameters.
10656 return C;
10657}
10658
10659template <typename Derived>
10660OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10661 // No need to rebuild this clause, no template-dependent parameters.
10662 return C;
10663}
10664
10665template <typename Derived>
10666OMPClause *
10667TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10668 // No need to rebuild this clause, no template-dependent parameters.
10669 return C;
10670}
10671
10672template <typename Derived>
10673OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10674 // No need to rebuild this clause, no template-dependent parameters.
10675 return C;
10676}
10677
10678template <typename Derived>
10679OMPClause *
10680TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10681 // No need to rebuild this clause, no template-dependent parameters.
10682 return C;
10683}
10684
10685template <typename Derived>
10686OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10687 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10688 if (IVR.isInvalid())
10689 return nullptr;
10690
10691 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10692 InteropInfo.PreferTypes.reserve(C->varlist_size() - 1);
10693 for (Expr *E : llvm::drop_begin(C->varlist())) {
10694 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
10695 if (ER.isInvalid())
10696 return nullptr;
10697 InteropInfo.PreferTypes.push_back(ER.get());
10698 }
10699 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10700 C->getBeginLoc(), C->getLParenLoc(),
10701 C->getVarLoc(), C->getEndLoc());
10702}
10703
10704template <typename Derived>
10705OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10706 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10707 if (ER.isInvalid())
10708 return nullptr;
10709 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10710 C->getLParenLoc(), C->getVarLoc(),
10711 C->getEndLoc());
10712}
10713
10714template <typename Derived>
10715OMPClause *
10716TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10717 ExprResult ER;
10718 if (Expr *IV = C->getInteropVar()) {
10719 ER = getDerived().TransformExpr(IV);
10720 if (ER.isInvalid())
10721 return nullptr;
10722 }
10723 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10724 C->getLParenLoc(), C->getVarLoc(),
10725 C->getEndLoc());
10726}
10727
10728template <typename Derived>
10729OMPClause *
10730TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10731 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10732 if (Cond.isInvalid())
10733 return nullptr;
10734 return getDerived().RebuildOMPNovariantsClause(
10735 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10736}
10737
10738template <typename Derived>
10739OMPClause *
10740TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
10741 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10742 if (Cond.isInvalid())
10743 return nullptr;
10744 return getDerived().RebuildOMPNocontextClause(
10745 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10746}
10747
10748template <typename Derived>
10749OMPClause *
10750TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
10751 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
10752 if (ThreadID.isInvalid())
10753 return nullptr;
10754 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10755 C->getLParenLoc(), C->getEndLoc());
10756}
10757
10758template <typename Derived>
10759OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10760 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10761 if (E.isInvalid())
10762 return nullptr;
10763 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10764 C->getLParenLoc(), C->getEndLoc());
10765}
10766
10767template <typename Derived>
10768OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10769 OMPUnifiedAddressClause *C) {
10770 llvm_unreachable("unified_address clause cannot appear in dependent context");
10771}
10772
10773template <typename Derived>
10774OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10775 OMPUnifiedSharedMemoryClause *C) {
10776 llvm_unreachable(
10777 "unified_shared_memory clause cannot appear in dependent context");
10778}
10779
10780template <typename Derived>
10781OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10782 OMPReverseOffloadClause *C) {
10783 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10784}
10785
10786template <typename Derived>
10787OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10788 OMPDynamicAllocatorsClause *C) {
10789 llvm_unreachable(
10790 "dynamic_allocators clause cannot appear in dependent context");
10791}
10792
10793template <typename Derived>
10794OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10795 OMPAtomicDefaultMemOrderClause *C) {
10796 llvm_unreachable(
10797 "atomic_default_mem_order clause cannot appear in dependent context");
10798}
10799
10800template <typename Derived>
10801OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10802 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10803 C->getBeginLoc(), C->getLParenLoc(),
10804 C->getEndLoc());
10805}
10806
10807template <typename Derived>
10808OMPClause *
10809TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10810 return getDerived().RebuildOMPSeverityClause(
10811 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10812 C->getLParenLoc(), C->getEndLoc());
10813}
10814
10815template <typename Derived>
10816OMPClause *
10817TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10818 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10819 if (E.isInvalid())
10820 return nullptr;
10821 return getDerived().RebuildOMPMessageClause(
10822 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10823 C->getEndLoc());
10824}
10825
10826template <typename Derived>
10827OMPClause *
10828TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10830 Vars.reserve(C->varlist_size());
10831 for (auto *VE : C->varlist()) {
10832 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10833 if (EVar.isInvalid())
10834 return nullptr;
10835 Vars.push_back(EVar.get());
10836 }
10837 return getDerived().RebuildOMPPrivateClause(
10838 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10839}
10840
10841template <typename Derived>
10842OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10843 OMPFirstprivateClause *C) {
10845 Vars.reserve(C->varlist_size());
10846 for (auto *VE : C->varlist()) {
10847 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10848 if (EVar.isInvalid())
10849 return nullptr;
10850 Vars.push_back(EVar.get());
10851 }
10852 return getDerived().RebuildOMPFirstprivateClause(
10853 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10854}
10855
10856template <typename Derived>
10857OMPClause *
10858TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10860 Vars.reserve(C->varlist_size());
10861 for (auto *VE : C->varlist()) {
10862 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10863 if (EVar.isInvalid())
10864 return nullptr;
10865 Vars.push_back(EVar.get());
10866 }
10867 return getDerived().RebuildOMPLastprivateClause(
10868 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10869 C->getLParenLoc(), C->getEndLoc());
10870}
10871
10872template <typename Derived>
10873OMPClause *
10874TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
10876 Vars.reserve(C->varlist_size());
10877 for (auto *VE : C->varlist()) {
10878 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10879 if (EVar.isInvalid())
10880 return nullptr;
10881 Vars.push_back(EVar.get());
10882 }
10883 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
10884 C->getLParenLoc(), C->getEndLoc());
10885}
10886
10887template <typename Derived>
10888OMPClause *
10889TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
10891 Vars.reserve(C->varlist_size());
10892 for (auto *VE : C->varlist()) {
10893 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10894 if (EVar.isInvalid())
10895 return nullptr;
10896 Vars.push_back(EVar.get());
10897 }
10898 CXXScopeSpec ReductionIdScopeSpec;
10899 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10900
10901 DeclarationNameInfo NameInfo = C->getNameInfo();
10902 if (NameInfo.getName()) {
10903 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10904 if (!NameInfo.getName())
10905 return nullptr;
10906 }
10907 // Build a list of all UDR decls with the same names ranged by the Scopes.
10908 // The Scope boundary is a duplication of the previous decl.
10909 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10910 for (auto *E : C->reduction_ops()) {
10911 // Transform all the decls.
10912 if (E) {
10913 auto *ULE = cast<UnresolvedLookupExpr>(E);
10914 UnresolvedSet<8> Decls;
10915 for (auto *D : ULE->decls()) {
10916 NamedDecl *InstD =
10917 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10918 Decls.addDecl(InstD, InstD->getAccess());
10919 }
10920 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10921 SemaRef.Context, /*NamingClass=*/nullptr,
10922 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10923 /*ADL=*/true, Decls.begin(), Decls.end(),
10924 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
10925 } else
10926 UnresolvedReductions.push_back(nullptr);
10927 }
10928 return getDerived().RebuildOMPReductionClause(
10929 Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(),
10930 C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
10931 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10932}
10933
10934template <typename Derived>
10935OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
10936 OMPTaskReductionClause *C) {
10938 Vars.reserve(C->varlist_size());
10939 for (auto *VE : C->varlist()) {
10940 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10941 if (EVar.isInvalid())
10942 return nullptr;
10943 Vars.push_back(EVar.get());
10944 }
10945 CXXScopeSpec ReductionIdScopeSpec;
10946 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10947
10948 DeclarationNameInfo NameInfo = C->getNameInfo();
10949 if (NameInfo.getName()) {
10950 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10951 if (!NameInfo.getName())
10952 return nullptr;
10953 }
10954 // Build a list of all UDR decls with the same names ranged by the Scopes.
10955 // The Scope boundary is a duplication of the previous decl.
10956 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10957 for (auto *E : C->reduction_ops()) {
10958 // Transform all the decls.
10959 if (E) {
10960 auto *ULE = cast<UnresolvedLookupExpr>(E);
10961 UnresolvedSet<8> Decls;
10962 for (auto *D : ULE->decls()) {
10963 NamedDecl *InstD =
10964 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10965 Decls.addDecl(InstD, InstD->getAccess());
10966 }
10967 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10968 SemaRef.Context, /*NamingClass=*/nullptr,
10969 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10970 /*ADL=*/true, Decls.begin(), Decls.end(),
10971 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
10972 } else
10973 UnresolvedReductions.push_back(nullptr);
10974 }
10975 return getDerived().RebuildOMPTaskReductionClause(
10976 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10977 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10978}
10979
10980template <typename Derived>
10981OMPClause *
10982TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
10984 Vars.reserve(C->varlist_size());
10985 for (auto *VE : C->varlist()) {
10986 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10987 if (EVar.isInvalid())
10988 return nullptr;
10989 Vars.push_back(EVar.get());
10990 }
10991 CXXScopeSpec ReductionIdScopeSpec;
10992 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10993
10994 DeclarationNameInfo NameInfo = C->getNameInfo();
10995 if (NameInfo.getName()) {
10996 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10997 if (!NameInfo.getName())
10998 return nullptr;
10999 }
11000 // Build a list of all UDR decls with the same names ranged by the Scopes.
11001 // The Scope boundary is a duplication of the previous decl.
11002 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11003 for (auto *E : C->reduction_ops()) {
11004 // Transform all the decls.
11005 if (E) {
11006 auto *ULE = cast<UnresolvedLookupExpr>(E);
11007 UnresolvedSet<8> Decls;
11008 for (auto *D : ULE->decls()) {
11009 NamedDecl *InstD =
11010 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11011 Decls.addDecl(InstD, InstD->getAccess());
11012 }
11013 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
11014 SemaRef.Context, /*NamingClass=*/nullptr,
11015 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
11016 /*ADL=*/true, Decls.begin(), Decls.end(),
11017 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11018 } else
11019 UnresolvedReductions.push_back(nullptr);
11020 }
11021 return getDerived().RebuildOMPInReductionClause(
11022 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11023 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11024}
11025
11026template <typename Derived>
11027OMPClause *
11028TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11030 Vars.reserve(C->varlist_size());
11031 for (auto *VE : C->varlist()) {
11032 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11033 if (EVar.isInvalid())
11034 return nullptr;
11035 Vars.push_back(EVar.get());
11036 }
11037 ExprResult Step = getDerived().TransformExpr(C->getStep());
11038 if (Step.isInvalid())
11039 return nullptr;
11040 return getDerived().RebuildOMPLinearClause(
11041 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11042 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11043 C->getEndLoc());
11044}
11045
11046template <typename Derived>
11047OMPClause *
11048TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11050 Vars.reserve(C->varlist_size());
11051 for (auto *VE : C->varlist()) {
11052 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11053 if (EVar.isInvalid())
11054 return nullptr;
11055 Vars.push_back(EVar.get());
11056 }
11057 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11058 if (Alignment.isInvalid())
11059 return nullptr;
11060 return getDerived().RebuildOMPAlignedClause(
11061 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11062 C->getColonLoc(), C->getEndLoc());
11063}
11064
11065template <typename Derived>
11066OMPClause *
11067TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11069 Vars.reserve(C->varlist_size());
11070 for (auto *VE : C->varlist()) {
11071 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11072 if (EVar.isInvalid())
11073 return nullptr;
11074 Vars.push_back(EVar.get());
11075 }
11076 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11077 C->getLParenLoc(), C->getEndLoc());
11078}
11079
11080template <typename Derived>
11081OMPClause *
11082TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11084 Vars.reserve(C->varlist_size());
11085 for (auto *VE : C->varlist()) {
11086 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11087 if (EVar.isInvalid())
11088 return nullptr;
11089 Vars.push_back(EVar.get());
11090 }
11091 return getDerived().RebuildOMPCopyprivateClause(
11092 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11093}
11094
11095template <typename Derived>
11096OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11098 Vars.reserve(C->varlist_size());
11099 for (auto *VE : C->varlist()) {
11100 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11101 if (EVar.isInvalid())
11102 return nullptr;
11103 Vars.push_back(EVar.get());
11104 }
11105 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11106 C->getLParenLoc(), C->getEndLoc());
11107}
11108
11109template <typename Derived>
11110OMPClause *
11111TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11112 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11113 if (E.isInvalid())
11114 return nullptr;
11115 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11116 C->getLParenLoc(), C->getEndLoc());
11117}
11118
11119template <typename Derived>
11120OMPClause *
11121TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11123 Expr *DepModifier = C->getModifier();
11124 if (DepModifier) {
11125 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11126 if (DepModRes.isInvalid())
11127 return nullptr;
11128 DepModifier = DepModRes.get();
11129 }
11130 Vars.reserve(C->varlist_size());
11131 for (auto *VE : C->varlist()) {
11132 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11133 if (EVar.isInvalid())
11134 return nullptr;
11135 Vars.push_back(EVar.get());
11136 }
11137 return getDerived().RebuildOMPDependClause(
11138 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11139 C->getOmpAllMemoryLoc()},
11140 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11141}
11142
11143template <typename Derived>
11144OMPClause *
11145TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11146 ExprResult E = getDerived().TransformExpr(C->getDevice());
11147 if (E.isInvalid())
11148 return nullptr;
11149 return getDerived().RebuildOMPDeviceClause(
11150 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11151 C->getModifierLoc(), C->getEndLoc());
11152}
11153
11154template <typename Derived, class T>
11157 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11158 DeclarationNameInfo &MapperIdInfo,
11159 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11160 // Transform expressions in the list.
11161 Vars.reserve(C->varlist_size());
11162 for (auto *VE : C->varlist()) {
11163 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11164 if (EVar.isInvalid())
11165 return true;
11166 Vars.push_back(EVar.get());
11167 }
11168 // Transform mapper scope specifier and identifier.
11169 NestedNameSpecifierLoc QualifierLoc;
11170 if (C->getMapperQualifierLoc()) {
11171 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11172 C->getMapperQualifierLoc());
11173 if (!QualifierLoc)
11174 return true;
11175 }
11176 MapperIdScopeSpec.Adopt(QualifierLoc);
11177 MapperIdInfo = C->getMapperIdInfo();
11178 if (MapperIdInfo.getName()) {
11179 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11180 if (!MapperIdInfo.getName())
11181 return true;
11182 }
11183 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11184 // the previous user-defined mapper lookup in dependent environment.
11185 for (auto *E : C->mapperlists()) {
11186 // Transform all the decls.
11187 if (E) {
11188 auto *ULE = cast<UnresolvedLookupExpr>(E);
11189 UnresolvedSet<8> Decls;
11190 for (auto *D : ULE->decls()) {
11191 NamedDecl *InstD =
11192 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11193 Decls.addDecl(InstD, InstD->getAccess());
11194 }
11195 UnresolvedMappers.push_back(UnresolvedLookupExpr::Create(
11196 TT.getSema().Context, /*NamingClass=*/nullptr,
11197 MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
11198 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11199 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11200 } else {
11201 UnresolvedMappers.push_back(nullptr);
11202 }
11203 }
11204 return false;
11205}
11206
11207template <typename Derived>
11208OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11209 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11211 Expr *IteratorModifier = C->getIteratorModifier();
11212 if (IteratorModifier) {
11213 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11214 if (MapModRes.isInvalid())
11215 return nullptr;
11216 IteratorModifier = MapModRes.get();
11217 }
11218 CXXScopeSpec MapperIdScopeSpec;
11219 DeclarationNameInfo MapperIdInfo;
11220 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11221 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11222 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11223 return nullptr;
11224 return getDerived().RebuildOMPMapClause(
11225 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11226 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11227 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11228}
11229
11230template <typename Derived>
11231OMPClause *
11232TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11233 Expr *Allocator = C->getAllocator();
11234 if (Allocator) {
11235 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11236 if (AllocatorRes.isInvalid())
11237 return nullptr;
11238 Allocator = AllocatorRes.get();
11239 }
11240 Expr *Alignment = C->getAlignment();
11241 if (Alignment) {
11242 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
11243 if (AlignmentRes.isInvalid())
11244 return nullptr;
11245 Alignment = AlignmentRes.get();
11246 }
11248 Vars.reserve(C->varlist_size());
11249 for (auto *VE : C->varlist()) {
11250 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11251 if (EVar.isInvalid())
11252 return nullptr;
11253 Vars.push_back(EVar.get());
11254 }
11255 return getDerived().RebuildOMPAllocateClause(
11256 Allocator, Alignment, C->getFirstAllocateModifier(),
11257 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
11258 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
11259 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11260}
11261
11262template <typename Derived>
11263OMPClause *
11264TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11266 Vars.reserve(C->varlist_size());
11267 for (auto *VE : C->varlist()) {
11268 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11269 if (EVar.isInvalid())
11270 return nullptr;
11271 Vars.push_back(EVar.get());
11272 }
11273 return getDerived().RebuildOMPNumTeamsClause(
11274 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11275}
11276
11277template <typename Derived>
11278OMPClause *
11279TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
11281 Vars.reserve(C->varlist_size());
11282 for (auto *VE : C->varlist()) {
11283 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11284 if (EVar.isInvalid())
11285 return nullptr;
11286 Vars.push_back(EVar.get());
11287 }
11288 return getDerived().RebuildOMPThreadLimitClause(
11289 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11290}
11291
11292template <typename Derived>
11293OMPClause *
11294TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
11295 ExprResult E = getDerived().TransformExpr(C->getPriority());
11296 if (E.isInvalid())
11297 return nullptr;
11298 return getDerived().RebuildOMPPriorityClause(
11299 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11300}
11301
11302template <typename Derived>
11303OMPClause *
11304TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
11305 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
11306 if (E.isInvalid())
11307 return nullptr;
11308 return getDerived().RebuildOMPGrainsizeClause(
11309 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11310 C->getModifierLoc(), C->getEndLoc());
11311}
11312
11313template <typename Derived>
11314OMPClause *
11315TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
11316 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
11317 if (E.isInvalid())
11318 return nullptr;
11319 return getDerived().RebuildOMPNumTasksClause(
11320 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11321 C->getModifierLoc(), C->getEndLoc());
11322}
11323
11324template <typename Derived>
11325OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
11326 ExprResult E = getDerived().TransformExpr(C->getHint());
11327 if (E.isInvalid())
11328 return nullptr;
11329 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
11330 C->getLParenLoc(), C->getEndLoc());
11331}
11332
11333template <typename Derived>
11334OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
11335 OMPDistScheduleClause *C) {
11336 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11337 if (E.isInvalid())
11338 return nullptr;
11339 return getDerived().RebuildOMPDistScheduleClause(
11340 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11341 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11342}
11343
11344template <typename Derived>
11345OMPClause *
11346TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
11347 // Rebuild Defaultmap Clause since we need to invoke the checking of
11348 // defaultmap(none:variable-category) after template initialization.
11349 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
11350 C->getDefaultmapKind(),
11351 C->getBeginLoc(),
11352 C->getLParenLoc(),
11353 C->getDefaultmapModifierLoc(),
11354 C->getDefaultmapKindLoc(),
11355 C->getEndLoc());
11356}
11357
11358template <typename Derived>
11359OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
11360 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11362 CXXScopeSpec MapperIdScopeSpec;
11363 DeclarationNameInfo MapperIdInfo;
11364 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11365 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
11366 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11367 return nullptr;
11368 return getDerived().RebuildOMPToClause(
11369 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11370 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11371}
11372
11373template <typename Derived>
11374OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
11375 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11377 CXXScopeSpec MapperIdScopeSpec;
11378 DeclarationNameInfo MapperIdInfo;
11379 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11380 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
11381 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11382 return nullptr;
11383 return getDerived().RebuildOMPFromClause(
11384 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11385 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11386}
11387
11388template <typename Derived>
11389OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
11390 OMPUseDevicePtrClause *C) {
11392 Vars.reserve(C->varlist_size());
11393 for (auto *VE : C->varlist()) {
11394 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11395 if (EVar.isInvalid())
11396 return nullptr;
11397 Vars.push_back(EVar.get());
11398 }
11399 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11400 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
11401}
11402
11403template <typename Derived>
11404OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11405 OMPUseDeviceAddrClause *C) {
11407 Vars.reserve(C->varlist_size());
11408 for (auto *VE : C->varlist()) {
11409 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11410 if (EVar.isInvalid())
11411 return nullptr;
11412 Vars.push_back(EVar.get());
11413 }
11414 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11415 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11416}
11417
11418template <typename Derived>
11419OMPClause *
11420TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11422 Vars.reserve(C->varlist_size());
11423 for (auto *VE : C->varlist()) {
11424 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11425 if (EVar.isInvalid())
11426 return nullptr;
11427 Vars.push_back(EVar.get());
11428 }
11429 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11430 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
11431}
11432
11433template <typename Derived>
11434OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
11435 OMPHasDeviceAddrClause *C) {
11437 Vars.reserve(C->varlist_size());
11438 for (auto *VE : C->varlist()) {
11439 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11440 if (EVar.isInvalid())
11441 return nullptr;
11442 Vars.push_back(EVar.get());
11443 }
11444 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11445 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
11446}
11447
11448template <typename Derived>
11449OMPClause *
11450TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
11452 Vars.reserve(C->varlist_size());
11453 for (auto *VE : C->varlist()) {
11454 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11455 if (EVar.isInvalid())
11456 return nullptr;
11457 Vars.push_back(EVar.get());
11458 }
11459 return getDerived().RebuildOMPNontemporalClause(
11460 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11461}
11462
11463template <typename Derived>
11464OMPClause *
11465TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
11467 Vars.reserve(C->varlist_size());
11468 for (auto *VE : C->varlist()) {
11469 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11470 if (EVar.isInvalid())
11471 return nullptr;
11472 Vars.push_back(EVar.get());
11473 }
11474 return getDerived().RebuildOMPInclusiveClause(
11475 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11476}
11477
11478template <typename Derived>
11479OMPClause *
11480TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
11482 Vars.reserve(C->varlist_size());
11483 for (auto *VE : C->varlist()) {
11484 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11485 if (EVar.isInvalid())
11486 return nullptr;
11487 Vars.push_back(EVar.get());
11488 }
11489 return getDerived().RebuildOMPExclusiveClause(
11490 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11491}
11492
11493template <typename Derived>
11494OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11495 OMPUsesAllocatorsClause *C) {
11497 Data.reserve(C->getNumberOfAllocators());
11498 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11499 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11500 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11501 if (Allocator.isInvalid())
11502 continue;
11503 ExprResult AllocatorTraits;
11504 if (Expr *AT = D.AllocatorTraits) {
11505 AllocatorTraits = getDerived().TransformExpr(AT);
11506 if (AllocatorTraits.isInvalid())
11507 continue;
11508 }
11509 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11510 NewD.Allocator = Allocator.get();
11511 NewD.AllocatorTraits = AllocatorTraits.get();
11512 NewD.LParenLoc = D.LParenLoc;
11513 NewD.RParenLoc = D.RParenLoc;
11514 }
11515 return getDerived().RebuildOMPUsesAllocatorsClause(
11516 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11517}
11518
11519template <typename Derived>
11520OMPClause *
11521TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11522 SmallVector<Expr *, 4> Locators;
11523 Locators.reserve(C->varlist_size());
11524 ExprResult ModifierRes;
11525 if (Expr *Modifier = C->getModifier()) {
11526 ModifierRes = getDerived().TransformExpr(Modifier);
11527 if (ModifierRes.isInvalid())
11528 return nullptr;
11529 }
11530 for (Expr *E : C->varlist()) {
11531 ExprResult Locator = getDerived().TransformExpr(E);
11532 if (Locator.isInvalid())
11533 continue;
11534 Locators.push_back(Locator.get());
11535 }
11536 return getDerived().RebuildOMPAffinityClause(
11537 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11538 ModifierRes.get(), Locators);
11539}
11540
11541template <typename Derived>
11542OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11543 return getDerived().RebuildOMPOrderClause(
11544 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11545 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11546}
11547
11548template <typename Derived>
11549OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11550 return getDerived().RebuildOMPBindClause(
11551 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11552 C->getLParenLoc(), C->getEndLoc());
11553}
11554
11555template <typename Derived>
11556OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11557 OMPXDynCGroupMemClause *C) {
11558 ExprResult Size = getDerived().TransformExpr(C->getSize());
11559 if (Size.isInvalid())
11560 return nullptr;
11561 return getDerived().RebuildOMPXDynCGroupMemClause(
11562 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11563}
11564
11565template <typename Derived>
11566OMPClause *
11567TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11569 Vars.reserve(C->varlist_size());
11570 for (auto *VE : C->varlist()) {
11571 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11572 if (EVar.isInvalid())
11573 return nullptr;
11574 Vars.push_back(EVar.get());
11575 }
11576 return getDerived().RebuildOMPDoacrossClause(
11577 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11578 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11579}
11580
11581template <typename Derived>
11582OMPClause *
11583TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11585 for (auto *A : C->getAttrs())
11586 NewAttrs.push_back(getDerived().TransformAttr(A));
11587 return getDerived().RebuildOMPXAttributeClause(
11588 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11589}
11590
11591template <typename Derived>
11592OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11593 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11594}
11595
11596//===----------------------------------------------------------------------===//
11597// OpenACC transformation
11598//===----------------------------------------------------------------------===//
11599namespace {
11600template <typename Derived>
11601class OpenACCClauseTransform final
11602 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11603 TreeTransform<Derived> &Self;
11604 ArrayRef<const OpenACCClause *> ExistingClauses;
11605 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11606 OpenACCClause *NewClause = nullptr;
11607
11608 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11609 llvm::SmallVector<Expr *> InstantiatedVarList;
11610 for (Expr *CurVar : VarList) {
11611 ExprResult Res = Self.TransformExpr(CurVar);
11612
11613 if (!Res.isUsable())
11614 continue;
11615
11616 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getClauseKind(),
11617 Res.get());
11618
11619 if (Res.isUsable())
11620 InstantiatedVarList.push_back(Res.get());
11621 }
11622
11623 return InstantiatedVarList;
11624 }
11625
11626public:
11627 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11628 ArrayRef<const OpenACCClause *> ExistingClauses,
11629 SemaOpenACC::OpenACCParsedClause &PC)
11630 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
11631
11632 OpenACCClause *CreatedClause() const { return NewClause; }
11633
11634#define VISIT_CLAUSE(CLAUSE_NAME) \
11635 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11636#include "clang/Basic/OpenACCClauses.def"
11637};
11638
11639template <typename Derived>
11640void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11641 const OpenACCDefaultClause &C) {
11642 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11643
11644 NewClause = OpenACCDefaultClause::Create(
11645 Self.getSema().getASTContext(), ParsedClause.getDefaultClauseKind(),
11646 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11647 ParsedClause.getEndLoc());
11648}
11649
11650template <typename Derived>
11651void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11652 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11653 assert(Cond && "If constructed with invalid Condition");
11654 Sema::ConditionResult Res = Self.TransformCondition(
11655 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11656
11657 if (Res.isInvalid() || !Res.get().second)
11658 return;
11659
11660 ParsedClause.setConditionDetails(Res.get().second);
11661
11662 NewClause = OpenACCIfClause::Create(
11663 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11664 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11665 ParsedClause.getEndLoc());
11666}
11667
11668template <typename Derived>
11669void OpenACCClauseTransform<Derived>::VisitSelfClause(
11670 const OpenACCSelfClause &C) {
11671
11672 // If this is an 'update' 'self' clause, this is actually a var list instead.
11673 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
11674 llvm::SmallVector<Expr *> InstantiatedVarList;
11675 for (Expr *CurVar : C.getVarList()) {
11676 ExprResult Res = Self.TransformExpr(CurVar);
11677
11678 if (!Res.isUsable())
11679 continue;
11680
11681 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getClauseKind(),
11682 Res.get());
11683
11684 if (Res.isUsable())
11685 InstantiatedVarList.push_back(Res.get());
11686 }
11687
11688 ParsedClause.setVarListDetails(InstantiatedVarList,
11689 /*IsReadOnly=*/false, /*IsZero=*/false);
11690
11691 NewClause = OpenACCSelfClause::Create(
11692 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11693 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11694 ParsedClause.getEndLoc());
11695 } else {
11696
11697 if (C.hasConditionExpr()) {
11698 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11699 Sema::ConditionResult Res =
11700 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
11702
11703 if (Res.isInvalid() || !Res.get().second)
11704 return;
11705
11706 ParsedClause.setConditionDetails(Res.get().second);
11707 }
11708
11709 NewClause = OpenACCSelfClause::Create(
11710 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11711 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11712 ParsedClause.getEndLoc());
11713 }
11714}
11715
11716template <typename Derived>
11717void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
11718 const OpenACCNumGangsClause &C) {
11719 llvm::SmallVector<Expr *> InstantiatedIntExprs;
11720
11721 for (Expr *CurIntExpr : C.getIntExprs()) {
11722 ExprResult Res = Self.TransformExpr(CurIntExpr);
11723
11724 if (!Res.isUsable())
11725 return;
11726
11727 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11728 C.getClauseKind(),
11729 C.getBeginLoc(), Res.get());
11730 if (!Res.isUsable())
11731 return;
11732
11733 InstantiatedIntExprs.push_back(Res.get());
11734 }
11735
11736 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
11738 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11739 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs(),
11740 ParsedClause.getEndLoc());
11741}
11742
11743template <typename Derived>
11744void OpenACCClauseTransform<Derived>::VisitPrivateClause(
11745 const OpenACCPrivateClause &C) {
11746 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11747 /*IsReadOnly=*/false, /*IsZero=*/false);
11748
11749 NewClause = OpenACCPrivateClause::Create(
11750 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11751 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11752 ParsedClause.getEndLoc());
11753}
11754
11755template <typename Derived>
11756void OpenACCClauseTransform<Derived>::VisitHostClause(
11757 const OpenACCHostClause &C) {
11758 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11759 /*IsReadOnly=*/false, /*IsZero=*/false);
11760
11761 NewClause = OpenACCHostClause::Create(
11762 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11763 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11764 ParsedClause.getEndLoc());
11765}
11766
11767template <typename Derived>
11768void OpenACCClauseTransform<Derived>::VisitDeviceClause(
11769 const OpenACCDeviceClause &C) {
11770 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11771 /*IsReadOnly=*/false, /*IsZero=*/false);
11772
11773 NewClause = OpenACCDeviceClause::Create(
11774 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11775 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11776 ParsedClause.getEndLoc());
11777}
11778
11779template <typename Derived>
11780void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
11781 const OpenACCFirstPrivateClause &C) {
11782 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11783 /*IsReadOnly=*/false, /*IsZero=*/false);
11784
11786 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11787 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11788 ParsedClause.getEndLoc());
11789}
11790
11791template <typename Derived>
11792void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
11793 const OpenACCNoCreateClause &C) {
11794 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11795 /*IsReadOnly=*/false, /*IsZero=*/false);
11796
11798 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11799 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11800 ParsedClause.getEndLoc());
11801}
11802
11803template <typename Derived>
11804void OpenACCClauseTransform<Derived>::VisitPresentClause(
11805 const OpenACCPresentClause &C) {
11806 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11807 /*IsReadOnly=*/false, /*IsZero=*/false);
11808
11809 NewClause = OpenACCPresentClause::Create(
11810 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11811 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11812 ParsedClause.getEndLoc());
11813}
11814
11815template <typename Derived>
11816void OpenACCClauseTransform<Derived>::VisitCopyClause(
11817 const OpenACCCopyClause &C) {
11818 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11819 /*IsReadOnly=*/false, /*IsZero=*/false);
11820
11821 NewClause = OpenACCCopyClause::Create(
11822 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11823 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11824 ParsedClause.getVarList(), ParsedClause.getEndLoc());
11825}
11826
11827template <typename Derived>
11828void OpenACCClauseTransform<Derived>::VisitCopyInClause(
11829 const OpenACCCopyInClause &C) {
11830 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()), C.isReadOnly(),
11831 /*IsZero=*/false);
11832
11833 NewClause = OpenACCCopyInClause::Create(
11834 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11835 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11836 ParsedClause.isReadOnly(), ParsedClause.getVarList(),
11837 ParsedClause.getEndLoc());
11838}
11839
11840template <typename Derived>
11841void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
11842 const OpenACCCopyOutClause &C) {
11843 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11844 /*IsReadOnly=*/false, C.isZero());
11845
11846 NewClause = OpenACCCopyOutClause::Create(
11847 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11848 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11849 ParsedClause.isZero(), ParsedClause.getVarList(),
11850 ParsedClause.getEndLoc());
11851}
11852
11853template <typename Derived>
11854void OpenACCClauseTransform<Derived>::VisitCreateClause(
11855 const OpenACCCreateClause &C) {
11856 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11857 /*IsReadOnly=*/false, C.isZero());
11858
11859 NewClause = OpenACCCreateClause::Create(
11860 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11861 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11862 ParsedClause.isZero(), ParsedClause.getVarList(),
11863 ParsedClause.getEndLoc());
11864}
11865template <typename Derived>
11866void OpenACCClauseTransform<Derived>::VisitAttachClause(
11867 const OpenACCAttachClause &C) {
11868 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
11869
11870 // Ensure each var is a pointer type.
11871 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
11872 return Self.getSema().OpenACC().CheckVarIsPointerType(
11873 OpenACCClauseKind::Attach, E);
11874 }), VarList.end());
11875
11876 ParsedClause.setVarListDetails(VarList,
11877 /*IsReadOnly=*/false, /*IsZero=*/false);
11878 NewClause = OpenACCAttachClause::Create(
11879 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11880 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11881 ParsedClause.getEndLoc());
11882}
11883
11884template <typename Derived>
11885void OpenACCClauseTransform<Derived>::VisitDetachClause(
11886 const OpenACCDetachClause &C) {
11887 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
11888
11889 // Ensure each var is a pointer type.
11890 VarList.erase(
11891 std::remove_if(VarList.begin(), VarList.end(),
11892 [&](Expr *E) {
11893 return Self.getSema().OpenACC().CheckVarIsPointerType(
11894 OpenACCClauseKind::Detach, E);
11895 }),
11896 VarList.end());
11897
11898 ParsedClause.setVarListDetails(VarList,
11899 /*IsReadOnly=*/false, /*IsZero=*/false);
11900 NewClause = OpenACCDetachClause::Create(
11901 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11902 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11903 ParsedClause.getEndLoc());
11904}
11905
11906template <typename Derived>
11907void OpenACCClauseTransform<Derived>::VisitDeleteClause(
11908 const OpenACCDeleteClause &C) {
11909 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11910 /*IsReadOnly=*/false, /*IsZero=*/false);
11911 NewClause = OpenACCDeleteClause::Create(
11912 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11913 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11914 ParsedClause.getEndLoc());
11915}
11916
11917template <typename Derived>
11918void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
11919 const OpenACCUseDeviceClause &C) {
11920 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11921 /*IsReadOnly=*/false, /*IsZero=*/false);
11923 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11924 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11925 ParsedClause.getEndLoc());
11926}
11927
11928template <typename Derived>
11929void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
11930 const OpenACCDevicePtrClause &C) {
11931 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
11932
11933 // Ensure each var is a pointer type.
11934 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
11935 return Self.getSema().OpenACC().CheckVarIsPointerType(
11936 OpenACCClauseKind::DevicePtr, E);
11937 }), VarList.end());
11938
11939 ParsedClause.setVarListDetails(VarList,
11940 /*IsReadOnly=*/false, /*IsZero=*/false);
11942 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11943 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11944 ParsedClause.getEndLoc());
11945}
11946
11947template <typename Derived>
11948void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
11949 const OpenACCNumWorkersClause &C) {
11950 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11951 assert(IntExpr && "num_workers clause constructed with invalid int expr");
11952
11953 ExprResult Res = Self.TransformExpr(IntExpr);
11954 if (!Res.isUsable())
11955 return;
11956
11957 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11958 C.getClauseKind(),
11959 C.getBeginLoc(), Res.get());
11960 if (!Res.isUsable())
11961 return;
11962
11963 ParsedClause.setIntExprDetails(Res.get());
11965 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11966 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
11967 ParsedClause.getEndLoc());
11968}
11969
11970template <typename Derived>
11971void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
11972 const OpenACCDeviceNumClause &C) {
11973 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11974 assert(IntExpr && "device_num clause constructed with invalid int expr");
11975
11976 ExprResult Res = Self.TransformExpr(IntExpr);
11977 if (!Res.isUsable())
11978 return;
11979
11980 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11981 C.getClauseKind(),
11982 C.getBeginLoc(), Res.get());
11983 if (!Res.isUsable())
11984 return;
11985
11986 ParsedClause.setIntExprDetails(Res.get());
11988 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11989 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
11990 ParsedClause.getEndLoc());
11991}
11992
11993template <typename Derived>
11994void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
11995 const OpenACCDefaultAsyncClause &C) {
11996 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11997 assert(IntExpr && "default_async clause constructed with invalid int expr");
11998
11999 ExprResult Res = Self.TransformExpr(IntExpr);
12000 if (!Res.isUsable())
12001 return;
12002
12003 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12004 C.getClauseKind(),
12005 C.getBeginLoc(), Res.get());
12006 if (!Res.isUsable())
12007 return;
12008
12009 ParsedClause.setIntExprDetails(Res.get());
12011 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12012 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
12013 ParsedClause.getEndLoc());
12014}
12015
12016template <typename Derived>
12017void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12018 const OpenACCVectorLengthClause &C) {
12019 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12020 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12021
12022 ExprResult Res = Self.TransformExpr(IntExpr);
12023 if (!Res.isUsable())
12024 return;
12025
12026 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12027 C.getClauseKind(),
12028 C.getBeginLoc(), Res.get());
12029 if (!Res.isUsable())
12030 return;
12031
12032 ParsedClause.setIntExprDetails(Res.get());
12034 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12035 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
12036 ParsedClause.getEndLoc());
12037}
12038
12039template <typename Derived>
12040void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12041 const OpenACCAsyncClause &C) {
12042 if (C.hasIntExpr()) {
12043 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12044 if (!Res.isUsable())
12045 return;
12046
12047 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12048 C.getClauseKind(),
12049 C.getBeginLoc(), Res.get());
12050 if (!Res.isUsable())
12051 return;
12052 ParsedClause.setIntExprDetails(Res.get());
12053 }
12054
12055 NewClause = OpenACCAsyncClause::Create(
12056 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12057 ParsedClause.getLParenLoc(),
12058 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12059 : nullptr,
12060 ParsedClause.getEndLoc());
12061}
12062
12063template <typename Derived>
12064void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12065 const OpenACCWorkerClause &C) {
12066 if (C.hasIntExpr()) {
12067 // restrictions on this expression are all "does it exist in certain
12068 // situations" that are not possible to be dependent, so the only check we
12069 // have is that it transforms, and is an int expression.
12070 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12071 if (!Res.isUsable())
12072 return;
12073
12074 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12075 C.getClauseKind(),
12076 C.getBeginLoc(), Res.get());
12077 if (!Res.isUsable())
12078 return;
12079 ParsedClause.setIntExprDetails(Res.get());
12080 }
12081
12082 NewClause = OpenACCWorkerClause::Create(
12083 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12084 ParsedClause.getLParenLoc(),
12085 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12086 : nullptr,
12087 ParsedClause.getEndLoc());
12088}
12089
12090template <typename Derived>
12091void OpenACCClauseTransform<Derived>::VisitVectorClause(
12092 const OpenACCVectorClause &C) {
12093 if (C.hasIntExpr()) {
12094 // restrictions on this expression are all "does it exist in certain
12095 // situations" that are not possible to be dependent, so the only check we
12096 // have is that it transforms, and is an int expression.
12097 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12098 if (!Res.isUsable())
12099 return;
12100
12101 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12102 C.getClauseKind(),
12103 C.getBeginLoc(), Res.get());
12104 if (!Res.isUsable())
12105 return;
12106 ParsedClause.setIntExprDetails(Res.get());
12107 }
12108
12109 NewClause = OpenACCVectorClause::Create(
12110 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12111 ParsedClause.getLParenLoc(),
12112 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12113 : nullptr,
12114 ParsedClause.getEndLoc());
12115}
12116
12117template <typename Derived>
12118void OpenACCClauseTransform<Derived>::VisitWaitClause(
12119 const OpenACCWaitClause &C) {
12120 if (!C.getLParenLoc().isInvalid()) {
12121 Expr *DevNumExpr = nullptr;
12122 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
12123
12124 // Instantiate devnum expr if it exists.
12125 if (C.getDevNumExpr()) {
12126 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
12127 if (!Res.isUsable())
12128 return;
12129 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12130 C.getClauseKind(),
12131 C.getBeginLoc(), Res.get());
12132 if (!Res.isUsable())
12133 return;
12134
12135 DevNumExpr = Res.get();
12136 }
12137
12138 // Instantiate queue ids.
12139 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
12140 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
12141 if (!Res.isUsable())
12142 return;
12143 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12144 C.getClauseKind(),
12145 C.getBeginLoc(), Res.get());
12146 if (!Res.isUsable())
12147 return;
12148
12149 InstantiatedQueueIdExprs.push_back(Res.get());
12150 }
12151
12152 ParsedClause.setWaitDetails(DevNumExpr, C.getQueuesLoc(),
12153 std::move(InstantiatedQueueIdExprs));
12154 }
12155
12156 NewClause = OpenACCWaitClause::Create(
12157 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12158 ParsedClause.getLParenLoc(), ParsedClause.getDevNumExpr(),
12159 ParsedClause.getQueuesLoc(), ParsedClause.getQueueIdExprs(),
12160 ParsedClause.getEndLoc());
12161}
12162
12163template <typename Derived>
12164void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
12165 const OpenACCDeviceTypeClause &C) {
12166 // Nothing to transform here, just create a new version of 'C'.
12168 Self.getSema().getASTContext(), C.getClauseKind(),
12169 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12170 C.getArchitectures(), ParsedClause.getEndLoc());
12171}
12172
12173template <typename Derived>
12174void OpenACCClauseTransform<Derived>::VisitAutoClause(
12175 const OpenACCAutoClause &C) {
12176 // Nothing to do, so just create a new node.
12177 NewClause = OpenACCAutoClause::Create(Self.getSema().getASTContext(),
12178 ParsedClause.getBeginLoc(),
12179 ParsedClause.getEndLoc());
12180}
12181
12182template <typename Derived>
12183void OpenACCClauseTransform<Derived>::VisitIndependentClause(
12184 const OpenACCIndependentClause &C) {
12185 NewClause = OpenACCIndependentClause::Create(Self.getSema().getASTContext(),
12186 ParsedClause.getBeginLoc(),
12187 ParsedClause.getEndLoc());
12188}
12189
12190template <typename Derived>
12191void OpenACCClauseTransform<Derived>::VisitSeqClause(
12192 const OpenACCSeqClause &C) {
12193 NewClause = OpenACCSeqClause::Create(Self.getSema().getASTContext(),
12194 ParsedClause.getBeginLoc(),
12195 ParsedClause.getEndLoc());
12196}
12197template <typename Derived>
12198void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
12199 const OpenACCFinalizeClause &C) {
12200 NewClause = OpenACCFinalizeClause::Create(Self.getSema().getASTContext(),
12201 ParsedClause.getBeginLoc(),
12202 ParsedClause.getEndLoc());
12203}
12204
12205template <typename Derived>
12206void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
12207 const OpenACCIfPresentClause &C) {
12208 NewClause = OpenACCIfPresentClause::Create(Self.getSema().getASTContext(),
12209 ParsedClause.getBeginLoc(),
12210 ParsedClause.getEndLoc());
12211}
12212
12213template <typename Derived>
12214void OpenACCClauseTransform<Derived>::VisitReductionClause(
12215 const OpenACCReductionClause &C) {
12216 SmallVector<Expr *> TransformedVars = VisitVarList(C.getVarList());
12217 SmallVector<Expr *> ValidVars;
12218
12219 for (Expr *Var : TransformedVars) {
12220 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
12221 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
12222 if (Res.isUsable())
12223 ValidVars.push_back(Res.get());
12224 }
12225
12226 NewClause = Self.getSema().OpenACC().CheckReductionClause(
12227 ExistingClauses, ParsedClause.getDirectiveKind(),
12228 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12229 C.getReductionOp(), ValidVars, ParsedClause.getEndLoc());
12230}
12231
12232template <typename Derived>
12233void OpenACCClauseTransform<Derived>::VisitCollapseClause(
12234 const OpenACCCollapseClause &C) {
12235 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
12236 assert(LoopCount && "collapse clause constructed with invalid loop count");
12237
12238 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
12239
12240 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
12242 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
12243
12244 NewLoopCount =
12245 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
12246
12247 if (!NewLoopCount.isUsable())
12248 return;
12249
12250 ParsedClause.setCollapseDetails(C.hasForce(), NewLoopCount.get());
12252 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12253 ParsedClause.getLParenLoc(), ParsedClause.isForce(),
12254 ParsedClause.getLoopCount(), ParsedClause.getEndLoc());
12255}
12256
12257template <typename Derived>
12258void OpenACCClauseTransform<Derived>::VisitTileClause(
12259 const OpenACCTileClause &C) {
12260
12261 llvm::SmallVector<Expr *> TransformedExprs;
12262
12263 for (Expr *E : C.getSizeExprs()) {
12264 ExprResult NewSizeExpr = Self.TransformExpr(E);
12265
12266 if (!NewSizeExpr.isUsable())
12267 return;
12268
12269 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
12271 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
12272
12273 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
12274
12275 if (!NewSizeExpr.isUsable())
12276 return;
12277 TransformedExprs.push_back(NewSizeExpr.get());
12278 }
12279
12280 ParsedClause.setIntExprDetails(TransformedExprs);
12281 NewClause = OpenACCTileClause::Create(
12282 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12283 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs(),
12284 ParsedClause.getEndLoc());
12285}
12286template <typename Derived>
12287void OpenACCClauseTransform<Derived>::VisitGangClause(
12288 const OpenACCGangClause &C) {
12289 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
12290 llvm::SmallVector<Expr *> TransformedIntExprs;
12291
12292 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
12293 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
12294 if (!ER.isUsable())
12295 continue;
12296
12297 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
12298 ParsedClause.getDirectiveKind(),
12299 C.getExpr(I).first, ER.get());
12300 if (!ER.isUsable())
12301 continue;
12302 TransformedGangKinds.push_back(C.getExpr(I).first);
12303 TransformedIntExprs.push_back(ER.get());
12304 }
12305
12306 NewClause = Self.getSema().OpenACC().CheckGangClause(
12307 ParsedClause.getDirectiveKind(), ExistingClauses,
12308 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12309 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
12310}
12311} // namespace
12312template <typename Derived>
12313OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
12314 ArrayRef<const OpenACCClause *> ExistingClauses,
12315 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
12316
12317 SemaOpenACC::OpenACCParsedClause ParsedClause(
12318 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
12319 ParsedClause.setEndLoc(OldClause->getEndLoc());
12320
12321 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(OldClause))
12322 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
12323
12324 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
12325 ParsedClause};
12326 Transform.Visit(OldClause);
12327
12328 return Transform.CreatedClause();
12329}
12330
12331template <typename Derived>
12333TreeTransform<Derived>::TransformOpenACCClauseList(
12335 llvm::SmallVector<OpenACCClause *> TransformedClauses;
12336 for (const auto *Clause : OldClauses) {
12337 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
12338 TransformedClauses, DirKind, Clause))
12339 TransformedClauses.push_back(TransformedClause);
12340 }
12341 return TransformedClauses;
12342}
12343
12344template <typename Derived>
12345StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
12346 OpenACCComputeConstruct *C) {
12347 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12348
12349 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12350 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12351 C->clauses());
12352
12353 if (getSema().OpenACC().ActOnStartStmtDirective(
12354 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12355 return StmtError();
12356
12357 // Transform Structured Block.
12358 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12359 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12360 C->clauses(), TransformedClauses);
12361 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12362 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12363 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12364
12365 return getDerived().RebuildOpenACCComputeConstruct(
12366 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12367 C->getEndLoc(), TransformedClauses, StrBlock);
12368}
12369
12370template <typename Derived>
12372TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
12373
12374 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12375
12376 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12377 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12378 C->clauses());
12379
12380 if (getSema().OpenACC().ActOnStartStmtDirective(
12381 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12382 return StmtError();
12383
12384 // Transform Loop.
12385 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12386 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12387 C->clauses(), TransformedClauses);
12388 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12389 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12390 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12391
12392 return getDerived().RebuildOpenACCLoopConstruct(
12393 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12394 TransformedClauses, Loop);
12395}
12396
12397template <typename Derived>
12398StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
12399 OpenACCCombinedConstruct *C) {
12400 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12401
12402 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12403 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12404 C->clauses());
12405
12406 if (getSema().OpenACC().ActOnStartStmtDirective(
12407 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12408 return StmtError();
12409
12410 // Transform Loop.
12411 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12412 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12413 C->clauses(), TransformedClauses);
12414 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12415 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12416 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12417
12418 return getDerived().RebuildOpenACCCombinedConstruct(
12419 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12420 C->getEndLoc(), TransformedClauses, Loop);
12421}
12422
12423template <typename Derived>
12425TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
12426 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12427
12428 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12429 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12430 C->clauses());
12431 if (getSema().OpenACC().ActOnStartStmtDirective(
12432 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12433 return StmtError();
12434
12435 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12436 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12437 C->clauses(), TransformedClauses);
12438 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12439 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12440 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12441
12442 return getDerived().RebuildOpenACCDataConstruct(
12443 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12444 TransformedClauses, StrBlock);
12445}
12446
12447template <typename Derived>
12448StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
12449 OpenACCEnterDataConstruct *C) {
12450 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12451
12452 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12453 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12454 C->clauses());
12455 if (getSema().OpenACC().ActOnStartStmtDirective(
12456 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12457 return StmtError();
12458
12459 return getDerived().RebuildOpenACCEnterDataConstruct(
12460 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12461 TransformedClauses);
12462}
12463
12464template <typename Derived>
12465StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
12466 OpenACCExitDataConstruct *C) {
12467 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12468
12469 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12470 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12471 C->clauses());
12472 if (getSema().OpenACC().ActOnStartStmtDirective(
12473 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12474 return StmtError();
12475
12476 return getDerived().RebuildOpenACCExitDataConstruct(
12477 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12478 TransformedClauses);
12479}
12480
12481template <typename Derived>
12482StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
12483 OpenACCHostDataConstruct *C) {
12484 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12485
12486 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12487 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12488 C->clauses());
12489 if (getSema().OpenACC().ActOnStartStmtDirective(
12490 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12491 return StmtError();
12492
12493 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12494 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12495 C->clauses(), TransformedClauses);
12496 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12497 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12498 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12499
12500 return getDerived().RebuildOpenACCHostDataConstruct(
12501 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12502 TransformedClauses, StrBlock);
12503}
12504
12505template <typename Derived>
12507TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
12508 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12509
12510 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12511 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12512 C->clauses());
12513 if (getSema().OpenACC().ActOnStartStmtDirective(
12514 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12515 return StmtError();
12516
12517 return getDerived().RebuildOpenACCInitConstruct(
12518 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12519 TransformedClauses);
12520}
12521
12522template <typename Derived>
12523StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
12524 OpenACCShutdownConstruct *C) {
12525 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12526
12527 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12528 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12529 C->clauses());
12530 if (getSema().OpenACC().ActOnStartStmtDirective(
12531 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12532 return StmtError();
12533
12534 return getDerived().RebuildOpenACCShutdownConstruct(
12535 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12536 TransformedClauses);
12537}
12538template <typename Derived>
12540TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
12541 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12542
12543 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12544 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12545 C->clauses());
12546 if (getSema().OpenACC().ActOnStartStmtDirective(
12547 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12548 return StmtError();
12549
12550 return getDerived().RebuildOpenACCSetConstruct(
12551 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12552 TransformedClauses);
12553}
12554
12555template <typename Derived>
12556StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
12557 OpenACCUpdateConstruct *C) {
12558 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12559
12560 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12561 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12562 C->clauses());
12563 if (getSema().OpenACC().ActOnStartStmtDirective(
12564 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12565 return StmtError();
12566
12567 return getDerived().RebuildOpenACCUpdateConstruct(
12568 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12569 TransformedClauses);
12570}
12571
12572template <typename Derived>
12574TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
12575 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12576
12577 ExprResult DevNumExpr;
12578 if (C->hasDevNumExpr()) {
12579 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
12580
12581 if (DevNumExpr.isUsable())
12582 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
12584 C->getBeginLoc(), DevNumExpr.get());
12585 }
12586
12587 llvm::SmallVector<Expr *> QueueIdExprs;
12588
12589 for (Expr *QE : C->getQueueIdExprs()) {
12590 assert(QE && "Null queue id expr?");
12591 ExprResult NewEQ = getDerived().TransformExpr(QE);
12592
12593 if (!NewEQ.isUsable())
12594 break;
12595 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
12597 C->getBeginLoc(), NewEQ.get());
12598 if (NewEQ.isUsable())
12599 QueueIdExprs.push_back(NewEQ.get());
12600 }
12601
12602 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12603 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12604 C->clauses());
12605
12606 if (getSema().OpenACC().ActOnStartStmtDirective(
12607 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12608 return StmtError();
12609
12610 return getDerived().RebuildOpenACCWaitConstruct(
12611 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12612 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
12613 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
12614}
12615
12616template <typename Derived>
12617ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
12618 OpenACCAsteriskSizeExpr *E) {
12619 if (getDerived().AlwaysRebuild())
12620 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
12621 // Nothing can ever change, so there is never anything to transform.
12622 return E;
12623}
12624
12625//===----------------------------------------------------------------------===//
12626// Expression transformation
12627//===----------------------------------------------------------------------===//
12628template<typename Derived>
12630TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
12631 return TransformExpr(E->getSubExpr());
12632}
12633
12634template <typename Derived>
12635ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
12636 SYCLUniqueStableNameExpr *E) {
12637 if (!E->isTypeDependent())
12638 return E;
12639
12640 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
12641
12642 if (!NewT)
12643 return ExprError();
12644
12645 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
12646 return E;
12647
12648 return getDerived().RebuildSYCLUniqueStableNameExpr(
12649 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
12650}
12651
12652template<typename Derived>
12654TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
12655 if (!E->isTypeDependent())
12656 return E;
12657
12658 return getDerived().RebuildPredefinedExpr(E->getLocation(),
12659 E->getIdentKind());
12660}
12661
12662template<typename Derived>
12664TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
12665 NestedNameSpecifierLoc QualifierLoc;
12666 if (E->getQualifierLoc()) {
12667 QualifierLoc
12668 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
12669 if (!QualifierLoc)
12670 return ExprError();
12671 }
12672
12673 ValueDecl *ND
12674 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
12675 E->getDecl()));
12676 if (!ND)
12677 return ExprError();
12678
12679 NamedDecl *Found = ND;
12680 if (E->getFoundDecl() != E->getDecl()) {
12681 Found = cast_or_null<NamedDecl>(
12682 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
12683 if (!Found)
12684 return ExprError();
12685 }
12686
12687 DeclarationNameInfo NameInfo = E->getNameInfo();
12688 if (NameInfo.getName()) {
12689 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
12690 if (!NameInfo.getName())
12691 return ExprError();
12692 }
12693
12694 if (!getDerived().AlwaysRebuild() &&
12695 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
12696 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
12697 Found == E->getFoundDecl() &&
12698 NameInfo.getName() == E->getDecl()->getDeclName() &&
12699 !E->hasExplicitTemplateArgs()) {
12700
12701 // Mark it referenced in the new context regardless.
12702 // FIXME: this is a bit instantiation-specific.
12703 SemaRef.MarkDeclRefReferenced(E);
12704
12705 return E;
12706 }
12707
12708 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
12709 if (E->hasExplicitTemplateArgs()) {
12710 TemplateArgs = &TransArgs;
12711 TransArgs.setLAngleLoc(E->getLAngleLoc());
12712 TransArgs.setRAngleLoc(E->getRAngleLoc());
12713 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
12714 E->getNumTemplateArgs(),
12715 TransArgs))
12716 return ExprError();
12717 }
12718
12719 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
12720 Found, TemplateArgs);
12721}
12722
12723template<typename Derived>
12725TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
12726 return E;
12727}
12728
12729template <typename Derived>
12730ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
12731 FixedPointLiteral *E) {
12732 return E;
12733}
12734
12735template<typename Derived>
12737TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
12738 return E;
12739}
12740
12741template<typename Derived>
12743TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
12744 return E;
12745}
12746
12747template<typename Derived>
12749TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
12750 return E;
12751}
12752
12753template<typename Derived>
12755TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
12756 return E;
12757}
12758
12759template<typename Derived>
12761TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
12762 return getDerived().TransformCallExpr(E);
12763}
12764
12765template<typename Derived>
12767TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
12768 ExprResult ControllingExpr;
12769 TypeSourceInfo *ControllingType = nullptr;
12770 if (E->isExprPredicate())
12771 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
12772 else
12773 ControllingType = getDerived().TransformType(E->getControllingType());
12774
12775 if (ControllingExpr.isInvalid() && !ControllingType)
12776 return ExprError();
12777
12778 SmallVector<Expr *, 4> AssocExprs;
12780 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
12781 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
12782 if (TSI) {
12783 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
12784 if (!AssocType)
12785 return ExprError();
12786 AssocTypes.push_back(AssocType);
12787 } else {
12788 AssocTypes.push_back(nullptr);
12789 }
12790
12791 ExprResult AssocExpr =
12792 getDerived().TransformExpr(Assoc.getAssociationExpr());
12793 if (AssocExpr.isInvalid())
12794 return ExprError();
12795 AssocExprs.push_back(AssocExpr.get());
12796 }
12797
12798 if (!ControllingType)
12799 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
12800 E->getDefaultLoc(),
12801 E->getRParenLoc(),
12802 ControllingExpr.get(),
12803 AssocTypes,
12804 AssocExprs);
12805 return getDerived().RebuildGenericSelectionExpr(
12806 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
12807 ControllingType, AssocTypes, AssocExprs);
12808}
12809
12810template<typename Derived>
12812TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
12813 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12814 if (SubExpr.isInvalid())
12815 return ExprError();
12816
12817 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
12818 return E;
12819
12820 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
12821 E->getRParen());
12822}
12823
12824/// The operand of a unary address-of operator has special rules: it's
12825/// allowed to refer to a non-static member of a class even if there's no 'this'
12826/// object available.
12827template<typename Derived>
12830 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
12831 return getDerived().TransformDependentScopeDeclRefExpr(
12832 DRE, /*IsAddressOfOperand=*/true, nullptr);
12833 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E))
12834 return getDerived().TransformUnresolvedLookupExpr(
12835 ULE, /*IsAddressOfOperand=*/true);
12836 else
12837 return getDerived().TransformExpr(E);
12838}
12839
12840template<typename Derived>
12843 ExprResult SubExpr;
12844 if (E->getOpcode() == UO_AddrOf)
12845 SubExpr = TransformAddressOfOperand(E->getSubExpr());
12846 else
12847 SubExpr = TransformExpr(E->getSubExpr());
12848 if (SubExpr.isInvalid())
12849 return ExprError();
12850
12851 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
12852 return E;
12853
12854 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
12855 E->getOpcode(),
12856 SubExpr.get());
12857}
12858
12859template<typename Derived>
12861TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
12862 // Transform the type.
12863 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
12864 if (!Type)
12865 return ExprError();
12866
12867 // Transform all of the components into components similar to what the
12868 // parser uses.
12869 // FIXME: It would be slightly more efficient in the non-dependent case to
12870 // just map FieldDecls, rather than requiring the rebuilder to look for
12871 // the fields again. However, __builtin_offsetof is rare enough in
12872 // template code that we don't care.
12873 bool ExprChanged = false;
12874 typedef Sema::OffsetOfComponent Component;
12875 SmallVector<Component, 4> Components;
12876 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
12877 const OffsetOfNode &ON = E->getComponent(I);
12878 Component Comp;
12879 Comp.isBrackets = true;
12880 Comp.LocStart = ON.getSourceRange().getBegin();
12881 Comp.LocEnd = ON.getSourceRange().getEnd();
12882 switch (ON.getKind()) {
12883 case OffsetOfNode::Array: {
12884 Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
12885 ExprResult Index = getDerived().TransformExpr(FromIndex);
12886 if (Index.isInvalid())
12887 return ExprError();
12888
12889 ExprChanged = ExprChanged || Index.get() != FromIndex;
12890 Comp.isBrackets = true;
12891 Comp.U.E = Index.get();
12892 break;
12893 }
12894
12897 Comp.isBrackets = false;
12898 Comp.U.IdentInfo = ON.getFieldName();
12899 if (!Comp.U.IdentInfo)
12900 continue;
12901
12902 break;
12903
12904 case OffsetOfNode::Base:
12905 // Will be recomputed during the rebuild.
12906 continue;
12907 }
12908
12909 Components.push_back(Comp);
12910 }
12911
12912 // If nothing changed, retain the existing expression.
12913 if (!getDerived().AlwaysRebuild() &&
12914 Type == E->getTypeSourceInfo() &&
12915 !ExprChanged)
12916 return E;
12917
12918 // Build a new offsetof expression.
12919 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
12920 Components, E->getRParenLoc());
12921}
12922
12923template<typename Derived>
12925TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
12926 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
12927 "opaque value expression requires transformation");
12928 return E;
12929}
12930
12931template<typename Derived>
12933TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
12934 return E;
12935}
12936
12937template <typename Derived>
12938ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
12940 bool Changed = false;
12941 for (Expr *C : E->subExpressions()) {
12942 ExprResult NewC = getDerived().TransformExpr(C);
12943 if (NewC.isInvalid())
12944 return ExprError();
12945 Children.push_back(NewC.get());
12946
12947 Changed |= NewC.get() != C;
12948 }
12949 if (!getDerived().AlwaysRebuild() && !Changed)
12950 return E;
12951 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
12952 Children, E->getType());
12953}
12954
12955template<typename Derived>
12957TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
12958 // Rebuild the syntactic form. The original syntactic form has
12959 // opaque-value expressions in it, so strip those away and rebuild
12960 // the result. This is a really awful way of doing this, but the
12961 // better solution (rebuilding the semantic expressions and
12962 // rebinding OVEs as necessary) doesn't work; we'd need
12963 // TreeTransform to not strip away implicit conversions.
12964 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
12965 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
12966 if (result.isInvalid()) return ExprError();
12967
12968 // If that gives us a pseudo-object result back, the pseudo-object
12969 // expression must have been an lvalue-to-rvalue conversion which we
12970 // should reapply.
12971 if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
12972 result = SemaRef.PseudoObject().checkRValue(result.get());
12973
12974 return result;
12975}
12976
12977template<typename Derived>
12979TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
12980 UnaryExprOrTypeTraitExpr *E) {
12981 if (E->isArgumentType()) {
12982 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
12983
12984 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
12985 if (!NewT)
12986 return ExprError();
12987
12988 if (!getDerived().AlwaysRebuild() && OldT == NewT)
12989 return E;
12990
12991 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
12992 E->getKind(),
12993 E->getSourceRange());
12994 }
12995
12996 // C++0x [expr.sizeof]p1:
12997 // The operand is either an expression, which is an unevaluated operand
12998 // [...]
12999 EnterExpressionEvaluationContext Unevaluated(
13002
13003 // Try to recover if we have something like sizeof(T::X) where X is a type.
13004 // Notably, there must be *exactly* one set of parens if X is a type.
13005 TypeSourceInfo *RecoveryTSI = nullptr;
13006 ExprResult SubExpr;
13007 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
13008 if (auto *DRE =
13009 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
13010 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
13011 PE, DRE, false, &RecoveryTSI);
13012 else
13013 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
13014
13015 if (RecoveryTSI) {
13016 return getDerived().RebuildUnaryExprOrTypeTrait(
13017 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
13018 } else if (SubExpr.isInvalid())
13019 return ExprError();
13020
13021 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
13022 return E;
13023
13024 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
13025 E->getOperatorLoc(),
13026 E->getKind(),
13027 E->getSourceRange());
13028}
13029
13030template<typename Derived>
13032TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
13033 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13034 if (LHS.isInvalid())
13035 return ExprError();
13036
13037 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13038 if (RHS.isInvalid())
13039 return ExprError();
13040
13041
13042 if (!getDerived().AlwaysRebuild() &&
13043 LHS.get() == E->getLHS() &&
13044 RHS.get() == E->getRHS())
13045 return E;
13046
13047 return getDerived().RebuildArraySubscriptExpr(
13048 LHS.get(),
13049 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
13050}
13051
13052template <typename Derived>
13054TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
13055 ExprResult Base = getDerived().TransformExpr(E->getBase());
13056 if (Base.isInvalid())
13057 return ExprError();
13058
13059 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13060 if (RowIdx.isInvalid())
13061 return ExprError();
13062
13063 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
13064 if (ColumnIdx.isInvalid())
13065 return ExprError();
13066
13067 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13068 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
13069 return E;
13070
13071 return getDerived().RebuildMatrixSubscriptExpr(
13072 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
13073}
13074
13075template <typename Derived>
13077TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
13078 ExprResult Base = getDerived().TransformExpr(E->getBase());
13079 if (Base.isInvalid())
13080 return ExprError();
13081
13082 ExprResult LowerBound;
13083 if (E->getLowerBound()) {
13084 LowerBound = getDerived().TransformExpr(E->getLowerBound());
13085 if (LowerBound.isInvalid())
13086 return ExprError();
13087 }
13088
13089 ExprResult Length;
13090 if (E->getLength()) {
13091 Length = getDerived().TransformExpr(E->getLength());
13092 if (Length.isInvalid())
13093 return ExprError();
13094 }
13095
13096 ExprResult Stride;
13097 if (E->isOMPArraySection()) {
13098 if (Expr *Str = E->getStride()) {
13099 Stride = getDerived().TransformExpr(Str);
13100 if (Stride.isInvalid())
13101 return ExprError();
13102 }
13103 }
13104
13105 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13106 LowerBound.get() == E->getLowerBound() &&
13107 Length.get() == E->getLength() &&
13108 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
13109 return E;
13110
13111 return getDerived().RebuildArraySectionExpr(
13112 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
13113 LowerBound.get(), E->getColonLocFirst(),
13114 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
13115 Length.get(), Stride.get(), E->getRBracketLoc());
13116}
13117
13118template <typename Derived>
13120TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
13121 ExprResult Base = getDerived().TransformExpr(E->getBase());
13122 if (Base.isInvalid())
13123 return ExprError();
13124
13126 bool ErrorFound = false;
13127 for (Expr *Dim : E->getDimensions()) {
13128 ExprResult DimRes = getDerived().TransformExpr(Dim);
13129 if (DimRes.isInvalid()) {
13130 ErrorFound = true;
13131 continue;
13132 }
13133 Dims.push_back(DimRes.get());
13134 }
13135
13136 if (ErrorFound)
13137 return ExprError();
13138 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
13139 E->getRParenLoc(), Dims,
13140 E->getBracketsRanges());
13141}
13142
13143template <typename Derived>
13145TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
13146 unsigned NumIterators = E->numOfIterators();
13148
13149 bool ErrorFound = false;
13150 bool NeedToRebuild = getDerived().AlwaysRebuild();
13151 for (unsigned I = 0; I < NumIterators; ++I) {
13152 auto *D = cast<VarDecl>(E->getIteratorDecl(I));
13153 Data[I].DeclIdent = D->getIdentifier();
13154 Data[I].DeclIdentLoc = D->getLocation();
13155 if (D->getLocation() == D->getBeginLoc()) {
13156 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
13157 "Implicit type must be int.");
13158 } else {
13159 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
13160 QualType DeclTy = getDerived().TransformType(D->getType());
13161 Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI);
13162 }
13163 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
13164 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
13165 ExprResult End = getDerived().TransformExpr(Range.End);
13166 ExprResult Step = getDerived().TransformExpr(Range.Step);
13167 ErrorFound = ErrorFound ||
13168 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
13169 !Data[I].Type.get().isNull())) ||
13170 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
13171 if (ErrorFound)
13172 continue;
13173 Data[I].Range.Begin = Begin.get();
13174 Data[I].Range.End = End.get();
13175 Data[I].Range.Step = Step.get();
13176 Data[I].AssignLoc = E->getAssignLoc(I);
13177 Data[I].ColonLoc = E->getColonLoc(I);
13178 Data[I].SecColonLoc = E->getSecondColonLoc(I);
13179 NeedToRebuild =
13180 NeedToRebuild ||
13181 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
13182 D->getType().getTypePtrOrNull()) ||
13183 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
13184 Range.Step != Data[I].Range.Step;
13185 }
13186 if (ErrorFound)
13187 return ExprError();
13188 if (!NeedToRebuild)
13189 return E;
13190
13191 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
13192 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
13193 if (!Res.isUsable())
13194 return Res;
13195 auto *IE = cast<OMPIteratorExpr>(Res.get());
13196 for (unsigned I = 0; I < NumIterators; ++I)
13197 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
13198 IE->getIteratorDecl(I));
13199 return Res;
13200}
13201
13202template<typename Derived>
13204TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
13205 // Transform the callee.
13206 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13207 if (Callee.isInvalid())
13208 return ExprError();
13209
13210 // Transform arguments.
13211 bool ArgChanged = false;
13213 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13214 &ArgChanged))
13215 return ExprError();
13216
13217 if (!getDerived().AlwaysRebuild() &&
13218 Callee.get() == E->getCallee() &&
13219 !ArgChanged)
13220 return SemaRef.MaybeBindToTemporary(E);
13221
13222 // FIXME: Wrong source location information for the '('.
13223 SourceLocation FakeLParenLoc
13224 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13225
13226 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13227 if (E->hasStoredFPFeatures()) {
13228 FPOptionsOverride NewOverrides = E->getFPFeatures();
13229 getSema().CurFPFeatures =
13230 NewOverrides.applyOverrides(getSema().getLangOpts());
13231 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13232 }
13233
13234 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13235 Args,
13236 E->getRParenLoc());
13237}
13238
13239template<typename Derived>
13241TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
13242 ExprResult Base = getDerived().TransformExpr(E->getBase());
13243 if (Base.isInvalid())
13244 return ExprError();
13245
13246 NestedNameSpecifierLoc QualifierLoc;
13247 if (E->hasQualifier()) {
13248 QualifierLoc
13249 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13250
13251 if (!QualifierLoc)
13252 return ExprError();
13253 }
13254 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13255
13256 ValueDecl *Member
13257 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
13258 E->getMemberDecl()));
13259 if (!Member)
13260 return ExprError();
13261
13262 NamedDecl *FoundDecl = E->getFoundDecl();
13263 if (FoundDecl == E->getMemberDecl()) {
13264 FoundDecl = Member;
13265 } else {
13266 FoundDecl = cast_or_null<NamedDecl>(
13267 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
13268 if (!FoundDecl)
13269 return ExprError();
13270 }
13271
13272 if (!getDerived().AlwaysRebuild() &&
13273 Base.get() == E->getBase() &&
13274 QualifierLoc == E->getQualifierLoc() &&
13275 Member == E->getMemberDecl() &&
13276 FoundDecl == E->getFoundDecl() &&
13277 !E->hasExplicitTemplateArgs()) {
13278
13279 // Skip for member expression of (this->f), rebuilt thisi->f is needed
13280 // for Openmp where the field need to be privatizized in the case.
13281 if (!(isa<CXXThisExpr>(E->getBase()) &&
13282 getSema().OpenMP().isOpenMPRebuildMemberExpr(
13283 cast<ValueDecl>(Member)))) {
13284 // Mark it referenced in the new context regardless.
13285 // FIXME: this is a bit instantiation-specific.
13286 SemaRef.MarkMemberReferenced(E);
13287 return E;
13288 }
13289 }
13290
13291 TemplateArgumentListInfo TransArgs;
13292 if (E->hasExplicitTemplateArgs()) {
13293 TransArgs.setLAngleLoc(E->getLAngleLoc());
13294 TransArgs.setRAngleLoc(E->getRAngleLoc());
13295 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13296 E->getNumTemplateArgs(),
13297 TransArgs))
13298 return ExprError();
13299 }
13300
13301 // FIXME: Bogus source location for the operator
13302 SourceLocation FakeOperatorLoc =
13303 SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
13304
13305 // FIXME: to do this check properly, we will need to preserve the
13306 // first-qualifier-in-scope here, just in case we had a dependent
13307 // base (and therefore couldn't do the check) and a
13308 // nested-name-qualifier (and therefore could do the lookup).
13309 NamedDecl *FirstQualifierInScope = nullptr;
13310 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
13311 if (MemberNameInfo.getName()) {
13312 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
13313 if (!MemberNameInfo.getName())
13314 return ExprError();
13315 }
13316
13317 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
13318 E->isArrow(),
13319 QualifierLoc,
13320 TemplateKWLoc,
13321 MemberNameInfo,
13322 Member,
13323 FoundDecl,
13324 (E->hasExplicitTemplateArgs()
13325 ? &TransArgs : nullptr),
13326 FirstQualifierInScope);
13327}
13328
13329template<typename Derived>
13331TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
13332 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13333 if (LHS.isInvalid())
13334 return ExprError();
13335
13336 ExprResult RHS =
13337 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
13338 if (RHS.isInvalid())
13339 return ExprError();
13340
13341 if (!getDerived().AlwaysRebuild() &&
13342 LHS.get() == E->getLHS() &&
13343 RHS.get() == E->getRHS())
13344 return E;
13345
13346 if (E->isCompoundAssignmentOp())
13347 // FPFeatures has already been established from trailing storage
13348 return getDerived().RebuildBinaryOperator(
13349 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
13350 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13351 FPOptionsOverride NewOverrides(E->getFPFeatures());
13352 getSema().CurFPFeatures =
13353 NewOverrides.applyOverrides(getSema().getLangOpts());
13354 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13355 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
13356 LHS.get(), RHS.get());
13357}
13358
13359template <typename Derived>
13360ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
13361 CXXRewrittenBinaryOperator *E) {
13362 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
13363
13364 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
13365 if (LHS.isInvalid())
13366 return ExprError();
13367
13368 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
13369 if (RHS.isInvalid())
13370 return ExprError();
13371
13372 // Extract the already-resolved callee declarations so that we can restrict
13373 // ourselves to using them as the unqualified lookup results when rebuilding.
13374 UnresolvedSet<2> UnqualLookups;
13375 bool ChangedAnyLookups = false;
13376 Expr *PossibleBinOps[] = {E->getSemanticForm(),
13377 const_cast<Expr *>(Decomp.InnerBinOp)};
13378 for (Expr *PossibleBinOp : PossibleBinOps) {
13379 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());
13380 if (!Op)
13381 continue;
13382 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());
13383 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))
13384 continue;
13385
13386 // Transform the callee in case we built a call to a local extern
13387 // declaration.
13388 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
13389 E->getOperatorLoc(), Callee->getFoundDecl()));
13390 if (!Found)
13391 return ExprError();
13392 if (Found != Callee->getFoundDecl())
13393 ChangedAnyLookups = true;
13394 UnqualLookups.addDecl(Found);
13395 }
13396
13397 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
13398 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
13399 // Mark all functions used in the rewrite as referenced. Note that when
13400 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
13401 // function calls, and/or there might be a user-defined conversion sequence
13402 // applied to the operands of the <.
13403 // FIXME: this is a bit instantiation-specific.
13404 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
13405 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);
13406 return E;
13407 }
13408
13409 return getDerived().RebuildCXXRewrittenBinaryOperator(
13410 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
13411}
13412
13413template<typename Derived>
13415TreeTransform<Derived>::TransformCompoundAssignOperator(
13416 CompoundAssignOperator *E) {
13417 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13418 FPOptionsOverride NewOverrides(E->getFPFeatures());
13419 getSema().CurFPFeatures =
13420 NewOverrides.applyOverrides(getSema().getLangOpts());
13421 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13422 return getDerived().TransformBinaryOperator(E);
13423}
13424
13425template<typename Derived>
13426ExprResult TreeTransform<Derived>::
13427TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
13428 // Just rebuild the common and RHS expressions and see whether we
13429 // get any changes.
13430
13431 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
13432 if (commonExpr.isInvalid())
13433 return ExprError();
13434
13435 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
13436 if (rhs.isInvalid())
13437 return ExprError();
13438
13439 if (!getDerived().AlwaysRebuild() &&
13440 commonExpr.get() == e->getCommon() &&
13441 rhs.get() == e->getFalseExpr())
13442 return e;
13443
13444 return getDerived().RebuildConditionalOperator(commonExpr.get(),
13445 e->getQuestionLoc(),
13446 nullptr,
13447 e->getColonLoc(),
13448 rhs.get());
13449}
13450
13451template<typename Derived>
13453TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
13454 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13455 if (Cond.isInvalid())
13456 return ExprError();
13457
13458 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13459 if (LHS.isInvalid())
13460 return ExprError();
13461
13462 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13463 if (RHS.isInvalid())
13464 return ExprError();
13465
13466 if (!getDerived().AlwaysRebuild() &&
13467 Cond.get() == E->getCond() &&
13468 LHS.get() == E->getLHS() &&
13469 RHS.get() == E->getRHS())
13470 return E;
13471
13472 return getDerived().RebuildConditionalOperator(Cond.get(),
13473 E->getQuestionLoc(),
13474 LHS.get(),
13475 E->getColonLoc(),
13476 RHS.get());
13477}
13478
13479template<typename Derived>
13481TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
13482 // Implicit casts are eliminated during transformation, since they
13483 // will be recomputed by semantic analysis after transformation.
13484 return getDerived().TransformExpr(E->getSubExprAsWritten());
13485}
13486
13487template<typename Derived>
13489TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
13490 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13491 if (!Type)
13492 return ExprError();
13493
13494 ExprResult SubExpr
13495 = getDerived().TransformExpr(E->getSubExprAsWritten());
13496 if (SubExpr.isInvalid())
13497 return ExprError();
13498
13499 if (!getDerived().AlwaysRebuild() &&
13500 Type == E->getTypeInfoAsWritten() &&
13501 SubExpr.get() == E->getSubExpr())
13502 return E;
13503
13504 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
13505 Type,
13506 E->getRParenLoc(),
13507 SubExpr.get());
13508}
13509
13510template<typename Derived>
13512TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
13513 TypeSourceInfo *OldT = E->getTypeSourceInfo();
13514 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13515 if (!NewT)
13516 return ExprError();
13517
13518 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
13519 if (Init.isInvalid())
13520 return ExprError();
13521
13522 if (!getDerived().AlwaysRebuild() &&
13523 OldT == NewT &&
13524 Init.get() == E->getInitializer())
13525 return SemaRef.MaybeBindToTemporary(E);
13526
13527 // Note: the expression type doesn't necessarily match the
13528 // type-as-written, but that's okay, because it should always be
13529 // derivable from the initializer.
13530
13531 return getDerived().RebuildCompoundLiteralExpr(
13532 E->getLParenLoc(), NewT,
13533 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
13534}
13535
13536template<typename Derived>
13538TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
13539 ExprResult Base = getDerived().TransformExpr(E->getBase());
13540 if (Base.isInvalid())
13541 return ExprError();
13542
13543 if (!getDerived().AlwaysRebuild() &&
13544 Base.get() == E->getBase())
13545 return E;
13546
13547 // FIXME: Bad source location
13548 SourceLocation FakeOperatorLoc =
13549 SemaRef.getLocForEndOfToken(E->getBase()->getEndLoc());
13550 return getDerived().RebuildExtVectorElementExpr(
13551 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
13552 E->getAccessor());
13553}
13554
13555template<typename Derived>
13557TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
13558 if (InitListExpr *Syntactic = E->getSyntacticForm())
13559 E = Syntactic;
13560
13561 bool InitChanged = false;
13562
13563 EnterExpressionEvaluationContext Context(
13565
13567 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
13568 Inits, &InitChanged))
13569 return ExprError();
13570
13571 if (!getDerived().AlwaysRebuild() && !InitChanged) {
13572 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
13573 // in some cases. We can't reuse it in general, because the syntactic and
13574 // semantic forms are linked, and we can't know that semantic form will
13575 // match even if the syntactic form does.
13576 }
13577
13578 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
13579 E->getRBraceLoc());
13580}
13581
13582template<typename Derived>
13584TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
13585 Designation Desig;
13586
13587 // transform the initializer value
13588 ExprResult Init = getDerived().TransformExpr(E->getInit());
13589 if (Init.isInvalid())
13590 return ExprError();
13591
13592 // transform the designators.
13593 SmallVector<Expr*, 4> ArrayExprs;
13594 bool ExprChanged = false;
13595 for (const DesignatedInitExpr::Designator &D : E->designators()) {
13596 if (D.isFieldDesignator()) {
13597 if (D.getFieldDecl()) {
13598 FieldDecl *Field = cast_or_null<FieldDecl>(
13599 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
13600 if (Field != D.getFieldDecl())
13601 // Rebuild the expression when the transformed FieldDecl is
13602 // different to the already assigned FieldDecl.
13603 ExprChanged = true;
13604 if (Field->isAnonymousStructOrUnion())
13605 continue;
13606 } else {
13607 // Ensure that the designator expression is rebuilt when there isn't
13608 // a resolved FieldDecl in the designator as we don't want to assign
13609 // a FieldDecl to a pattern designator that will be instantiated again.
13610 ExprChanged = true;
13611 }
13612 Desig.AddDesignator(Designator::CreateFieldDesignator(
13613 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
13614 continue;
13615 }
13616
13617 if (D.isArrayDesignator()) {
13618 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
13619 if (Index.isInvalid())
13620 return ExprError();
13621
13622 Desig.AddDesignator(
13623 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
13624
13625 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
13626 ArrayExprs.push_back(Index.get());
13627 continue;
13628 }
13629
13630 assert(D.isArrayRangeDesignator() && "New kind of designator?");
13631 ExprResult Start
13632 = getDerived().TransformExpr(E->getArrayRangeStart(D));
13633 if (Start.isInvalid())
13634 return ExprError();
13635
13636 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
13637 if (End.isInvalid())
13638 return ExprError();
13639
13640 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
13641 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
13642
13643 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
13644 End.get() != E->getArrayRangeEnd(D);
13645
13646 ArrayExprs.push_back(Start.get());
13647 ArrayExprs.push_back(End.get());
13648 }
13649
13650 if (!getDerived().AlwaysRebuild() &&
13651 Init.get() == E->getInit() &&
13652 !ExprChanged)
13653 return E;
13654
13655 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
13656 E->getEqualOrColonLoc(),
13657 E->usesGNUSyntax(), Init.get());
13658}
13659
13660// Seems that if TransformInitListExpr() only works on the syntactic form of an
13661// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
13662template<typename Derived>
13664TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
13665 DesignatedInitUpdateExpr *E) {
13666 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
13667 "initializer");
13668 return ExprError();
13669}
13670
13671template<typename Derived>
13673TreeTransform<Derived>::TransformNoInitExpr(
13674 NoInitExpr *E) {
13675 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
13676 return ExprError();
13677}
13678
13679template<typename Derived>
13681TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
13682 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
13683 return ExprError();
13684}
13685
13686template<typename Derived>
13688TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
13689 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
13690 return ExprError();
13691}
13692
13693template<typename Derived>
13695TreeTransform<Derived>::TransformImplicitValueInitExpr(
13696 ImplicitValueInitExpr *E) {
13697 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
13698
13699 // FIXME: Will we ever have proper type location here? Will we actually
13700 // need to transform the type?
13701 QualType T = getDerived().TransformType(E->getType());
13702 if (T.isNull())
13703 return ExprError();
13704
13705 if (!getDerived().AlwaysRebuild() &&
13706 T == E->getType())
13707 return E;
13708
13709 return getDerived().RebuildImplicitValueInitExpr(T);
13710}
13711
13712template<typename Derived>
13714TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
13715 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
13716 if (!TInfo)
13717 return ExprError();
13718
13719 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13720 if (SubExpr.isInvalid())
13721 return ExprError();
13722
13723 if (!getDerived().AlwaysRebuild() &&
13724 TInfo == E->getWrittenTypeInfo() &&
13725 SubExpr.get() == E->getSubExpr())
13726 return E;
13727
13728 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
13729 TInfo, E->getRParenLoc());
13730}
13731
13732template<typename Derived>
13734TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
13735 bool ArgumentChanged = false;
13737 if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits,
13738 &ArgumentChanged))
13739 return ExprError();
13740
13741 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
13742 Inits,
13743 E->getRParenLoc());
13744}
13745
13746/// Transform an address-of-label expression.
13747///
13748/// By default, the transformation of an address-of-label expression always
13749/// rebuilds the expression, so that the label identifier can be resolved to
13750/// the corresponding label statement by semantic analysis.
13751template<typename Derived>
13753TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
13754 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
13755 E->getLabel());
13756 if (!LD)
13757 return ExprError();
13758
13759 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
13760 cast<LabelDecl>(LD));
13761}
13762
13763template<typename Derived>
13765TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
13766 SemaRef.ActOnStartStmtExpr();
13767 StmtResult SubStmt
13768 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
13769 if (SubStmt.isInvalid()) {
13770 SemaRef.ActOnStmtExprError();
13771 return ExprError();
13772 }
13773
13774 unsigned OldDepth = E->getTemplateDepth();
13775 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
13776
13777 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
13778 SubStmt.get() == E->getSubStmt()) {
13779 // Calling this an 'error' is unintuitive, but it does the right thing.
13780 SemaRef.ActOnStmtExprError();
13781 return SemaRef.MaybeBindToTemporary(E);
13782 }
13783
13784 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
13785 E->getRParenLoc(), NewDepth);
13786}
13787
13788template<typename Derived>
13790TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
13791 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13792 if (Cond.isInvalid())
13793 return ExprError();
13794
13795 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13796 if (LHS.isInvalid())
13797 return ExprError();
13798
13799 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13800 if (RHS.isInvalid())
13801 return ExprError();
13802
13803 if (!getDerived().AlwaysRebuild() &&
13804 Cond.get() == E->getCond() &&
13805 LHS.get() == E->getLHS() &&
13806 RHS.get() == E->getRHS())
13807 return E;
13808
13809 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
13810 Cond.get(), LHS.get(), RHS.get(),
13811 E->getRParenLoc());
13812}
13813
13814template<typename Derived>
13816TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
13817 return E;
13818}
13819
13820template<typename Derived>
13822TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
13823 switch (E->getOperator()) {
13824 case OO_New:
13825 case OO_Delete:
13826 case OO_Array_New:
13827 case OO_Array_Delete:
13828 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
13829
13830 case OO_Subscript:
13831 case OO_Call: {
13832 // This is a call to an object's operator().
13833 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
13834
13835 // Transform the object itself.
13836 ExprResult Object = getDerived().TransformExpr(E->getArg(0));
13837 if (Object.isInvalid())
13838 return ExprError();
13839
13840 // FIXME: Poor location information
13841 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
13842 static_cast<Expr *>(Object.get())->getEndLoc());
13843
13844 // Transform the call arguments.
13846 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
13847 Args))
13848 return ExprError();
13849
13850 if (E->getOperator() == OO_Subscript)
13851 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
13852 Args, E->getEndLoc());
13853
13854 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
13855 E->getEndLoc());
13856 }
13857
13858#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
13859 case OO_##Name: \
13860 break;
13861
13862#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
13863#include "clang/Basic/OperatorKinds.def"
13864
13865 case OO_Conditional:
13866 llvm_unreachable("conditional operator is not actually overloadable");
13867
13868 case OO_None:
13870 llvm_unreachable("not an overloaded operator?");
13871 }
13872
13874 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
13875 First = getDerived().TransformAddressOfOperand(E->getArg(0));
13876 else
13877 First = getDerived().TransformExpr(E->getArg(0));
13878 if (First.isInvalid())
13879 return ExprError();
13880
13881 ExprResult Second;
13882 if (E->getNumArgs() == 2) {
13883 Second =
13884 getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);
13885 if (Second.isInvalid())
13886 return ExprError();
13887 }
13888
13889 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13890 FPOptionsOverride NewOverrides(E->getFPFeatures());
13891 getSema().CurFPFeatures =
13892 NewOverrides.applyOverrides(getSema().getLangOpts());
13893 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13894
13895 Expr *Callee = E->getCallee();
13896 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
13897 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
13899 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
13900 return ExprError();
13901
13902 return getDerived().RebuildCXXOperatorCallExpr(
13903 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
13904 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
13905 }
13906
13907 UnresolvedSet<1> Functions;
13908 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
13909 Callee = ICE->getSubExprAsWritten();
13910 NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();
13911 ValueDecl *VD = cast_or_null<ValueDecl>(
13912 getDerived().TransformDecl(DR->getLocation(), DR));
13913 if (!VD)
13914 return ExprError();
13915
13916 if (!isa<CXXMethodDecl>(VD))
13917 Functions.addDecl(VD);
13918
13919 return getDerived().RebuildCXXOperatorCallExpr(
13920 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
13921 /*RequiresADL=*/false, Functions, First.get(), Second.get());
13922}
13923
13924template<typename Derived>
13926TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
13927 return getDerived().TransformCallExpr(E);
13928}
13929
13930template <typename Derived>
13931ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
13932 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(E->getIdentKind()) &&
13933 getSema().CurContext != E->getParentContext();
13934
13935 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
13936 return E;
13937
13938 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
13939 E->getBeginLoc(), E->getEndLoc(),
13940 getSema().CurContext);
13941}
13942
13943template <typename Derived>
13944ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
13945 return E;
13946}
13947
13948template<typename Derived>
13950TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
13951 // Transform the callee.
13952 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13953 if (Callee.isInvalid())
13954 return ExprError();
13955
13956 // Transform exec config.
13957 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
13958 if (EC.isInvalid())
13959 return ExprError();
13960
13961 // Transform arguments.
13962 bool ArgChanged = false;
13964 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13965 &ArgChanged))
13966 return ExprError();
13967
13968 if (!getDerived().AlwaysRebuild() &&
13969 Callee.get() == E->getCallee() &&
13970 !ArgChanged)
13971 return SemaRef.MaybeBindToTemporary(E);
13972
13973 // FIXME: Wrong source location information for the '('.
13974 SourceLocation FakeLParenLoc
13975 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13976 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13977 Args,
13978 E->getRParenLoc(), EC.get());
13979}
13980
13981template<typename Derived>
13984 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13985 if (!Type)
13986 return ExprError();
13987
13988 ExprResult SubExpr
13989 = getDerived().TransformExpr(E->getSubExprAsWritten());
13990 if (SubExpr.isInvalid())
13991 return ExprError();
13992
13993 if (!getDerived().AlwaysRebuild() &&
13994 Type == E->getTypeInfoAsWritten() &&
13995 SubExpr.get() == E->getSubExpr())
13996 return E;
13997 return getDerived().RebuildCXXNamedCastExpr(
13998 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
13999 Type, E->getAngleBrackets().getEnd(),
14000 // FIXME. this should be '(' location
14001 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
14002}
14003
14004template<typename Derived>
14007 TypeSourceInfo *TSI =
14008 getDerived().TransformType(BCE->getTypeInfoAsWritten());
14009 if (!TSI)
14010 return ExprError();
14011
14012 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
14013 if (Sub.isInvalid())
14014 return ExprError();
14015
14016 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
14017 Sub.get(), BCE->getEndLoc());
14018}
14019
14020template<typename Derived>
14022TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
14023 return getDerived().TransformCXXNamedCastExpr(E);
14024}
14025
14026template<typename Derived>
14028TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
14029 return getDerived().TransformCXXNamedCastExpr(E);
14030}
14031
14032template<typename Derived>
14034TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
14035 CXXReinterpretCastExpr *E) {
14036 return getDerived().TransformCXXNamedCastExpr(E);
14037}
14038
14039template<typename Derived>
14041TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
14042 return getDerived().TransformCXXNamedCastExpr(E);
14043}
14044
14045template<typename Derived>
14047TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
14048 return getDerived().TransformCXXNamedCastExpr(E);
14049}
14050
14051template<typename Derived>
14053TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
14054 CXXFunctionalCastExpr *E) {
14055 TypeSourceInfo *Type =
14056 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
14057 if (!Type)
14058 return ExprError();
14059
14060 ExprResult SubExpr
14061 = getDerived().TransformExpr(E->getSubExprAsWritten());
14062 if (SubExpr.isInvalid())
14063 return ExprError();
14064
14065 if (!getDerived().AlwaysRebuild() &&
14066 Type == E->getTypeInfoAsWritten() &&
14067 SubExpr.get() == E->getSubExpr())
14068 return E;
14069
14070 return getDerived().RebuildCXXFunctionalCastExpr(Type,
14071 E->getLParenLoc(),
14072 SubExpr.get(),
14073 E->getRParenLoc(),
14074 E->isListInitialization());
14075}
14076
14077template<typename Derived>
14079TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
14080 if (E->isTypeOperand()) {
14081 TypeSourceInfo *TInfo
14082 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14083 if (!TInfo)
14084 return ExprError();
14085
14086 if (!getDerived().AlwaysRebuild() &&
14087 TInfo == E->getTypeOperandSourceInfo())
14088 return E;
14089
14090 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14091 TInfo, E->getEndLoc());
14092 }
14093
14094 // Typeid's operand is an unevaluated context, unless it's a polymorphic
14095 // type. We must not unilaterally enter unevaluated context here, as then
14096 // semantic processing can re-transform an already transformed operand.
14097 Expr *Op = E->getExprOperand();
14099 if (E->isGLValue())
14100 if (auto *RecordT = Op->getType()->getAs<RecordType>())
14101 if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
14102 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
14103
14104 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
14106
14107 ExprResult SubExpr = getDerived().TransformExpr(Op);
14108 if (SubExpr.isInvalid())
14109 return ExprError();
14110
14111 if (!getDerived().AlwaysRebuild() &&
14112 SubExpr.get() == E->getExprOperand())
14113 return E;
14114
14115 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14116 SubExpr.get(), E->getEndLoc());
14117}
14118
14119template<typename Derived>
14121TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
14122 if (E->isTypeOperand()) {
14123 TypeSourceInfo *TInfo
14124 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14125 if (!TInfo)
14126 return ExprError();
14127
14128 if (!getDerived().AlwaysRebuild() &&
14129 TInfo == E->getTypeOperandSourceInfo())
14130 return E;
14131
14132 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14133 TInfo, E->getEndLoc());
14134 }
14135
14136 EnterExpressionEvaluationContext Unevaluated(
14138
14139 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
14140 if (SubExpr.isInvalid())
14141 return ExprError();
14142
14143 if (!getDerived().AlwaysRebuild() &&
14144 SubExpr.get() == E->getExprOperand())
14145 return E;
14146
14147 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14148 SubExpr.get(), E->getEndLoc());
14149}
14150
14151template<typename Derived>
14153TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
14154 return E;
14155}
14156
14157template<typename Derived>
14159TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
14160 CXXNullPtrLiteralExpr *E) {
14161 return E;
14162}
14163
14164template<typename Derived>
14166TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
14167
14168 // In lambdas, the qualifiers of the type depends of where in
14169 // the call operator `this` appear, and we do not have a good way to
14170 // rebuild this information, so we transform the type.
14171 //
14172 // In other contexts, the type of `this` may be overrided
14173 // for type deduction, so we need to recompute it.
14174 //
14175 // Always recompute the type if we're in the body of a lambda, and
14176 // 'this' is dependent on a lambda's explicit object parameter.
14177 QualType T = [&]() {
14178 auto &S = getSema();
14179 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
14180 return S.getCurrentThisType();
14181 if (S.getCurLambda())
14182 return getDerived().TransformType(E->getType());
14183 return S.getCurrentThisType();
14184 }();
14185
14186 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
14187 // Mark it referenced in the new context regardless.
14188 // FIXME: this is a bit instantiation-specific.
14189 getSema().MarkThisReferenced(E);
14190 return E;
14191 }
14192
14193 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
14194}
14195
14196template<typename Derived>
14198TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
14199 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14200 if (SubExpr.isInvalid())
14201 return ExprError();
14202
14203 if (!getDerived().AlwaysRebuild() &&
14204 SubExpr.get() == E->getSubExpr())
14205 return E;
14206
14207 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
14208 E->isThrownVariableInScope());
14209}
14210
14211template<typename Derived>
14213TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
14214 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
14215 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
14216 if (!Param)
14217 return ExprError();
14218
14219 ExprResult InitRes;
14220 if (E->hasRewrittenInit()) {
14221 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
14222 if (InitRes.isInvalid())
14223 return ExprError();
14224 }
14225
14226 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
14227 E->getUsedContext() == SemaRef.CurContext &&
14228 InitRes.get() == E->getRewrittenExpr())
14229 return E;
14230
14231 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
14232 InitRes.get());
14233}
14234
14235template<typename Derived>
14237TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
14238 FieldDecl *Field = cast_or_null<FieldDecl>(
14239 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
14240 if (!Field)
14241 return ExprError();
14242
14243 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
14244 E->getUsedContext() == SemaRef.CurContext)
14245 return E;
14246
14247 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
14248}
14249
14250template<typename Derived>
14252TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
14253 CXXScalarValueInitExpr *E) {
14254 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
14255 if (!T)
14256 return ExprError();
14257
14258 if (!getDerived().AlwaysRebuild() &&
14259 T == E->getTypeSourceInfo())
14260 return E;
14261
14262 return getDerived().RebuildCXXScalarValueInitExpr(T,
14263 /*FIXME:*/T->getTypeLoc().getEndLoc(),
14264 E->getRParenLoc());
14265}
14266
14267template<typename Derived>
14269TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
14270 // Transform the type that we're allocating
14271 TypeSourceInfo *AllocTypeInfo =
14272 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
14273 if (!AllocTypeInfo)
14274 return ExprError();
14275
14276 // Transform the size of the array we're allocating (if any).
14277 std::optional<Expr *> ArraySize;
14278 if (E->isArray()) {
14279 ExprResult NewArraySize;
14280 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
14281 NewArraySize = getDerived().TransformExpr(*OldArraySize);
14282 if (NewArraySize.isInvalid())
14283 return ExprError();
14284 }
14285 ArraySize = NewArraySize.get();
14286 }
14287
14288 // Transform the placement arguments (if any).
14289 bool ArgumentChanged = false;
14290 SmallVector<Expr*, 8> PlacementArgs;
14291 if (getDerived().TransformExprs(E->getPlacementArgs(),
14292 E->getNumPlacementArgs(), true,
14293 PlacementArgs, &ArgumentChanged))
14294 return ExprError();
14295
14296 // Transform the initializer (if any).
14297 Expr *OldInit = E->getInitializer();
14298 ExprResult NewInit;
14299 if (OldInit)
14300 NewInit = getDerived().TransformInitializer(OldInit, true);
14301 if (NewInit.isInvalid())
14302 return ExprError();
14303
14304 // Transform new operator and delete operator.
14305 FunctionDecl *OperatorNew = nullptr;
14306 if (E->getOperatorNew()) {
14307 OperatorNew = cast_or_null<FunctionDecl>(
14308 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
14309 if (!OperatorNew)
14310 return ExprError();
14311 }
14312
14313 FunctionDecl *OperatorDelete = nullptr;
14314 if (E->getOperatorDelete()) {
14315 OperatorDelete = cast_or_null<FunctionDecl>(
14316 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14317 if (!OperatorDelete)
14318 return ExprError();
14319 }
14320
14321 if (!getDerived().AlwaysRebuild() &&
14322 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
14323 ArraySize == E->getArraySize() &&
14324 NewInit.get() == OldInit &&
14325 OperatorNew == E->getOperatorNew() &&
14326 OperatorDelete == E->getOperatorDelete() &&
14327 !ArgumentChanged) {
14328 // Mark any declarations we need as referenced.
14329 // FIXME: instantiation-specific.
14330 if (OperatorNew)
14331 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorNew);
14332 if (OperatorDelete)
14333 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
14334
14335 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
14336 QualType ElementType
14337 = SemaRef.Context.getBaseElementType(E->getAllocatedType());
14338 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
14339 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
14340 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
14342 }
14343 }
14344 }
14345
14346 return E;
14347 }
14348
14349 QualType AllocType = AllocTypeInfo->getType();
14350 if (!ArraySize) {
14351 // If no array size was specified, but the new expression was
14352 // instantiated with an array type (e.g., "new T" where T is
14353 // instantiated with "int[4]"), extract the outer bound from the
14354 // array type as our array size. We do this with constant and
14355 // dependently-sized array types.
14356 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);
14357 if (!ArrayT) {
14358 // Do nothing
14359 } else if (const ConstantArrayType *ConsArrayT
14360 = dyn_cast<ConstantArrayType>(ArrayT)) {
14361 ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),
14362 SemaRef.Context.getSizeType(),
14363 /*FIXME:*/ E->getBeginLoc());
14364 AllocType = ConsArrayT->getElementType();
14365 } else if (const DependentSizedArrayType *DepArrayT
14366 = dyn_cast<DependentSizedArrayType>(ArrayT)) {
14367 if (DepArrayT->getSizeExpr()) {
14368 ArraySize = DepArrayT->getSizeExpr();
14369 AllocType = DepArrayT->getElementType();
14370 }
14371 }
14372 }
14373
14374 return getDerived().RebuildCXXNewExpr(
14375 E->getBeginLoc(), E->isGlobalNew(),
14376 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
14377 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
14378 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
14379}
14380
14381template<typename Derived>
14383TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
14384 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
14385 if (Operand.isInvalid())
14386 return ExprError();
14387
14388 // Transform the delete operator, if known.
14389 FunctionDecl *OperatorDelete = nullptr;
14390 if (E->getOperatorDelete()) {
14391 OperatorDelete = cast_or_null<FunctionDecl>(
14392 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14393 if (!OperatorDelete)
14394 return ExprError();
14395 }
14396
14397 if (!getDerived().AlwaysRebuild() &&
14398 Operand.get() == E->getArgument() &&
14399 OperatorDelete == E->getOperatorDelete()) {
14400 // Mark any declarations we need as referenced.
14401 // FIXME: instantiation-specific.
14402 if (OperatorDelete)
14403 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
14404
14405 if (!E->getArgument()->isTypeDependent()) {
14406 QualType Destroyed = SemaRef.Context.getBaseElementType(
14407 E->getDestroyedType());
14408 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
14409 CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
14411 SemaRef.LookupDestructor(Record));
14412 }
14413 }
14414
14415 return E;
14416 }
14417
14418 return getDerived().RebuildCXXDeleteExpr(
14419 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
14420}
14421
14422template<typename Derived>
14424TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
14425 CXXPseudoDestructorExpr *E) {
14426 ExprResult Base = getDerived().TransformExpr(E->getBase());
14427 if (Base.isInvalid())
14428 return ExprError();
14429
14430 ParsedType ObjectTypePtr;
14431 bool MayBePseudoDestructor = false;
14432 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
14433 E->getOperatorLoc(),
14434 E->isArrow()? tok::arrow : tok::period,
14435 ObjectTypePtr,
14436 MayBePseudoDestructor);
14437 if (Base.isInvalid())
14438 return ExprError();
14439
14440 QualType ObjectType = ObjectTypePtr.get();
14441 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
14442 if (QualifierLoc) {
14443 QualifierLoc
14444 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
14445 if (!QualifierLoc)
14446 return ExprError();
14447 }
14448 CXXScopeSpec SS;
14449 SS.Adopt(QualifierLoc);
14450
14451 PseudoDestructorTypeStorage Destroyed;
14452 if (E->getDestroyedTypeInfo()) {
14453 TypeSourceInfo *DestroyedTypeInfo
14454 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
14455 ObjectType, nullptr, SS);
14456 if (!DestroyedTypeInfo)
14457 return ExprError();
14458 Destroyed = DestroyedTypeInfo;
14459 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
14460 // We aren't likely to be able to resolve the identifier down to a type
14461 // now anyway, so just retain the identifier.
14462 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
14463 E->getDestroyedTypeLoc());
14464 } else {
14465 // Look for a destructor known with the given name.
14466 ParsedType T = SemaRef.getDestructorName(
14467 *E->getDestroyedTypeIdentifier(), E->getDestroyedTypeLoc(),
14468 /*Scope=*/nullptr, SS, ObjectTypePtr, false);
14469 if (!T)
14470 return ExprError();
14471
14472 Destroyed
14474 E->getDestroyedTypeLoc());
14475 }
14476
14477 TypeSourceInfo *ScopeTypeInfo = nullptr;
14478 if (E->getScopeTypeInfo()) {
14479 CXXScopeSpec EmptySS;
14480 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
14481 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
14482 if (!ScopeTypeInfo)
14483 return ExprError();
14484 }
14485
14486 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
14487 E->getOperatorLoc(),
14488 E->isArrow(),
14489 SS,
14490 ScopeTypeInfo,
14491 E->getColonColonLoc(),
14492 E->getTildeLoc(),
14493 Destroyed);
14494}
14495
14496template <typename Derived>
14498 bool RequiresADL,
14499 LookupResult &R) {
14500 // Transform all the decls.
14501 bool AllEmptyPacks = true;
14502 for (auto *OldD : Old->decls()) {
14503 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
14504 if (!InstD) {
14505 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
14506 // This can happen because of dependent hiding.
14507 if (isa<UsingShadowDecl>(OldD))
14508 continue;
14509 else {
14510 R.clear();
14511 return true;
14512 }
14513 }
14514
14515 // Expand using pack declarations.
14516 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
14517 ArrayRef<NamedDecl*> Decls = SingleDecl;
14518 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
14519 Decls = UPD->expansions();
14520
14521 // Expand using declarations.
14522 for (auto *D : Decls) {
14523 if (auto *UD = dyn_cast<UsingDecl>(D)) {
14524 for (auto *SD : UD->shadows())
14525 R.addDecl(SD);
14526 } else {
14527 R.addDecl(D);
14528 }
14529 }
14530
14531 AllEmptyPacks &= Decls.empty();
14532 }
14533
14534 // C++ [temp.res]/8.4.2:
14535 // The program is ill-formed, no diagnostic required, if [...] lookup for
14536 // a name in the template definition found a using-declaration, but the
14537 // lookup in the corresponding scope in the instantiation odoes not find
14538 // any declarations because the using-declaration was a pack expansion and
14539 // the corresponding pack is empty
14540 if (AllEmptyPacks && !RequiresADL) {
14541 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
14542 << isa<UnresolvedMemberExpr>(Old) << Old->getName();
14543 return true;
14544 }
14545
14546 // Resolve a kind, but don't do any further analysis. If it's
14547 // ambiguous, the callee needs to deal with it.
14548 R.resolveKind();
14549
14550 if (Old->hasTemplateKeyword() && !R.empty()) {
14552 getSema().FilterAcceptableTemplateNames(R,
14553 /*AllowFunctionTemplates=*/true,
14554 /*AllowDependent=*/true);
14555 if (R.empty()) {
14556 // If a 'template' keyword was used, a lookup that finds only non-template
14557 // names is an error.
14558 getSema().Diag(R.getNameLoc(),
14559 diag::err_template_kw_refers_to_non_template)
14561 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
14562 getSema().Diag(FoundDecl->getLocation(),
14563 diag::note_template_kw_refers_to_non_template)
14564 << R.getLookupName();
14565 return true;
14566 }
14567 }
14568
14569 return false;
14570}
14571
14572template <typename Derived>
14574 UnresolvedLookupExpr *Old) {
14575 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
14576}
14577
14578template <typename Derived>
14581 bool IsAddressOfOperand) {
14582 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
14584
14585 // Transform the declaration set.
14586 if (TransformOverloadExprDecls(Old, Old->requiresADL(), R))
14587 return ExprError();
14588
14589 // Rebuild the nested-name qualifier, if present.
14590 CXXScopeSpec SS;
14591 if (Old->getQualifierLoc()) {
14592 NestedNameSpecifierLoc QualifierLoc
14593 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
14594 if (!QualifierLoc)
14595 return ExprError();
14596
14597 SS.Adopt(QualifierLoc);
14598 }
14599
14600 if (Old->getNamingClass()) {
14601 CXXRecordDecl *NamingClass
14602 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
14603 Old->getNameLoc(),
14604 Old->getNamingClass()));
14605 if (!NamingClass) {
14606 R.clear();
14607 return ExprError();
14608 }
14609
14610 R.setNamingClass(NamingClass);
14611 }
14612
14613 // Rebuild the template arguments, if any.
14614 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
14615 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
14616 if (Old->hasExplicitTemplateArgs() &&
14617 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14618 Old->getNumTemplateArgs(),
14619 TransArgs)) {
14620 R.clear();
14621 return ExprError();
14622 }
14623
14624 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
14625 // a non-static data member is named in an unevaluated operand, or when
14626 // a member is named in a dependent class scope function template explicit
14627 // specialization that is neither declared static nor with an explicit object
14628 // parameter.
14629 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
14630 return SemaRef.BuildPossibleImplicitMemberExpr(
14631 SS, TemplateKWLoc, R,
14632 Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
14633 /*S=*/nullptr);
14634
14635 // If we have neither explicit template arguments, nor the template keyword,
14636 // it's a normal declaration name or member reference.
14637 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
14638 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
14639
14640 // If we have template arguments, then rebuild the template-id expression.
14641 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
14642 Old->requiresADL(), &TransArgs);
14643}
14644
14645template<typename Derived>
14647TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
14648 bool ArgChanged = false;
14650 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
14651 TypeSourceInfo *From = E->getArg(I);
14652 TypeLoc FromTL = From->getTypeLoc();
14653 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
14654 TypeLocBuilder TLB;
14655 TLB.reserve(FromTL.getFullDataSize());
14656 QualType To = getDerived().TransformType(TLB, FromTL);
14657 if (To.isNull())
14658 return ExprError();
14659
14660 if (To == From->getType())
14661 Args.push_back(From);
14662 else {
14663 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14664 ArgChanged = true;
14665 }
14666 continue;
14667 }
14668
14669 ArgChanged = true;
14670
14671 // We have a pack expansion. Instantiate it.
14672 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
14673 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
14675 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
14676
14677 // Determine whether the set of unexpanded parameter packs can and should
14678 // be expanded.
14679 bool Expand = true;
14680 bool RetainExpansion = false;
14681 std::optional<unsigned> OrigNumExpansions =
14682 ExpansionTL.getTypePtr()->getNumExpansions();
14683 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14684 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
14685 PatternTL.getSourceRange(),
14686 Unexpanded,
14687 Expand, RetainExpansion,
14688 NumExpansions))
14689 return ExprError();
14690
14691 if (!Expand) {
14692 // The transform has determined that we should perform a simple
14693 // transformation on the pack expansion, producing another pack
14694 // expansion.
14695 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14696
14697 TypeLocBuilder TLB;
14698 TLB.reserve(From->getTypeLoc().getFullDataSize());
14699
14700 QualType To = getDerived().TransformType(TLB, PatternTL);
14701 if (To.isNull())
14702 return ExprError();
14703
14704 To = getDerived().RebuildPackExpansionType(To,
14705 PatternTL.getSourceRange(),
14706 ExpansionTL.getEllipsisLoc(),
14707 NumExpansions);
14708 if (To.isNull())
14709 return ExprError();
14710
14711 PackExpansionTypeLoc ToExpansionTL
14712 = TLB.push<PackExpansionTypeLoc>(To);
14713 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14714 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14715 continue;
14716 }
14717
14718 // Expand the pack expansion by substituting for each argument in the
14719 // pack(s).
14720 for (unsigned I = 0; I != *NumExpansions; ++I) {
14721 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
14722 TypeLocBuilder TLB;
14723 TLB.reserve(PatternTL.getFullDataSize());
14724 QualType To = getDerived().TransformType(TLB, PatternTL);
14725 if (To.isNull())
14726 return ExprError();
14727
14728 if (To->containsUnexpandedParameterPack()) {
14729 To = getDerived().RebuildPackExpansionType(To,
14730 PatternTL.getSourceRange(),
14731 ExpansionTL.getEllipsisLoc(),
14732 NumExpansions);
14733 if (To.isNull())
14734 return ExprError();
14735
14736 PackExpansionTypeLoc ToExpansionTL
14737 = TLB.push<PackExpansionTypeLoc>(To);
14738 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14739 }
14740
14741 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14742 }
14743
14744 if (!RetainExpansion)
14745 continue;
14746
14747 // If we're supposed to retain a pack expansion, do so by temporarily
14748 // forgetting the partially-substituted parameter pack.
14749 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14750
14751 TypeLocBuilder TLB;
14752 TLB.reserve(From->getTypeLoc().getFullDataSize());
14753
14754 QualType To = getDerived().TransformType(TLB, PatternTL);
14755 if (To.isNull())
14756 return ExprError();
14757
14758 To = getDerived().RebuildPackExpansionType(To,
14759 PatternTL.getSourceRange(),
14760 ExpansionTL.getEllipsisLoc(),
14761 NumExpansions);
14762 if (To.isNull())
14763 return ExprError();
14764
14765 PackExpansionTypeLoc ToExpansionTL
14766 = TLB.push<PackExpansionTypeLoc>(To);
14767 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14768 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
14769 }
14770
14771 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14772 return E;
14773
14774 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
14775 E->getEndLoc());
14776}
14777
14778template<typename Derived>
14780TreeTransform<Derived>::TransformConceptSpecializationExpr(
14781 ConceptSpecializationExpr *E) {
14782 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
14783 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
14784 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14785 Old->NumTemplateArgs, TransArgs))
14786 return ExprError();
14787
14788 return getDerived().RebuildConceptSpecializationExpr(
14789 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
14790 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
14791 &TransArgs);
14792}
14793
14794template<typename Derived>
14796TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
14797 SmallVector<ParmVarDecl*, 4> TransParams;
14798 SmallVector<QualType, 4> TransParamTypes;
14799 Sema::ExtParameterInfoBuilder ExtParamInfos;
14800
14801 // C++2a [expr.prim.req]p2
14802 // Expressions appearing within a requirement-body are unevaluated operands.
14803 EnterExpressionEvaluationContext Ctx(
14806
14807 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
14808 getSema().Context, getSema().CurContext,
14809 E->getBody()->getBeginLoc());
14810
14811 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
14812
14813 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
14814 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
14815 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
14816
14817 for (ParmVarDecl *Param : TransParams)
14818 if (Param)
14819 Param->setDeclContext(Body);
14820
14821 // On failure to transform, TransformRequiresTypeParams returns an expression
14822 // in the event that the transformation of the type params failed in some way.
14823 // It is expected that this will result in a 'not satisfied' Requires clause
14824 // when instantiating.
14825 if (!TypeParamResult.isUnset())
14826 return TypeParamResult;
14827
14829 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
14830 TransReqs))
14831 return ExprError();
14832
14833 for (concepts::Requirement *Req : TransReqs) {
14834 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
14835 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
14836 ER->getReturnTypeRequirement()
14837 .getTypeConstraintTemplateParameterList()->getParam(0)
14838 ->setDeclContext(Body);
14839 }
14840 }
14841 }
14842
14843 return getDerived().RebuildRequiresExpr(
14844 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
14845 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
14846}
14847
14848template<typename Derived>
14852 for (concepts::Requirement *Req : Reqs) {
14853 concepts::Requirement *TransReq = nullptr;
14854 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
14855 TransReq = getDerived().TransformTypeRequirement(TypeReq);
14856 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
14857 TransReq = getDerived().TransformExprRequirement(ExprReq);
14858 else
14859 TransReq = getDerived().TransformNestedRequirement(
14860 cast<concepts::NestedRequirement>(Req));
14861 if (!TransReq)
14862 return true;
14863 Transformed.push_back(TransReq);
14864 }
14865 return false;
14866}
14867
14868template<typename Derived>
14872 if (Req->isSubstitutionFailure()) {
14873 if (getDerived().AlwaysRebuild())
14874 return getDerived().RebuildTypeRequirement(
14876 return Req;
14877 }
14878 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
14879 if (!TransType)
14880 return nullptr;
14881 return getDerived().RebuildTypeRequirement(TransType);
14882}
14883
14884template<typename Derived>
14887 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
14888 if (Req->isExprSubstitutionFailure())
14889 TransExpr = Req->getExprSubstitutionDiagnostic();
14890 else {
14891 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
14892 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
14893 TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
14894 if (TransExprRes.isInvalid())
14895 return nullptr;
14896 TransExpr = TransExprRes.get();
14897 }
14898
14899 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
14900 const auto &RetReq = Req->getReturnTypeRequirement();
14901 if (RetReq.isEmpty())
14902 TransRetReq.emplace();
14903 else if (RetReq.isSubstitutionFailure())
14904 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
14905 else if (RetReq.isTypeConstraint()) {
14906 TemplateParameterList *OrigTPL =
14907 RetReq.getTypeConstraintTemplateParameterList();
14909 getDerived().TransformTemplateParameterList(OrigTPL);
14910 if (!TPL)
14911 return nullptr;
14912 TransRetReq.emplace(TPL);
14913 }
14914 assert(TransRetReq && "All code paths leading here must set TransRetReq");
14915 if (Expr *E = dyn_cast<Expr *>(TransExpr))
14916 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
14917 Req->getNoexceptLoc(),
14918 std::move(*TransRetReq));
14919 return getDerived().RebuildExprRequirement(
14920 cast<concepts::Requirement::SubstitutionDiagnostic *>(TransExpr),
14921 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
14922}
14923
14924template<typename Derived>
14928 if (Req->hasInvalidConstraint()) {
14929 if (getDerived().AlwaysRebuild())
14930 return getDerived().RebuildNestedRequirement(
14932 return Req;
14933 }
14934 ExprResult TransConstraint =
14935 getDerived().TransformExpr(Req->getConstraintExpr());
14936 if (TransConstraint.isInvalid())
14937 return nullptr;
14938 return getDerived().RebuildNestedRequirement(TransConstraint.get());
14939}
14940
14941template<typename Derived>
14944 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
14945 if (!T)
14946 return ExprError();
14947
14948 if (!getDerived().AlwaysRebuild() &&
14949 T == E->getQueriedTypeSourceInfo())
14950 return E;
14951
14952 ExprResult SubExpr;
14953 {
14956 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
14957 if (SubExpr.isInvalid())
14958 return ExprError();
14959 }
14960
14961 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
14962 SubExpr.get(), E->getEndLoc());
14963}
14964
14965template<typename Derived>
14967TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
14968 ExprResult SubExpr;
14969 {
14970 EnterExpressionEvaluationContext Unevaluated(
14972 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
14973 if (SubExpr.isInvalid())
14974 return ExprError();
14975
14976 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
14977 return E;
14978 }
14979
14980 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
14981 SubExpr.get(), E->getEndLoc());
14982}
14983
14984template <typename Derived>
14986 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
14987 TypeSourceInfo **RecoveryTSI) {
14988 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
14989 DRE, AddrTaken, RecoveryTSI);
14990
14991 // Propagate both errors and recovered types, which return ExprEmpty.
14992 if (!NewDRE.isUsable())
14993 return NewDRE;
14994
14995 // We got an expr, wrap it up in parens.
14996 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
14997 return PE;
14998 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
14999 PE->getRParen());
15000}
15001
15002template <typename Derived>
15005 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
15006 nullptr);
15007}
15008
15009template <typename Derived>
15011 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
15012 TypeSourceInfo **RecoveryTSI) {
15013 assert(E->getQualifierLoc());
15014 NestedNameSpecifierLoc QualifierLoc =
15015 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
15016 if (!QualifierLoc)
15017 return ExprError();
15018 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15019
15020 // TODO: If this is a conversion-function-id, verify that the
15021 // destination type name (if present) resolves the same way after
15022 // instantiation as it did in the local scope.
15023
15024 DeclarationNameInfo NameInfo =
15025 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
15026 if (!NameInfo.getName())
15027 return ExprError();
15028
15029 if (!E->hasExplicitTemplateArgs()) {
15030 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
15031 // Note: it is sufficient to compare the Name component of NameInfo:
15032 // if name has not changed, DNLoc has not changed either.
15033 NameInfo.getName() == E->getDeclName())
15034 return E;
15035
15036 return getDerived().RebuildDependentScopeDeclRefExpr(
15037 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
15038 IsAddressOfOperand, RecoveryTSI);
15039 }
15040
15041 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15042 if (getDerived().TransformTemplateArguments(
15043 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
15044 return ExprError();
15045
15046 return getDerived().RebuildDependentScopeDeclRefExpr(
15047 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
15048 RecoveryTSI);
15049}
15050
15051template<typename Derived>
15053TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
15054 // CXXConstructExprs other than for list-initialization and
15055 // CXXTemporaryObjectExpr are always implicit, so when we have
15056 // a 1-argument construction we just transform that argument.
15057 if (getDerived().AllowSkippingCXXConstructExpr() &&
15058 ((E->getNumArgs() == 1 ||
15059 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) &&
15060 (!getDerived().DropCallArgument(E->getArg(0))) &&
15061 !E->isListInitialization()))
15062 return getDerived().TransformInitializer(E->getArg(0),
15063 /*DirectInit*/ false);
15064
15065 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
15066
15067 QualType T = getDerived().TransformType(E->getType());
15068 if (T.isNull())
15069 return ExprError();
15070
15071 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15072 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15073 if (!Constructor)
15074 return ExprError();
15075
15076 bool ArgumentChanged = false;
15078 {
15079 EnterExpressionEvaluationContext Context(
15081 E->isListInitialization());
15082 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15083 &ArgumentChanged))
15084 return ExprError();
15085 }
15086
15087 if (!getDerived().AlwaysRebuild() &&
15088 T == E->getType() &&
15089 Constructor == E->getConstructor() &&
15090 !ArgumentChanged) {
15091 // Mark the constructor as referenced.
15092 // FIXME: Instantiation-specific
15093 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
15094 return E;
15095 }
15096
15097 return getDerived().RebuildCXXConstructExpr(
15098 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
15099 E->hadMultipleCandidates(), E->isListInitialization(),
15100 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
15101 E->getConstructionKind(), E->getParenOrBraceRange());
15102}
15103
15104template<typename Derived>
15105ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
15106 CXXInheritedCtorInitExpr *E) {
15107 QualType T = getDerived().TransformType(E->getType());
15108 if (T.isNull())
15109 return ExprError();
15110
15111 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15112 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15113 if (!Constructor)
15114 return ExprError();
15115
15116 if (!getDerived().AlwaysRebuild() &&
15117 T == E->getType() &&
15118 Constructor == E->getConstructor()) {
15119 // Mark the constructor as referenced.
15120 // FIXME: Instantiation-specific
15121 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
15122 return E;
15123 }
15124
15125 return getDerived().RebuildCXXInheritedCtorInitExpr(
15126 T, E->getLocation(), Constructor,
15127 E->constructsVBase(), E->inheritedFromVBase());
15128}
15129
15130/// Transform a C++ temporary-binding expression.
15131///
15132/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
15133/// transform the subexpression and return that.
15134template<typename Derived>
15136TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
15137 if (auto *Dtor = E->getTemporary()->getDestructor())
15139 const_cast<CXXDestructorDecl *>(Dtor));
15140 return getDerived().TransformExpr(E->getSubExpr());
15141}
15142
15143/// Transform a C++ expression that contains cleanups that should
15144/// be run after the expression is evaluated.
15145///
15146/// Since ExprWithCleanups nodes are implicitly generated, we
15147/// just transform the subexpression and return that.
15148template<typename Derived>
15150TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
15151 return getDerived().TransformExpr(E->getSubExpr());
15152}
15153
15154template<typename Derived>
15156TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
15157 CXXTemporaryObjectExpr *E) {
15158 TypeSourceInfo *T =
15159 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15160 if (!T)
15161 return ExprError();
15162
15163 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15164 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15165 if (!Constructor)
15166 return ExprError();
15167
15168 bool ArgumentChanged = false;
15170 Args.reserve(E->getNumArgs());
15171 {
15172 EnterExpressionEvaluationContext Context(
15174 E->isListInitialization());
15175 if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15176 &ArgumentChanged))
15177 return ExprError();
15178
15179 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
15180 ExprResult Res = RebuildInitList(E->getBeginLoc(), Args, E->getEndLoc());
15181 if (Res.isInvalid())
15182 return ExprError();
15183 Args = {Res.get()};
15184 }
15185 }
15186
15187 if (!getDerived().AlwaysRebuild() &&
15188 T == E->getTypeSourceInfo() &&
15189 Constructor == E->getConstructor() &&
15190 !ArgumentChanged) {
15191 // FIXME: Instantiation-specific
15192 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
15193 return SemaRef.MaybeBindToTemporary(E);
15194 }
15195
15196 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
15197 return getDerived().RebuildCXXTemporaryObjectExpr(
15198 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
15199}
15200
15201template<typename Derived>
15203TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
15204 // Transform any init-capture expressions before entering the scope of the
15205 // lambda body, because they are not semantically within that scope.
15206 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
15207 struct TransformedInitCapture {
15208 // The location of the ... if the result is retaining a pack expansion.
15209 SourceLocation EllipsisLoc;
15210 // Zero or more expansions of the init-capture.
15212 };
15214 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
15215 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15216 CEnd = E->capture_end();
15217 C != CEnd; ++C) {
15218 if (!E->isInitCapture(C))
15219 continue;
15220
15221 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
15222 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
15223
15224 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
15225 std::optional<unsigned> NumExpansions) {
15226 ExprResult NewExprInitResult = getDerived().TransformInitializer(
15227 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
15228
15229 if (NewExprInitResult.isInvalid()) {
15230 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
15231 return;
15232 }
15233 Expr *NewExprInit = NewExprInitResult.get();
15234
15235 QualType NewInitCaptureType =
15236 getSema().buildLambdaInitCaptureInitialization(
15237 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
15238 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
15239 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=
15241 NewExprInit);
15242 Result.Expansions.push_back(
15243 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
15244 };
15245
15246 // If this is an init-capture pack, consider expanding the pack now.
15247 if (OldVD->isParameterPack()) {
15248 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
15249 ->getTypeLoc()
15250 .castAs<PackExpansionTypeLoc>();
15252 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
15253
15254 // Determine whether the set of unexpanded parameter packs can and should
15255 // be expanded.
15256 bool Expand = true;
15257 bool RetainExpansion = false;
15258 std::optional<unsigned> OrigNumExpansions =
15259 ExpansionTL.getTypePtr()->getNumExpansions();
15260 std::optional<unsigned> NumExpansions = OrigNumExpansions;
15261 if (getDerived().TryExpandParameterPacks(
15262 ExpansionTL.getEllipsisLoc(),
15263 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
15264 RetainExpansion, NumExpansions))
15265 return ExprError();
15266 assert(!RetainExpansion && "Should not need to retain expansion after a "
15267 "capture since it cannot be extended");
15268 if (Expand) {
15269 for (unsigned I = 0; I != *NumExpansions; ++I) {
15270 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
15271 SubstInitCapture(SourceLocation(), std::nullopt);
15272 }
15273 } else {
15274 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
15275 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
15276 }
15277 } else {
15278 SubstInitCapture(SourceLocation(), std::nullopt);
15279 }
15280 }
15281
15282 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
15283 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
15284
15285 // Create the local class that will describe the lambda.
15286
15287 // FIXME: DependencyKind below is wrong when substituting inside a templated
15288 // context that isn't a DeclContext (such as a variable template), or when
15289 // substituting an unevaluated lambda inside of a function's parameter's type
15290 // - as parameter types are not instantiated from within a function's DC. We
15291 // use evaluation contexts to distinguish the function parameter case.
15294 DeclContext *DC = getSema().CurContext;
15295 // A RequiresExprBodyDecl is not interesting for dependencies.
15296 // For the following case,
15297 //
15298 // template <typename>
15299 // concept C = requires { [] {}; };
15300 //
15301 // template <class F>
15302 // struct Widget;
15303 //
15304 // template <C F>
15305 // struct Widget<F> {};
15306 //
15307 // While we are substituting Widget<F>, the parent of DC would be
15308 // the template specialization itself. Thus, the lambda expression
15309 // will be deemed as dependent even if there are no dependent template
15310 // arguments.
15311 // (A ClassTemplateSpecializationDecl is always a dependent context.)
15312 while (DC->isRequiresExprBody())
15313 DC = DC->getParent();
15314 if ((getSema().isUnevaluatedContext() ||
15315 getSema().isConstantEvaluatedContext()) &&
15316 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
15317 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
15318
15319 CXXRecordDecl *OldClass = E->getLambdaClass();
15320 CXXRecordDecl *Class = getSema().createLambdaClosureType(
15321 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
15322 E->getCaptureDefault());
15323 getDerived().transformedLocalDecl(OldClass, {Class});
15324
15325 CXXMethodDecl *NewCallOperator =
15326 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
15327
15328 // Enter the scope of the lambda.
15329 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
15330 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
15331 E->hasExplicitParameters(), E->isMutable());
15332
15333 // Introduce the context of the call operator.
15334 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
15335 /*NewThisContext*/false);
15336
15337 bool Invalid = false;
15338
15339 // Transform captures.
15340 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15341 CEnd = E->capture_end();
15342 C != CEnd; ++C) {
15343 // When we hit the first implicit capture, tell Sema that we've finished
15344 // the list of explicit captures.
15345 if (C->isImplicit())
15346 break;
15347
15348 // Capturing 'this' is trivial.
15349 if (C->capturesThis()) {
15350 // If this is a lambda that is part of a default member initialiser
15351 // and which we're instantiating outside the class that 'this' is
15352 // supposed to refer to, adjust the type of 'this' accordingly.
15353 //
15354 // Otherwise, leave the type of 'this' as-is.
15355 Sema::CXXThisScopeRAII ThisScope(
15356 getSema(),
15357 dyn_cast_if_present<CXXRecordDecl>(
15358 getSema().getFunctionLevelDeclContext()),
15359 Qualifiers());
15360 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15361 /*BuildAndDiagnose*/ true, nullptr,
15362 C->getCaptureKind() == LCK_StarThis);
15363 continue;
15364 }
15365 // Captured expression will be recaptured during captured variables
15366 // rebuilding.
15367 if (C->capturesVLAType())
15368 continue;
15369
15370 // Rebuild init-captures, including the implied field declaration.
15371 if (E->isInitCapture(C)) {
15372 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
15373
15374 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
15376
15377 for (InitCaptureInfoTy &Info : NewC.Expansions) {
15378 ExprResult Init = Info.first;
15379 QualType InitQualType = Info.second;
15380 if (Init.isInvalid() || InitQualType.isNull()) {
15381 Invalid = true;
15382 break;
15383 }
15384 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
15385 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
15386 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
15387 getSema().CurContext);
15388 if (!NewVD) {
15389 Invalid = true;
15390 break;
15391 }
15392 NewVDs.push_back(NewVD);
15393 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
15394 // Cases we want to tackle:
15395 // ([C(Pack)] {}, ...)
15396 // But rule out cases e.g.
15397 // [...C = Pack()] {}
15398 if (NewC.EllipsisLoc.isInvalid())
15399 LSI->ContainsUnexpandedParameterPack |=
15400 Init.get()->containsUnexpandedParameterPack();
15401 }
15402
15403 if (Invalid)
15404 break;
15405
15406 getDerived().transformedLocalDecl(OldVD, NewVDs);
15407 continue;
15408 }
15409
15410 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15411
15412 // Determine the capture kind for Sema.
15414 = C->isImplicit()? Sema::TryCapture_Implicit
15415 : C->getCaptureKind() == LCK_ByCopy
15418 SourceLocation EllipsisLoc;
15419 if (C->isPackExpansion()) {
15420 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
15421 bool ShouldExpand = false;
15422 bool RetainExpansion = false;
15423 std::optional<unsigned> NumExpansions;
15424 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
15425 C->getLocation(),
15426 Unexpanded,
15427 ShouldExpand, RetainExpansion,
15428 NumExpansions)) {
15429 Invalid = true;
15430 continue;
15431 }
15432
15433 if (ShouldExpand) {
15434 // The transform has determined that we should perform an expansion;
15435 // transform and capture each of the arguments.
15436 // expansion of the pattern. Do so.
15437 auto *Pack = cast<ValueDecl>(C->getCapturedVar());
15438 for (unsigned I = 0; I != *NumExpansions; ++I) {
15439 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
15440 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
15441 getDerived().TransformDecl(C->getLocation(), Pack));
15442 if (!CapturedVar) {
15443 Invalid = true;
15444 continue;
15445 }
15446
15447 // Capture the transformed variable.
15448 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
15449 }
15450
15451 // FIXME: Retain a pack expansion if RetainExpansion is true.
15452
15453 continue;
15454 }
15455
15456 EllipsisLoc = C->getEllipsisLoc();
15457 }
15458
15459 // Transform the captured variable.
15460 auto *CapturedVar = cast_or_null<ValueDecl>(
15461 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15462 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
15463 Invalid = true;
15464 continue;
15465 }
15466
15467 // This is not an init-capture; however it contains an unexpanded pack e.g.
15468 // ([Pack] {}(), ...)
15469 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
15470 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
15471
15472 // Capture the transformed variable.
15473 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
15474 EllipsisLoc);
15475 }
15476 getSema().finishLambdaExplicitCaptures(LSI);
15477
15478 // Transform the template parameters, and add them to the current
15479 // instantiation scope. The null case is handled correctly.
15480 auto TPL = getDerived().TransformTemplateParameterList(
15481 E->getTemplateParameterList());
15482 LSI->GLTemplateParameterList = TPL;
15483 if (TPL) {
15484 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
15485 TPL);
15486 LSI->ContainsUnexpandedParameterPack |=
15487 TPL->containsUnexpandedParameterPack();
15488 }
15489
15490 TypeLocBuilder NewCallOpTLBuilder;
15491 TypeLoc OldCallOpTypeLoc =
15492 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
15493 QualType NewCallOpType =
15494 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
15495 if (NewCallOpType.isNull())
15496 return ExprError();
15497 LSI->ContainsUnexpandedParameterPack |=
15498 NewCallOpType->containsUnexpandedParameterPack();
15499 TypeSourceInfo *NewCallOpTSI =
15500 NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
15501
15502 // The type may be an AttributedType or some other kind of sugar;
15503 // get the actual underlying FunctionProtoType.
15504 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
15505 assert(FPTL && "Not a FunctionProtoType?");
15506
15507 getSema().CompleteLambdaCallOperator(
15508 NewCallOperator, E->getCallOperator()->getLocation(),
15509 E->getCallOperator()->getInnerLocStart(),
15510 E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
15511 E->getCallOperator()->getConstexprKind(),
15512 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
15513 E->hasExplicitResultType());
15514
15515 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
15516 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
15517
15518 {
15519 // Number the lambda for linkage purposes if necessary.
15520 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
15521
15522 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
15523 if (getDerived().ReplacingOriginal()) {
15524 Numbering = OldClass->getLambdaNumbering();
15525 }
15526
15527 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
15528 }
15529
15530 // FIXME: Sema's lambda-building mechanism expects us to push an expression
15531 // evaluation context even if we're not transforming the function body.
15532 getSema().PushExpressionEvaluationContext(
15533 E->getCallOperator()->isConsteval() ?
15536 getSema().currentEvaluationContext().InImmediateEscalatingFunctionContext =
15537 getSema().getLangOpts().CPlusPlus20 &&
15538 E->getCallOperator()->isImmediateEscalating();
15539
15540 Sema::CodeSynthesisContext C;
15542 C.PointOfInstantiation = E->getBody()->getBeginLoc();
15543 getSema().pushCodeSynthesisContext(C);
15544
15545 // Instantiate the body of the lambda expression.
15546 StmtResult Body =
15547 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
15548
15549 getSema().popCodeSynthesisContext();
15550
15551 // ActOnLambda* will pop the function scope for us.
15552 FuncScopeCleanup.disable();
15553
15554 if (Body.isInvalid()) {
15555 SavedContext.pop();
15556 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
15557 /*IsInstantiation=*/true);
15558 return ExprError();
15559 }
15560
15561 // Copy the LSI before ActOnFinishFunctionBody removes it.
15562 // FIXME: This is dumb. Store the lambda information somewhere that outlives
15563 // the call operator.
15564 auto LSICopy = *LSI;
15565 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
15566 /*IsInstantiation*/ true);
15567 SavedContext.pop();
15568
15569 // Recompute the dependency of the lambda so that we can defer the lambda call
15570 // construction until after we have all the necessary template arguments. For
15571 // example, given
15572 //
15573 // template <class> struct S {
15574 // template <class U>
15575 // using Type = decltype([](U){}(42.0));
15576 // };
15577 // void foo() {
15578 // using T = S<int>::Type<float>;
15579 // ^~~~~~
15580 // }
15581 //
15582 // We would end up here from instantiating S<int> when ensuring its
15583 // completeness. That would transform the lambda call expression regardless of
15584 // the absence of the corresponding argument for U.
15585 //
15586 // Going ahead with unsubstituted type U makes things worse: we would soon
15587 // compare the argument type (which is float) against the parameter U
15588 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
15589 // error suggesting unmatched types 'U' and 'float'!
15590 //
15591 // That said, everything will be fine if we defer that semantic checking.
15592 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
15593 // dependent. Since the CallExpr's dependency boils down to the lambda's
15594 // dependency in this case, we can harness that by recomputing the dependency
15595 // from the instantiation arguments.
15596 //
15597 // FIXME: Creating the type of a lambda requires us to have a dependency
15598 // value, which happens before its substitution. We update its dependency
15599 // *after* the substitution in case we can't decide the dependency
15600 // so early, e.g. because we want to see if any of the *substituted*
15601 // parameters are dependent.
15602 DependencyKind = getDerived().ComputeLambdaDependency(&LSICopy);
15603 Class->setLambdaDependencyKind(DependencyKind);
15604 // Clean up the type cache created previously. Then, we re-create a type for
15605 // such Decl with the new DependencyKind.
15606 Class->setTypeForDecl(nullptr);
15607 getSema().Context.getTypeDeclType(Class);
15608
15609 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
15610 Body.get()->getEndLoc(), &LSICopy);
15611}
15612
15613template<typename Derived>
15616 return TransformStmt(S);
15617}
15618
15619template<typename Derived>
15622 // Transform captures.
15623 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15624 CEnd = E->capture_end();
15625 C != CEnd; ++C) {
15626 // When we hit the first implicit capture, tell Sema that we've finished
15627 // the list of explicit captures.
15628 if (!C->isImplicit())
15629 continue;
15630
15631 // Capturing 'this' is trivial.
15632 if (C->capturesThis()) {
15633 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15634 /*BuildAndDiagnose*/ true, nullptr,
15635 C->getCaptureKind() == LCK_StarThis);
15636 continue;
15637 }
15638 // Captured expression will be recaptured during captured variables
15639 // rebuilding.
15640 if (C->capturesVLAType())
15641 continue;
15642
15643 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15644 assert(!E->isInitCapture(C) && "implicit init-capture?");
15645
15646 // Transform the captured variable.
15647 VarDecl *CapturedVar = cast_or_null<VarDecl>(
15648 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15649 if (!CapturedVar || CapturedVar->isInvalidDecl())
15650 return StmtError();
15651
15652 // Capture the transformed variable.
15653 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
15654 }
15655
15656 return S;
15657}
15658
15659template<typename Derived>
15663 TypeSourceInfo *T =
15664 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15665 if (!T)
15666 return ExprError();
15667
15668 bool ArgumentChanged = false;
15670 Args.reserve(E->getNumArgs());
15671 {
15674 E->isListInitialization());
15675 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
15676 &ArgumentChanged))
15677 return ExprError();
15678 }
15679
15680 if (!getDerived().AlwaysRebuild() &&
15681 T == E->getTypeSourceInfo() &&
15682 !ArgumentChanged)
15683 return E;
15684
15685 // FIXME: we're faking the locations of the commas
15686 return getDerived().RebuildCXXUnresolvedConstructExpr(
15687 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
15688}
15689
15690template<typename Derived>
15692TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
15693 CXXDependentScopeMemberExpr *E) {
15694 // Transform the base of the expression.
15695 ExprResult Base((Expr*) nullptr);
15696 Expr *OldBase;
15697 QualType BaseType;
15698 QualType ObjectType;
15699 if (!E->isImplicitAccess()) {
15700 OldBase = E->getBase();
15701 Base = getDerived().TransformExpr(OldBase);
15702 if (Base.isInvalid())
15703 return ExprError();
15704
15705 // Start the member reference and compute the object's type.
15706 ParsedType ObjectTy;
15707 bool MayBePseudoDestructor = false;
15708 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
15709 E->getOperatorLoc(),
15710 E->isArrow()? tok::arrow : tok::period,
15711 ObjectTy,
15712 MayBePseudoDestructor);
15713 if (Base.isInvalid())
15714 return ExprError();
15715
15716 ObjectType = ObjectTy.get();
15717 BaseType = ((Expr*) Base.get())->getType();
15718 } else {
15719 OldBase = nullptr;
15720 BaseType = getDerived().TransformType(E->getBaseType());
15721 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
15722 }
15723
15724 // Transform the first part of the nested-name-specifier that qualifies
15725 // the member name.
15726 NamedDecl *FirstQualifierInScope
15727 = getDerived().TransformFirstQualifierInScope(
15728 E->getFirstQualifierFoundInScope(),
15729 E->getQualifierLoc().getBeginLoc());
15730
15731 NestedNameSpecifierLoc QualifierLoc;
15732 if (E->getQualifier()) {
15733 QualifierLoc
15734 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
15735 ObjectType,
15736 FirstQualifierInScope);
15737 if (!QualifierLoc)
15738 return ExprError();
15739 }
15740
15741 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15742
15743 // TODO: If this is a conversion-function-id, verify that the
15744 // destination type name (if present) resolves the same way after
15745 // instantiation as it did in the local scope.
15746
15747 DeclarationNameInfo NameInfo
15748 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
15749 if (!NameInfo.getName())
15750 return ExprError();
15751
15752 if (!E->hasExplicitTemplateArgs()) {
15753 // This is a reference to a member without an explicitly-specified
15754 // template argument list. Optimize for this common case.
15755 if (!getDerived().AlwaysRebuild() &&
15756 Base.get() == OldBase &&
15757 BaseType == E->getBaseType() &&
15758 QualifierLoc == E->getQualifierLoc() &&
15759 NameInfo.getName() == E->getMember() &&
15760 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
15761 return E;
15762
15763 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15764 BaseType,
15765 E->isArrow(),
15766 E->getOperatorLoc(),
15767 QualifierLoc,
15768 TemplateKWLoc,
15769 FirstQualifierInScope,
15770 NameInfo,
15771 /*TemplateArgs*/nullptr);
15772 }
15773
15774 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15775 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
15776 E->getNumTemplateArgs(),
15777 TransArgs))
15778 return ExprError();
15779
15780 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15781 BaseType,
15782 E->isArrow(),
15783 E->getOperatorLoc(),
15784 QualifierLoc,
15785 TemplateKWLoc,
15786 FirstQualifierInScope,
15787 NameInfo,
15788 &TransArgs);
15789}
15790
15791template <typename Derived>
15792ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
15793 UnresolvedMemberExpr *Old) {
15794 // Transform the base of the expression.
15795 ExprResult Base((Expr *)nullptr);
15796 QualType BaseType;
15797 if (!Old->isImplicitAccess()) {
15798 Base = getDerived().TransformExpr(Old->getBase());
15799 if (Base.isInvalid())
15800 return ExprError();
15801 Base =
15802 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
15803 if (Base.isInvalid())
15804 return ExprError();
15805 BaseType = Base.get()->getType();
15806 } else {
15807 BaseType = getDerived().TransformType(Old->getBaseType());
15808 }
15809
15810 NestedNameSpecifierLoc QualifierLoc;
15811 if (Old->getQualifierLoc()) {
15812 QualifierLoc =
15813 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
15814 if (!QualifierLoc)
15815 return ExprError();
15816 }
15817
15818 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
15819
15820 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
15821
15822 // Transform the declaration set.
15823 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ false, R))
15824 return ExprError();
15825
15826 // Determine the naming class.
15827 if (Old->getNamingClass()) {
15828 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
15829 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
15830 if (!NamingClass)
15831 return ExprError();
15832
15833 R.setNamingClass(NamingClass);
15834 }
15835
15836 TemplateArgumentListInfo TransArgs;
15837 if (Old->hasExplicitTemplateArgs()) {
15838 TransArgs.setLAngleLoc(Old->getLAngleLoc());
15839 TransArgs.setRAngleLoc(Old->getRAngleLoc());
15840 if (getDerived().TransformTemplateArguments(
15841 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
15842 return ExprError();
15843 }
15844
15845 // FIXME: to do this check properly, we will need to preserve the
15846 // first-qualifier-in-scope here, just in case we had a dependent
15847 // base (and therefore couldn't do the check) and a
15848 // nested-name-qualifier (and therefore could do the lookup).
15849 NamedDecl *FirstQualifierInScope = nullptr;
15850
15851 return getDerived().RebuildUnresolvedMemberExpr(
15852 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
15853 TemplateKWLoc, FirstQualifierInScope, R,
15854 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
15855}
15856
15857template<typename Derived>
15859TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
15860 EnterExpressionEvaluationContext Unevaluated(
15862 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
15863 if (SubExpr.isInvalid())
15864 return ExprError();
15865
15866 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
15867 return E;
15868
15869 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
15870}
15871
15872template<typename Derived>
15874TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
15875 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
15876 if (Pattern.isInvalid())
15877 return ExprError();
15878
15879 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
15880 return E;
15881
15882 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
15883 E->getNumExpansions());
15884}
15885
15886template<typename Derived>
15888TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
15889 // If E is not value-dependent, then nothing will change when we transform it.
15890 // Note: This is an instantiation-centric view.
15891 if (!E->isValueDependent())
15892 return E;
15893
15894 EnterExpressionEvaluationContext Unevaluated(
15896
15898 TemplateArgument ArgStorage;
15899
15900 // Find the argument list to transform.
15901 if (E->isPartiallySubstituted()) {
15902 PackArgs = E->getPartialArguments();
15903 } else if (E->isValueDependent()) {
15904 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
15905 bool ShouldExpand = false;
15906 bool RetainExpansion = false;
15907 std::optional<unsigned> NumExpansions;
15908 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
15909 Unexpanded,
15910 ShouldExpand, RetainExpansion,
15911 NumExpansions))
15912 return ExprError();
15913
15914 // If we need to expand the pack, build a template argument from it and
15915 // expand that.
15916 if (ShouldExpand) {
15917 auto *Pack = E->getPack();
15918 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) {
15919 ArgStorage = getSema().Context.getPackExpansionType(
15920 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
15921 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {
15922 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
15923 } else {
15924 auto *VD = cast<ValueDecl>(Pack);
15925 ExprResult DRE = getSema().BuildDeclRefExpr(
15926 VD, VD->getType().getNonLValueExprType(getSema().Context),
15927 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
15928 E->getPackLoc());
15929 if (DRE.isInvalid())
15930 return ExprError();
15931 ArgStorage = new (getSema().Context)
15932 PackExpansionExpr(getSema().Context.DependentTy, DRE.get(),
15933 E->getPackLoc(), std::nullopt);
15934 }
15935 PackArgs = ArgStorage;
15936 }
15937 }
15938
15939 // If we're not expanding the pack, just transform the decl.
15940 if (!PackArgs.size()) {
15941 auto *Pack = cast_or_null<NamedDecl>(
15942 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
15943 if (!Pack)
15944 return ExprError();
15945 return getDerived().RebuildSizeOfPackExpr(
15946 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
15947 std::nullopt, {});
15948 }
15949
15950 // Try to compute the result without performing a partial substitution.
15951 std::optional<unsigned> Result = 0;
15952 for (const TemplateArgument &Arg : PackArgs) {
15953 if (!Arg.isPackExpansion()) {
15954 Result = *Result + 1;
15955 continue;
15956 }
15957
15958 TemplateArgumentLoc ArgLoc;
15959 InventTemplateArgumentLoc(Arg, ArgLoc);
15960
15961 // Find the pattern of the pack expansion.
15962 SourceLocation Ellipsis;
15963 std::optional<unsigned> OrigNumExpansions;
15964 TemplateArgumentLoc Pattern =
15965 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
15966 OrigNumExpansions);
15967
15968 // Substitute under the pack expansion. Do not expand the pack (yet).
15969 TemplateArgumentLoc OutPattern;
15970 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15971 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
15972 /*Uneval*/ true))
15973 return true;
15974
15975 // See if we can determine the number of arguments from the result.
15976 std::optional<unsigned> NumExpansions =
15977 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
15978 if (!NumExpansions) {
15979 // No: we must be in an alias template expansion, and we're going to need
15980 // to actually expand the packs.
15981 Result = std::nullopt;
15982 break;
15983 }
15984
15985 Result = *Result + *NumExpansions;
15986 }
15987
15988 // Common case: we could determine the number of expansions without
15989 // substituting.
15990 if (Result)
15991 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
15992 E->getPackLoc(),
15993 E->getRParenLoc(), *Result, {});
15994
15995 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
15996 E->getPackLoc());
15997 {
15998 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
15999 typedef TemplateArgumentLocInventIterator<
16000 Derived, const TemplateArgument*> PackLocIterator;
16001 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
16002 PackLocIterator(*this, PackArgs.end()),
16003 TransformedPackArgs, /*Uneval*/true))
16004 return ExprError();
16005 }
16006
16007 // Check whether we managed to fully-expand the pack.
16008 // FIXME: Is it possible for us to do so and not hit the early exit path?
16010 bool PartialSubstitution = false;
16011 for (auto &Loc : TransformedPackArgs.arguments()) {
16012 Args.push_back(Loc.getArgument());
16013 if (Loc.getArgument().isPackExpansion())
16014 PartialSubstitution = true;
16015 }
16016
16017 if (PartialSubstitution)
16018 return getDerived().RebuildSizeOfPackExpr(
16019 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16020 std::nullopt, Args);
16021
16022 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
16023 E->getPackLoc(), E->getRParenLoc(),
16024 Args.size(), {});
16025}
16026
16027template <typename Derived>
16029TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
16030 if (!E->isValueDependent())
16031 return E;
16032
16033 // Transform the index
16034 ExprResult IndexExpr;
16035 {
16036 EnterExpressionEvaluationContext ConstantContext(
16038 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
16039 if (IndexExpr.isInvalid())
16040 return ExprError();
16041 }
16042
16043 SmallVector<Expr *, 5> ExpandedExprs;
16044 bool FullySubstituted = true;
16045 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
16046 Expr *Pattern = E->getPackIdExpression();
16048 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
16049 Unexpanded);
16050 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16051
16052 // Determine whether the set of unexpanded parameter packs can and should
16053 // be expanded.
16054 bool ShouldExpand = true;
16055 bool RetainExpansion = false;
16056 std::optional<unsigned> OrigNumExpansions;
16057 std::optional<unsigned> NumExpansions = OrigNumExpansions;
16058 if (getDerived().TryExpandParameterPacks(
16059 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16060 ShouldExpand, RetainExpansion, NumExpansions))
16061 return true;
16062 if (!ShouldExpand) {
16063 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
16064 ExprResult Pack = getDerived().TransformExpr(Pattern);
16065 if (Pack.isInvalid())
16066 return ExprError();
16067 return getDerived().RebuildPackIndexingExpr(
16068 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
16069 {}, /*FullySubstituted=*/false);
16070 }
16071 for (unsigned I = 0; I != *NumExpansions; ++I) {
16072 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
16073 ExprResult Out = getDerived().TransformExpr(Pattern);
16074 if (Out.isInvalid())
16075 return true;
16076 if (Out.get()->containsUnexpandedParameterPack()) {
16077 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16078 OrigNumExpansions);
16079 if (Out.isInvalid())
16080 return true;
16081 FullySubstituted = false;
16082 }
16083 ExpandedExprs.push_back(Out.get());
16084 }
16085 // If we're supposed to retain a pack expansion, do so by temporarily
16086 // forgetting the partially-substituted parameter pack.
16087 if (RetainExpansion) {
16088 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16089
16090 ExprResult Out = getDerived().TransformExpr(Pattern);
16091 if (Out.isInvalid())
16092 return true;
16093
16094 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16095 OrigNumExpansions);
16096 if (Out.isInvalid())
16097 return true;
16098 FullySubstituted = false;
16099 ExpandedExprs.push_back(Out.get());
16100 }
16101 } else if (!E->expandsToEmptyPack()) {
16102 if (getDerived().TransformExprs(E->getExpressions().data(),
16103 E->getExpressions().size(), false,
16104 ExpandedExprs))
16105 return ExprError();
16106 }
16107
16108 return getDerived().RebuildPackIndexingExpr(
16109 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
16110 IndexExpr.get(), ExpandedExprs, FullySubstituted);
16111}
16112
16113template<typename Derived>
16115TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
16116 SubstNonTypeTemplateParmPackExpr *E) {
16117 // Default behavior is to do nothing with this transformation.
16118 return E;
16119}
16120
16121template<typename Derived>
16123TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
16124 SubstNonTypeTemplateParmExpr *E) {
16125 // Default behavior is to do nothing with this transformation.
16126 return E;
16127}
16128
16129template<typename Derived>
16131TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
16132 // Default behavior is to do nothing with this transformation.
16133 return E;
16134}
16135
16136template <typename Derived>
16137ExprResult TreeTransform<Derived>::TransformResolvedUnexpandedPackExpr(
16138 ResolvedUnexpandedPackExpr *E) {
16139 bool ArgumentChanged = false;
16140 SmallVector<Expr *, 12> NewExprs;
16141 if (TransformExprs(E->getExprs().begin(), E->getNumExprs(),
16142 /*IsCall=*/false, NewExprs, &ArgumentChanged))
16143 return ExprError();
16144
16145 if (!AlwaysRebuild() && !ArgumentChanged)
16146 return E;
16147
16148 // NOTE: The type is just a superficial PackExpansionType
16149 // that needs no substitution.
16150 return RebuildResolvedUnexpandedPackExpr(E->getBeginLoc(), E->getType(),
16151 NewExprs);
16152}
16153
16154template<typename Derived>
16156TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
16157 MaterializeTemporaryExpr *E) {
16158 return getDerived().TransformExpr(E->getSubExpr());
16159}
16160
16161template<typename Derived>
16163TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
16164 UnresolvedLookupExpr *Callee = nullptr;
16165 if (Expr *OldCallee = E->getCallee()) {
16166 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
16167 if (CalleeResult.isInvalid())
16168 return ExprError();
16169 Callee = cast<UnresolvedLookupExpr>(CalleeResult.get());
16170 }
16171
16172 Expr *Pattern = E->getPattern();
16173
16175 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
16176 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16177
16178 // Determine whether the set of unexpanded parameter packs can and should
16179 // be expanded.
16180 bool Expand = true;
16181 bool RetainExpansion = false;
16182 std::optional<unsigned> OrigNumExpansions = E->getNumExpansions(),
16183 NumExpansions = OrigNumExpansions;
16184 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
16185 Pattern->getSourceRange(),
16186 Unexpanded,
16187 Expand, RetainExpansion,
16188 NumExpansions))
16189 return true;
16190
16191 if (!Expand) {
16192 // Do not expand any packs here, just transform and rebuild a fold
16193 // expression.
16194 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
16195
16196 ExprResult LHS =
16197 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
16198 if (LHS.isInvalid())
16199 return true;
16200
16201 ExprResult RHS =
16202 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
16203 if (RHS.isInvalid())
16204 return true;
16205
16206 if (!getDerived().AlwaysRebuild() &&
16207 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
16208 return E;
16209
16210 return getDerived().RebuildCXXFoldExpr(
16211 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
16212 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
16213 }
16214
16215 // Formally a fold expression expands to nested parenthesized expressions.
16216 // Enforce this limit to avoid creating trees so deep we can't safely traverse
16217 // them.
16218 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) {
16219 SemaRef.Diag(E->getEllipsisLoc(),
16220 clang::diag::err_fold_expression_limit_exceeded)
16221 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
16222 << E->getSourceRange();
16223 SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);
16224 return ExprError();
16225 }
16226
16227 // The transform has determined that we should perform an elementwise
16228 // expansion of the pattern. Do so.
16229 ExprResult Result = getDerived().TransformExpr(E->getInit());
16230 if (Result.isInvalid())
16231 return true;
16232 bool LeftFold = E->isLeftFold();
16233
16234 // If we're retaining an expansion for a right fold, it is the innermost
16235 // component and takes the init (if any).
16236 if (!LeftFold && RetainExpansion) {
16237 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16238
16239 ExprResult Out = getDerived().TransformExpr(Pattern);
16240 if (Out.isInvalid())
16241 return true;
16242
16243 Result = getDerived().RebuildCXXFoldExpr(
16244 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
16245 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
16246 if (Result.isInvalid())
16247 return true;
16248 }
16249
16250 for (unsigned I = 0; I != *NumExpansions; ++I) {
16251 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(
16252 getSema(), LeftFold ? I : *NumExpansions - I - 1);
16253 ExprResult Out = getDerived().TransformExpr(Pattern);
16254 if (Out.isInvalid())
16255 return true;
16256
16257 if (Out.get()->containsUnexpandedParameterPack()) {
16258 // We still have a pack; retain a pack expansion for this slice.
16259 Result = getDerived().RebuildCXXFoldExpr(
16260 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
16261 E->getOperator(), E->getEllipsisLoc(),
16262 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
16263 OrigNumExpansions);
16264 } else if (Result.isUsable()) {
16265 // We've got down to a single element; build a binary operator.
16266 Expr *LHS = LeftFold ? Result.get() : Out.get();
16267 Expr *RHS = LeftFold ? Out.get() : Result.get();
16268 if (Callee) {
16269 UnresolvedSet<16> Functions;
16270 Functions.append(Callee->decls_begin(), Callee->decls_end());
16271 Result = getDerived().RebuildCXXOperatorCallExpr(
16273 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
16274 Functions, LHS, RHS);
16275 } else {
16276 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
16277 E->getOperator(), LHS, RHS);
16278 }
16279 } else
16280 Result = Out;
16281
16282 if (Result.isInvalid())
16283 return true;
16284 }
16285
16286 // If we're retaining an expansion for a left fold, it is the outermost
16287 // component and takes the complete expansion so far as its init (if any).
16288 if (LeftFold && RetainExpansion) {
16289 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16290
16291 ExprResult Out = getDerived().TransformExpr(Pattern);
16292 if (Out.isInvalid())
16293 return true;
16294
16295 Result = getDerived().RebuildCXXFoldExpr(
16296 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
16297 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
16298 if (Result.isInvalid())
16299 return true;
16300 }
16301
16302 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Result.get()))
16303 PE->setIsProducedByFoldExpansion();
16304
16305 // If we had no init and an empty pack, and we're not retaining an expansion,
16306 // then produce a fallback value or error.
16307 if (Result.isUnset())
16308 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
16309 E->getOperator());
16310 return Result;
16311}
16312
16313template <typename Derived>
16315TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
16316 SmallVector<Expr *, 4> TransformedInits;
16317 ArrayRef<Expr *> InitExprs = E->getInitExprs();
16318 if (TransformExprs(InitExprs.data(), InitExprs.size(), true,
16319 TransformedInits))
16320 return ExprError();
16321
16322 return getDerived().RebuildParenListExpr(E->getBeginLoc(), TransformedInits,
16323 E->getEndLoc());
16324}
16325
16326template<typename Derived>
16328TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
16329 CXXStdInitializerListExpr *E) {
16330 return getDerived().TransformExpr(E->getSubExpr());
16331}
16332
16333template<typename Derived>
16335TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
16336 return SemaRef.MaybeBindToTemporary(E);
16337}
16338
16339template<typename Derived>
16341TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
16342 return E;
16343}
16344
16345template<typename Derived>
16347TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
16348 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
16349 if (SubExpr.isInvalid())
16350 return ExprError();
16351
16352 if (!getDerived().AlwaysRebuild() &&
16353 SubExpr.get() == E->getSubExpr())
16354 return E;
16355
16356 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
16357}
16358
16359template<typename Derived>
16361TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
16362 // Transform each of the elements.
16363 SmallVector<Expr *, 8> Elements;
16364 bool ArgChanged = false;
16365 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
16366 /*IsCall=*/false, Elements, &ArgChanged))
16367 return ExprError();
16368
16369 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16370 return SemaRef.MaybeBindToTemporary(E);
16371
16372 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
16373 Elements.data(),
16374 Elements.size());
16375}
16376
16377template<typename Derived>
16379TreeTransform<Derived>::TransformObjCDictionaryLiteral(
16380 ObjCDictionaryLiteral *E) {
16381 // Transform each of the elements.
16383 bool ArgChanged = false;
16384 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
16385 ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);
16386
16387 if (OrigElement.isPackExpansion()) {
16388 // This key/value element is a pack expansion.
16390 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
16391 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
16392 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16393
16394 // Determine whether the set of unexpanded parameter packs can
16395 // and should be expanded.
16396 bool Expand = true;
16397 bool RetainExpansion = false;
16398 std::optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
16399 std::optional<unsigned> NumExpansions = OrigNumExpansions;
16400 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
16401 OrigElement.Value->getEndLoc());
16402 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
16403 PatternRange, Unexpanded, Expand,
16404 RetainExpansion, NumExpansions))
16405 return ExprError();
16406
16407 if (!Expand) {
16408 // The transform has determined that we should perform a simple
16409 // transformation on the pack expansion, producing another pack
16410 // expansion.
16411 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
16412 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16413 if (Key.isInvalid())
16414 return ExprError();
16415
16416 if (Key.get() != OrigElement.Key)
16417 ArgChanged = true;
16418
16419 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16420 if (Value.isInvalid())
16421 return ExprError();
16422
16423 if (Value.get() != OrigElement.Value)
16424 ArgChanged = true;
16425
16426 ObjCDictionaryElement Expansion = {
16427 Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions
16428 };
16429 Elements.push_back(Expansion);
16430 continue;
16431 }
16432
16433 // Record right away that the argument was changed. This needs
16434 // to happen even if the array expands to nothing.
16435 ArgChanged = true;
16436
16437 // The transform has determined that we should perform an elementwise
16438 // expansion of the pattern. Do so.
16439 for (unsigned I = 0; I != *NumExpansions; ++I) {
16440 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
16441 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16442 if (Key.isInvalid())
16443 return ExprError();
16444
16445 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16446 if (Value.isInvalid())
16447 return ExprError();
16448
16449 ObjCDictionaryElement Element = {
16450 Key.get(), Value.get(), SourceLocation(), NumExpansions
16451 };
16452
16453 // If any unexpanded parameter packs remain, we still have a
16454 // pack expansion.
16455 // FIXME: Can this really happen?
16456 if (Key.get()->containsUnexpandedParameterPack() ||
16457 Value.get()->containsUnexpandedParameterPack())
16458 Element.EllipsisLoc = OrigElement.EllipsisLoc;
16459
16460 Elements.push_back(Element);
16461 }
16462
16463 // FIXME: Retain a pack expansion if RetainExpansion is true.
16464
16465 // We've finished with this pack expansion.
16466 continue;
16467 }
16468
16469 // Transform and check key.
16470 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16471 if (Key.isInvalid())
16472 return ExprError();
16473
16474 if (Key.get() != OrigElement.Key)
16475 ArgChanged = true;
16476
16477 // Transform and check value.
16479 = getDerived().TransformExpr(OrigElement.Value);
16480 if (Value.isInvalid())
16481 return ExprError();
16482
16483 if (Value.get() != OrigElement.Value)
16484 ArgChanged = true;
16485
16486 ObjCDictionaryElement Element = {Key.get(), Value.get(), SourceLocation(),
16487 std::nullopt};
16488 Elements.push_back(Element);
16489 }
16490
16491 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16492 return SemaRef.MaybeBindToTemporary(E);
16493
16494 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
16495 Elements);
16496}
16497
16498template<typename Derived>
16500TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
16501 TypeSourceInfo *EncodedTypeInfo
16502 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
16503 if (!EncodedTypeInfo)
16504 return ExprError();
16505
16506 if (!getDerived().AlwaysRebuild() &&
16507 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
16508 return E;
16509
16510 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
16511 EncodedTypeInfo,
16512 E->getRParenLoc());
16513}
16514
16515template<typename Derived>
16516ExprResult TreeTransform<Derived>::
16517TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
16518 // This is a kind of implicit conversion, and it needs to get dropped
16519 // and recomputed for the same general reasons that ImplicitCastExprs
16520 // do, as well a more specific one: this expression is only valid when
16521 // it appears *immediately* as an argument expression.
16522 return getDerived().TransformExpr(E->getSubExpr());
16523}
16524
16525template<typename Derived>
16526ExprResult TreeTransform<Derived>::
16527TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
16528 TypeSourceInfo *TSInfo
16529 = getDerived().TransformType(E->getTypeInfoAsWritten());
16530 if (!TSInfo)
16531 return ExprError();
16532
16533 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
16534 if (Result.isInvalid())
16535 return ExprError();
16536
16537 if (!getDerived().AlwaysRebuild() &&
16538 TSInfo == E->getTypeInfoAsWritten() &&
16539 Result.get() == E->getSubExpr())
16540 return E;
16541
16542 return SemaRef.ObjC().BuildObjCBridgedCast(
16543 E->getLParenLoc(), E->getBridgeKind(), E->getBridgeKeywordLoc(), TSInfo,
16544 Result.get());
16545}
16546
16547template <typename Derived>
16548ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
16549 ObjCAvailabilityCheckExpr *E) {
16550 return E;
16551}
16552
16553template<typename Derived>
16555TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
16556 // Transform arguments.
16557 bool ArgChanged = false;
16559 Args.reserve(E->getNumArgs());
16560 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
16561 &ArgChanged))
16562 return ExprError();
16563
16564 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
16565 // Class message: transform the receiver type.
16566 TypeSourceInfo *ReceiverTypeInfo
16567 = getDerived().TransformType(E->getClassReceiverTypeInfo());
16568 if (!ReceiverTypeInfo)
16569 return ExprError();
16570
16571 // If nothing changed, just retain the existing message send.
16572 if (!getDerived().AlwaysRebuild() &&
16573 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
16574 return SemaRef.MaybeBindToTemporary(E);
16575
16576 // Build a new class message send.
16578 E->getSelectorLocs(SelLocs);
16579 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
16580 E->getSelector(),
16581 SelLocs,
16582 E->getMethodDecl(),
16583 E->getLeftLoc(),
16584 Args,
16585 E->getRightLoc());
16586 }
16587 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
16588 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
16589 if (!E->getMethodDecl())
16590 return ExprError();
16591
16592 // Build a new class message send to 'super'.
16594 E->getSelectorLocs(SelLocs);
16595 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
16596 E->getSelector(),
16597 SelLocs,
16598 E->getReceiverType(),
16599 E->getMethodDecl(),
16600 E->getLeftLoc(),
16601 Args,
16602 E->getRightLoc());
16603 }
16604
16605 // Instance message: transform the receiver
16606 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
16607 "Only class and instance messages may be instantiated");
16608 ExprResult Receiver
16609 = getDerived().TransformExpr(E->getInstanceReceiver());
16610 if (Receiver.isInvalid())
16611 return ExprError();
16612
16613 // If nothing changed, just retain the existing message send.
16614 if (!getDerived().AlwaysRebuild() &&
16615 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
16616 return SemaRef.MaybeBindToTemporary(E);
16617
16618 // Build a new instance message send.
16620 E->getSelectorLocs(SelLocs);
16621 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
16622 E->getSelector(),
16623 SelLocs,
16624 E->getMethodDecl(),
16625 E->getLeftLoc(),
16626 Args,
16627 E->getRightLoc());
16628}
16629
16630template<typename Derived>
16632TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
16633 return E;
16634}
16635
16636template<typename Derived>
16638TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
16639 return E;
16640}
16641
16642template<typename Derived>
16644TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
16645 // Transform the base expression.
16646 ExprResult Base = getDerived().TransformExpr(E->getBase());
16647 if (Base.isInvalid())
16648 return ExprError();
16649
16650 // We don't need to transform the ivar; it will never change.
16651
16652 // If nothing changed, just retain the existing expression.
16653 if (!getDerived().AlwaysRebuild() &&
16654 Base.get() == E->getBase())
16655 return E;
16656
16657 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
16658 E->getLocation(),
16659 E->isArrow(), E->isFreeIvar());
16660}
16661
16662template<typename Derived>
16664TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
16665 // 'super' and types never change. Property never changes. Just
16666 // retain the existing expression.
16667 if (!E->isObjectReceiver())
16668 return E;
16669
16670 // Transform the base expression.
16671 ExprResult Base = getDerived().TransformExpr(E->getBase());
16672 if (Base.isInvalid())
16673 return ExprError();
16674
16675 // We don't need to transform the property; it will never change.
16676
16677 // If nothing changed, just retain the existing expression.
16678 if (!getDerived().AlwaysRebuild() &&
16679 Base.get() == E->getBase())
16680 return E;
16681
16682 if (E->isExplicitProperty())
16683 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
16684 E->getExplicitProperty(),
16685 E->getLocation());
16686
16687 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
16688 SemaRef.Context.PseudoObjectTy,
16689 E->getImplicitPropertyGetter(),
16690 E->getImplicitPropertySetter(),
16691 E->getLocation());
16692}
16693
16694template<typename Derived>
16696TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
16697 // Transform the base expression.
16698 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
16699 if (Base.isInvalid())
16700 return ExprError();
16701
16702 // Transform the key expression.
16703 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
16704 if (Key.isInvalid())
16705 return ExprError();
16706
16707 // If nothing changed, just retain the existing expression.
16708 if (!getDerived().AlwaysRebuild() &&
16709 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
16710 return E;
16711
16712 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
16713 Base.get(), Key.get(),
16714 E->getAtIndexMethodDecl(),
16715 E->setAtIndexMethodDecl());
16716}
16717
16718template<typename Derived>
16720TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
16721 // Transform the base expression.
16722 ExprResult Base = getDerived().TransformExpr(E->getBase());
16723 if (Base.isInvalid())
16724 return ExprError();
16725
16726 // If nothing changed, just retain the existing expression.
16727 if (!getDerived().AlwaysRebuild() &&
16728 Base.get() == E->getBase())
16729 return E;
16730
16731 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
16732 E->getOpLoc(),
16733 E->isArrow());
16734}
16735
16736template<typename Derived>
16738TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
16739 bool ArgumentChanged = false;
16740 SmallVector<Expr*, 8> SubExprs;
16741 SubExprs.reserve(E->getNumSubExprs());
16742 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
16743 SubExprs, &ArgumentChanged))
16744 return ExprError();
16745
16746 if (!getDerived().AlwaysRebuild() &&
16747 !ArgumentChanged)
16748 return E;
16749
16750 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
16751 SubExprs,
16752 E->getRParenLoc());
16753}
16754
16755template<typename Derived>
16757TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
16758 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
16759 if (SrcExpr.isInvalid())
16760 return ExprError();
16761
16762 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
16763 if (!Type)
16764 return ExprError();
16765
16766 if (!getDerived().AlwaysRebuild() &&
16767 Type == E->getTypeSourceInfo() &&
16768 SrcExpr.get() == E->getSrcExpr())
16769 return E;
16770
16771 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
16772 SrcExpr.get(), Type,
16773 E->getRParenLoc());
16774}
16775
16776template<typename Derived>
16778TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
16779 BlockDecl *oldBlock = E->getBlockDecl();
16780
16781 SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr);
16782 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
16783
16784 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
16785 blockScope->TheDecl->setBlockMissingReturnType(
16786 oldBlock->blockMissingReturnType());
16787
16789 SmallVector<QualType, 4> paramTypes;
16790
16791 const FunctionProtoType *exprFunctionType = E->getFunctionType();
16792
16793 // Parameter substitution.
16794 Sema::ExtParameterInfoBuilder extParamInfos;
16795 if (getDerived().TransformFunctionTypeParams(
16796 E->getCaretLocation(), oldBlock->parameters(), nullptr,
16797 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
16798 extParamInfos)) {
16799 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
16800 return ExprError();
16801 }
16802
16803 QualType exprResultType =
16804 getDerived().TransformType(exprFunctionType->getReturnType());
16805
16806 auto epi = exprFunctionType->getExtProtoInfo();
16807 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size());
16808
16809 QualType functionType =
16810 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
16811 blockScope->FunctionType = functionType;
16812
16813 // Set the parameters on the block decl.
16814 if (!params.empty())
16815 blockScope->TheDecl->setParams(params);
16816
16817 if (!oldBlock->blockMissingReturnType()) {
16818 blockScope->HasImplicitReturnType = false;
16819 blockScope->ReturnType = exprResultType;
16820 }
16821
16822 // Transform the body
16823 StmtResult body = getDerived().TransformStmt(E->getBody());
16824 if (body.isInvalid()) {
16825 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
16826 return ExprError();
16827 }
16828
16829#ifndef NDEBUG
16830 // In builds with assertions, make sure that we captured everything we
16831 // captured before.
16832 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
16833 for (const auto &I : oldBlock->captures()) {
16834 VarDecl *oldCapture = I.getVariable();
16835
16836 // Ignore parameter packs.
16837 if (oldCapture->isParameterPack())
16838 continue;
16839
16840 VarDecl *newCapture =
16841 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
16842 oldCapture));
16843 assert(blockScope->CaptureMap.count(newCapture));
16844 }
16845
16846 // The this pointer may not be captured by the instantiated block, even when
16847 // it's captured by the original block, if the expression causing the
16848 // capture is in the discarded branch of a constexpr if statement.
16849 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
16850 "this pointer isn't captured in the old block");
16851 }
16852#endif
16853
16854 return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(),
16855 /*Scope=*/nullptr);
16856}
16857
16858template<typename Derived>
16860TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
16861 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
16862 if (SrcExpr.isInvalid())
16863 return ExprError();
16864
16865 QualType Type = getDerived().TransformType(E->getType());
16866
16867 return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(),
16868 E->getRParenLoc());
16869}
16870
16871template<typename Derived>
16873TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
16874 bool ArgumentChanged = false;
16875 SmallVector<Expr*, 8> SubExprs;
16876 SubExprs.reserve(E->getNumSubExprs());
16877 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
16878 SubExprs, &ArgumentChanged))
16879 return ExprError();
16880
16881 if (!getDerived().AlwaysRebuild() &&
16882 !ArgumentChanged)
16883 return E;
16884
16885 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
16886 E->getOp(), E->getRParenLoc());
16887}
16888
16889//===----------------------------------------------------------------------===//
16890// Type reconstruction
16891//===----------------------------------------------------------------------===//
16892
16893template<typename Derived>
16896 return SemaRef.BuildPointerType(PointeeType, Star,
16897 getDerived().getBaseEntity());
16898}
16899
16900template<typename Derived>
16903 return SemaRef.BuildBlockPointerType(PointeeType, Star,
16904 getDerived().getBaseEntity());
16905}
16906
16907template<typename Derived>
16910 bool WrittenAsLValue,
16911 SourceLocation Sigil) {
16912 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue,
16913 Sigil, getDerived().getBaseEntity());
16914}
16915
16916template<typename Derived>
16919 QualType ClassType,
16920 SourceLocation Sigil) {
16921 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil,
16922 getDerived().getBaseEntity());
16923}
16924
16925template<typename Derived>
16927 const ObjCTypeParamDecl *Decl,
16928 SourceLocation ProtocolLAngleLoc,
16930 ArrayRef<SourceLocation> ProtocolLocs,
16931 SourceLocation ProtocolRAngleLoc) {
16932 return SemaRef.ObjC().BuildObjCTypeParamType(
16933 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
16934 /*FailOnError=*/true);
16935}
16936
16937template<typename Derived>
16939 QualType BaseType,
16941 SourceLocation TypeArgsLAngleLoc,
16943 SourceLocation TypeArgsRAngleLoc,
16944 SourceLocation ProtocolLAngleLoc,
16946 ArrayRef<SourceLocation> ProtocolLocs,
16947 SourceLocation ProtocolRAngleLoc) {
16948 return SemaRef.ObjC().BuildObjCObjectType(
16949 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
16950 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
16951 /*FailOnError=*/true,
16952 /*Rebuilding=*/true);
16953}
16954
16955template<typename Derived>
16957 QualType PointeeType,
16959 return SemaRef.Context.getObjCObjectPointerType(PointeeType);
16960}
16961
16962template <typename Derived>
16964 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
16965 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
16966 if (SizeExpr || !Size)
16967 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
16968 IndexTypeQuals, BracketsRange,
16969 getDerived().getBaseEntity());
16970
16971 QualType Types[] = {
16975 };
16976 QualType SizeType;
16977 for (const auto &T : Types)
16978 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
16979 SizeType = T;
16980 break;
16981 }
16982
16983 // Note that we can return a VariableArrayType here in the case where
16984 // the element type was a dependent VariableArrayType.
16985 IntegerLiteral *ArraySize
16986 = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType,
16987 /*FIXME*/BracketsRange.getBegin());
16988 return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize,
16989 IndexTypeQuals, BracketsRange,
16990 getDerived().getBaseEntity());
16991}
16992
16993template <typename Derived>
16995 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
16996 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
16997 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
16998 IndexTypeQuals, BracketsRange);
16999}
17000
17001template <typename Derived>
17003 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
17004 SourceRange BracketsRange) {
17005 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
17006 IndexTypeQuals, BracketsRange);
17007}
17008
17009template <typename Derived>
17011 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17012 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17013 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17014 SizeExpr,
17015 IndexTypeQuals, BracketsRange);
17016}
17017
17018template <typename Derived>
17020 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17021 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17022 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17023 SizeExpr,
17024 IndexTypeQuals, BracketsRange);
17025}
17026
17027template <typename Derived>
17029 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
17030 return SemaRef.BuildAddressSpaceAttr(PointeeType, AddrSpaceExpr,
17031 AttributeLoc);
17032}
17033
17034template <typename Derived>
17036 unsigned NumElements,
17037 VectorKind VecKind) {
17038 // FIXME: semantic checking!
17039 return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);
17040}
17041
17042template <typename Derived>
17044 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
17045 VectorKind VecKind) {
17046 return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc);
17047}
17048
17049template<typename Derived>
17051 unsigned NumElements,
17052 SourceLocation AttributeLoc) {
17053 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
17054 NumElements, true);
17055 IntegerLiteral *VectorSize
17056 = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
17057 AttributeLoc);
17058 return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
17059}
17060
17061template<typename Derived>
17064 Expr *SizeExpr,
17065 SourceLocation AttributeLoc) {
17066 return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
17067}
17068
17069template <typename Derived>
17071 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
17072 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
17073 NumColumns);
17074}
17075
17076template <typename Derived>
17078 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
17079 SourceLocation AttributeLoc) {
17080 return SemaRef.BuildMatrixType(ElementType, RowExpr, ColumnExpr,
17081 AttributeLoc);
17082}
17083
17084template <typename Derived>
17088 return SemaRef.BuildFunctionType(T, ParamTypes,
17089 getDerived().getBaseLocation(),
17090 getDerived().getBaseEntity(),
17091 EPI);
17092}
17093
17094template<typename Derived>
17096 return SemaRef.Context.getFunctionNoProtoType(T);
17097}
17098
17099template<typename Derived>
17101 Decl *D) {
17102 assert(D && "no decl found");
17103 if (D->isInvalidDecl()) return QualType();
17104
17105 // FIXME: Doesn't account for ObjCInterfaceDecl!
17106 if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
17107 // A valid resolved using typename pack expansion decl can have multiple
17108 // UsingDecls, but they must each have exactly one type, and it must be
17109 // the same type in every case. But we must have at least one expansion!
17110 if (UPD->expansions().empty()) {
17111 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
17112 << UPD->isCXXClassMember() << UPD;
17113 return QualType();
17114 }
17115
17116 // We might still have some unresolved types. Try to pick a resolved type
17117 // if we can. The final instantiation will check that the remaining
17118 // unresolved types instantiate to the type we pick.
17119 QualType FallbackT;
17120 QualType T;
17121 for (auto *E : UPD->expansions()) {
17122 QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
17123 if (ThisT.isNull())
17124 continue;
17125 else if (ThisT->getAs<UnresolvedUsingType>())
17126 FallbackT = ThisT;
17127 else if (T.isNull())
17128 T = ThisT;
17129 else
17130 assert(getSema().Context.hasSameType(ThisT, T) &&
17131 "mismatched resolved types in using pack expansion");
17132 }
17133 return T.isNull() ? FallbackT : T;
17134 } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
17135 assert(Using->hasTypename() &&
17136 "UnresolvedUsingTypenameDecl transformed to non-typename using");
17137
17138 // A valid resolved using typename decl points to exactly one type decl.
17139 assert(++Using->shadow_begin() == Using->shadow_end());
17140
17141 UsingShadowDecl *Shadow = *Using->shadow_begin();
17142 if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), Loc))
17143 return QualType();
17144 return SemaRef.Context.getUsingType(
17145 Shadow, SemaRef.Context.getTypeDeclType(
17146 cast<TypeDecl>(Shadow->getTargetDecl())));
17147 } else {
17148 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
17149 "UnresolvedUsingTypenameDecl transformed to non-using decl");
17150 return SemaRef.Context.getTypeDeclType(
17151 cast<UnresolvedUsingTypenameDecl>(D));
17152 }
17153}
17154
17155template <typename Derived>
17157 TypeOfKind Kind) {
17158 return SemaRef.BuildTypeofExprType(E, Kind);
17159}
17160
17161template<typename Derived>
17163 TypeOfKind Kind) {
17164 return SemaRef.Context.getTypeOfType(Underlying, Kind);
17165}
17166
17167template <typename Derived>
17169 return SemaRef.BuildDecltypeType(E);
17170}
17171
17172template <typename Derived>
17174 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
17175 SourceLocation EllipsisLoc, bool FullySubstituted,
17176 ArrayRef<QualType> Expansions) {
17177 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
17178 FullySubstituted, Expansions);
17179}
17180
17181template<typename Derived>
17185 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
17186}
17187
17188template<typename Derived>
17190 TemplateName Template,
17191 SourceLocation TemplateNameLoc,
17192 TemplateArgumentListInfo &TemplateArgs) {
17193 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
17194}
17195
17196template<typename Derived>
17198 SourceLocation KWLoc) {
17199 return SemaRef.BuildAtomicType(ValueType, KWLoc);
17200}
17201
17202template<typename Derived>
17204 SourceLocation KWLoc,
17205 bool isReadPipe) {
17206 return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc)
17207 : SemaRef.BuildWritePipeType(ValueType, KWLoc);
17208}
17209
17210template <typename Derived>
17212 unsigned NumBits,
17214 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
17215 NumBits, true);
17216 IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,
17217 SemaRef.Context.IntTy, Loc);
17218 return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc);
17219}
17220
17221template <typename Derived>
17223 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
17224 return SemaRef.BuildBitIntType(IsUnsigned, NumBitsExpr, Loc);
17225}
17226
17227template<typename Derived>
17230 bool TemplateKW,
17231 TemplateDecl *Template) {
17232 return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW,
17233 TemplateName(Template));
17234}
17235
17236template<typename Derived>
17239 SourceLocation TemplateKWLoc,
17240 const IdentifierInfo &Name,
17241 SourceLocation NameLoc,
17242 QualType ObjectType,
17243 NamedDecl *FirstQualifierInScope,
17244 bool AllowInjectedClassName) {
17246 TemplateName.setIdentifier(&Name, NameLoc);
17247 Sema::TemplateTy Template;
17248 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
17249 TemplateName, ParsedType::make(ObjectType),
17250 /*EnteringContext=*/false, Template,
17251 AllowInjectedClassName);
17252 return Template.get();
17253}
17254
17255template<typename Derived>
17258 SourceLocation TemplateKWLoc,
17259 OverloadedOperatorKind Operator,
17260 SourceLocation NameLoc,
17261 QualType ObjectType,
17262 bool AllowInjectedClassName) {
17263 UnqualifiedId Name;
17264 // FIXME: Bogus location information.
17265 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
17266 Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);
17267 Sema::TemplateTy Template;
17268 getSema().ActOnTemplateName(
17269 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(ObjectType),
17270 /*EnteringContext=*/false, Template, AllowInjectedClassName);
17271 return Template.get();
17272}
17273
17274template <typename Derived>
17277 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
17278 Expr *Second) {
17279 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
17280
17281 if (First->getObjectKind() == OK_ObjCProperty) {
17284 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/nullptr, OpLoc,
17285 Opc, First, Second);
17287 if (Result.isInvalid())
17288 return ExprError();
17289 First = Result.get();
17290 }
17291
17292 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
17293 ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
17294 if (Result.isInvalid())
17295 return ExprError();
17296 Second = Result.get();
17297 }
17298
17299 // Determine whether this should be a builtin operation.
17300 if (Op == OO_Subscript) {
17301 if (!First->getType()->isOverloadableType() &&
17302 !Second->getType()->isOverloadableType())
17303 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
17304 OpLoc);
17305 } else if (Op == OO_Arrow) {
17306 // It is possible that the type refers to a RecoveryExpr created earlier
17307 // in the tree transformation.
17308 if (First->getType()->isDependentType())
17309 return ExprError();
17310 // -> is never a builtin operation.
17311 return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);
17312 } else if (Second == nullptr || isPostIncDec) {
17313 if (!First->getType()->isOverloadableType() ||
17314 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
17315 // The argument is not of overloadable type, or this is an expression
17316 // of the form &Class::member, so try to create a built-in unary
17317 // operation.
17319 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
17320
17321 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
17322 }
17323 } else {
17324 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
17325 !First->getType()->isOverloadableType() &&
17326 !Second->getType()->isOverloadableType()) {
17327 // Neither of the arguments is type-dependent or has an overloadable
17328 // type, so try to create a built-in binary operation.
17331 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
17332 if (Result.isInvalid())
17333 return ExprError();
17334
17335 return Result;
17336 }
17337 }
17338
17339 // Create the overloaded operator invocation for unary operators.
17340 if (!Second || isPostIncDec) {
17342 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
17343 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First,
17344 RequiresADL);
17345 }
17346
17347 // Create the overloaded operator invocation for binary operators.
17349 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions,
17350 First, Second, RequiresADL);
17351 if (Result.isInvalid())
17352 return ExprError();
17353
17354 return Result;
17355}
17356
17357template<typename Derived>
17360 SourceLocation OperatorLoc,
17361 bool isArrow,
17362 CXXScopeSpec &SS,
17363 TypeSourceInfo *ScopeType,
17364 SourceLocation CCLoc,
17365 SourceLocation TildeLoc,
17366 PseudoDestructorTypeStorage Destroyed) {
17367 QualType BaseType = Base->getType();
17368 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
17369 (!isArrow && !BaseType->getAs<RecordType>()) ||
17370 (isArrow && BaseType->getAs<PointerType>() &&
17371 !BaseType->castAs<PointerType>()->getPointeeType()
17372 ->template getAs<RecordType>())){
17373 // This pseudo-destructor expression is still a pseudo-destructor.
17374 return SemaRef.BuildPseudoDestructorExpr(
17375 Base, OperatorLoc, isArrow ? tok::arrow : tok::period, SS, ScopeType,
17376 CCLoc, TildeLoc, Destroyed);
17377 }
17378
17379 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
17381 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
17382 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
17383 NameInfo.setNamedTypeInfo(DestroyedType);
17384
17385 // The scope type is now known to be a valid nested name specifier
17386 // component. Tack it on to the end of the nested name specifier.
17387 if (ScopeType) {
17388 if (!ScopeType->getType()->getAs<TagType>()) {
17389 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
17390 diag::err_expected_class_or_namespace)
17391 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
17392 return ExprError();
17393 }
17394 SS.Extend(SemaRef.Context, SourceLocation(), ScopeType->getTypeLoc(),
17395 CCLoc);
17396 }
17397
17398 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
17399 return getSema().BuildMemberReferenceExpr(Base, BaseType,
17400 OperatorLoc, isArrow,
17401 SS, TemplateKWLoc,
17402 /*FIXME: FirstQualifier*/ nullptr,
17403 NameInfo,
17404 /*TemplateArgs*/ nullptr,
17405 /*S*/nullptr);
17406}
17407
17408template<typename Derived>
17411 SourceLocation Loc = S->getBeginLoc();
17412 CapturedDecl *CD = S->getCapturedDecl();
17413 unsigned NumParams = CD->getNumParams();
17414 unsigned ContextParamPos = CD->getContextParamPosition();
17416 for (unsigned I = 0; I < NumParams; ++I) {
17417 if (I != ContextParamPos) {
17418 Params.push_back(
17419 std::make_pair(
17420 CD->getParam(I)->getName(),
17421 getDerived().TransformType(CD->getParam(I)->getType())));
17422 } else {
17423 Params.push_back(std::make_pair(StringRef(), QualType()));
17424 }
17425 }
17426 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
17427 S->getCapturedRegionKind(), Params);
17428 StmtResult Body;
17429 {
17430 Sema::CompoundScopeRAII CompoundScope(getSema());
17431 Body = getDerived().TransformStmt(S->getCapturedStmt());
17432 }
17433
17434 if (Body.isInvalid()) {
17435 getSema().ActOnCapturedRegionError();
17436 return StmtError();
17437 }
17438
17439 return getSema().ActOnCapturedRegionEnd(Body.get());
17440}
17441
17442template <typename Derived>
17444TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
17445 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
17446 // function definition or instantiation of a function template specialization
17447 // and will therefore never appear in a dependent context.
17448 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
17449 "context");
17450}
17451
17452template <typename Derived>
17453ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
17454 // We can transform the base expression and allow argument resolution to fill
17455 // in the rest.
17456 return getDerived().TransformExpr(E->getArgLValue());
17457}
17458
17459} // end namespace clang
17460
17461#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:1181
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:3060
unsigned Iter
Definition: HTMLLogger.cpp:153
#define X(type, name)
Definition: Value.h:144
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:1122
SourceRange Range
Definition: SemaObjC.cpp:758
SourceLocation Loc
Definition: SemaObjC.cpp:759
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.
This file defines SYCL AST classes used to represent calls to SYCL kernels.
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:1141
unsigned getIntWidth(QualType T) 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:684
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType, const Attr *attr=nullptr) const
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.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2723
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2739
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 getSubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl, unsigned Index, std::optional< unsigned > PackIndex, SubstTemplateTypeParmTypeFlag Flag=SubstTemplateTypeParmTypeFlag::None) const
Retrieve a substitution-result type.
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:1703
IdentifierTable & Idents
Definition: ASTContext.h:680
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:1170
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:1169
CanQualType PseudoObjectTy
Definition: ASTContext.h:1191
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2296
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.
QualType getPackExpansionType(QualType Pattern, std::optional< unsigned > NumExpansions, bool ExpectPackInType=true) const
Form a pack expansion type with the given pattern.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
CanQualType UnsignedInt128Ty
Definition: ASTContext.h:1171
CanQualType BuiltinFnTy
Definition: ASTContext.h:1190
CanQualType UnsignedCharTy
Definition: ASTContext.h:1170
CanQualType UnsignedIntTy
Definition: ASTContext.h:1170
CanQualType UnsignedLongLongTy
Definition: ASTContext.h:1171
CanQualType UnsignedShortTy
Definition: ASTContext.h:1170
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 getHLSLAttributedResourceType(QualType Wrapped, QualType Contained, const HLSLAttributedResourceType::Attributes &Attrs)
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 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:2853
SourceLocation getRParenLoc() const
Definition: TypeLoc.h:2666
TypeLoc getValueLoc() const
Definition: TypeLoc.h:2642
SourceLocation getKWLoc() const
Definition: TypeLoc.h:2650
SourceLocation getLParenLoc() const
Definition: TypeLoc.h:2658
Attr - This represents one attribute.
Definition: Attr.h:43
attr::Kind getKind() const
Definition: Attr.h:89
Represents an attribute applied to a statement.
Definition: Stmt.h:2107
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:6562
ArrayRef< TemplateArgument > getTypeConstraintArguments() const
Definition: Type.h:6572
ConceptDecl * getTypeConstraintConcept() const
Definition: Type.h:6577
AutoTypeKeyword getKeyword() const
Definition: Type.h:6593
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:2195
bool isAssignmentOp() const
Definition: Expr.h:4048
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO)
Retrieve the binary opcode that corresponds to the given overloaded operator.
Definition: Expr.cpp:2157
void setIsVariadic(bool value)
Definition: Decl.h:4579
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition: ExprCXX.h:5296
SourceLocation getEndLoc() const LLVM_READONLY
Definition: ExprCXX.h:5315
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprCXX.h:5314
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:568
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprCXX.cpp:562
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:2592
static CXXDefaultArgExpr * Create(const ASTContext &C, SourceLocation Loc, ParmVarDecl *Param, Expr *RewrittenExpr, DeclContext *UsedContext)
Definition: ExprCXX.cpp:1018
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:1871
An expression "T()" which creates an rvalue of a non-class type T.
Definition: ExprCXX.h:2182
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:101
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
Definition: DeclSpec.cpp:149
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:111
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:51
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
Definition: DeclSpec.cpp:129
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:3557
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:1498
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition: Decl.h:4779
unsigned getNumParams() const
Definition: Decl.h:4821
unsigned getContextParamPosition() const
Definition: Decl.h:4850
ImplicitParamDecl * getParam(unsigned i) const
Definition: Decl.h:4823
This captures a statement into a function.
Definition: Stmt.h:3784
Expr * getSubExpr()
Definition: Expr.h:3597
SourceLocation getBegin() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1628
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:87
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:422
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1372
reference front() const
Definition: DeclBase.h:1395
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1439
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1866
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1780
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:1519
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
SourceLocation getEndLoc() const LLVM_READONLY
Definition: DeclBase.h:438
bool isInvalidDecl() const
Definition: DeclBase.h:591
SourceLocation getLocation() const
Definition: DeclBase.h:442
DeclContext * getDeclContext()
Definition: DeclBase.h:451
AccessSpecifier getAccess() const
Definition: DeclBase.h:510
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:434
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:781
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:768
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1904
QualType getDeducedType() const
Get the type deduced for this placeholder type, or null if it has not been deduced.
Definition: Type.h:6549
bool isDeduced() const
Definition: Type.h:6550
A qualified reference to a name whose declaration cannot yet be resolved.
Definition: ExprCXX.h:3323
Represents a dependent template name that cannot be resolved prior to template instantiation.
Definition: TemplateName.h:548
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc)
Definition: TypeLoc.h:2504
SourceLocation getTemplateNameLoc() const
Definition: TypeLoc.h:2528
void setTemplateKeywordLoc(SourceLocation Loc)
Definition: TypeLoc.h:2524
SourceLocation getTemplateKeywordLoc() const
Definition: TypeLoc.h:2520
void setElaboratedKeywordLoc(SourceLocation Loc)
Definition: TypeLoc.h:2492
void setRAngleLoc(SourceLocation Loc)
Definition: TypeLoc.h:2548
SourceLocation getElaboratedKeywordLoc() const
Definition: TypeLoc.h:2488
void setLAngleLoc(SourceLocation Loc)
Definition: TypeLoc.h:2540
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI)
Definition: TypeLoc.h:2556
void setTemplateNameLoc(SourceLocation Loc)
Definition: TypeLoc.h:2532
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: Type.h:7082
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:868
Wrap a function effect's condition expression in another struct so that FunctionProtoType's TrailingO...
Definition: Type.h:4829
Expr * getCondition() const
Definition: Type.h:4836
SourceLocation getElaboratedKeywordLoc() const
Definition: TypeLoc.h:2351
NestedNameSpecifierLoc getQualifierLoc() const
Definition: TypeLoc.h:2363
void setElaboratedKeywordLoc(SourceLocation Loc)
Definition: TypeLoc.h:2355
TypeLoc getNamedTypeLoc() const
Definition: TypeLoc.h:2393
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc)
Definition: TypeLoc.h:2369
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:6949
RAII object that enters a new expression evaluation context.
Represents an enum.
Definition: Decl.h:3868
TypeSourceInfo * getTypeInfoAsWritten() const
getTypeInfoAsWritten - Returns the type source info for the type that this expression is casting to.
Definition: Expr.h:3821
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:276
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:979
Represents a member of a struct/union/class.
Definition: Decl.h:3040
Represents a function declaration or definition.
Definition: Decl.h:1935
QualType getReturnType() const
Definition: Decl.h:2727
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2656
QualType getCallResultType() const
Determine the type of an expression that calls this function.
Definition: Decl.h:2763
Represents an abstract function effect, using just an enumeration describing its kind.
Definition: Type.h:4722
StringRef name() const
The description printed in diagnostics, e.g. 'nonblocking'.
Definition: Type.cpp:5221
Kind oppositeKind() const
Return the opposite kind, for effects which have opposites.
Definition: Type.cpp:5207
ArrayRef< EffectConditionExpr > conditions() const
Definition: Type.h:4943
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: Type.h:4687
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5108
QualType desugar() const
Definition: Type.h:5652
param_type_iterator param_type_begin() const
Definition: Type.h:5521
const ExtParameterInfo * getExtParameterInfosOrNull() const
Return a pointer to the beginning of the array of extra parameter information, if present,...
Definition: Type.h:5559
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition: Type.h:5501
ExtProtoInfo getExtProtoInfo() const
Definition: Type.h:5372
ArrayRef< QualType > getParamTypes() const
Definition: Type.h:5368
unsigned getNumParams() const
Definition: TypeLoc.h:1532
SourceLocation getLocalRangeEnd() const
Definition: TypeLoc.h:1484
void setLocalRangeBegin(SourceLocation L)
Definition: TypeLoc.h:1480
void setLParenLoc(SourceLocation Loc)
Definition: TypeLoc.h:1496
SourceRange getExceptionSpecRange() const
Definition: TypeLoc.h:1512
void setParam(unsigned i, ParmVarDecl *VD)
Definition: TypeLoc.h:1539
ArrayRef< ParmVarDecl * > getParams() const
Definition: TypeLoc.h:1523
void setRParenLoc(SourceLocation Loc)
Definition: TypeLoc.h:1504
void setLocalRangeEnd(SourceLocation L)
Definition: TypeLoc.h:1488
void setExceptionSpecRange(SourceRange R)
Definition: TypeLoc.h:1518
TypeLoc getReturnLoc() const
Definition: TypeLoc.h:1541
SourceLocation getLocalRangeBegin() const
Definition: TypeLoc.h:1476
SourceLocation getLParenLoc() const
Definition: TypeLoc.h:1492
SourceLocation getRParenLoc() const
Definition: TypeLoc.h:1500
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
Definition: Type.h:4348
QualType getReturnType() const
Definition: Type.h:4649
AssociationTy< false > Association
Definition: Expr.h:6197
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:3724
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5841
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:515
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:979
Represents the declaration of a label.
Definition: Decl.h:503
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:484
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:4732
This represents a decl that may have a name.
Definition: Decl.h:253
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition: Decl.h:466
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:274
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:280
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:319
Represents a C++ namespace alias.
Definition: DeclCXX.h:3182
Represent a C++ namespace.
Definition: Decl.h:551
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:955
@ Instance
The receiver is an object instance.
Definition: ExprObjC.h:949
@ SuperClass
The receiver is a superclass.
Definition: ExprObjC.h:952
@ Class
The receiver is a class.
Definition: ExprObjC.h:946
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:2418
@ Identifier
A field in a dependent type, known only by its name.
Definition: Expr.h:2422
@ Field
A field.
Definition: Expr.h:2420
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Definition: Expr.h:2425
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 OpenACCCollapseClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, bool HasForce, Expr *LoopCount, SourceLocation EndLoc)
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 OpenACCDefaultAsyncClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCDefaultClause * Create(const ASTContext &C, OpenACCDefaultClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
static OpenACCDeleteClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDetachClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDeviceClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDeviceNumClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, 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 OpenACCFinalizeClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCFirstPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCHostClause * 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 OpenACCIfPresentClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, 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 OpenACCSelfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
static OpenACCSeqClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc)
static OpenACCTileClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > SizeExprs, SourceLocation EndLoc)
static OpenACCUseDeviceClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCVectorClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, 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)
static OpenACCWorkerClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
Definition: ExprCXX.h:2983
bool hasExplicitTemplateArgs() const
Determines whether this expression had explicit template arguments.
Definition: ExprCXX.h:3135
SourceLocation getLAngleLoc() const
Retrieve the location of the left angle bracket starting the explicit template argument list followin...
Definition: ExprCXX.h:3117
SourceLocation getNameLoc() const
Gets the location of the name.
Definition: ExprCXX.h:3096
SourceLocation getTemplateKeywordLoc() const
Retrieve the location of the template keyword preceding this name, if any.
Definition: ExprCXX.h:3109
NestedNameSpecifierLoc getQualifierLoc() const
Fetches the nested-name qualifier with source-location information, if one was given.
Definition: ExprCXX.h:3105
TemplateArgumentLoc const * getTemplateArgs() const
Definition: ExprCXX.h:3137
llvm::iterator_range< decls_iterator > decls() const
Definition: ExprCXX.h:3082
unsigned getNumTemplateArgs() const
Definition: ExprCXX.h:3143
DeclarationName getName() const
Gets the name looked up.
Definition: ExprCXX.h:3093
SourceLocation getRAngleLoc() const
Retrieve the location of the right angle bracket ending the explicit template argument list following...
Definition: ExprCXX.h:3125
bool hasTemplateKeyword() const
Determines whether the name was preceded by the template keyword.
Definition: ExprCXX.h:3132
Represents a C++11 pack expansion that produces a sequence of expressions.
Definition: ExprCXX.h:4180
void setEllipsisLoc(SourceLocation Loc)
Definition: TypeLoc.h:2614
SourceLocation getEllipsisLoc() const
Definition: TypeLoc.h:2610
TypeLoc getPatternLoc() const
Definition: TypeLoc.h:2626
Represents a pack expansion of types.
Definition: Type.h:7147
std::optional< unsigned > getNumExpansions() const
Retrieve the number of expansions that this pack expansion will generate, if known.
Definition: Type.h:7172
ParenExpr - This represents a parenthesized expression, e.g.
Definition: Expr.h:2170
SourceLocation getLParen() const
Get the location of the left parentheses '('.
Definition: Expr.h:2195
SourceLocation getRParen() const
Get the location of the right parentheses ')'.
Definition: Expr.h:2199
Represents a parameter to a function.
Definition: Decl.h:1725
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
Definition: Decl.h:1785
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
Definition: Decl.h:1758
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:2918
unsigned getFunctionScopeDepth() const
Definition: Decl.h:1775
void setSigilLoc(SourceLocation Loc)
Definition: TypeLoc.h:1310
TypeLoc getPointeeLoc() const
Definition: TypeLoc.h:1314
SourceLocation getSigilLoc() const
Definition: TypeLoc.h:1306
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3199
QualType getPointeeType() const
Definition: Type.h:3209
Stores the type being destroyed by a pseudo-destructor expression.
Definition: ExprCXX.h:2566
const IdentifierInfo * getIdentifier() const
Definition: ExprCXX.h:2586
SourceLocation getLocation() const
Definition: ExprCXX.h:2590
TypeSourceInfo * getTypeSourceInfo() const
Definition: ExprCXX.h:2582
A (possibly-)qualified type.
Definition: Type.h:929
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:996
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7937
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:7977
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:8031
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
Definition: Type.h:7969
Represents a template name as written in source code.
Definition: TemplateName.h:491
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:324
void removeObjCLifetime()
Definition: Type.h:544
bool hasRestrict() const
Definition: Type.h:470
static Qualifiers fromCVRMask(unsigned CVR)
Definition: Type.h:428
bool hasObjCLifetime() const
Definition: Type.h:537
bool empty() const
Definition: Type.h:640
LangAS getAddressSpace() const
Definition: Type.h:564
Represents a struct/union/class.
Definition: Decl.h:4169
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:6078
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3440
QualType getPointeeTypeAsWritten() const
Definition: Type.h:3456
Represents the body of a requires-expression.
Definition: DeclCXX.h:2086
static RequiresExprBodyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc)
Definition: DeclCXX.cpp:2313
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Definition: ExprConcepts.h:502
static RequiresExpr * Create(ASTContext &C, SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, SourceLocation LParenLoc, ArrayRef< ParmVarDecl * > LocalParameters, SourceLocation RParenLoc, ArrayRef< concepts::Requirement * > Requirements, SourceLocation RBraceLoc)
static ResolvedUnexpandedPackExpr * Create(ASTContext &C, SourceLocation BeginLoc, QualType T, unsigned NumExprs)
Definition: ExprCXX.cpp:1991
static SEHFinallyStmt * Create(const ASTContext &C, SourceLocation FinallyLoc, Stmt *Block)
Definition: Stmt.cpp:1283
Represents a __leave statement.
Definition: Stmt.h:3745
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:36
StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)
FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.
Definition: SemaObjC.cpp:198
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:485
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:325
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:223
StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body)
Definition: SemaObjC.cpp:218
StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw)
Definition: SemaObjC.cpp:243
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:712
ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand)
Definition: SemaObjC.cpp:287
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:207
StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body)
Definition: SemaObjC.cpp:334
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:338
OpenACCDirectiveKind getDirectiveKind() const
Definition: SemaOpenACC.h:260
void setLParenLoc(SourceLocation EndLoc)
Definition: SemaOpenACC.h:467
void setConditionDetails(Expr *ConditionExpr)
Definition: SemaOpenACC.h:476
void setCollapseDetails(bool IsForce, Expr *LoopCount)
Definition: SemaOpenACC.h:642
OpenACCClauseKind getClauseKind() const
Definition: SemaOpenACC.h:262
SourceLocation getLParenLoc() const
Definition: SemaOpenACC.h:266
SourceLocation getBeginLoc() const
Definition: SemaOpenACC.h:264
void setDefaultDetails(OpenACCDefaultClauseKind DefKind)
Definition: SemaOpenACC.h:470
SourceLocation getQueuesLoc() const
Definition: SemaOpenACC.h:318
void setVarListDetails(ArrayRef< Expr * > VarList, bool IsReadOnly, bool IsZero)
Definition: SemaOpenACC.h:536
void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc, llvm::SmallVector< Expr * > &&IntExprs)
Definition: SemaOpenACC.h:628
void setEndLoc(SourceLocation EndLoc)
Definition: SemaOpenACC.h:468
void setIntExprDetails(ArrayRef< Expr * > IntExprs)
Definition: SemaOpenACC.h:490
OpenACCDefaultClauseKind getDefaultClauseKind() const
Definition: SemaOpenACC.h:270
void ActOnWhileStmt(SourceLocation WhileLoc)
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation DirLoc, SourceLocation LParenLoc, SourceLocation MiscLoc, ArrayRef< Expr * > Exprs, SourceLocation RParenLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
ExprResult ActOnOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)
void ActOnDoStmt(SourceLocation DoLoc)
void ActOnRangeForStmtBegin(SourceLocation ForLoc, const Stmt *OldRangeFor, const Stmt *RangeFor)
void ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body)
void ActOnForStmtBegin(SourceLocation ForLoc, const Stmt *First, const Stmt *Second, const Stmt *Third)
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 * ActOnOpenMPToClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers={})
Called on well-formed 'to' 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 * 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 * ActOnOpenMPPermutationClause(ArrayRef< Expr * > PermExprs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'permutation' clause after parsing its arguments.
OMPClause * ActOnOpenMPNontemporalClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nontemporal' clause.
OMPClause * ActOnOpenMPFromClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers={})
Called on well-formed 'from' 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)
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 * ActOnOpenMPTaskReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions={})
Called on well-formed 'task_reduction' clause.
OMPClause * ActOnOpenMPOrderClause(OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'order' 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={})
Called on well-formed 'reduction' 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 * ActOnOpenMPInReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions={})
Called on well-formed 'in_reduction' 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 * 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 * ActOnOpenMPAllocateClause(Expr *Allocator, Expr *Alignment, OpenMPAllocateClauseModifier FirstModifier, SourceLocation FirstModifierLoc, OpenMPAllocateClauseModifier SecondModifier, SourceLocation SecondModifierLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocate' clause.
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' 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={})
Called on well-formed 'map' 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 * 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:143
RAII object used to change the argument pack substitution index within a Sema object.
Definition: Sema.h:13243
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
Definition: Sema.h:8062
A RAII object to enter scope of a compound statement.
Definition: Sema.h:918
A helper class for building up ExtParameterInfos.
Definition: Sema.h:12646
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:12665
void set(unsigned index, FunctionProtoType::ExtParameterInfo info)
Set the ExtParameterInfo for the parameter at the given index,.
Definition: Sema.h:12653
Records and restores the CurFPFeatures state on entry/exit of compound statements.
Definition: Sema.h:13613
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:466
QualType BuildParenType(QualType T)
Build a paren type including T.
Definition: SemaType.cpp:1675
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
Definition: SemaType.cpp:6395
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:4481
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition: Sema.h:9004
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
Definition: Sema.h:9012
@ LookupTagName
Tag name lookup, which finds the names of enums, classes, structs, and unions.
Definition: Sema.h:9007
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:6498
ExprResult ActOnConstantExpression(ExprResult Res)
Definition: SemaExpr.cpp:19678
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:4415
QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc)
Definition: SemaType.cpp:2327
StmtResult BuildAttributedStmt(SourceLocation AttrsLoc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)
Definition: SemaStmt.cpp:651
SemaOpenMP & OpenMP()
Definition: Sema.h:1128
@ IER_DoesNotExist
The symbol does not exist.
Definition: Sema.h:8479
@ IER_Dependent
The name is a dependent name, so the results will differ from one instantiation to the next.
Definition: Sema.h:8483
@ IER_Error
An error occurred.
Definition: Sema.h:8486
@ IER_Exists
The symbol exists.
Definition: Sema.h:8476
void ActOnStartStmtExpr()
Definition: SemaExpr.cpp:15864
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:15870
void MarkDeclarationsReferencedInExpr(Expr *E, bool SkipLocalVariables=false, ArrayRef< const Expr * > StopAt={})
Mark any declarations that appear within this expression or any potentially-evaluated subexpressions ...
Definition: SemaExpr.cpp:20195
std::optional< FunctionEffectMode > ActOnEffectExpression(Expr *CondExpr, StringRef AttributeName)
Try to parse the conditional expression attached to an effect attribute (e.g.
Definition: SemaType.cpp:7625
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:20411
ConditionKind
Definition: Sema.h:7355
@ 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:394
StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, LabelDecl *TheDecl)
Definition: SemaStmt.cpp:3219
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:500
QualType BuildExtVectorType(QualType T, Expr *ArraySize, SourceLocation AttrLoc)
Build an ext-vector type.
Definition: SemaType.cpp:2393
ExprResult ActOnDesignatedInitializer(Designation &Desig, SourceLocation EqualOrColonLoc, bool GNUSyntax, ExprResult Init)
Definition: SemaInit.cpp:3503
ExprResult BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, SourceLocation RPLoc, unsigned TemplateDepth)
Definition: SemaExpr.cpp:15883
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:1153
ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E, TypeSourceInfo *TInfo, SourceLocation RPLoc)
Definition: SemaExpr.cpp:16526
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:911
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:2633
ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow)
Perform conversions on the LHS of a member access expression.
DiagnosticsEngine & getDiagnostics() const
Definition: Sema.h:531
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.
SemaObjC & ObjC()
Definition: Sema.h:1113
ExprResult BuildPackIndexingExpr(Expr *PackExpression, SourceLocation EllipsisLoc, Expr *IndexExpr, SourceLocation RSquareLoc, ArrayRef< Expr * > ExpandedExprs={}, bool FullySubstituted=false)
ParsedType getDestructorName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec &SS, ParsedType ObjectType, bool EnteringContext)
ASTContext & getASTContext() const
Definition: Sema.h:534
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:15801
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:4405
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:692
ExprResult BuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK)
Definition: SemaExpr.cpp:3499
ExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, SourceLocation RParenLoc, Expr *LiteralExpr)
Definition: SemaExpr.cpp:7068
ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc, LabelDecl *TheDecl)
ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
Definition: SemaExpr.cpp:15851
ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)
Definition: SemaExpr.cpp:7923
QualType BuildCountAttributedArrayOrPointerType(QualType WrappedTy, Expr *CountExpr, bool CountInBytes, bool OrNull)
Definition: SemaType.cpp:9615
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:16979
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
Definition: SemaExpr.cpp:2217
QualType BuildBitIntType(bool IsUnsigned, Expr *BitWidth, SourceLocation Loc)
Build a bit-precise integer type.
Definition: SemaType.cpp:1940
ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr, SourceLocation RPLoc)
Definition: SemaExpr.cpp:16139
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:1684
QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs, const DeclSpec *DS=nullptr)
Definition: SemaType.cpp:1581
StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body)
Definition: SemaStmt.cpp:1308
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
Definition: Sema.cpp:82
const LangOptions & getLangOpts() const
Definition: Sema.h:527
StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, ConditionResult Cond, SourceLocation RParenLoc, Stmt *Body)
Definition: SemaStmt.cpp:1792
SemaOpenACC & OpenACC()
Definition: Sema.h:1118
@ ReuseLambdaContextDecl
Definition: Sema.h:6535
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:16807
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:15953
sema::LambdaScopeInfo * getCurLambda(bool IgnoreNonLambdaCapturingScope=false)
Retrieve the current lambda scope info, if any.
Definition: Sema.cpp:2407
ExprResult TemporaryMaterializationConversion(Expr *E)
If E is a prvalue denoting an unmaterialized temporary, materialize it as an xvalue.
Definition: SemaInit.cpp:7600
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:738
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:16954
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:3355
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:942
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
Definition: SemaDecl.cpp:14903
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:1857
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:13237
ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool NeedsADL, bool AcceptInvalidDecl=false)
Definition: SemaExpr.cpp:3202
sema::BlockScopeInfo * getCurBlock()
Retrieve the current block, if any.
Definition: Sema.cpp:2362
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:1046
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.
void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base=nullptr)
Perform reference-marking and odr-use handling for a DeclRefExpr.
Definition: SemaExpr.cpp:20039
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:2909
StmtResult ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *First, ConditionResult Second, FullExprArg Third, SourceLocation RParenLoc, Stmt *Body)
Definition: SemaStmt.cpp:2255
StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, Expr *DestExp)
Definition: SemaStmt.cpp:3234
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Definition: SemaExpr.cpp:4122
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Definition: SemaExpr.cpp:20995
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:3845
@ NTK_TypeAliasTemplate
Definition: Sema.h:3853
TryCaptureKind
Definition: Sema.h:6597
@ TryCapture_Implicit
Definition: Sema.h:6598
@ TryCapture_ExplicitByVal
Definition: Sema.h:6599
@ TryCapture_ExplicitByRef
Definition: Sema.h:6600
ExprResult BuildAsTypeExpr(Expr *E, QualType DestTy, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
Create a new AsTypeExpr node (bitcast) from the arguments.
Definition: SemaExpr.cpp:6724
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:8795
QualType BuildPackIndexingType(QualType Pattern, Expr *IndexExpr, SourceLocation Loc, SourceLocation EllipsisLoc, bool FullySubstituted=false, ArrayRef< QualType > Expansions={})
Definition: SemaType.cpp:9737
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:10020
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:13897
bool diagnoseConflictingFunctionEffect(const FunctionEffectsRef &FX, const FunctionEffectWithCondition &EC, SourceLocation NewAttrLoc)
Warn and return true if adding a function effect to a set would create a conflict.
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:216
StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, bool AllowRecovery=false)
Definition: SemaStmt.cpp:3885
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:1805
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:2683
StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation CondLParen, Expr *Cond, SourceLocation CondRParen)
Definition: SemaStmt.cpp:1822
StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc)
Definition: SemaStmt.cpp:1184
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:9705
QualType BuildUnaryTransformType(QualType BaseType, UTTKind UKind, SourceLocation Loc)
Definition: SemaType.cpp:9964
StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
Definition: SemaStmt.cpp:4443
ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo, SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, SourceRange R)
Build a sizeof or alignof expression given a type operand.
Definition: SemaExpr.cpp:4630
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
Definition: SemaStmt.cpp:76
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:7931
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:2048
ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field)
Definition: SemaExpr.cpp:5595
QualType BuildReadPipeType(QualType T, SourceLocation Loc)
Build a Read-only Pipe type.
Definition: SemaType.cpp:1932
concepts::NestedRequirement * BuildNestedRequirement(Expr *E)
QualType BuildWritePipeType(QualType T, SourceLocation Loc)
Build a Write-only Pipe type.
Definition: SemaType.cpp:1936
@ BFRK_Rebuild
Instantiation or recovery rebuild of a for-range statement.
Definition: Sema.h:10775
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:583
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:16325
QualType BuildTypeofExprType(Expr *E, TypeOfKind Kind)
Definition: SemaType.cpp:9592
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:20061
ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)
Definition: SemaCast.cpp:296
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:18109
QualType BuildMatrixType(QualType T, Expr *NumRows, Expr *NumColumns, SourceLocation AttrLoc)
Definition: SemaType.cpp:2447
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:21192
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
Definition: SemaExpr.cpp:15369
ExprResult PerformObjectMemberConversion(Expr *From, NestedNameSpecifier *Qualifier, NamedDecl *FoundDecl, NamedDecl *Member)
Cast a base object to a member's actual type.
Definition: SemaExpr.cpp:2982
StmtResult ActOnIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)
Definition: SemaStmt.cpp:962
ExprResult BuildInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList, SourceLocation RBraceLoc)
Definition: SemaExpr.cpp:7268
void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope)
ActOnBlockStart - This callback is invoked when a block literal is started.
Definition: SemaExpr.cpp:16177
ExprResult ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, MultiExprArg ArgExprs, SourceLocation RLoc)
Definition: SemaExpr.cpp:4843
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:14792
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:6451
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Definition: SemaType.cpp:2751
static ConditionResult ConditionError()
Definition: Sema.h:7342
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
Definition: SemaStmt.cpp:451
SemaPseudoObject & PseudoObject()
Definition: Sema.h:1138
StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt)
Definition: SemaStmt.cpp:608
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:4292
StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope)
Definition: SemaStmt.cpp:588
ExprResult HandleExprEvaluationContextForTypeof(Expr *E)
Definition: SemaExpr.cpp:17936
StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHS, SourceLocation DotDotDotLoc, ExprResult RHS, SourceLocation ColonLoc)
Definition: SemaStmt.cpp:552
QualType BuildMemberPointerType(QualType T, QualType Class, SourceLocation Loc, DeclarationName Entity)
Build a member pointer type T Class::*.
Definition: SemaType.cpp:2682
QualType BuildBlockPointerType(QualType T, SourceLocation Loc, DeclarationName Entity)
Build a block pointer type.
Definition: SemaType.cpp:2734
StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body)
FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement.
Definition: SemaStmt.cpp:3201
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Definition: Sema.h:8282
ExprResult CreateBuiltinMatrixSubscriptExpr(Expr *Base, Expr *RowIdx, Expr *ColumnIdx, SourceLocation RBLoc)
Definition: SemaExpr.cpp:5020
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={})
Definition: ExprCXX.cpp:1693
static bool MayBeDependent(SourceLocIdentKind Kind)
Definition: Expr.h:4870
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:358
StmtClass
Definition: Stmt.h:86
@ NoStmtClass
Definition: Stmt.h:87
StmtClass getStmtClass() const
Definition: Stmt.h:1380
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:334
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:346
A structure for storing an already-substituted template template parameter pack.
Definition: TemplateName.h:149
Wrapper for substituted template type parameters.
Definition: TypeLoc.h:865
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3585
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:398
Represents a C++ template name within the type system.
Definition: TemplateName.h:220
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:1719
void setTemplateKeywordLoc(SourceLocation Loc)
Definition: TypeLoc.h:1695
void setTemplateNameLoc(SourceLocation Loc)
Definition: TypeLoc.h:1736
void setLAngleLoc(SourceLocation Loc)
Definition: TypeLoc.h:1703
SourceLocation getTemplateNameLoc() const
Definition: TypeLoc.h:1732
void setRAngleLoc(SourceLocation Loc)
Definition: TypeLoc.h:1711
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:6667
Wrapper for template type parameters.
Definition: TypeLoc.h:759
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.
StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult StrBlock)
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.
StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses)
ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc, TypeSourceInfo *EncodeTypeInfo, SourceLocation RParenLoc)
Build a new Objective-C @encode expression.
StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K, SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult Loop)
StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body)
Alternative implementation of TransformLambdaBody that skips transforming the body.
StmtResult RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses)
StmtResult RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses)
OMPClause * RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment, OpenMPAllocateClauseModifier FirstModifier, SourceLocation FirstModifierLoc, OpenMPAllocateClauseModifier SecondModifier, SourceLocation SecondModifierLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Build a new OpenMP 'allocate' clause.
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.
StmtResult RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses)
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.
StmtResult RebuildOpenACCWaitConstruct(SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc, Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef< Expr * > QueueIdExprs, SourceLocation RParenLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses)
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 RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses)
StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *Object, Stmt *Body)
Build a new Objective-C @synchronized statement.
ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc)
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.
ExprResult RebuildResolvedUnexpandedPackExpr(SourceLocation BeginLoc, QualType T, ArrayRef< Expr * > Exprs)
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...
StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult StrBlock)
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.
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 RebuildPackIndexingExpr(SourceLocation EllipsisLoc, SourceLocation RSquareLoc, Expr *PackIdExpression, Expr *IndexExpr, ArrayRef< Expr * > ExpandedExprs, bool FullySubstituted=false)
StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses)
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.
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 * RebuildOMPPermutationClause(ArrayRef< Expr * > PermExprs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'permutation' clause.
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:756
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition: TypeLoc.h:2716
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:192
A container of type source information.
Definition: Type.h:7908
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:7919
static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword)
Converts an elaborated type keyword into a TagTypeKind.
Definition: Type.cpp:3211
ElaboratedTypeKeyword getKeyword() const
Definition: Type.h:6907
The base class of the type hierarchy.
Definition: Type.h:1828
bool isPointerType() const
Definition: Type.h:8192
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8810
bool isReferenceType() const
Definition: Type.h:8210
bool isEnumeralType() const
Definition: Type.h:8296
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:738
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.h:2812
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2707
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:2361
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
Definition: Type.h:8661
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
Definition: Type.cpp:5046
bool isFunctionType() const
Definition: Type.h:8188
bool isObjCObjectPointerType() const
Definition: Type.h:8334
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8741
bool isRecordType() const
Definition: Type.h:8292
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3434
Wrapper for source info for typedefs.
Definition: TypeLoc.h:694
TypedefNameDecl * getTypedefNameDecl() const
Definition: TypeLoc.h:696
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2232
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO, bool Postfix)
Retrieve the unary opcode that corresponds to the given overloaded operator.
Definition: Expr.cpp:1416
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:3203
CXXRecordDecl * getNamingClass()
Gets the 'naming class' (in the sense of C++0x [class.access.base]p5) of the lookup.
Definition: ExprCXX.h:3277
bool requiresADL() const
True if this declaration should be extended by argument-dependent lookup.
Definition: ExprCXX.h:3272
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:419
A set of unresolved declarations.
Definition: UnresolvedSet.h:62
void addDecl(NamedDecl *D)
Definition: UnresolvedSet.h:91
A set of unresolved declarations.
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition: Type.h:5673
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition: DeclCXX.h:3382
NamedDecl * getTargetDecl() const
Gets the underlying declaration which has been brought into the local scope.
Definition: DeclCXX.h:3446
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:671
QualType getType() const
Definition: Decl.h:682
bool isParameterPack() const
Determine whether this value is actually a function parameter pack, init-capture pack,...
Definition: Decl.cpp:5420
Represents a variable declaration or definition.
Definition: Decl.h:886
@ CInit
C-style initialization with assignment.
Definition: Decl.h:891
@ CallInit
Call-style initialization (C++98)
Definition: Decl.h:894
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition: Decl.h:1123
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 this contains an unexpanded parameter pack.
Definition: ScopeInfo.h:728
CXXRecordDecl * Lambda
The class that describes the lambda.
Definition: ScopeInfo.h:871
CXXMethodDecl * CallOperator
The lambda's compiler-generated operator().
Definition: ScopeInfo.h:874
@ AttributedType
The l-value was considered opaque, so the alignment was determined from a type, but that type was an ...
@ 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:824
bool Comp(InterpState &S, CodePtr OpPC)
1) Pops the value from the stack.
Definition: Interp.h:925
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
Definition: Descriptor.h:29
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.
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
OpenACCDirectiveKind
Definition: OpenACCKinds.h:25
ArrayTypeTrait
Names for the array type traits.
Definition: TypeTraits.h:42
@ CPlusPlus23
Definition: LangStandard.h:60
AutoTypeKeyword
Which keyword(s) were used to create an AutoType.
Definition: Type.h:1778
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
Definition: OpenMPKinds.h:25
OpenMPDefaultmapClauseModifier
OpenMP modifiers for 'defaultmap' clause.
Definition: OpenMPKinds.h:119
OpenMPOrderClauseModifier
OpenMP modifiers for 'order' clause.
Definition: OpenMPKinds.h:172
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:136
@ 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:187
BinaryOperatorKind
@ Invalid
Represents an invalid clause, for the purposes of parsing.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
TypeOfKind
The kind of 'typeof' expression we're after.
Definition: Type.h:910
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
Definition: OpenMPKinds.h:39
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
Definition: OpenMPKinds.h:104
OpenMPDoacrossClauseModifier
OpenMP dependence types for 'doacross' clause.
Definition: OpenMPKinds.h:220
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
Definition: TypeTraits.h:51
ExprResult ExprEmpty()
Definition: Ownership.h:271
std::pair< llvm::PointerUnion< const TemplateTypeParmType *, NamedDecl *, ResolvedUnexpandedPackExpr * >, SourceLocation > UnexpandedParameterPack
Definition: Sema.h:238
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:201
ArraySizeModifier
Capture whether this is a normal array (e.g.
Definition: Type.h:3575
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
OpenMPLastprivateModifier
OpenMP 'lastprivate' clause modifier.
Definition: OpenMPKinds.h:158
OpenMPGrainsizeClauseModifier
Definition: OpenMPKinds.h:207
OpenMPNumTasksClauseModifier
Definition: OpenMPKinds.h:213
UnaryOperatorKind
ActionResult< Expr * > ExprResult
Definition: Ownership.h:248
TagTypeKind
The kind of a tag type.
Definition: Type.h:6877
bool transformOMPMappableExprListClause(TreeTransform< Derived > &TT, OMPMappableExprListClause< T > *C, llvm::SmallVectorImpl< Expr * > &Vars, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperIdInfo, llvm::SmallVectorImpl< Expr * > &UnresolvedMappers)
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:1492
OpenMPSeverityClauseKind
OpenMP attributes for 'severity' clause.
Definition: OpenMPKinds.h:143
ActionResult< Stmt * > StmtResult
Definition: Ownership.h:249
OpenMPDefaultmapClauseKind
OpenMP attributes for 'defaultmap' clause.
Definition: OpenMPKinds.h:111
OpenMPAllocateClauseModifier
OpenMP modifiers for 'allocate' clause.
Definition: OpenMPKinds.h:227
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Definition: OpenMPKinds.h:63
@ 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
VectorKind
Definition: Type.h:3994
OpenMPDeviceClauseModifier
OpenMP modifiers for 'device' clause.
Definition: OpenMPKinds.h:48
SourceLocIdentKind
Definition: Expr.h:4797
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
Definition: Type.h:6852
@ 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:165
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:31
static QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T)
MutableArrayRef< Expr * > MultiExprArg
Definition: Ownership.h:258
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
Definition: OpenMPKinds.h:71
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:4846
EffectConditionExpr Cond
Definition: Type.h:4848
Holds information about the various types of exception specification.
Definition: Type.h:5165
FunctionDecl * SourceTemplate
The function template whose exception specification this is instantiated from, for EST_Uninstantiated...
Definition: Type.h:5181
ExceptionSpecificationType Type
The kind of exception specification this is.
Definition: Type.h:5167
ArrayRef< QualType > Exceptions
Explicitly-specified list of exception types.
Definition: Type.h:5170
Expr * NoexceptExpr
Noexcept expression, if this is a computed noexcept specification.
Definition: Type.h:5173
Extra information about a function prototype.
Definition: Type.h:5193
ExceptionSpecInfo ExceptionSpec
Definition: Type.h:5200
FunctionEffectsRef FunctionEffects
Definition: Type.h:5203
const ExtParameterInfo * ExtParameterInfos
Definition: Type.h:5201
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:12723
Keeps information about an identifier in a nested-name-spec.
Definition: Sema.h:2813
Location information for a TemplateArgument.
Definition: TemplateBase.h:472