clang 19.0.0git
TreeTransform.h
Go to the documentation of this file.
1//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//===----------------------------------------------------------------------===//
7//
8// This file implements a semantic tree transformation that takes a given
9// AST and rebuilds it, possibly transforming some nodes in the process.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
14#define LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
15
17#include "TypeLocBuilder.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclObjC.h"
21#include "clang/AST/Expr.h"
22#include "clang/AST/ExprCXX.h"
24#include "clang/AST/ExprObjC.h"
27#include "clang/AST/Stmt.h"
28#include "clang/AST/StmtCXX.h"
29#include "clang/AST/StmtObjC.h"
36#include "clang/Sema/Lookup.h"
42#include "clang/Sema/SemaObjC.h"
45#include "clang/Sema/SemaSYCL.h"
46#include "llvm/ADT/ArrayRef.h"
47#include "llvm/Support/ErrorHandling.h"
48#include <algorithm>
49#include <optional>
50
51using namespace llvm::omp;
52
53namespace clang {
54using namespace sema;
55
56/// A semantic tree transformation that allows one to transform one
57/// abstract syntax tree into another.
58///
59/// A new tree transformation is defined by creating a new subclass \c X of
60/// \c TreeTransform<X> and then overriding certain operations to provide
61/// behavior specific to that transformation. For example, template
62/// instantiation is implemented as a tree transformation where the
63/// transformation of TemplateTypeParmType nodes involves substituting the
64/// template arguments for their corresponding template parameters; a similar
65/// transformation is performed for non-type template parameters and
66/// template template parameters.
67///
68/// This tree-transformation template uses static polymorphism to allow
69/// subclasses to customize any of its operations. Thus, a subclass can
70/// override any of the transformation or rebuild operators by providing an
71/// operation with the same signature as the default implementation. The
72/// overriding function should not be virtual.
73///
74/// Semantic tree transformations are split into two stages, either of which
75/// can be replaced by a subclass. The "transform" step transforms an AST node
76/// or the parts of an AST node using the various transformation functions,
77/// then passes the pieces on to the "rebuild" step, which constructs a new AST
78/// node of the appropriate kind from the pieces. The default transformation
79/// routines recursively transform the operands to composite AST nodes (e.g.,
80/// the pointee type of a PointerType node) and, if any of those operand nodes
81/// were changed by the transformation, invokes the rebuild operation to create
82/// a new AST node.
83///
84/// Subclasses can customize the transformation at various levels. The
85/// most coarse-grained transformations involve replacing TransformType(),
86/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
87/// TransformTemplateName(), or TransformTemplateArgument() with entirely
88/// new implementations.
89///
90/// For more fine-grained transformations, subclasses can replace any of the
91/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
92/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
93/// replacing TransformTemplateTypeParmType() allows template instantiation
94/// to substitute template arguments for their corresponding template
95/// parameters. Additionally, subclasses can override the \c RebuildXXX
96/// functions to control how AST nodes are rebuilt when their operands change.
97/// By default, \c TreeTransform will invoke semantic analysis to rebuild
98/// AST nodes. However, certain other tree transformations (e.g, cloning) may
99/// be able to use more efficient rebuild steps.
100///
101/// There are a handful of other functions that can be overridden, allowing one
102/// to avoid traversing nodes that don't need any transformation
103/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
104/// operands have not changed (\c AlwaysRebuild()), and customize the
105/// default locations and entity names used for type-checking
106/// (\c getBaseLocation(), \c getBaseEntity()).
107template<typename Derived>
109 /// Private RAII object that helps us forget and then re-remember
110 /// the template argument corresponding to a partially-substituted parameter
111 /// pack.
112 class ForgetPartiallySubstitutedPackRAII {
113 Derived &Self;
115
116 public:
117 ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) {
118 Old = Self.ForgetPartiallySubstitutedPack();
119 }
120
121 ~ForgetPartiallySubstitutedPackRAII() {
122 Self.RememberPartiallySubstitutedPack(Old);
123 }
124 };
125
126protected:
128
129 /// The set of local declarations that have been transformed, for
130 /// cases where we are forced to build new declarations within the transformer
131 /// rather than in the subclass (e.g., lambda closure types).
132 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
133
134public:
135 /// Initializes a new tree transformer.
137
138 /// Retrieves a reference to the derived class.
139 Derived &getDerived() { return static_cast<Derived&>(*this); }
140
141 /// Retrieves a reference to the derived class.
142 const Derived &getDerived() const {
143 return static_cast<const Derived&>(*this);
144 }
145
146 static inline ExprResult Owned(Expr *E) { return E; }
147 static inline StmtResult Owned(Stmt *S) { return S; }
148
149 /// Retrieves a reference to the semantic analysis object used for
150 /// this tree transform.
151 Sema &getSema() const { return SemaRef; }
152
153 /// Whether the transformation should always rebuild AST nodes, even
154 /// if none of the children have changed.
155 ///
156 /// Subclasses may override this function to specify when the transformation
157 /// should rebuild all AST nodes.
158 ///
159 /// We must always rebuild all AST nodes when performing variadic template
160 /// pack expansion, in order to avoid violating the AST invariant that each
161 /// statement node appears at most once in its containing declaration.
163
164 /// Whether the transformation is forming an expression or statement that
165 /// replaces the original. In this case, we'll reuse mangling numbers from
166 /// existing lambdas.
167 bool ReplacingOriginal() { return false; }
168
169 /// Wether CXXConstructExpr can be skipped when they are implicit.
170 /// They will be reconstructed when used if needed.
171 /// This is useful when the user that cause rebuilding of the
172 /// CXXConstructExpr is outside of the expression at which the TreeTransform
173 /// started.
174 bool AllowSkippingCXXConstructExpr() { return true; }
175
176 /// Returns the location of the entity being transformed, if that
177 /// information was not available elsewhere in the AST.
178 ///
179 /// By default, returns no source-location information. Subclasses can
180 /// provide an alternative implementation that provides better location
181 /// information.
183
184 /// Returns the name of the entity being transformed, if that
185 /// information was not available elsewhere in the AST.
186 ///
187 /// By default, returns an empty name. Subclasses can provide an alternative
188 /// implementation with a more precise name.
190
191 /// Sets the "base" location and entity when that
192 /// information is known based on another transformation.
193 ///
194 /// By default, the source location and entity are ignored. Subclasses can
195 /// override this function to provide a customized implementation.
197
198 /// RAII object that temporarily sets the base location and entity
199 /// used for reporting diagnostics in types.
201 TreeTransform &Self;
202 SourceLocation OldLocation;
203 DeclarationName OldEntity;
204
205 public:
207 DeclarationName Entity) : Self(Self) {
208 OldLocation = Self.getDerived().getBaseLocation();
209 OldEntity = Self.getDerived().getBaseEntity();
210
211 if (Location.isValid())
212 Self.getDerived().setBase(Location, Entity);
213 }
214
216 Self.getDerived().setBase(OldLocation, OldEntity);
217 }
218 };
219
220 /// Determine whether the given type \p T has already been
221 /// transformed.
222 ///
223 /// Subclasses can provide an alternative implementation of this routine
224 /// to short-circuit evaluation when it is known that a given type will
225 /// not change. For example, template instantiation need not traverse
226 /// non-dependent types.
228 return T.isNull();
229 }
230
231 /// Transform a template parameter depth level.
232 ///
233 /// During a transformation that transforms template parameters, this maps
234 /// an old template parameter depth to a new depth.
235 unsigned TransformTemplateDepth(unsigned Depth) {
236 return Depth;
237 }
238
239 /// Determine whether the given call argument should be dropped, e.g.,
240 /// because it is a default argument.
241 ///
242 /// Subclasses can provide an alternative implementation of this routine to
243 /// determine which kinds of call arguments get dropped. By default,
244 /// CXXDefaultArgument nodes are dropped (prior to transformation).
246 return E->isDefaultArgument();
247 }
248
249 /// Determine whether we should expand a pack expansion with the
250 /// given set of parameter packs into separate arguments by repeatedly
251 /// transforming the pattern.
252 ///
253 /// By default, the transformer never tries to expand pack expansions.
254 /// Subclasses can override this routine to provide different behavior.
255 ///
256 /// \param EllipsisLoc The location of the ellipsis that identifies the
257 /// pack expansion.
258 ///
259 /// \param PatternRange The source range that covers the entire pattern of
260 /// the pack expansion.
261 ///
262 /// \param Unexpanded The set of unexpanded parameter packs within the
263 /// pattern.
264 ///
265 /// \param ShouldExpand Will be set to \c true if the transformer should
266 /// expand the corresponding pack expansions into separate arguments. When
267 /// set, \c NumExpansions must also be set.
268 ///
269 /// \param RetainExpansion Whether the caller should add an unexpanded
270 /// pack expansion after all of the expanded arguments. This is used
271 /// when extending explicitly-specified template argument packs per
272 /// C++0x [temp.arg.explicit]p9.
273 ///
274 /// \param NumExpansions The number of separate arguments that will be in
275 /// the expanded form of the corresponding pack expansion. This is both an
276 /// input and an output parameter, which can be set by the caller if the
277 /// number of expansions is known a priori (e.g., due to a prior substitution)
278 /// and will be set by the callee when the number of expansions is known.
279 /// The callee must set this value when \c ShouldExpand is \c true; it may
280 /// set this value in other cases.
281 ///
282 /// \returns true if an error occurred (e.g., because the parameter packs
283 /// are to be instantiated with arguments of different lengths), false
284 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
285 /// must be set.
287 SourceRange PatternRange,
289 bool &ShouldExpand, bool &RetainExpansion,
290 std::optional<unsigned> &NumExpansions) {
291 ShouldExpand = false;
292 return false;
293 }
294
295 /// "Forget" about the partially-substituted pack template argument,
296 /// when performing an instantiation that must preserve the parameter pack
297 /// use.
298 ///
299 /// This routine is meant to be overridden by the template instantiator.
301 return TemplateArgument();
302 }
303
304 /// "Remember" the partially-substituted pack template argument
305 /// after performing an instantiation that must preserve the parameter pack
306 /// use.
307 ///
308 /// This routine is meant to be overridden by the template instantiator.
310
311 /// Note to the derived class when a function parameter pack is
312 /// being expanded.
314
315 /// Transforms the given type into another type.
316 ///
317 /// By default, this routine transforms a type by creating a
318 /// TypeSourceInfo for it and delegating to the appropriate
319 /// function. This is expensive, but we don't mind, because
320 /// this method is deprecated anyway; all users should be
321 /// switched to storing TypeSourceInfos.
322 ///
323 /// \returns the transformed type.
325
326 /// Transforms the given type-with-location into a new
327 /// type-with-location.
328 ///
329 /// By default, this routine transforms a type by delegating to the
330 /// appropriate TransformXXXType to build a new type. Subclasses
331 /// may override this function (to take over all type
332 /// transformations) or some set of the TransformXXXType functions
333 /// to alter the transformation.
335
336 /// Transform the given type-with-location into a new
337 /// type, collecting location information in the given builder
338 /// as necessary.
339 ///
341
342 /// Transform a type that is permitted to produce a
343 /// DeducedTemplateSpecializationType.
344 ///
345 /// This is used in the (relatively rare) contexts where it is acceptable
346 /// for transformation to produce a class template type with deduced
347 /// template arguments.
348 /// @{
351 /// @}
352
353 /// The reason why the value of a statement is not discarded, if any.
358 };
359
360 /// Transform the given statement.
361 ///
362 /// By default, this routine transforms a statement by delegating to the
363 /// appropriate TransformXXXStmt function to transform a specific kind of
364 /// statement or the TransformExpr() function to transform an expression.
365 /// Subclasses may override this function to transform statements using some
366 /// other mechanism.
367 ///
368 /// \returns the transformed statement.
370
371 /// Transform the given statement.
372 ///
373 /// By default, this routine transforms a statement by delegating to the
374 /// appropriate TransformOMPXXXClause function to transform a specific kind
375 /// of clause. Subclasses may override this function to transform statements
376 /// using some other mechanism.
377 ///
378 /// \returns the transformed OpenMP clause.
380
381 /// Transform the given attribute.
382 ///
383 /// By default, this routine transforms a statement by delegating to the
384 /// appropriate TransformXXXAttr function to transform a specific kind
385 /// of attribute. Subclasses may override this function to transform
386 /// attributed statements/types using some other mechanism.
387 ///
388 /// \returns the transformed attribute
389 const Attr *TransformAttr(const Attr *S);
390
391 // Transform the given statement attribute.
392 //
393 // Delegates to the appropriate TransformXXXAttr function to transform a
394 // specific kind of statement attribute. Unlike the non-statement taking
395 // version of this, this implements all attributes, not just pragmas.
396 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
397 const Attr *A);
398
399 // Transform the specified attribute.
400 //
401 // Subclasses should override the transformation of attributes with a pragma
402 // spelling to transform expressions stored within the attribute.
403 //
404 // \returns the transformed attribute.
405#define ATTR(X) \
406 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
407#include "clang/Basic/AttrList.inc"
408
409 // Transform the specified attribute.
410 //
411 // Subclasses should override the transformation of attributes to do
412 // transformation and checking of statement attributes. By default, this
413 // delegates to the non-statement taking version.
414 //
415 // \returns the transformed attribute.
416#define ATTR(X) \
417 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
418 const X##Attr *A) { \
419 return getDerived().Transform##X##Attr(A); \
420 }
421#include "clang/Basic/AttrList.inc"
422
423 /// Transform the given expression.
424 ///
425 /// By default, this routine transforms an expression by delegating to the
426 /// appropriate TransformXXXExpr function to build a new expression.
427 /// Subclasses may override this function to transform expressions using some
428 /// other mechanism.
429 ///
430 /// \returns the transformed expression.
432
433 /// Transform the given initializer.
434 ///
435 /// By default, this routine transforms an initializer by stripping off the
436 /// semantic nodes added by initialization, then passing the result to
437 /// TransformExpr or TransformExprs.
438 ///
439 /// \returns the transformed initializer.
441
442 /// Transform the given list of expressions.
443 ///
444 /// This routine transforms a list of expressions by invoking
445 /// \c TransformExpr() for each subexpression. However, it also provides
446 /// support for variadic templates by expanding any pack expansions (if the
447 /// derived class permits such expansion) along the way. When pack expansions
448 /// are present, the number of outputs may not equal the number of inputs.
449 ///
450 /// \param Inputs The set of expressions to be transformed.
451 ///
452 /// \param NumInputs The number of expressions in \c Inputs.
453 ///
454 /// \param IsCall If \c true, then this transform is being performed on
455 /// function-call arguments, and any arguments that should be dropped, will
456 /// be.
457 ///
458 /// \param Outputs The transformed input expressions will be added to this
459 /// vector.
460 ///
461 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
462 /// due to transformation.
463 ///
464 /// \returns true if an error occurred, false otherwise.
465 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
467 bool *ArgChanged = nullptr);
468
469 /// Transform the given declaration, which is referenced from a type
470 /// or expression.
471 ///
472 /// By default, acts as the identity function on declarations, unless the
473 /// transformer has had to transform the declaration itself. Subclasses
474 /// may override this function to provide alternate behavior.
476 llvm::DenseMap<Decl *, Decl *>::iterator Known
477 = TransformedLocalDecls.find(D);
478 if (Known != TransformedLocalDecls.end())
479 return Known->second;
480
481 return D;
482 }
483
484 /// Transform the specified condition.
485 ///
486 /// By default, this transforms the variable and expression and rebuilds
487 /// the condition.
489 Expr *Expr,
491
492 /// Transform the attributes associated with the given declaration and
493 /// place them on the new declaration.
494 ///
495 /// By default, this operation does nothing. Subclasses may override this
496 /// behavior to transform attributes.
497 void transformAttrs(Decl *Old, Decl *New) { }
498
499 /// Note that a local declaration has been transformed by this
500 /// transformer.
501 ///
502 /// Local declarations are typically transformed via a call to
503 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
504 /// the transformer itself has to transform the declarations. This routine
505 /// can be overridden by a subclass that keeps track of such mappings.
507 assert(New.size() == 1 &&
508 "must override transformedLocalDecl if performing pack expansion");
509 TransformedLocalDecls[Old] = New.front();
510 }
511
512 /// Transform the definition of the given declaration.
513 ///
514 /// By default, invokes TransformDecl() to transform the declaration.
515 /// Subclasses may override this function to provide alternate behavior.
517 return getDerived().TransformDecl(Loc, D);
518 }
519
520 /// Transform the given declaration, which was the first part of a
521 /// nested-name-specifier in a member access expression.
522 ///
523 /// This specific declaration transformation only applies to the first
524 /// identifier in a nested-name-specifier of a member access expression, e.g.,
525 /// the \c T in \c x->T::member
526 ///
527 /// By default, invokes TransformDecl() to transform the declaration.
528 /// Subclasses may override this function to provide alternate behavior.
530 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
531 }
532
533 /// Transform the set of declarations in an OverloadExpr.
534 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
535 LookupResult &R);
536
537 /// Transform the given nested-name-specifier with source-location
538 /// information.
539 ///
540 /// By default, transforms all of the types and declarations within the
541 /// nested-name-specifier. Subclasses may override this function to provide
542 /// alternate behavior.
545 QualType ObjectType = QualType(),
546 NamedDecl *FirstQualifierInScope = nullptr);
547
548 /// Transform the given declaration name.
549 ///
550 /// By default, transforms the types of conversion function, constructor,
551 /// and destructor names and then (if needed) rebuilds the declaration name.
552 /// Identifiers and selectors are returned unmodified. Subclasses may
553 /// override this function to provide alternate behavior.
556
566
567 /// Transform the given template name.
568 ///
569 /// \param SS The nested-name-specifier that qualifies the template
570 /// name. This nested-name-specifier must already have been transformed.
571 ///
572 /// \param Name The template name to transform.
573 ///
574 /// \param NameLoc The source location of the template name.
575 ///
576 /// \param ObjectType If we're translating a template name within a member
577 /// access expression, this is the type of the object whose member template
578 /// is being referenced.
579 ///
580 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
581 /// also refers to a name within the current (lexical) scope, this is the
582 /// declaration it refers to.
583 ///
584 /// By default, transforms the template name by transforming the declarations
585 /// and nested-name-specifiers that occur within the template name.
586 /// Subclasses may override this function to provide alternate behavior.
589 SourceLocation NameLoc,
590 QualType ObjectType = QualType(),
591 NamedDecl *FirstQualifierInScope = nullptr,
592 bool AllowInjectedClassName = false);
593
594 /// Transform the given template argument.
595 ///
596 /// By default, this operation transforms the type, expression, or
597 /// declaration stored within the template argument and constructs a
598 /// new template argument from the transformed result. Subclasses may
599 /// override this function to provide alternate behavior.
600 ///
601 /// Returns true if there was an error.
603 TemplateArgumentLoc &Output,
604 bool Uneval = false);
605
606 /// Transform the given set of template arguments.
607 ///
608 /// By default, this operation transforms all of the template arguments
609 /// in the input set using \c TransformTemplateArgument(), and appends
610 /// the transformed arguments to the output list.
611 ///
612 /// Note that this overload of \c TransformTemplateArguments() is merely
613 /// a convenience function. Subclasses that wish to override this behavior
614 /// should override the iterator-based member template version.
615 ///
616 /// \param Inputs The set of template arguments to be transformed.
617 ///
618 /// \param NumInputs The number of template arguments in \p Inputs.
619 ///
620 /// \param Outputs The set of transformed template arguments output by this
621 /// routine.
622 ///
623 /// Returns true if an error occurred.
625 unsigned NumInputs,
627 bool Uneval = false) {
628 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
629 Uneval);
630 }
631
632 /// Transform the given set of template arguments.
633 ///
634 /// By default, this operation transforms all of the template arguments
635 /// in the input set using \c TransformTemplateArgument(), and appends
636 /// the transformed arguments to the output list.
637 ///
638 /// \param First An iterator to the first template argument.
639 ///
640 /// \param Last An iterator one step past the last template argument.
641 ///
642 /// \param Outputs The set of transformed template arguments output by this
643 /// routine.
644 ///
645 /// Returns true if an error occurred.
646 template<typename InputIterator>
648 InputIterator Last,
650 bool Uneval = false);
651
652 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
654 TemplateArgumentLoc &ArgLoc);
655
656 /// Fakes up a TypeSourceInfo for a type.
660 }
661
662#define ABSTRACT_TYPELOC(CLASS, PARENT)
663#define TYPELOC(CLASS, PARENT) \
664 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
665#include "clang/AST/TypeLocNodes.def"
666
669 bool SuppressObjCLifetime);
673 bool SuppressObjCLifetime);
674
675 template<typename Fn>
678 CXXRecordDecl *ThisContext,
679 Qualifiers ThisTypeQuals,
681
682 template <typename Fn>
684 Fn TransformModifiedType);
685
688 SmallVectorImpl<QualType> &Exceptions,
689 bool &Changed);
690
692
696 TemplateName Template);
697
701 TemplateName Template,
702 CXXScopeSpec &SS);
703
706 NestedNameSpecifierLoc QualifierLoc);
707
708 /// Transforms the parameters of a function type into the
709 /// given vectors.
710 ///
711 /// The result vectors should be kept in sync; null entries in the
712 /// variables vector are acceptable.
713 ///
714 /// LastParamTransformed, if non-null, will be set to the index of the last
715 /// parameter on which transfromation was started. In the event of an error,
716 /// this will contain the parameter which failed to instantiate.
717 ///
718 /// Return true on error.
721 const QualType *ParamTypes,
722 const FunctionProtoType::ExtParameterInfo *ParamInfos,
724 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
725
728 const QualType *ParamTypes,
729 const FunctionProtoType::ExtParameterInfo *ParamInfos,
732 return getDerived().TransformFunctionTypeParams(
733 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
734 }
735
736 /// Transforms the parameters of a requires expresison into the given vectors.
737 ///
738 /// The result vectors should be kept in sync; null entries in the
739 /// variables vector are acceptable.
740 ///
741 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
742 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
743 /// which are cases where transformation shouldn't continue.
745 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
751 KWLoc, Params, /*ParamTypes=*/nullptr,
752 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
753 return ExprError();
754
755 return ExprResult{};
756 }
757
758 /// Transforms a single function-type parameter. Return null
759 /// on error.
760 ///
761 /// \param indexAdjustment - A number to add to the parameter's
762 /// scope index; can be negative
764 int indexAdjustment,
765 std::optional<unsigned> NumExpansions,
766 bool ExpectParameterPack);
767
768 /// Transform the body of a lambda-expression.
770 /// Alternative implementation of TransformLambdaBody that skips transforming
771 /// the body.
773
776 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
778 }
779
781
784
787 return TPL;
788 }
789
791
793 bool IsAddressOfOperand,
794 TypeSourceInfo **RecoveryTSI);
795
797 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
798 TypeSourceInfo **RecoveryTSI);
799
801 bool IsAddressOfOperand);
802
804
805// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
806// amount of stack usage with clang.
807#define STMT(Node, Parent) \
808 LLVM_ATTRIBUTE_NOINLINE \
809 StmtResult Transform##Node(Node *S);
810#define VALUESTMT(Node, Parent) \
811 LLVM_ATTRIBUTE_NOINLINE \
812 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
813#define EXPR(Node, Parent) \
814 LLVM_ATTRIBUTE_NOINLINE \
815 ExprResult Transform##Node(Node *E);
816#define ABSTRACT_STMT(Stmt)
817#include "clang/AST/StmtNodes.inc"
818
819#define GEN_CLANG_CLAUSE_CLASS
820#define CLAUSE_CLASS(Enum, Str, Class) \
821 LLVM_ATTRIBUTE_NOINLINE \
822 OMPClause *Transform##Class(Class *S);
823#include "llvm/Frontend/OpenMP/OMP.inc"
824
825 /// Build a new qualified type given its unqualified type and type location.
826 ///
827 /// By default, this routine adds type qualifiers only to types that can
828 /// have qualifiers, and silently suppresses those qualifiers that are not
829 /// permitted. Subclasses may override this routine to provide different
830 /// behavior.
832
833 /// Build a new pointer type given its pointee type.
834 ///
835 /// By default, performs semantic analysis when building the pointer type.
836 /// Subclasses may override this routine to provide different behavior.
838
839 /// Build a new block pointer type given its pointee type.
840 ///
841 /// By default, performs semantic analysis when building the block pointer
842 /// type. Subclasses may override this routine to provide different behavior.
844
845 /// Build a new reference type given the type it references.
846 ///
847 /// By default, performs semantic analysis when building the
848 /// reference type. Subclasses may override this routine to provide
849 /// different behavior.
850 ///
851 /// \param LValue whether the type was written with an lvalue sigil
852 /// or an rvalue sigil.
854 bool LValue,
855 SourceLocation Sigil);
856
857 /// Build a new member pointer type given the pointee type and the
858 /// class type it refers into.
859 ///
860 /// By default, performs semantic analysis when building the member pointer
861 /// type. Subclasses may override this routine to provide different behavior.
863 SourceLocation Sigil);
864
866 SourceLocation ProtocolLAngleLoc,
868 ArrayRef<SourceLocation> ProtocolLocs,
869 SourceLocation ProtocolRAngleLoc);
870
871 /// Build an Objective-C object type.
872 ///
873 /// By default, performs semantic analysis when building the object type.
874 /// Subclasses may override this routine to provide different behavior.
877 SourceLocation TypeArgsLAngleLoc,
879 SourceLocation TypeArgsRAngleLoc,
880 SourceLocation ProtocolLAngleLoc,
882 ArrayRef<SourceLocation> ProtocolLocs,
883 SourceLocation ProtocolRAngleLoc);
884
885 /// Build a new Objective-C object pointer type given the pointee type.
886 ///
887 /// By default, directly builds the pointer type, with no additional semantic
888 /// analysis.
891
892 /// Build a new array type given the element type, size
893 /// modifier, size of the array (if known), size expression, and index type
894 /// qualifiers.
895 ///
896 /// By default, performs semantic analysis when building the array type.
897 /// Subclasses may override this routine to provide different behavior.
898 /// Also by default, all of the other Rebuild*Array
900 const llvm::APInt *Size, Expr *SizeExpr,
901 unsigned IndexTypeQuals, SourceRange BracketsRange);
902
903 /// Build a new constant array type given the element type, size
904 /// modifier, (known) size of the array, and index type qualifiers.
905 ///
906 /// By default, performs semantic analysis when building the array type.
907 /// Subclasses may override this routine to provide different behavior.
909 ArraySizeModifier SizeMod,
910 const llvm::APInt &Size, Expr *SizeExpr,
911 unsigned IndexTypeQuals,
912 SourceRange BracketsRange);
913
914 /// Build a new incomplete array type given the element type, size
915 /// modifier, and index type qualifiers.
916 ///
917 /// By default, performs semantic analysis when building the array type.
918 /// Subclasses may override this routine to provide different behavior.
920 ArraySizeModifier SizeMod,
921 unsigned IndexTypeQuals,
922 SourceRange BracketsRange);
923
924 /// Build a new variable-length array type given the element type,
925 /// size modifier, size expression, and index type qualifiers.
926 ///
927 /// By default, performs semantic analysis when building the array type.
928 /// Subclasses may override this routine to provide different behavior.
930 ArraySizeModifier SizeMod, Expr *SizeExpr,
931 unsigned IndexTypeQuals,
932 SourceRange BracketsRange);
933
934 /// Build a new dependent-sized array type given the element type,
935 /// size modifier, size expression, and index type qualifiers.
936 ///
937 /// By default, performs semantic analysis when building the array type.
938 /// Subclasses may override this routine to provide different behavior.
940 ArraySizeModifier SizeMod,
941 Expr *SizeExpr,
942 unsigned IndexTypeQuals,
943 SourceRange BracketsRange);
944
945 /// Build a new vector type given the element type and
946 /// number of elements.
947 ///
948 /// By default, performs semantic analysis when building the vector type.
949 /// Subclasses may override this routine to provide different behavior.
950 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
951 VectorKind VecKind);
952
953 /// Build a new potentially dependently-sized extended vector type
954 /// given the element type and number of elements.
955 ///
956 /// By default, performs semantic analysis when building the vector type.
957 /// Subclasses may override this routine to provide different behavior.
959 SourceLocation AttributeLoc, VectorKind);
960
961 /// Build a new extended vector type given the element type and
962 /// number of elements.
963 ///
964 /// By default, performs semantic analysis when building the vector type.
965 /// Subclasses may override this routine to provide different behavior.
966 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
967 SourceLocation AttributeLoc);
968
969 /// Build a new potentially dependently-sized extended vector type
970 /// given the element type and number of elements.
971 ///
972 /// By default, performs semantic analysis when building the vector type.
973 /// Subclasses may override this routine to provide different behavior.
975 Expr *SizeExpr,
976 SourceLocation AttributeLoc);
977
978 /// Build a new matrix type given the element type and dimensions.
979 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
980 unsigned NumColumns);
981
982 /// Build a new matrix type given the type and dependently-defined
983 /// dimensions.
985 Expr *ColumnExpr,
986 SourceLocation AttributeLoc);
987
988 /// Build a new DependentAddressSpaceType or return the pointee
989 /// type variable with the correct address space (retrieved from
990 /// AddrSpaceExpr) applied to it. The former will be returned in cases
991 /// where the address space remains dependent.
992 ///
993 /// By default, performs semantic analysis when building the type with address
994 /// space applied. Subclasses may override this routine to provide different
995 /// behavior.
997 Expr *AddrSpaceExpr,
998 SourceLocation AttributeLoc);
999
1000 /// Build a new function type.
1001 ///
1002 /// By default, performs semantic analysis when building the function type.
1003 /// Subclasses may override this routine to provide different behavior.
1005 MutableArrayRef<QualType> ParamTypes,
1007
1008 /// Build a new unprototyped function type.
1010
1011 /// Rebuild an unresolved typename type, given the decl that
1012 /// the UnresolvedUsingTypenameDecl was transformed to.
1014
1015 /// Build a new type found via an alias.
1017 return SemaRef.Context.getUsingType(Found, Underlying);
1018 }
1019
1020 /// Build a new typedef type.
1022 return SemaRef.Context.getTypeDeclType(Typedef);
1023 }
1024
1025 /// Build a new MacroDefined type.
1027 const IdentifierInfo *MacroII) {
1028 return SemaRef.Context.getMacroQualifiedType(T, MacroII);
1029 }
1030
1031 /// Build a new class/struct/union type.
1034 }
1035
1036 /// Build a new Enum type.
1039 }
1040
1041 /// Build a new typeof(expr) type.
1042 ///
1043 /// By default, performs semantic analysis when building the typeof type.
1044 /// Subclasses may override this routine to provide different behavior.
1046 TypeOfKind Kind);
1047
1048 /// Build a new typeof(type) type.
1049 ///
1050 /// By default, builds a new TypeOfType with the given underlying type.
1052
1053 /// Build a new unary transform type.
1057
1058 /// Build a new C++11 decltype type.
1059 ///
1060 /// By default, performs semantic analysis when building the decltype type.
1061 /// Subclasses may override this routine to provide different behavior.
1063
1066 SourceLocation EllipsisLoc,
1067 bool FullySubstituted,
1068 ArrayRef<QualType> Expansions = {});
1069
1070 /// Build a new C++11 auto type.
1071 ///
1072 /// By default, builds a new AutoType with the given deduced type.
1074 ConceptDecl *TypeConstraintConcept,
1075 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1076 // Note, IsDependent is always false here: we implicitly convert an 'auto'
1077 // which has been deduced to a dependent type into an undeduced 'auto', so
1078 // that we'll retry deduction after the transformation.
1079 return SemaRef.Context.getAutoType(Deduced, Keyword,
1080 /*IsDependent*/ false, /*IsPack=*/false,
1081 TypeConstraintConcept,
1082 TypeConstraintArgs);
1083 }
1084
1085 /// By default, builds a new DeducedTemplateSpecializationType with the given
1086 /// deduced type.
1088 QualType Deduced) {
1090 Template, Deduced, /*IsDependent*/ false);
1091 }
1092
1093 /// Build a new template specialization type.
1094 ///
1095 /// By default, performs semantic analysis when building the template
1096 /// specialization type. Subclasses may override this routine to provide
1097 /// different behavior.
1099 SourceLocation TemplateLoc,
1101
1102 /// Build a new parenthesized type.
1103 ///
1104 /// By default, builds a new ParenType type from the inner type.
1105 /// Subclasses may override this routine to provide different behavior.
1107 return SemaRef.BuildParenType(InnerType);
1108 }
1109
1110 /// Build a new qualified name type.
1111 ///
1112 /// By default, builds a new ElaboratedType type from the keyword,
1113 /// the nested-name-specifier and the named type.
1114 /// Subclasses may override this routine to provide different behavior.
1116 ElaboratedTypeKeyword Keyword,
1117 NestedNameSpecifierLoc QualifierLoc,
1118 QualType Named) {
1119 return SemaRef.Context.getElaboratedType(Keyword,
1120 QualifierLoc.getNestedNameSpecifier(),
1121 Named);
1122 }
1123
1124 /// Build a new typename type that refers to a template-id.
1125 ///
1126 /// By default, builds a new DependentNameType type from the
1127 /// nested-name-specifier and the given type. Subclasses may override
1128 /// this routine to provide different behavior.
1130 ElaboratedTypeKeyword Keyword,
1131 NestedNameSpecifierLoc QualifierLoc,
1132 SourceLocation TemplateKWLoc,
1133 const IdentifierInfo *Name,
1134 SourceLocation NameLoc,
1136 bool AllowInjectedClassName) {
1137 // Rebuild the template name.
1138 // TODO: avoid TemplateName abstraction
1139 CXXScopeSpec SS;
1140 SS.Adopt(QualifierLoc);
1141 TemplateName InstName = getDerived().RebuildTemplateName(
1142 SS, TemplateKWLoc, *Name, NameLoc, QualType(), nullptr,
1143 AllowInjectedClassName);
1144
1145 if (InstName.isNull())
1146 return QualType();
1147
1148 // If it's still dependent, make a dependent specialization.
1149 if (InstName.getAsDependentTemplateName())
1151 Keyword, QualifierLoc.getNestedNameSpecifier(), Name,
1152 Args.arguments());
1153
1154 // Otherwise, make an elaborated type wrapping a non-dependent
1155 // specialization.
1156 QualType T =
1157 getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
1158 if (T.isNull())
1159 return QualType();
1161 Keyword, QualifierLoc.getNestedNameSpecifier(), T);
1162 }
1163
1164 /// Build a new typename type that refers to an identifier.
1165 ///
1166 /// By default, performs semantic analysis when building the typename type
1167 /// (or elaborated type). Subclasses may override this routine to provide
1168 /// different behavior.
1170 SourceLocation KeywordLoc,
1171 NestedNameSpecifierLoc QualifierLoc,
1172 const IdentifierInfo *Id,
1173 SourceLocation IdLoc,
1174 bool DeducedTSTContext) {
1175 CXXScopeSpec SS;
1176 SS.Adopt(QualifierLoc);
1177
1178 if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
1179 // If the name is still dependent, just build a new dependent name type.
1180 if (!SemaRef.computeDeclContext(SS))
1181 return SemaRef.Context.getDependentNameType(Keyword,
1182 QualifierLoc.getNestedNameSpecifier(),
1183 Id);
1184 }
1185
1186 if (Keyword == ElaboratedTypeKeyword::None ||
1188 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1189 *Id, IdLoc, DeducedTSTContext);
1190 }
1191
1193
1194 // We had a dependent elaborated-type-specifier that has been transformed
1195 // into a non-dependent elaborated-type-specifier. Find the tag we're
1196 // referring to.
1198 DeclContext *DC = SemaRef.computeDeclContext(SS, false);
1199 if (!DC)
1200 return QualType();
1201
1203 return QualType();
1204
1205 TagDecl *Tag = nullptr;
1207 switch (Result.getResultKind()) {
1210 break;
1211
1213 Tag = Result.getAsSingle<TagDecl>();
1214 break;
1215
1218 llvm_unreachable("Tag lookup cannot find non-tags");
1219
1221 // Let the LookupResult structure handle ambiguities.
1222 return QualType();
1223 }
1224
1225 if (!Tag) {
1226 // Check where the name exists but isn't a tag type and use that to emit
1227 // better diagnostics.
1230 switch (Result.getResultKind()) {
1234 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1235 Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind);
1236 SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag)
1237 << SomeDecl << NTK << llvm::to_underlying(Kind);
1238 SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
1239 break;
1240 }
1241 default:
1242 SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
1243 << llvm::to_underlying(Kind) << Id << DC
1244 << QualifierLoc.getSourceRange();
1245 break;
1246 }
1247 return QualType();
1248 }
1249
1250 if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false,
1251 IdLoc, Id)) {
1252 SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
1253 SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
1254 return QualType();
1255 }
1256
1257 // Build the elaborated-type-specifier type.
1259 return SemaRef.Context.getElaboratedType(Keyword,
1260 QualifierLoc.getNestedNameSpecifier(),
1261 T);
1262 }
1263
1264 /// Build a new pack expansion type.
1265 ///
1266 /// By default, builds a new PackExpansionType type from the given pattern.
1267 /// Subclasses may override this routine to provide different behavior.
1269 SourceLocation EllipsisLoc,
1270 std::optional<unsigned> NumExpansions) {
1271 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1272 NumExpansions);
1273 }
1274
1275 /// Build a new atomic type given its value type.
1276 ///
1277 /// By default, performs semantic analysis when building the atomic type.
1278 /// Subclasses may override this routine to provide different behavior.
1280
1281 /// Build a new pipe type given its value type.
1283 bool isReadPipe);
1284
1285 /// Build a bit-precise int given its value type.
1286 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1288
1289 /// Build a dependent bit-precise int given its value type.
1290 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1292
1293 /// Build a new template name given a nested name specifier, a flag
1294 /// indicating whether the "template" keyword was provided, and the template
1295 /// that the template name refers to.
1296 ///
1297 /// By default, builds the new template name directly. Subclasses may override
1298 /// this routine to provide different behavior.
1300 bool TemplateKW,
1301 TemplateDecl *Template);
1302
1303 /// Build a new template name given a nested name specifier and the
1304 /// name that is referred to as a template.
1305 ///
1306 /// By default, performs semantic analysis to determine whether the name can
1307 /// be resolved to a specific template, then builds the appropriate kind of
1308 /// template name. Subclasses may override this routine to provide different
1309 /// behavior.
1311 SourceLocation TemplateKWLoc,
1312 const IdentifierInfo &Name,
1313 SourceLocation NameLoc, QualType ObjectType,
1314 NamedDecl *FirstQualifierInScope,
1315 bool AllowInjectedClassName);
1316
1317 /// Build a new template name given a nested name specifier and the
1318 /// overloaded operator name that is referred to as a template.
1319 ///
1320 /// By default, performs semantic analysis to determine whether the name can
1321 /// be resolved to a specific template, then builds the appropriate kind of
1322 /// template name. Subclasses may override this routine to provide different
1323 /// behavior.
1325 SourceLocation TemplateKWLoc,
1326 OverloadedOperatorKind Operator,
1327 SourceLocation NameLoc, QualType ObjectType,
1328 bool AllowInjectedClassName);
1329
1330 /// Build a new template name given a template template parameter pack
1331 /// and the
1332 ///
1333 /// By default, performs semantic analysis to determine whether the name can
1334 /// be resolved to a specific template, then builds the appropriate kind of
1335 /// template name. Subclasses may override this routine to provide different
1336 /// behavior.
1338 Decl *AssociatedDecl, unsigned Index,
1339 bool Final) {
1341 ArgPack, AssociatedDecl, Index, Final);
1342 }
1343
1344 /// Build a new compound statement.
1345 ///
1346 /// By default, performs semantic analysis to build the new statement.
1347 /// Subclasses may override this routine to provide different behavior.
1349 MultiStmtArg Statements,
1350 SourceLocation RBraceLoc,
1351 bool IsStmtExpr) {
1352 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1353 IsStmtExpr);
1354 }
1355
1356 /// Build a new case statement.
1357 ///
1358 /// By default, performs semantic analysis to build the new statement.
1359 /// Subclasses may override this routine to provide different behavior.
1361 Expr *LHS,
1362 SourceLocation EllipsisLoc,
1363 Expr *RHS,
1364 SourceLocation ColonLoc) {
1365 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1366 ColonLoc);
1367 }
1368
1369 /// Attach the body to a new case statement.
1370 ///
1371 /// By default, performs semantic analysis to build the new statement.
1372 /// Subclasses may override this routine to provide different behavior.
1374 getSema().ActOnCaseStmtBody(S, Body);
1375 return S;
1376 }
1377
1378 /// Build a new default statement.
1379 ///
1380 /// By default, performs semantic analysis to build the new statement.
1381 /// Subclasses may override this routine to provide different behavior.
1383 SourceLocation ColonLoc,
1384 Stmt *SubStmt) {
1385 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1386 /*CurScope=*/nullptr);
1387 }
1388
1389 /// Build a new label statement.
1390 ///
1391 /// By default, performs semantic analysis to build the new statement.
1392 /// Subclasses may override this routine to provide different behavior.
1394 SourceLocation ColonLoc, Stmt *SubStmt) {
1395 return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt);
1396 }
1397
1398 /// Build a new attributed statement.
1399 ///
1400 /// By default, performs semantic analysis to build the new statement.
1401 /// Subclasses may override this routine to provide different behavior.
1404 Stmt *SubStmt) {
1406 return StmtError();
1407 return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt);
1408 }
1409
1410 /// Build a new "if" statement.
1411 ///
1412 /// By default, performs semantic analysis to build the new statement.
1413 /// Subclasses may override this routine to provide different behavior.
1415 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1416 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1417 SourceLocation ElseLoc, Stmt *Else) {
1418 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1419 Then, ElseLoc, Else);
1420 }
1421
1422 /// Start building a new switch statement.
1423 ///
1424 /// By default, performs semantic analysis to build the new statement.
1425 /// Subclasses may override this routine to provide different behavior.
1427 SourceLocation LParenLoc, Stmt *Init,
1429 SourceLocation RParenLoc) {
1430 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1431 RParenLoc);
1432 }
1433
1434 /// Attach the body to the switch statement.
1435 ///
1436 /// By default, performs semantic analysis to build the new statement.
1437 /// Subclasses may override this routine to provide different behavior.
1439 Stmt *Switch, Stmt *Body) {
1440 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1441 }
1442
1443 /// Build a new while statement.
1444 ///
1445 /// By default, performs semantic analysis to build the new statement.
1446 /// Subclasses may override this routine to provide different behavior.
1449 SourceLocation RParenLoc, Stmt *Body) {
1450 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1451 }
1452
1453 /// Build a new do-while statement.
1454 ///
1455 /// By default, performs semantic analysis to build the new statement.
1456 /// Subclasses may override this routine to provide different behavior.
1458 SourceLocation WhileLoc, SourceLocation LParenLoc,
1459 Expr *Cond, SourceLocation RParenLoc) {
1460 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1461 Cond, RParenLoc);
1462 }
1463
1464 /// Build a new for statement.
1465 ///
1466 /// By default, performs semantic analysis to build the new statement.
1467 /// Subclasses may override this routine to provide different behavior.
1470 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1471 Stmt *Body) {
1472 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1473 Inc, RParenLoc, Body);
1474 }
1475
1476 /// Build a new goto statement.
1477 ///
1478 /// By default, performs semantic analysis to build the new statement.
1479 /// Subclasses may override this routine to provide different behavior.
1481 LabelDecl *Label) {
1482 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1483 }
1484
1485 /// Build a new indirect goto statement.
1486 ///
1487 /// By default, performs semantic analysis to build the new statement.
1488 /// Subclasses may override this routine to provide different behavior.
1490 SourceLocation StarLoc,
1491 Expr *Target) {
1492 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1493 }
1494
1495 /// Build a new return statement.
1496 ///
1497 /// By default, performs semantic analysis to build the new statement.
1498 /// Subclasses may override this routine to provide different behavior.
1500 return getSema().BuildReturnStmt(ReturnLoc, Result);
1501 }
1502
1503 /// Build a new declaration statement.
1504 ///
1505 /// By default, performs semantic analysis to build the new statement.
1506 /// Subclasses may override this routine to provide different behavior.
1508 SourceLocation StartLoc, SourceLocation EndLoc) {
1510 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1511 }
1512
1513 /// Build a new inline asm statement.
1514 ///
1515 /// By default, performs semantic analysis to build the new statement.
1516 /// Subclasses may override this routine to provide different behavior.
1518 bool IsVolatile, unsigned NumOutputs,
1519 unsigned NumInputs, IdentifierInfo **Names,
1520 MultiExprArg Constraints, MultiExprArg Exprs,
1521 Expr *AsmString, MultiExprArg Clobbers,
1522 unsigned NumLabels,
1523 SourceLocation RParenLoc) {
1524 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1525 NumInputs, Names, Constraints, Exprs,
1526 AsmString, Clobbers, NumLabels, RParenLoc);
1527 }
1528
1529 /// Build a new MS style inline asm statement.
1530 ///
1531 /// By default, performs semantic analysis to build the new statement.
1532 /// Subclasses may override this routine to provide different behavior.
1534 ArrayRef<Token> AsmToks,
1535 StringRef AsmString,
1536 unsigned NumOutputs, unsigned NumInputs,
1537 ArrayRef<StringRef> Constraints,
1538 ArrayRef<StringRef> Clobbers,
1539 ArrayRef<Expr*> Exprs,
1540 SourceLocation EndLoc) {
1541 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1542 NumOutputs, NumInputs,
1543 Constraints, Clobbers, Exprs, EndLoc);
1544 }
1545
1546 /// Build a new co_return statement.
1547 ///
1548 /// By default, performs semantic analysis to build the new statement.
1549 /// Subclasses may override this routine to provide different behavior.
1551 bool IsImplicit) {
1552 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1553 }
1554
1555 /// Build a new co_await expression.
1556 ///
1557 /// By default, performs semantic analysis to build the new expression.
1558 /// Subclasses may override this routine to provide different behavior.
1560 UnresolvedLookupExpr *OpCoawaitLookup,
1561 bool IsImplicit) {
1562 // This function rebuilds a coawait-expr given its operator.
1563 // For an explicit coawait-expr, the rebuild involves the full set
1564 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1565 // including calling await_transform().
1566 // For an implicit coawait-expr, we need to rebuild the "operator
1567 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1568 // This mirrors how the implicit CoawaitExpr is originally created
1569 // in Sema::ActOnCoroutineBodyStart().
1570 if (IsImplicit) {
1572 CoawaitLoc, Operand, OpCoawaitLookup);
1573 if (Suspend.isInvalid())
1574 return ExprError();
1575 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1576 Suspend.get(), true);
1577 }
1578
1579 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1580 OpCoawaitLookup);
1581 }
1582
1583 /// Build a new co_await expression.
1584 ///
1585 /// By default, performs semantic analysis to build the new expression.
1586 /// Subclasses may override this routine to provide different behavior.
1588 Expr *Result,
1589 UnresolvedLookupExpr *Lookup) {
1590 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1591 }
1592
1593 /// Build a new co_yield expression.
1594 ///
1595 /// By default, performs semantic analysis to build the new expression.
1596 /// Subclasses may override this routine to provide different behavior.
1598 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1599 }
1600
1602 return getSema().BuildCoroutineBodyStmt(Args);
1603 }
1604
1605 /// Build a new Objective-C \@try statement.
1606 ///
1607 /// By default, performs semantic analysis to build the new statement.
1608 /// Subclasses may override this routine to provide different behavior.
1610 Stmt *TryBody,
1611 MultiStmtArg CatchStmts,
1612 Stmt *Finally) {
1613 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1614 Finally);
1615 }
1616
1617 /// Rebuild an Objective-C exception declaration.
1618 ///
1619 /// By default, performs semantic analysis to build the new declaration.
1620 /// Subclasses may override this routine to provide different behavior.
1622 TypeSourceInfo *TInfo, QualType T) {
1624 TInfo, T, ExceptionDecl->getInnerLocStart(),
1625 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1626 }
1627
1628 /// Build a new Objective-C \@catch statement.
1629 ///
1630 /// By default, performs semantic analysis to build the new statement.
1631 /// Subclasses may override this routine to provide different behavior.
1633 SourceLocation RParenLoc,
1634 VarDecl *Var,
1635 Stmt *Body) {
1636 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1637 }
1638
1639 /// Build a new Objective-C \@finally statement.
1640 ///
1641 /// By default, performs semantic analysis to build the new statement.
1642 /// Subclasses may override this routine to provide different behavior.
1644 Stmt *Body) {
1645 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1646 }
1647
1648 /// Build a new Objective-C \@throw statement.
1649 ///
1650 /// By default, performs semantic analysis to build the new statement.
1651 /// Subclasses may override this routine to provide different behavior.
1653 Expr *Operand) {
1654 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1655 }
1656
1657 /// Build a new OpenMP Canonical loop.
1658 ///
1659 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1660 /// OMPCanonicalLoop.
1662 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1663 }
1664
1665 /// Build a new OpenMP executable directive.
1666 ///
1667 /// By default, performs semantic analysis to build the new statement.
1668 /// Subclasses may override this routine to provide different behavior.
1671 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
1672 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
1673 OpenMPDirectiveKind PrevMappedDirective = OMPD_unknown) {
1674
1676 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc,
1677 PrevMappedDirective);
1678 }
1679
1680 /// Build a new OpenMP 'if' clause.
1681 ///
1682 /// By default, performs semantic analysis to build the new OpenMP clause.
1683 /// Subclasses may override this routine to provide different behavior.
1685 Expr *Condition, SourceLocation StartLoc,
1686 SourceLocation LParenLoc,
1687 SourceLocation NameModifierLoc,
1688 SourceLocation ColonLoc,
1689 SourceLocation EndLoc) {
1691 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1692 EndLoc);
1693 }
1694
1695 /// Build a new OpenMP 'final' clause.
1696 ///
1697 /// By default, performs semantic analysis to build the new OpenMP clause.
1698 /// Subclasses may override this routine to provide different behavior.
1700 SourceLocation LParenLoc,
1701 SourceLocation EndLoc) {
1702 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1703 LParenLoc, EndLoc);
1704 }
1705
1706 /// Build a new OpenMP 'num_threads' clause.
1707 ///
1708 /// By default, performs semantic analysis to build the new OpenMP clause.
1709 /// Subclasses may override this routine to provide different behavior.
1711 SourceLocation StartLoc,
1712 SourceLocation LParenLoc,
1713 SourceLocation EndLoc) {
1714 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc,
1715 LParenLoc, EndLoc);
1716 }
1717
1718 /// Build a new OpenMP 'safelen' clause.
1719 ///
1720 /// By default, performs semantic analysis to build the new OpenMP clause.
1721 /// Subclasses may override this routine to provide different behavior.
1723 SourceLocation LParenLoc,
1724 SourceLocation EndLoc) {
1725 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1726 EndLoc);
1727 }
1728
1729 /// Build a new OpenMP 'simdlen' clause.
1730 ///
1731 /// By default, performs semantic analysis to build the new OpenMP clause.
1732 /// Subclasses may override this routine to provide different behavior.
1734 SourceLocation LParenLoc,
1735 SourceLocation EndLoc) {
1736 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1737 EndLoc);
1738 }
1739
1741 SourceLocation StartLoc,
1742 SourceLocation LParenLoc,
1743 SourceLocation EndLoc) {
1744 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1745 EndLoc);
1746 }
1747
1748 /// Build a new OpenMP 'full' clause.
1750 SourceLocation EndLoc) {
1751 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1752 }
1753
1754 /// Build a new OpenMP 'partial' clause.
1756 SourceLocation LParenLoc,
1757 SourceLocation EndLoc) {
1758 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1759 LParenLoc, EndLoc);
1760 }
1761
1762 /// Build a new OpenMP 'allocator' clause.
1763 ///
1764 /// By default, performs semantic analysis to build the new OpenMP clause.
1765 /// Subclasses may override this routine to provide different behavior.
1767 SourceLocation LParenLoc,
1768 SourceLocation EndLoc) {
1769 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1770 EndLoc);
1771 }
1772
1773 /// Build a new OpenMP 'collapse' clause.
1774 ///
1775 /// By default, performs semantic analysis to build the new OpenMP clause.
1776 /// Subclasses may override this routine to provide different behavior.
1778 SourceLocation LParenLoc,
1779 SourceLocation EndLoc) {
1780 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1781 LParenLoc, EndLoc);
1782 }
1783
1784 /// Build a new OpenMP 'default' clause.
1785 ///
1786 /// By default, performs semantic analysis to build the new OpenMP clause.
1787 /// Subclasses may override this routine to provide different behavior.
1789 SourceLocation StartLoc,
1790 SourceLocation LParenLoc,
1791 SourceLocation EndLoc) {
1793 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1794 }
1795
1796 /// Build a new OpenMP 'proc_bind' clause.
1797 ///
1798 /// By default, performs semantic analysis to build the new OpenMP clause.
1799 /// Subclasses may override this routine to provide different behavior.
1801 SourceLocation KindKwLoc,
1802 SourceLocation StartLoc,
1803 SourceLocation LParenLoc,
1804 SourceLocation EndLoc) {
1806 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1807 }
1808
1809 /// Build a new OpenMP 'schedule' clause.
1810 ///
1811 /// By default, performs semantic analysis to build the new OpenMP clause.
1812 /// Subclasses may override this routine to provide different behavior.
1815 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1816 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1817 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1819 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1820 CommaLoc, EndLoc);
1821 }
1822
1823 /// Build a new OpenMP 'ordered' clause.
1824 ///
1825 /// By default, performs semantic analysis to build the new OpenMP clause.
1826 /// Subclasses may override this routine to provide different behavior.
1828 SourceLocation EndLoc,
1829 SourceLocation LParenLoc, Expr *Num) {
1830 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1831 LParenLoc, Num);
1832 }
1833
1834 /// Build a new OpenMP 'private' clause.
1835 ///
1836 /// By default, performs semantic analysis to build the new OpenMP clause.
1837 /// Subclasses may override this routine to provide different behavior.
1839 SourceLocation StartLoc,
1840 SourceLocation LParenLoc,
1841 SourceLocation EndLoc) {
1842 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1843 LParenLoc, EndLoc);
1844 }
1845
1846 /// Build a new OpenMP 'firstprivate' clause.
1847 ///
1848 /// By default, performs semantic analysis to build the new OpenMP clause.
1849 /// Subclasses may override this routine to provide different behavior.
1851 SourceLocation StartLoc,
1852 SourceLocation LParenLoc,
1853 SourceLocation EndLoc) {
1854 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1855 LParenLoc, EndLoc);
1856 }
1857
1858 /// Build a new OpenMP 'lastprivate' clause.
1859 ///
1860 /// By default, performs semantic analysis to build the new OpenMP clause.
1861 /// Subclasses may override this routine to provide different behavior.
1864 SourceLocation LPKindLoc,
1865 SourceLocation ColonLoc,
1866 SourceLocation StartLoc,
1867 SourceLocation LParenLoc,
1868 SourceLocation EndLoc) {
1870 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1871 }
1872
1873 /// Build a new OpenMP 'shared' clause.
1874 ///
1875 /// By default, performs semantic analysis to build the new OpenMP clause.
1876 /// Subclasses may override this routine to provide different behavior.
1878 SourceLocation StartLoc,
1879 SourceLocation LParenLoc,
1880 SourceLocation EndLoc) {
1881 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1882 LParenLoc, EndLoc);
1883 }
1884
1885 /// Build a new OpenMP 'reduction' clause.
1886 ///
1887 /// By default, performs semantic analysis to build the new statement.
1888 /// Subclasses may override this routine to provide different behavior.
1891 SourceLocation StartLoc, SourceLocation LParenLoc,
1892 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1893 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1894 const DeclarationNameInfo &ReductionId,
1895 ArrayRef<Expr *> UnresolvedReductions) {
1897 VarList, Modifier, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
1898 ReductionIdScopeSpec, ReductionId, UnresolvedReductions);
1899 }
1900
1901 /// Build a new OpenMP 'task_reduction' clause.
1902 ///
1903 /// By default, performs semantic analysis to build the new statement.
1904 /// Subclasses may override this routine to provide different behavior.
1906 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1907 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1908 CXXScopeSpec &ReductionIdScopeSpec,
1909 const DeclarationNameInfo &ReductionId,
1910 ArrayRef<Expr *> UnresolvedReductions) {
1912 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1913 ReductionId, UnresolvedReductions);
1914 }
1915
1916 /// Build a new OpenMP 'in_reduction' clause.
1917 ///
1918 /// By default, performs semantic analysis to build the new statement.
1919 /// Subclasses may override this routine to provide different behavior.
1920 OMPClause *
1922 SourceLocation LParenLoc, SourceLocation ColonLoc,
1923 SourceLocation EndLoc,
1924 CXXScopeSpec &ReductionIdScopeSpec,
1925 const DeclarationNameInfo &ReductionId,
1926 ArrayRef<Expr *> UnresolvedReductions) {
1928 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1929 ReductionId, UnresolvedReductions);
1930 }
1931
1932 /// Build a new OpenMP 'linear' clause.
1933 ///
1934 /// By default, performs semantic analysis to build the new OpenMP clause.
1935 /// Subclasses may override this routine to provide different behavior.
1937 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1938 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1939 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1940 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
1942 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
1943 StepModifierLoc, EndLoc);
1944 }
1945
1946 /// Build a new OpenMP 'aligned' clause.
1947 ///
1948 /// By default, performs semantic analysis to build the new OpenMP clause.
1949 /// Subclasses may override this routine to provide different behavior.
1951 SourceLocation StartLoc,
1952 SourceLocation LParenLoc,
1953 SourceLocation ColonLoc,
1954 SourceLocation EndLoc) {
1956 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
1957 }
1958
1959 /// Build a new OpenMP 'copyin' clause.
1960 ///
1961 /// By default, performs semantic analysis to build the new OpenMP clause.
1962 /// Subclasses may override this routine to provide different behavior.
1964 SourceLocation StartLoc,
1965 SourceLocation LParenLoc,
1966 SourceLocation EndLoc) {
1967 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
1968 LParenLoc, EndLoc);
1969 }
1970
1971 /// Build a new OpenMP 'copyprivate' 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 EndLoc) {
1979 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
1980 LParenLoc, EndLoc);
1981 }
1982
1983 /// Build a new OpenMP 'flush' pseudo clause.
1984 ///
1985 /// By default, performs semantic analysis to build the new OpenMP clause.
1986 /// Subclasses may override this routine to provide different behavior.
1988 SourceLocation StartLoc,
1989 SourceLocation LParenLoc,
1990 SourceLocation EndLoc) {
1991 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
1992 LParenLoc, EndLoc);
1993 }
1994
1995 /// Build a new OpenMP 'depobj' pseudo clause.
1996 ///
1997 /// By default, performs semantic analysis to build the new OpenMP clause.
1998 /// Subclasses may override this routine to provide different behavior.
2000 SourceLocation LParenLoc,
2001 SourceLocation EndLoc) {
2002 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2003 LParenLoc, EndLoc);
2004 }
2005
2006 /// Build a new OpenMP 'depend' pseudo clause.
2007 ///
2008 /// By default, performs semantic analysis to build the new OpenMP clause.
2009 /// Subclasses may override this routine to provide different behavior.
2011 Expr *DepModifier, ArrayRef<Expr *> VarList,
2012 SourceLocation StartLoc,
2013 SourceLocation LParenLoc,
2014 SourceLocation EndLoc) {
2016 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2017 }
2018
2019 /// Build a new OpenMP 'device' clause.
2020 ///
2021 /// By default, performs semantic analysis to build the new statement.
2022 /// Subclasses may override this routine to provide different behavior.
2024 Expr *Device, SourceLocation StartLoc,
2025 SourceLocation LParenLoc,
2026 SourceLocation ModifierLoc,
2027 SourceLocation EndLoc) {
2029 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2030 }
2031
2032 /// Build a new OpenMP 'map' clause.
2033 ///
2034 /// By default, performs semantic analysis to build the new OpenMP clause.
2035 /// Subclasses may override this routine to provide different behavior.
2037 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2038 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2039 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2040 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2041 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2042 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2044 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2045 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2046 ColonLoc, VarList, Locs,
2047 /*NoDiagnose=*/false, UnresolvedMappers);
2048 }
2049
2050 /// Build a new OpenMP 'allocate' clause.
2051 ///
2052 /// By default, performs semantic analysis to build the new OpenMP clause.
2053 /// Subclasses may override this routine to provide different behavior.
2055 SourceLocation StartLoc,
2056 SourceLocation LParenLoc,
2057 SourceLocation ColonLoc,
2058 SourceLocation EndLoc) {
2060 Allocate, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2061 }
2062
2063 /// Build a new OpenMP 'num_teams' clause.
2064 ///
2065 /// By default, performs semantic analysis to build the new statement.
2066 /// Subclasses may override this routine to provide different behavior.
2068 SourceLocation LParenLoc,
2069 SourceLocation EndLoc) {
2070 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(NumTeams, StartLoc,
2071 LParenLoc, EndLoc);
2072 }
2073
2074 /// Build a new OpenMP 'thread_limit' clause.
2075 ///
2076 /// By default, performs semantic analysis to build the new statement.
2077 /// Subclasses may override this routine to provide different behavior.
2079 SourceLocation StartLoc,
2080 SourceLocation LParenLoc,
2081 SourceLocation EndLoc) {
2083 ThreadLimit, StartLoc, LParenLoc, EndLoc);
2084 }
2085
2086 /// Build a new OpenMP 'priority' clause.
2087 ///
2088 /// By default, performs semantic analysis to build the new statement.
2089 /// Subclasses may override this routine to provide different behavior.
2091 SourceLocation LParenLoc,
2092 SourceLocation EndLoc) {
2093 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2094 LParenLoc, EndLoc);
2095 }
2096
2097 /// Build a new OpenMP 'grainsize' clause.
2098 ///
2099 /// By default, performs semantic analysis to build the new statement.
2100 /// Subclasses may override this routine to provide different behavior.
2102 Expr *Device, SourceLocation StartLoc,
2103 SourceLocation LParenLoc,
2104 SourceLocation ModifierLoc,
2105 SourceLocation EndLoc) {
2107 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2108 }
2109
2110 /// Build a new OpenMP 'num_tasks' clause.
2111 ///
2112 /// By default, performs semantic analysis to build the new statement.
2113 /// Subclasses may override this routine to provide different behavior.
2115 Expr *NumTasks, SourceLocation StartLoc,
2116 SourceLocation LParenLoc,
2117 SourceLocation ModifierLoc,
2118 SourceLocation EndLoc) {
2120 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2121 }
2122
2123 /// Build a new OpenMP 'hint' clause.
2124 ///
2125 /// By default, performs semantic analysis to build the new statement.
2126 /// Subclasses may override this routine to provide different behavior.
2128 SourceLocation LParenLoc,
2129 SourceLocation EndLoc) {
2130 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2131 EndLoc);
2132 }
2133
2134 /// Build a new OpenMP 'detach' clause.
2135 ///
2136 /// By default, performs semantic analysis to build the new statement.
2137 /// Subclasses may override this routine to provide different behavior.
2139 SourceLocation LParenLoc,
2140 SourceLocation EndLoc) {
2141 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2142 EndLoc);
2143 }
2144
2145 /// Build a new OpenMP 'dist_schedule' clause.
2146 ///
2147 /// By default, performs semantic analysis to build the new OpenMP clause.
2148 /// Subclasses may override this routine to provide different behavior.
2149 OMPClause *
2151 Expr *ChunkSize, SourceLocation StartLoc,
2152 SourceLocation LParenLoc, SourceLocation KindLoc,
2153 SourceLocation CommaLoc, SourceLocation EndLoc) {
2155 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2156 }
2157
2158 /// Build a new OpenMP 'to' clause.
2159 ///
2160 /// By default, performs semantic analysis to build the new statement.
2161 /// Subclasses may override this routine to provide different behavior.
2162 OMPClause *
2164 ArrayRef<SourceLocation> MotionModifiersLoc,
2165 CXXScopeSpec &MapperIdScopeSpec,
2166 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2167 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2168 ArrayRef<Expr *> UnresolvedMappers) {
2170 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2171 ColonLoc, VarList, Locs, UnresolvedMappers);
2172 }
2173
2174 /// Build a new OpenMP 'from' clause.
2175 ///
2176 /// By default, performs semantic analysis to build the new statement.
2177 /// Subclasses may override this routine to provide different behavior.
2178 OMPClause *
2180 ArrayRef<SourceLocation> MotionModifiersLoc,
2181 CXXScopeSpec &MapperIdScopeSpec,
2182 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2183 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2184 ArrayRef<Expr *> UnresolvedMappers) {
2186 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2187 ColonLoc, VarList, Locs, UnresolvedMappers);
2188 }
2189
2190 /// Build a new OpenMP 'use_device_ptr' clause.
2191 ///
2192 /// By default, performs semantic analysis to build the new OpenMP clause.
2193 /// Subclasses may override this routine to provide different behavior.
2195 const OMPVarListLocTy &Locs) {
2196 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2197 }
2198
2199 /// Build a new OpenMP 'use_device_addr' clause.
2200 ///
2201 /// By default, performs semantic analysis to build the new OpenMP clause.
2202 /// Subclasses may override this routine to provide different behavior.
2204 const OMPVarListLocTy &Locs) {
2205 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2206 }
2207
2208 /// Build a new OpenMP 'is_device_ptr' clause.
2209 ///
2210 /// By default, performs semantic analysis to build the new OpenMP clause.
2211 /// Subclasses may override this routine to provide different behavior.
2213 const OMPVarListLocTy &Locs) {
2214 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2215 }
2216
2217 /// Build a new OpenMP 'has_device_addr' clause.
2218 ///
2219 /// By default, performs semantic analysis to build the new OpenMP clause.
2220 /// Subclasses may override this routine to provide different behavior.
2222 const OMPVarListLocTy &Locs) {
2223 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2224 }
2225
2226 /// Build a new OpenMP 'defaultmap' clause.
2227 ///
2228 /// By default, performs semantic analysis to build the new OpenMP clause.
2229 /// Subclasses may override this routine to provide different behavior.
2232 SourceLocation StartLoc,
2233 SourceLocation LParenLoc,
2234 SourceLocation MLoc,
2235 SourceLocation KindLoc,
2236 SourceLocation EndLoc) {
2238 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2239 }
2240
2241 /// Build a new OpenMP 'nontemporal' clause.
2242 ///
2243 /// By default, performs semantic analysis to build the new OpenMP clause.
2244 /// Subclasses may override this routine to provide different behavior.
2246 SourceLocation StartLoc,
2247 SourceLocation LParenLoc,
2248 SourceLocation EndLoc) {
2249 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2250 LParenLoc, EndLoc);
2251 }
2252
2253 /// Build a new OpenMP 'inclusive' clause.
2254 ///
2255 /// By default, performs semantic analysis to build the new OpenMP clause.
2256 /// Subclasses may override this routine to provide different behavior.
2258 SourceLocation StartLoc,
2259 SourceLocation LParenLoc,
2260 SourceLocation EndLoc) {
2261 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2262 LParenLoc, EndLoc);
2263 }
2264
2265 /// Build a new OpenMP 'exclusive' clause.
2266 ///
2267 /// By default, performs semantic analysis to build the new OpenMP clause.
2268 /// Subclasses may override this routine to provide different behavior.
2270 SourceLocation StartLoc,
2271 SourceLocation LParenLoc,
2272 SourceLocation EndLoc) {
2273 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2274 LParenLoc, EndLoc);
2275 }
2276
2277 /// Build a new OpenMP 'uses_allocators' clause.
2278 ///
2279 /// By default, performs semantic analysis to build the new OpenMP clause.
2280 /// Subclasses may override this routine to provide different behavior.
2283 SourceLocation LParenLoc, SourceLocation EndLoc) {
2285 StartLoc, LParenLoc, EndLoc, Data);
2286 }
2287
2288 /// Build a new OpenMP 'affinity' clause.
2289 ///
2290 /// By default, performs semantic analysis to build the new OpenMP clause.
2291 /// Subclasses may override this routine to provide different behavior.
2293 SourceLocation LParenLoc,
2294 SourceLocation ColonLoc,
2295 SourceLocation EndLoc, Expr *Modifier,
2296 ArrayRef<Expr *> Locators) {
2298 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2299 }
2300
2301 /// Build a new OpenMP 'order' clause.
2302 ///
2303 /// By default, performs semantic analysis to build the new OpenMP clause.
2304 /// Subclasses may override this routine to provide different behavior.
2306 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2307 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2308 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2310 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2311 }
2312
2313 /// Build a new OpenMP 'init' clause.
2314 ///
2315 /// By default, performs semantic analysis to build the new OpenMP clause.
2316 /// Subclasses may override this routine to provide different behavior.
2318 SourceLocation StartLoc,
2319 SourceLocation LParenLoc,
2320 SourceLocation VarLoc,
2321 SourceLocation EndLoc) {
2323 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2324 }
2325
2326 /// Build a new OpenMP 'use' clause.
2327 ///
2328 /// By default, performs semantic analysis to build the new OpenMP clause.
2329 /// Subclasses may override this routine to provide different behavior.
2331 SourceLocation LParenLoc,
2332 SourceLocation VarLoc, SourceLocation EndLoc) {
2333 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2334 LParenLoc, VarLoc, EndLoc);
2335 }
2336
2337 /// Build a new OpenMP 'destroy' clause.
2338 ///
2339 /// By default, performs semantic analysis to build the new OpenMP clause.
2340 /// Subclasses may override this routine to provide different behavior.
2342 SourceLocation LParenLoc,
2343 SourceLocation VarLoc,
2344 SourceLocation EndLoc) {
2346 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2347 }
2348
2349 /// Build a new OpenMP 'novariants' clause.
2350 ///
2351 /// By default, performs semantic analysis to build the new OpenMP clause.
2352 /// Subclasses may override this routine to provide different behavior.
2354 SourceLocation StartLoc,
2355 SourceLocation LParenLoc,
2356 SourceLocation EndLoc) {
2358 LParenLoc, EndLoc);
2359 }
2360
2361 /// Build a new OpenMP 'nocontext' clause.
2362 ///
2363 /// By default, performs semantic analysis to build the new OpenMP clause.
2364 /// Subclasses may override this routine to provide different behavior.
2366 SourceLocation LParenLoc,
2367 SourceLocation EndLoc) {
2369 LParenLoc, EndLoc);
2370 }
2371
2372 /// Build a new OpenMP 'filter' clause.
2373 ///
2374 /// By default, performs semantic analysis to build the new OpenMP clause.
2375 /// Subclasses may override this routine to provide different behavior.
2377 SourceLocation LParenLoc,
2378 SourceLocation EndLoc) {
2379 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2380 LParenLoc, EndLoc);
2381 }
2382
2383 /// Build a new OpenMP 'bind' clause.
2384 ///
2385 /// By default, performs semantic analysis to build the new OpenMP clause.
2386 /// Subclasses may override this routine to provide different behavior.
2388 SourceLocation KindLoc,
2389 SourceLocation StartLoc,
2390 SourceLocation LParenLoc,
2391 SourceLocation EndLoc) {
2392 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2393 LParenLoc, EndLoc);
2394 }
2395
2396 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2397 ///
2398 /// By default, performs semantic analysis to build the new OpenMP clause.
2399 /// Subclasses may override this routine to provide different behavior.
2401 SourceLocation LParenLoc,
2402 SourceLocation EndLoc) {
2403 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2404 LParenLoc, EndLoc);
2405 }
2406
2407 /// Build a new OpenMP 'ompx_attribute' clause.
2408 ///
2409 /// By default, performs semantic analysis to build the new OpenMP clause.
2410 /// Subclasses may override this routine to provide different behavior.
2412 SourceLocation StartLoc,
2413 SourceLocation LParenLoc,
2414 SourceLocation EndLoc) {
2415 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2416 LParenLoc, EndLoc);
2417 }
2418
2419 /// Build a new OpenMP 'ompx_bare' clause.
2420 ///
2421 /// By default, performs semantic analysis to build the new OpenMP clause.
2422 /// Subclasses may override this routine to provide different behavior.
2424 SourceLocation EndLoc) {
2425 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2426 }
2427
2428 /// Build a new OpenMP 'align' clause.
2429 ///
2430 /// By default, performs semantic analysis to build the new OpenMP clause.
2431 /// Subclasses may override this routine to provide different behavior.
2433 SourceLocation LParenLoc,
2434 SourceLocation EndLoc) {
2435 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2436 EndLoc);
2437 }
2438
2439 /// Build a new OpenMP 'at' clause.
2440 ///
2441 /// By default, performs semantic analysis to build the new OpenMP clause.
2442 /// Subclasses may override this routine to provide different behavior.
2444 SourceLocation StartLoc,
2445 SourceLocation LParenLoc,
2446 SourceLocation EndLoc) {
2447 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2448 LParenLoc, EndLoc);
2449 }
2450
2451 /// Build a new OpenMP 'severity' clause.
2452 ///
2453 /// By default, performs semantic analysis to build the new OpenMP clause.
2454 /// Subclasses may override this routine to provide different behavior.
2456 SourceLocation KwLoc,
2457 SourceLocation StartLoc,
2458 SourceLocation LParenLoc,
2459 SourceLocation EndLoc) {
2460 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2461 LParenLoc, EndLoc);
2462 }
2463
2464 /// Build a new OpenMP 'message' clause.
2465 ///
2466 /// By default, performs semantic analysis to build the new OpenMP clause.
2467 /// Subclasses may override this routine to provide different behavior.
2469 SourceLocation LParenLoc,
2470 SourceLocation EndLoc) {
2471 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2472 EndLoc);
2473 }
2474
2475 /// Build a new OpenMP 'doacross' clause.
2476 ///
2477 /// By default, performs semantic analysis to build the new OpenMP clause.
2478 /// Subclasses may override this routine to provide different behavior.
2479 OMPClause *
2481 SourceLocation DepLoc, SourceLocation ColonLoc,
2482 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2483 SourceLocation LParenLoc, SourceLocation EndLoc) {
2485 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2486 }
2487
2488 /// Rebuild the operand to an Objective-C \@synchronized statement.
2489 ///
2490 /// By default, performs semantic analysis to build the new statement.
2491 /// Subclasses may override this routine to provide different behavior.
2493 Expr *object) {
2494 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2495 }
2496
2497 /// Build a new Objective-C \@synchronized statement.
2498 ///
2499 /// By default, performs semantic analysis to build the new statement.
2500 /// Subclasses may override this routine to provide different behavior.
2502 Expr *Object, Stmt *Body) {
2503 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2504 }
2505
2506 /// Build a new Objective-C \@autoreleasepool statement.
2507 ///
2508 /// By default, performs semantic analysis to build the new statement.
2509 /// Subclasses may override this routine to provide different behavior.
2511 Stmt *Body) {
2512 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2513 }
2514
2515 /// Build a new Objective-C fast enumeration statement.
2516 ///
2517 /// By default, performs semantic analysis to build the new statement.
2518 /// Subclasses may override this routine to provide different behavior.
2520 Stmt *Element,
2521 Expr *Collection,
2522 SourceLocation RParenLoc,
2523 Stmt *Body) {
2525 ForLoc, Element, Collection, RParenLoc);
2526 if (ForEachStmt.isInvalid())
2527 return StmtError();
2528
2529 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2530 Body);
2531 }
2532
2533 /// Build a new C++ exception declaration.
2534 ///
2535 /// By default, performs semantic analysis to build the new decaration.
2536 /// Subclasses may override this routine to provide different behavior.
2539 SourceLocation StartLoc,
2540 SourceLocation IdLoc,
2541 IdentifierInfo *Id) {
2543 StartLoc, IdLoc, Id);
2544 if (Var)
2545 getSema().CurContext->addDecl(Var);
2546 return Var;
2547 }
2548
2549 /// Build a new C++ catch statement.
2550 ///
2551 /// By default, performs semantic analysis to build the new statement.
2552 /// Subclasses may override this routine to provide different behavior.
2554 VarDecl *ExceptionDecl,
2555 Stmt *Handler) {
2556 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2557 Handler));
2558 }
2559
2560 /// Build a new C++ try statement.
2561 ///
2562 /// By default, performs semantic analysis to build the new statement.
2563 /// Subclasses may override this routine to provide different behavior.
2565 ArrayRef<Stmt *> Handlers) {
2566 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2567 }
2568
2569 /// Build a new C++0x range-based for statement.
2570 ///
2571 /// By default, performs semantic analysis to build the new statement.
2572 /// Subclasses may override this routine to provide different behavior.
2574 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2575 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2576 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2577 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2578 // If we've just learned that the range is actually an Objective-C
2579 // collection, treat this as an Objective-C fast enumeration loop.
2580 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
2581 if (RangeStmt->isSingleDecl()) {
2582 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
2583 if (RangeVar->isInvalidDecl())
2584 return StmtError();
2585
2586 Expr *RangeExpr = RangeVar->getInit();
2587 if (!RangeExpr->isTypeDependent() &&
2588 RangeExpr->getType()->isObjCObjectPointerType()) {
2589 // FIXME: Support init-statements in Objective-C++20 ranged for
2590 // statement.
2591 if (Init) {
2592 return SemaRef.Diag(Init->getBeginLoc(),
2593 diag::err_objc_for_range_init_stmt)
2594 << Init->getSourceRange();
2595 }
2597 ForLoc, LoopVar, RangeExpr, RParenLoc);
2598 }
2599 }
2600 }
2601 }
2602
2604 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2605 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
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 bool IsIfExists,
2614 NestedNameSpecifierLoc QualifierLoc,
2615 DeclarationNameInfo NameInfo,
2616 Stmt *Nested) {
2617 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2618 QualifierLoc, NameInfo, Nested);
2619 }
2620
2621 /// Attach body to a C++0x range-based for statement.
2622 ///
2623 /// By default, performs semantic analysis to finish the new statement.
2624 /// Subclasses may override this routine to provide different behavior.
2626 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2627 }
2628
2630 Stmt *TryBlock, Stmt *Handler) {
2631 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2632 }
2633
2635 Stmt *Block) {
2636 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2637 }
2638
2640 return SEHFinallyStmt::Create(getSema().getASTContext(), Loc, Block);
2641 }
2642
2644 SourceLocation LParen,
2645 SourceLocation RParen,
2646 TypeSourceInfo *TSI) {
2647 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2648 TSI);
2649 }
2650
2651 /// Build a new predefined expression.
2652 ///
2653 /// By default, performs semantic analysis to build the new expression.
2654 /// Subclasses may override this routine to provide different behavior.
2656 return getSema().BuildPredefinedExpr(Loc, IK);
2657 }
2658
2659 /// Build a new expression that references a declaration.
2660 ///
2661 /// By default, performs semantic analysis to build the new expression.
2662 /// Subclasses may override this routine to provide different behavior.
2664 LookupResult &R,
2665 bool RequiresADL) {
2666 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2667 }
2668
2669
2670 /// Build a new expression that references a declaration.
2671 ///
2672 /// By default, performs semantic analysis to build the new expression.
2673 /// Subclasses may override this routine to provide different behavior.
2675 ValueDecl *VD,
2676 const DeclarationNameInfo &NameInfo,
2677 NamedDecl *Found,
2678 TemplateArgumentListInfo *TemplateArgs) {
2679 CXXScopeSpec SS;
2680 SS.Adopt(QualifierLoc);
2681 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2682 TemplateArgs);
2683 }
2684
2685 /// Build a new expression in parentheses.
2686 ///
2687 /// By default, performs semantic analysis to build the new expression.
2688 /// Subclasses may override this routine to provide different behavior.
2690 SourceLocation RParen) {
2691 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2692 }
2693
2694 /// Build a new pseudo-destructor expression.
2695 ///
2696 /// By default, performs semantic analysis to build the new expression.
2697 /// Subclasses may override this routine to provide different behavior.
2699 SourceLocation OperatorLoc,
2700 bool isArrow,
2701 CXXScopeSpec &SS,
2702 TypeSourceInfo *ScopeType,
2703 SourceLocation CCLoc,
2704 SourceLocation TildeLoc,
2705 PseudoDestructorTypeStorage Destroyed);
2706
2707 /// Build a new unary operator expression.
2708 ///
2709 /// By default, performs semantic analysis to build the new expression.
2710 /// Subclasses may override this routine to provide different behavior.
2713 Expr *SubExpr) {
2714 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2715 }
2716
2717 /// Build a new builtin offsetof expression.
2718 ///
2719 /// By default, performs semantic analysis to build the new expression.
2720 /// Subclasses may override this routine to provide different behavior.
2724 SourceLocation RParenLoc) {
2725 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2726 RParenLoc);
2727 }
2728
2729 /// Build a new sizeof, alignof or vec_step expression with a
2730 /// type argument.
2731 ///
2732 /// By default, performs semantic analysis to build the new expression.
2733 /// Subclasses may override this routine to provide different behavior.
2735 SourceLocation OpLoc,
2736 UnaryExprOrTypeTrait ExprKind,
2737 SourceRange R) {
2738 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2739 }
2740
2741 /// Build a new sizeof, alignof or vec step expression with an
2742 /// expression argument.
2743 ///
2744 /// By default, performs semantic analysis to build the new expression.
2745 /// Subclasses may override this routine to provide different behavior.
2747 UnaryExprOrTypeTrait ExprKind,
2748 SourceRange R) {
2750 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2751 if (Result.isInvalid())
2752 return ExprError();
2753
2754 return Result;
2755 }
2756
2757 /// Build a new array subscript expression.
2758 ///
2759 /// By default, performs semantic analysis to build the new expression.
2760 /// Subclasses may override this routine to provide different behavior.
2762 SourceLocation LBracketLoc,
2763 Expr *RHS,
2764 SourceLocation RBracketLoc) {
2765 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2766 LBracketLoc, RHS,
2767 RBracketLoc);
2768 }
2769
2770 /// Build a new matrix subscript expression.
2771 ///
2772 /// By default, performs semantic analysis to build the new expression.
2773 /// Subclasses may override this routine to provide different behavior.
2775 Expr *ColumnIdx,
2776 SourceLocation RBracketLoc) {
2777 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2778 RBracketLoc);
2779 }
2780
2781 /// Build a new array section expression.
2782 ///
2783 /// By default, performs semantic analysis to build the new expression.
2784 /// Subclasses may override this routine to provide different behavior.
2786 SourceLocation LBracketLoc,
2787 Expr *LowerBound,
2788 SourceLocation ColonLocFirst,
2789 SourceLocation ColonLocSecond,
2790 Expr *Length, Expr *Stride,
2791 SourceLocation RBracketLoc) {
2792 if (IsOMPArraySection)
2794 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2795 Stride, RBracketLoc);
2796
2797 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2798 "Stride/second colon not allowed for OpenACC");
2799
2801 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2802 }
2803
2804 /// Build a new array shaping expression.
2805 ///
2806 /// By default, performs semantic analysis to build the new expression.
2807 /// Subclasses may override this routine to provide different behavior.
2809 SourceLocation RParenLoc,
2810 ArrayRef<Expr *> Dims,
2811 ArrayRef<SourceRange> BracketsRanges) {
2813 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2814 }
2815
2816 /// Build a new iterator expression.
2817 ///
2818 /// By default, performs semantic analysis to build the new expression.
2819 /// Subclasses may override this routine to provide different behavior.
2822 SourceLocation RLoc,
2825 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2826 }
2827
2828 /// Build a new call expression.
2829 ///
2830 /// By default, performs semantic analysis to build the new expression.
2831 /// Subclasses may override this routine to provide different behavior.
2833 MultiExprArg Args,
2834 SourceLocation RParenLoc,
2835 Expr *ExecConfig = nullptr) {
2836 return getSema().ActOnCallExpr(
2837 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2838 }
2839
2841 MultiExprArg Args,
2842 SourceLocation RParenLoc) {
2844 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2845 }
2846
2847 /// Build a new member access expression.
2848 ///
2849 /// By default, performs semantic analysis to build the new expression.
2850 /// Subclasses may override this routine to provide different behavior.
2852 bool isArrow,
2853 NestedNameSpecifierLoc QualifierLoc,
2854 SourceLocation TemplateKWLoc,
2855 const DeclarationNameInfo &MemberNameInfo,
2857 NamedDecl *FoundDecl,
2858 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2859 NamedDecl *FirstQualifierInScope) {
2861 isArrow);
2862 if (!Member->getDeclName()) {
2863 // We have a reference to an unnamed field. This is always the
2864 // base of an anonymous struct/union member access, i.e. the
2865 // field is always of record type.
2866 assert(Member->getType()->isRecordType() &&
2867 "unnamed member not of record type?");
2868
2869 BaseResult =
2871 QualifierLoc.getNestedNameSpecifier(),
2872 FoundDecl, Member);
2873 if (BaseResult.isInvalid())
2874 return ExprError();
2875 Base = BaseResult.get();
2876
2877 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
2878 // from the AST, so we need to re-insert them if needed (since
2879 // `BuildFieldRefereneExpr()` doesn't do this).
2880 if (!isArrow && Base->isPRValue()) {
2882 if (BaseResult.isInvalid())
2883 return ExprError();
2884 Base = BaseResult.get();
2885 }
2886
2887 CXXScopeSpec EmptySS;
2889 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
2890 DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()),
2891 MemberNameInfo);
2892 }
2893
2894 CXXScopeSpec SS;
2895 SS.Adopt(QualifierLoc);
2896
2897 Base = BaseResult.get();
2898 QualType BaseType = Base->getType();
2899
2900 if (isArrow && !BaseType->isPointerType())
2901 return ExprError();
2902
2903 // FIXME: this involves duplicating earlier analysis in a lot of
2904 // cases; we should avoid this when possible.
2905 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2906 R.addDecl(FoundDecl);
2907 R.resolveKind();
2908
2909 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2910 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {
2911 if (auto *ThisClass = cast<CXXThisExpr>(Base)
2912 ->getType()
2913 ->getPointeeType()
2914 ->getAsCXXRecordDecl()) {
2915 auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());
2916 // In unevaluated contexts, an expression supposed to be a member access
2917 // might reference a member in an unrelated class.
2918 if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))
2919 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2920 VK_LValue, Member->getLocation());
2921 }
2922 }
2923
2924 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2925 SS, TemplateKWLoc,
2926 FirstQualifierInScope,
2927 R, ExplicitTemplateArgs,
2928 /*S*/nullptr);
2929 }
2930
2931 /// Build a new binary operator expression.
2932 ///
2933 /// By default, performs semantic analysis to build the new expression.
2934 /// Subclasses may override this routine to provide different behavior.
2937 Expr *LHS, Expr *RHS) {
2938 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS);
2939 }
2940
2941 /// Build a new rewritten operator expression.
2942 ///
2943 /// By default, performs semantic analysis to build the new expression.
2944 /// Subclasses may override this routine to provide different behavior.
2946 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2947 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2948 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2949 RHS, /*RequiresADL*/false);
2950 }
2951
2952 /// Build a new conditional operator expression.
2953 ///
2954 /// By default, performs semantic analysis to build the new expression.
2955 /// Subclasses may override this routine to provide different behavior.
2957 SourceLocation QuestionLoc,
2958 Expr *LHS,
2959 SourceLocation ColonLoc,
2960 Expr *RHS) {
2961 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
2962 LHS, RHS);
2963 }
2964
2965 /// Build a new C-style cast expression.
2966 ///
2967 /// By default, performs semantic analysis to build the new expression.
2968 /// Subclasses may override this routine to provide different behavior.
2970 TypeSourceInfo *TInfo,
2971 SourceLocation RParenLoc,
2972 Expr *SubExpr) {
2973 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
2974 SubExpr);
2975 }
2976
2977 /// Build a new compound literal expression.
2978 ///
2979 /// By default, performs semantic analysis to build the new expression.
2980 /// Subclasses may override this routine to provide different behavior.
2982 TypeSourceInfo *TInfo,
2983 SourceLocation RParenLoc,
2984 Expr *Init) {
2985 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
2986 Init);
2987 }
2988
2989 /// Build a new extended vector element access expression.
2990 ///
2991 /// By default, performs semantic analysis to build the new expression.
2992 /// Subclasses may override this routine to provide different behavior.
2994 bool IsArrow,
2995 SourceLocation AccessorLoc,
2996 IdentifierInfo &Accessor) {
2997
2998 CXXScopeSpec SS;
2999 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3001 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3002 /*FirstQualifierInScope*/ nullptr, NameInfo,
3003 /* TemplateArgs */ nullptr,
3004 /*S*/ nullptr);
3005 }
3006
3007 /// Build a new initializer list expression.
3008 ///
3009 /// By default, performs semantic analysis to build the new expression.
3010 /// Subclasses may override this routine to provide different behavior.
3012 MultiExprArg Inits,
3013 SourceLocation RBraceLoc) {
3014 return SemaRef.BuildInitList(LBraceLoc, Inits, RBraceLoc);
3015 }
3016
3017 /// Build a new designated initializer expression.
3018 ///
3019 /// By default, performs semantic analysis to build the new expression.
3020 /// Subclasses may override this routine to provide different behavior.
3022 MultiExprArg ArrayExprs,
3023 SourceLocation EqualOrColonLoc,
3024 bool GNUSyntax,
3025 Expr *Init) {
3027 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3028 Init);
3029 if (Result.isInvalid())
3030 return ExprError();
3031
3032 return Result;
3033 }
3034
3035 /// Build a new value-initialized expression.
3036 ///
3037 /// By default, builds the implicit value initialization without performing
3038 /// any semantic analysis. Subclasses may override this routine to provide
3039 /// different behavior.
3041 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3042 }
3043
3044 /// Build a new \c va_arg expression.
3045 ///
3046 /// By default, performs semantic analysis to build the new expression.
3047 /// Subclasses may override this routine to provide different behavior.
3049 Expr *SubExpr, TypeSourceInfo *TInfo,
3050 SourceLocation RParenLoc) {
3051 return getSema().BuildVAArgExpr(BuiltinLoc,
3052 SubExpr, TInfo,
3053 RParenLoc);
3054 }
3055
3056 /// Build a new expression list in parentheses.
3057 ///
3058 /// By default, performs semantic analysis to build the new expression.
3059 /// Subclasses may override this routine to provide different behavior.
3061 MultiExprArg SubExprs,
3062 SourceLocation RParenLoc) {
3063 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3064 }
3065
3066 /// Build a new address-of-label expression.
3067 ///
3068 /// By default, performs semantic analysis, using the name of the label
3069 /// rather than attempting to map the label statement itself.
3070 /// Subclasses may override this routine to provide different behavior.
3072 SourceLocation LabelLoc, LabelDecl *Label) {
3073 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3074 }
3075
3076 /// Build a new GNU statement expression.
3077 ///
3078 /// By default, performs semantic analysis to build the new expression.
3079 /// Subclasses may override this routine to provide different behavior.
3081 SourceLocation RParenLoc, unsigned TemplateDepth) {
3082 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3083 TemplateDepth);
3084 }
3085
3086 /// Build a new __builtin_choose_expr 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 *Cond, Expr *LHS, Expr *RHS,
3092 SourceLocation RParenLoc) {
3093 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3094 Cond, LHS, RHS,
3095 RParenLoc);
3096 }
3097
3098 /// Build a new generic selection expression with an expression predicate.
3099 ///
3100 /// By default, performs semantic analysis to build the new expression.
3101 /// Subclasses may override this routine to provide different behavior.
3103 SourceLocation DefaultLoc,
3104 SourceLocation RParenLoc,
3105 Expr *ControllingExpr,
3107 ArrayRef<Expr *> Exprs) {
3108 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3109 /*PredicateIsExpr=*/true,
3110 ControllingExpr, Types, Exprs);
3111 }
3112
3113 /// Build a new generic selection expression with a type predicate.
3114 ///
3115 /// By default, performs semantic analysis to build the new expression.
3116 /// Subclasses may override this routine to provide different behavior.
3118 SourceLocation DefaultLoc,
3119 SourceLocation RParenLoc,
3120 TypeSourceInfo *ControllingType,
3122 ArrayRef<Expr *> Exprs) {
3123 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3124 /*PredicateIsExpr=*/false,
3125 ControllingType, Types, Exprs);
3126 }
3127
3128 /// Build a new overloaded operator call expression.
3129 ///
3130 /// By default, performs semantic analysis to build the new expression.
3131 /// The semantic analysis provides the behavior of template instantiation,
3132 /// copying with transformations that turn what looks like an overloaded
3133 /// operator call into a use of a builtin operator, performing
3134 /// argument-dependent lookup, etc. Subclasses may override this routine to
3135 /// provide different behavior.
3137 SourceLocation OpLoc,
3138 SourceLocation CalleeLoc,
3139 bool RequiresADL,
3140 const UnresolvedSetImpl &Functions,
3141 Expr *First, Expr *Second);
3142
3143 /// Build a new C++ "named" cast expression, such as static_cast or
3144 /// reinterpret_cast.
3145 ///
3146 /// By default, this routine dispatches to one of the more-specific routines
3147 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3148 /// Subclasses may override this routine to provide different behavior.
3151 SourceLocation LAngleLoc,
3152 TypeSourceInfo *TInfo,
3153 SourceLocation RAngleLoc,
3154 SourceLocation LParenLoc,
3155 Expr *SubExpr,
3156 SourceLocation RParenLoc) {
3157 switch (Class) {
3158 case Stmt::CXXStaticCastExprClass:
3159 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3160 RAngleLoc, LParenLoc,
3161 SubExpr, RParenLoc);
3162
3163 case Stmt::CXXDynamicCastExprClass:
3164 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3165 RAngleLoc, LParenLoc,
3166 SubExpr, RParenLoc);
3167
3168 case Stmt::CXXReinterpretCastExprClass:
3169 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3170 RAngleLoc, LParenLoc,
3171 SubExpr,
3172 RParenLoc);
3173
3174 case Stmt::CXXConstCastExprClass:
3175 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3176 RAngleLoc, LParenLoc,
3177 SubExpr, RParenLoc);
3178
3179 case Stmt::CXXAddrspaceCastExprClass:
3180 return getDerived().RebuildCXXAddrspaceCastExpr(
3181 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3182
3183 default:
3184 llvm_unreachable("Invalid C++ named cast");
3185 }
3186 }
3187
3188 /// Build a new C++ static_cast expression.
3189 ///
3190 /// By default, performs semantic analysis to build the new expression.
3191 /// 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 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3200 TInfo, SubExpr,
3201 SourceRange(LAngleLoc, RAngleLoc),
3202 SourceRange(LParenLoc, RParenLoc));
3203 }
3204
3205 /// Build a new C++ dynamic_cast expression.
3206 ///
3207 /// By default, performs semantic analysis to build the new expression.
3208 /// Subclasses may override this routine to provide different behavior.
3210 SourceLocation LAngleLoc,
3211 TypeSourceInfo *TInfo,
3212 SourceLocation RAngleLoc,
3213 SourceLocation LParenLoc,
3214 Expr *SubExpr,
3215 SourceLocation RParenLoc) {
3216 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3217 TInfo, SubExpr,
3218 SourceRange(LAngleLoc, RAngleLoc),
3219 SourceRange(LParenLoc, RParenLoc));
3220 }
3221
3222 /// Build a new C++ reinterpret_cast expression.
3223 ///
3224 /// By default, performs semantic analysis to build the new expression.
3225 /// Subclasses may override this routine to provide different behavior.
3227 SourceLocation LAngleLoc,
3228 TypeSourceInfo *TInfo,
3229 SourceLocation RAngleLoc,
3230 SourceLocation LParenLoc,
3231 Expr *SubExpr,
3232 SourceLocation RParenLoc) {
3233 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3234 TInfo, SubExpr,
3235 SourceRange(LAngleLoc, RAngleLoc),
3236 SourceRange(LParenLoc, RParenLoc));
3237 }
3238
3239 /// Build a new C++ const_cast expression.
3240 ///
3241 /// By default, performs semantic analysis to build the new expression.
3242 /// Subclasses may override this routine to provide different behavior.
3244 SourceLocation LAngleLoc,
3245 TypeSourceInfo *TInfo,
3246 SourceLocation RAngleLoc,
3247 SourceLocation LParenLoc,
3248 Expr *SubExpr,
3249 SourceLocation RParenLoc) {
3250 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3251 TInfo, SubExpr,
3252 SourceRange(LAngleLoc, RAngleLoc),
3253 SourceRange(LParenLoc, RParenLoc));
3254 }
3255
3258 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3259 SourceLocation LParenLoc, Expr *SubExpr,
3260 SourceLocation RParenLoc) {
3261 return getSema().BuildCXXNamedCast(
3262 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3263 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3264 }
3265
3266 /// Build a new C++ functional-style cast expression.
3267 ///
3268 /// By default, performs semantic analysis to build the new expression.
3269 /// Subclasses may override this routine to provide different behavior.
3271 SourceLocation LParenLoc,
3272 Expr *Sub,
3273 SourceLocation RParenLoc,
3274 bool ListInitialization) {
3275 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3276 // CXXParenListInitExpr. Pass its expanded arguments so that the
3277 // CXXParenListInitExpr can be rebuilt.
3278 if (auto *PLE = dyn_cast<ParenListExpr>(Sub))
3280 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3281 RParenLoc, ListInitialization);
3282 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3283 MultiExprArg(&Sub, 1), RParenLoc,
3284 ListInitialization);
3285 }
3286
3287 /// Build a new C++ __builtin_bit_cast expression.
3288 ///
3289 /// By default, performs semantic analysis to build the new expression.
3290 /// Subclasses may override this routine to provide different behavior.
3292 TypeSourceInfo *TSI, Expr *Sub,
3293 SourceLocation RParenLoc) {
3294 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3295 }
3296
3297 /// Build a new C++ typeid(type) expression.
3298 ///
3299 /// By default, performs semantic analysis to build the new expression.
3300 /// Subclasses may override this routine to provide different behavior.
3302 SourceLocation TypeidLoc,
3303 TypeSourceInfo *Operand,
3304 SourceLocation RParenLoc) {
3305 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3306 RParenLoc);
3307 }
3308
3309
3310 /// Build a new C++ typeid(expr) expression.
3311 ///
3312 /// By default, performs semantic analysis to build the new expression.
3313 /// Subclasses may override this routine to provide different behavior.
3315 SourceLocation TypeidLoc,
3316 Expr *Operand,
3317 SourceLocation RParenLoc) {
3318 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3319 RParenLoc);
3320 }
3321
3322 /// Build a new C++ __uuidof(type) expression.
3323 ///
3324 /// By default, performs semantic analysis to build the new expression.
3325 /// Subclasses may override this routine to provide different behavior.
3327 TypeSourceInfo *Operand,
3328 SourceLocation RParenLoc) {
3329 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3330 }
3331
3332 /// Build a new C++ __uuidof(expr) expression.
3333 ///
3334 /// By default, performs semantic analysis to build the new expression.
3335 /// Subclasses may override this routine to provide different behavior.
3337 Expr *Operand, SourceLocation RParenLoc) {
3338 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3339 }
3340
3341 /// Build a new C++ "this" expression.
3342 ///
3343 /// By default, performs semantic analysis to build a new "this" expression.
3344 /// Subclasses may override this routine to provide different behavior.
3346 QualType ThisType,
3347 bool isImplicit) {
3348 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3349 return ExprError();
3350 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3351 }
3352
3353 /// Build a new C++ throw expression.
3354 ///
3355 /// By default, performs semantic analysis to build the new expression.
3356 /// Subclasses may override this routine to provide different behavior.
3358 bool IsThrownVariableInScope) {
3359 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3360 }
3361
3362 /// Build a new C++ default-argument expression.
3363 ///
3364 /// By default, builds a new default-argument expression, which does not
3365 /// require any semantic analysis. Subclasses may override this routine to
3366 /// provide different behavior.
3368 Expr *RewrittenExpr) {
3369 return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param,
3370 RewrittenExpr, getSema().CurContext);
3371 }
3372
3373 /// Build a new C++11 default-initialization expression.
3374 ///
3375 /// By default, builds a new default field initialization expression, which
3376 /// does not require any semantic analysis. Subclasses may override this
3377 /// routine to provide different behavior.
3379 FieldDecl *Field) {
3380 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3381 }
3382
3383 /// Build a new C++ zero-initialization expression.
3384 ///
3385 /// By default, performs semantic analysis to build the new expression.
3386 /// Subclasses may override this routine to provide different behavior.
3388 SourceLocation LParenLoc,
3389 SourceLocation RParenLoc) {
3390 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, std::nullopt,
3391 RParenLoc,
3392 /*ListInitialization=*/false);
3393 }
3394
3395 /// Build a new C++ "new" expression.
3396 ///
3397 /// By default, performs semantic analysis to build the new expression.
3398 /// Subclasses may override this routine to provide different behavior.
3400 SourceLocation PlacementLParen,
3401 MultiExprArg PlacementArgs,
3402 SourceLocation PlacementRParen,
3403 SourceRange TypeIdParens, QualType AllocatedType,
3404 TypeSourceInfo *AllocatedTypeInfo,
3405 std::optional<Expr *> ArraySize,
3406 SourceRange DirectInitRange, Expr *Initializer) {
3407 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3408 PlacementLParen,
3409 PlacementArgs,
3410 PlacementRParen,
3411 TypeIdParens,
3412 AllocatedType,
3413 AllocatedTypeInfo,
3414 ArraySize,
3415 DirectInitRange,
3416 Initializer);
3417 }
3418
3419 /// Build a new C++ "delete" expression.
3420 ///
3421 /// By default, performs semantic analysis to build the new expression.
3422 /// Subclasses may override this routine to provide different behavior.
3424 bool IsGlobalDelete,
3425 bool IsArrayForm,
3426 Expr *Operand) {
3427 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3428 Operand);
3429 }
3430
3431 /// Build a new type trait expression.
3432 ///
3433 /// By default, performs semantic analysis to build the new expression.
3434 /// Subclasses may override this routine to provide different behavior.
3436 SourceLocation StartLoc,
3438 SourceLocation RParenLoc) {
3439 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3440 }
3441
3442 /// Build a new array type trait expression.
3443 ///
3444 /// By default, performs semantic analysis to build the new expression.
3445 /// Subclasses may override this routine to provide different behavior.
3447 SourceLocation StartLoc,
3448 TypeSourceInfo *TSInfo,
3449 Expr *DimExpr,
3450 SourceLocation RParenLoc) {
3451 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3452 }
3453
3454 /// Build a new expression trait expression.
3455 ///
3456 /// By default, performs semantic analysis to build the new expression.
3457 /// Subclasses may override this routine to provide different behavior.
3459 SourceLocation StartLoc,
3460 Expr *Queried,
3461 SourceLocation RParenLoc) {
3462 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3463 }
3464
3465 /// Build a new (previously unresolved) declaration reference
3466 /// expression.
3467 ///
3468 /// By default, performs semantic analysis to build the new expression.
3469 /// Subclasses may override this routine to provide different behavior.
3471 NestedNameSpecifierLoc QualifierLoc,
3472 SourceLocation TemplateKWLoc,
3473 const DeclarationNameInfo &NameInfo,
3474 const TemplateArgumentListInfo *TemplateArgs,
3475 bool IsAddressOfOperand,
3476 TypeSourceInfo **RecoveryTSI) {
3477 CXXScopeSpec SS;
3478 SS.Adopt(QualifierLoc);
3479
3480 if (TemplateArgs || TemplateKWLoc.isValid())
3482 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3483
3485 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3486 }
3487
3488 /// Build a new template-id expression.
3489 ///
3490 /// By default, performs semantic analysis to build the new expression.
3491 /// Subclasses may override this routine to provide different behavior.
3493 SourceLocation TemplateKWLoc,
3494 LookupResult &R,
3495 bool RequiresADL,
3496 const TemplateArgumentListInfo *TemplateArgs) {
3497 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3498 TemplateArgs);
3499 }
3500
3501 /// Build a new object-construction expression.
3502 ///
3503 /// By default, performs semantic analysis to build the new expression.
3504 /// Subclasses may override this routine to provide different behavior.
3507 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3508 bool ListInitialization, bool StdInitListInitialization,
3509 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3510 SourceRange ParenRange) {
3511 // Reconstruct the constructor we originally found, which might be
3512 // different if this is a call to an inherited constructor.
3513 CXXConstructorDecl *FoundCtor = Constructor;
3514 if (Constructor->isInheritingConstructor())
3515 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3516
3517 SmallVector<Expr *, 8> ConvertedArgs;
3518 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3519 ConvertedArgs))
3520 return ExprError();
3521
3522 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3523 IsElidable,
3524 ConvertedArgs,
3525 HadMultipleCandidates,
3526 ListInitialization,
3527 StdInitListInitialization,
3528 RequiresZeroInit, ConstructKind,
3529 ParenRange);
3530 }
3531
3532 /// Build a new implicit construction via inherited constructor
3533 /// expression.
3535 CXXConstructorDecl *Constructor,
3536 bool ConstructsVBase,
3537 bool InheritedFromVBase) {
3539 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
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.
3547 SourceLocation LParenOrBraceLoc,
3548 MultiExprArg Args,
3549 SourceLocation RParenOrBraceLoc,
3550 bool ListInitialization) {
3552 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3553 }
3554
3555 /// Build a new object-construction expression.
3556 ///
3557 /// By default, performs semantic analysis to build the new expression.
3558 /// Subclasses may override this routine to provide different behavior.
3560 SourceLocation LParenLoc,
3561 MultiExprArg Args,
3562 SourceLocation RParenLoc,
3563 bool ListInitialization) {
3564 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3565 RParenLoc, ListInitialization);
3566 }
3567
3568 /// Build a new member reference expression.
3569 ///
3570 /// By default, performs semantic analysis to build the new expression.
3571 /// Subclasses may override this routine to provide different behavior.
3573 QualType BaseType,
3574 bool IsArrow,
3575 SourceLocation OperatorLoc,
3576 NestedNameSpecifierLoc QualifierLoc,
3577 SourceLocation TemplateKWLoc,
3578 NamedDecl *FirstQualifierInScope,
3579 const DeclarationNameInfo &MemberNameInfo,
3580 const TemplateArgumentListInfo *TemplateArgs) {
3581 CXXScopeSpec SS;
3582 SS.Adopt(QualifierLoc);
3583
3584 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3585 OperatorLoc, IsArrow,
3586 SS, TemplateKWLoc,
3587 FirstQualifierInScope,
3588 MemberNameInfo,
3589 TemplateArgs, /*S*/nullptr);
3590 }
3591
3592 /// Build a new member reference expression.
3593 ///
3594 /// By default, performs semantic analysis to build the new expression.
3595 /// Subclasses may override this routine to provide different behavior.
3597 SourceLocation OperatorLoc,
3598 bool IsArrow,
3599 NestedNameSpecifierLoc QualifierLoc,
3600 SourceLocation TemplateKWLoc,
3601 NamedDecl *FirstQualifierInScope,
3602 LookupResult &R,
3603 const TemplateArgumentListInfo *TemplateArgs) {
3604 CXXScopeSpec SS;
3605 SS.Adopt(QualifierLoc);
3606
3607 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
3608 OperatorLoc, IsArrow,
3609 SS, TemplateKWLoc,
3610 FirstQualifierInScope,
3611 R, TemplateArgs, /*S*/nullptr);
3612 }
3613
3614 /// Build a new noexcept expression.
3615 ///
3616 /// By default, performs semantic analysis to build the new expression.
3617 /// Subclasses may override this routine to provide different behavior.
3619 return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd());
3620 }
3621
3622 /// Build a new expression to compute the length of a parameter pack.
3624 SourceLocation PackLoc,
3625 SourceLocation RParenLoc,
3626 std::optional<unsigned> Length,
3627 ArrayRef<TemplateArgument> PartialArgs) {
3628 return SizeOfPackExpr::Create(SemaRef.Context, OperatorLoc, Pack, PackLoc,
3629 RParenLoc, Length, PartialArgs);
3630 }
3631
3633 SourceLocation RSquareLoc,
3634 Expr *PackIdExpression, Expr *IndexExpr,
3635 ArrayRef<Expr *> ExpandedExprs,
3636 bool EmptyPack = false) {
3637 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3638 IndexExpr, RSquareLoc, ExpandedExprs,
3639 EmptyPack);
3640 }
3641
3642 /// Build a new expression representing a call to a source location
3643 /// builtin.
3644 ///
3645 /// By default, performs semantic analysis to build the new expression.
3646 /// Subclasses may override this routine to provide different behavior.
3648 SourceLocation BuiltinLoc,
3649 SourceLocation RPLoc,
3650 DeclContext *ParentContext) {
3651 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3652 ParentContext);
3653 }
3654
3655 /// Build a new Objective-C boxed expression.
3656 ///
3657 /// By default, performs semantic analysis to build the new expression.
3658 /// Subclasses may override this routine to provide different behavior.
3660 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3661 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3663 CXXScopeSpec SS;
3664 SS.Adopt(NNS);
3665 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3666 ConceptNameInfo,
3667 FoundDecl,
3668 NamedConcept, TALI);
3669 if (Result.isInvalid())
3670 return ExprError();
3671 return Result;
3672 }
3673
3674 /// \brief Build a new requires expression.
3675 ///
3676 /// By default, performs semantic analysis to build the new expression.
3677 /// Subclasses may override this routine to provide different behavior.
3680 SourceLocation LParenLoc,
3681 ArrayRef<ParmVarDecl *> LocalParameters,
3682 SourceLocation RParenLoc,
3684 SourceLocation ClosingBraceLoc) {
3685 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3686 LocalParameters, RParenLoc, Requirements,
3687 ClosingBraceLoc);
3688 }
3689
3693 return SemaRef.BuildTypeRequirement(SubstDiag);
3694 }
3695
3698 }
3699
3702 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3703 SourceLocation NoexceptLoc,
3705 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
3706 std::move(Ret));
3707 }
3708
3710 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3712 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
3713 std::move(Ret));
3714 }
3715
3717 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3718 const ASTConstraintSatisfaction &Satisfaction) {
3719 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3720 Satisfaction);
3721 }
3722
3724 return SemaRef.BuildNestedRequirement(Constraint);
3725 }
3726
3727 /// \brief Build a new Objective-C boxed expression.
3728 ///
3729 /// By default, performs semantic analysis to build the new expression.
3730 /// Subclasses may override this routine to provide different behavior.
3732 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3733 }
3734
3735 /// Build a new Objective-C array literal.
3736 ///
3737 /// By default, performs semantic analysis to build the new expression.
3738 /// Subclasses may override this routine to provide different behavior.
3740 Expr **Elements, unsigned NumElements) {
3742 Range, MultiExprArg(Elements, NumElements));
3743 }
3744
3746 Expr *Base, Expr *Key,
3747 ObjCMethodDecl *getterMethod,
3748 ObjCMethodDecl *setterMethod) {
3750 RB, Base, Key, getterMethod, setterMethod);
3751 }
3752
3753 /// Build a new Objective-C dictionary literal.
3754 ///
3755 /// By default, performs semantic analysis to build the new expression.
3756 /// Subclasses may override this routine to provide different behavior.
3759 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3760 }
3761
3762 /// Build a new Objective-C \@encode expression.
3763 ///
3764 /// By default, performs semantic analysis to build the new expression.
3765 /// Subclasses may override this routine to provide different behavior.
3767 TypeSourceInfo *EncodeTypeInfo,
3768 SourceLocation RParenLoc) {
3769 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
3770 RParenLoc);
3771 }
3772
3773 /// Build a new Objective-C class message.
3775 Selector Sel,
3776 ArrayRef<SourceLocation> SelectorLocs,
3777 ObjCMethodDecl *Method,
3778 SourceLocation LBracLoc,
3779 MultiExprArg Args,
3780 SourceLocation RBracLoc) {
3782 ReceiverTypeInfo, ReceiverTypeInfo->getType(),
3783 /*SuperLoc=*/SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3784 RBracLoc, Args);
3785 }
3786
3787 /// Build a new Objective-C instance message.
3789 Selector Sel,
3790 ArrayRef<SourceLocation> SelectorLocs,
3791 ObjCMethodDecl *Method,
3792 SourceLocation LBracLoc,
3793 MultiExprArg Args,
3794 SourceLocation RBracLoc) {
3795 return SemaRef.ObjC().BuildInstanceMessage(Receiver, Receiver->getType(),
3796 /*SuperLoc=*/SourceLocation(),
3797 Sel, Method, LBracLoc,
3798 SelectorLocs, RBracLoc, Args);
3799 }
3800
3801 /// Build a new Objective-C instance/class message to 'super'.
3803 Selector Sel,
3804 ArrayRef<SourceLocation> SelectorLocs,
3805 QualType SuperType,
3806 ObjCMethodDecl *Method,
3807 SourceLocation LBracLoc,
3808 MultiExprArg Args,
3809 SourceLocation RBracLoc) {
3810 return Method->isInstanceMethod()
3812 nullptr, SuperType, SuperLoc, Sel, Method, LBracLoc,
3813 SelectorLocs, RBracLoc, Args)
3814 : SemaRef.ObjC().BuildClassMessage(nullptr, SuperType, SuperLoc,
3815 Sel, Method, LBracLoc,
3816 SelectorLocs, RBracLoc, Args);
3817 }
3818
3819 /// Build a new Objective-C ivar reference expression.
3820 ///
3821 /// By default, performs semantic analysis to build the new expression.
3822 /// Subclasses may override this routine to provide different behavior.
3824 SourceLocation IvarLoc,
3825 bool IsArrow, bool IsFreeIvar) {
3826 CXXScopeSpec SS;
3827 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3829 BaseArg, BaseArg->getType(),
3830 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3831 /*FirstQualifierInScope=*/nullptr, NameInfo,
3832 /*TemplateArgs=*/nullptr,
3833 /*S=*/nullptr);
3834 if (IsFreeIvar && Result.isUsable())
3835 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
3836 return Result;
3837 }
3838
3839 /// Build a new Objective-C property reference expression.
3840 ///
3841 /// By default, performs semantic analysis to build the new expression.
3842 /// Subclasses may override this routine to provide different behavior.
3845 SourceLocation PropertyLoc) {
3846 CXXScopeSpec SS;
3847 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3848 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3849 /*FIXME:*/PropertyLoc,
3850 /*IsArrow=*/false,
3851 SS, SourceLocation(),
3852 /*FirstQualifierInScope=*/nullptr,
3853 NameInfo,
3854 /*TemplateArgs=*/nullptr,
3855 /*S=*/nullptr);
3856 }
3857
3858 /// Build a new Objective-C property reference expression.
3859 ///
3860 /// By default, performs semantic analysis to build the new expression.
3861 /// Subclasses may override this routine to provide different behavior.
3863 ObjCMethodDecl *Getter,
3864 ObjCMethodDecl *Setter,
3865 SourceLocation PropertyLoc) {
3866 // Since these expressions can only be value-dependent, we do not
3867 // need to perform semantic analysis again.
3868 return Owned(
3869 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3871 PropertyLoc, Base));
3872 }
3873
3874 /// Build a new Objective-C "isa" expression.
3875 ///
3876 /// By default, performs semantic analysis to build the new expression.
3877 /// Subclasses may override this routine to provide different behavior.
3879 SourceLocation OpLoc, bool IsArrow) {
3880 CXXScopeSpec SS;
3881 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3882 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3883 OpLoc, IsArrow,
3884 SS, SourceLocation(),
3885 /*FirstQualifierInScope=*/nullptr,
3886 NameInfo,
3887 /*TemplateArgs=*/nullptr,
3888 /*S=*/nullptr);
3889 }
3890
3891 /// Build a new shuffle vector expression.
3892 ///
3893 /// By default, performs semantic analysis to build the new expression.
3894 /// Subclasses may override this routine to provide different behavior.
3896 MultiExprArg SubExprs,
3897 SourceLocation RParenLoc) {
3898 // Find the declaration for __builtin_shufflevector
3899 const IdentifierInfo &Name
3900 = SemaRef.Context.Idents.get("__builtin_shufflevector");
3902 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
3903 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3904
3905 // Build a reference to the __builtin_shufflevector builtin
3906 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
3907 Expr *Callee = new (SemaRef.Context)
3908 DeclRefExpr(SemaRef.Context, Builtin, false,
3909 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3910 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
3911 Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
3912 CK_BuiltinFnToFnPtr).get();
3913
3914 // Build the CallExpr
3915 ExprResult TheCall = CallExpr::Create(
3916 SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),
3917 Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc,
3919
3920 // Type-check the __builtin_shufflevector expression.
3921 return SemaRef.BuiltinShuffleVector(cast<CallExpr>(TheCall.get()));
3922 }
3923
3924 /// Build a new convert vector expression.
3926 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3927 SourceLocation RParenLoc) {
3928 return SemaRef.ConvertVectorExpr(SrcExpr, DstTInfo, BuiltinLoc, RParenLoc);
3929 }
3930
3931 /// Build a new template argument pack expansion.
3932 ///
3933 /// By default, performs semantic analysis to build a new pack expansion
3934 /// for a template argument. Subclasses may override this routine to provide
3935 /// different behavior.
3938 std::optional<unsigned> NumExpansions) {
3939 switch (Pattern.getArgument().getKind()) {
3943 EllipsisLoc, NumExpansions);
3944 if (Result.isInvalid())
3945 return TemplateArgumentLoc();
3946
3947 return TemplateArgumentLoc(Result.get(), Result.get());
3948 }
3949
3951 return TemplateArgumentLoc(
3954 NumExpansions),
3955 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
3956 EllipsisLoc);
3957
3965 llvm_unreachable("Pack expansion pattern has no parameter packs");
3966
3968 if (TypeSourceInfo *Expansion
3969 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
3970 EllipsisLoc,
3971 NumExpansions))
3972 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
3973 Expansion);
3974 break;
3975 }
3976
3977 return TemplateArgumentLoc();
3978 }
3979
3980 /// Build a new expression pack expansion.
3981 ///
3982 /// By default, performs semantic analysis to build a new pack expansion
3983 /// for an expression. Subclasses may override this routine to provide
3984 /// different behavior.
3986 std::optional<unsigned> NumExpansions) {
3987 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
3988 }
3989
3990 /// Build a new C++1z fold-expression.
3991 ///
3992 /// By default, performs semantic analysis in order to build a new fold
3993 /// expression.
3995 SourceLocation LParenLoc, Expr *LHS,
3996 BinaryOperatorKind Operator,
3997 SourceLocation EllipsisLoc, Expr *RHS,
3998 SourceLocation RParenLoc,
3999 std::optional<unsigned> NumExpansions) {
4000 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4001 EllipsisLoc, RHS, RParenLoc,
4002 NumExpansions);
4003 }
4004
4005 /// Build an empty C++1z fold-expression with the given operator.
4006 ///
4007 /// By default, produces the fallback value for the fold-expression, or
4008 /// produce an error if there is no fallback value.
4010 BinaryOperatorKind Operator) {
4011 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4012 }
4013
4014 /// Build a new atomic operation expression.
4015 ///
4016 /// By default, performs semantic analysis to build the new expression.
4017 /// Subclasses may override this routine to provide different behavior.
4020 SourceLocation RParenLoc) {
4021 // Use this for all of the locations, since we don't know the difference
4022 // between the call and the expr at this point.
4023 SourceRange Range{BuiltinLoc, RParenLoc};
4024 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4026 }
4027
4029 ArrayRef<Expr *> SubExprs, QualType Type) {
4030 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4031 }
4032
4034 SourceLocation BeginLoc,
4035 SourceLocation EndLoc,
4037 StmtResult StrBlock) {
4038 return getSema().OpenACC().ActOnEndStmtDirective(K, BeginLoc, EndLoc,
4039 Clauses, StrBlock);
4040 }
4041
4042private:
4043 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
4044 QualType ObjectType,
4045 NamedDecl *FirstQualifierInScope,
4046 CXXScopeSpec &SS);
4047
4048 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4049 QualType ObjectType,
4050 NamedDecl *FirstQualifierInScope,
4051 CXXScopeSpec &SS);
4052
4053 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
4054 NamedDecl *FirstQualifierInScope,
4055 CXXScopeSpec &SS);
4056
4057 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4059 bool DeducibleTSTContext);
4060
4062 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4064
4066 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4067 OpenACCDirectiveKind DirKind,
4068 const OpenACCClause *OldClause);
4069};
4070
4071template <typename Derived>
4073 if (!S)
4074 return S;
4075
4076 switch (S->getStmtClass()) {
4077 case Stmt::NoStmtClass: break;
4078
4079 // Transform individual statement nodes
4080 // Pass SDK into statements that can produce a value
4081#define STMT(Node, Parent) \
4082 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4083#define VALUESTMT(Node, Parent) \
4084 case Stmt::Node##Class: \
4085 return getDerived().Transform##Node(cast<Node>(S), SDK);
4086#define ABSTRACT_STMT(Node)
4087#define EXPR(Node, Parent)
4088#include "clang/AST/StmtNodes.inc"
4089
4090 // Transform expressions by calling TransformExpr.
4091#define STMT(Node, Parent)
4092#define ABSTRACT_STMT(Stmt)
4093#define EXPR(Node, Parent) case Stmt::Node##Class:
4094#include "clang/AST/StmtNodes.inc"
4095 {
4096 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
4097
4098 if (SDK == SDK_StmtExprResult)
4099 E = getSema().ActOnStmtExprResult(E);
4100 return getSema().ActOnExprStmt(E, SDK == SDK_Discarded);
4101 }
4102 }
4103
4104 return S;
4105}
4106
4107template<typename Derived>
4109 if (!S)
4110 return S;
4111
4112 switch (S->getClauseKind()) {
4113 default: break;
4114 // Transform individual clause nodes
4115#define GEN_CLANG_CLAUSE_CLASS
4116#define CLAUSE_CLASS(Enum, Str, Class) \
4117 case Enum: \
4118 return getDerived().Transform##Class(cast<Class>(S));
4119#include "llvm/Frontend/OpenMP/OMP.inc"
4120 }
4121
4122 return S;
4123}
4124
4125
4126template<typename Derived>
4128 if (!E)
4129 return E;
4130
4131 switch (E->getStmtClass()) {
4132 case Stmt::NoStmtClass: break;
4133#define STMT(Node, Parent) case Stmt::Node##Class: break;
4134#define ABSTRACT_STMT(Stmt)
4135#define EXPR(Node, Parent) \
4136 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4137#include "clang/AST/StmtNodes.inc"
4138 }
4139
4140 return E;
4141}
4142
4143template<typename Derived>
4145 bool NotCopyInit) {
4146 // Initializers are instantiated like expressions, except that various outer
4147 // layers are stripped.
4148 if (!Init)
4149 return Init;
4150
4151 if (auto *FE = dyn_cast<FullExpr>(Init))
4152 Init = FE->getSubExpr();
4153
4154 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {
4155 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4156 Init = OVE->getSourceExpr();
4157 }
4158
4159 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
4160 Init = MTE->getSubExpr();
4161
4162 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
4163 Init = Binder->getSubExpr();
4164
4165 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
4166 Init = ICE->getSubExprAsWritten();
4167
4168 if (CXXStdInitializerListExpr *ILE =
4169 dyn_cast<CXXStdInitializerListExpr>(Init))
4170 return TransformInitializer(ILE->getSubExpr(), NotCopyInit);
4171
4172 // If this is copy-initialization, we only need to reconstruct
4173 // InitListExprs. Other forms of copy-initialization will be a no-op if
4174 // the initializer is already the right type.
4175 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
4176 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4177 return getDerived().TransformExpr(Init);
4178
4179 // Revert value-initialization back to empty parens.
4180 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
4181 SourceRange Parens = VIE->getSourceRange();
4182 return getDerived().RebuildParenListExpr(Parens.getBegin(), std::nullopt,
4183 Parens.getEnd());
4184 }
4185
4186 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4187 if (isa<ImplicitValueInitExpr>(Init))
4188 return getDerived().RebuildParenListExpr(SourceLocation(), std::nullopt,
4189 SourceLocation());
4190
4191 // Revert initialization by constructor back to a parenthesized or braced list
4192 // of expressions. Any other form of initializer can just be reused directly.
4193 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
4194 return getDerived().TransformExpr(Init);
4195
4196 // If the initialization implicitly converted an initializer list to a
4197 // std::initializer_list object, unwrap the std::initializer_list too.
4198 if (Construct && Construct->isStdInitListInitialization())
4199 return TransformInitializer(Construct->getArg(0), NotCopyInit);
4200
4201 // Enter a list-init context if this was list initialization.
4204 Construct->isListInitialization());
4205
4206 getSema().keepInLifetimeExtendingContext();
4207 SmallVector<Expr*, 8> NewArgs;
4208 bool ArgChanged = false;
4209 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4210 /*IsCall*/true, NewArgs, &ArgChanged))
4211 return ExprError();
4212
4213 // If this was list initialization, revert to syntactic list form.
4214 if (Construct->isListInitialization())
4215 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4216 Construct->getEndLoc());
4217
4218 // Build a ParenListExpr to represent anything else.
4220 if (Parens.isInvalid()) {
4221 // This was a variable declaration's initialization for which no initializer
4222 // was specified.
4223 assert(NewArgs.empty() &&
4224 "no parens or braces but have direct init with arguments?");
4225 return ExprEmpty();
4226 }
4227 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4228 Parens.getEnd());
4229}
4230
4231template<typename Derived>
4233 unsigned NumInputs,
4234 bool IsCall,
4235 SmallVectorImpl<Expr *> &Outputs,
4236 bool *ArgChanged) {
4237 for (unsigned I = 0; I != NumInputs; ++I) {
4238 // If requested, drop call arguments that need to be dropped.
4239 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4240 if (ArgChanged)
4241 *ArgChanged = true;
4242
4243 break;
4244 }
4245
4246 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
4247 Expr *Pattern = Expansion->getPattern();
4248
4250 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4251 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4252
4253 // Determine whether the set of unexpanded parameter packs can and should
4254 // be expanded.
4255 bool Expand = true;
4256 bool RetainExpansion = false;
4257 std::optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions();
4258 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4259 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4260 Pattern->getSourceRange(),
4261 Unexpanded,
4262 Expand, RetainExpansion,
4263 NumExpansions))
4264 return true;
4265
4266 if (!Expand) {
4267 // The transform has determined that we should perform a simple
4268 // transformation on the pack expansion, producing another pack
4269 // expansion.
4270 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4271 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4272 if (OutPattern.isInvalid())
4273 return true;
4274
4275 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4276 Expansion->getEllipsisLoc(),
4277 NumExpansions);
4278 if (Out.isInvalid())
4279 return true;
4280
4281 if (ArgChanged)
4282 *ArgChanged = true;
4283 Outputs.push_back(Out.get());
4284 continue;
4285 }
4286
4287 // Record right away that the argument was changed. This needs
4288 // to happen even if the array expands to nothing.
4289 if (ArgChanged) *ArgChanged = true;
4290
4291 // The transform has determined that we should perform an elementwise
4292 // expansion of the pattern. Do so.
4293 for (unsigned I = 0; I != *NumExpansions; ++I) {
4294 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4295 ExprResult Out = getDerived().TransformExpr(Pattern);
4296 if (Out.isInvalid())
4297 return true;
4298
4299 if (Out.get()->containsUnexpandedParameterPack()) {
4300 Out = getDerived().RebuildPackExpansion(
4301 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4302 if (Out.isInvalid())
4303 return true;
4304 }
4305
4306 Outputs.push_back(Out.get());
4307 }
4308
4309 // If we're supposed to retain a pack expansion, do so by temporarily
4310 // forgetting the partially-substituted parameter pack.
4311 if (RetainExpansion) {
4312 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4313
4314 ExprResult Out = getDerived().TransformExpr(Pattern);
4315 if (Out.isInvalid())
4316 return true;
4317
4318 Out = getDerived().RebuildPackExpansion(
4319 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4320 if (Out.isInvalid())
4321 return true;
4322
4323 Outputs.push_back(Out.get());
4324 }
4325
4326 continue;
4327 }
4328
4330 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4331 : getDerived().TransformExpr(Inputs[I]);
4332 if (Result.isInvalid())
4333 return true;
4334
4335 if (Result.get() != Inputs[I] && ArgChanged)
4336 *ArgChanged = true;
4337
4338 Outputs.push_back(Result.get());
4339 }
4340
4341 return false;
4342}
4343
4344template <typename Derived>
4347 if (Var) {
4348 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4349 getDerived().TransformDefinition(Var->getLocation(), Var));
4350
4351 if (!ConditionVar)
4352 return Sema::ConditionError();
4353
4354 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4355 }
4356
4357 if (Expr) {
4358 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4359
4360 if (CondExpr.isInvalid())
4361 return Sema::ConditionError();
4362
4363 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4364 /*MissingOK=*/true);
4365 }
4366
4367 return Sema::ConditionResult();
4368}
4369
4370template <typename Derived>
4372 NestedNameSpecifierLoc NNS, QualType ObjectType,
4373 NamedDecl *FirstQualifierInScope) {
4375
4376 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4377 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4378 Qualifier = Qualifier.getPrefix())
4379 Qualifiers.push_back(Qualifier);
4380 };
4381 insertNNS(NNS);
4382
4383 CXXScopeSpec SS;
4384 while (!Qualifiers.empty()) {
4385 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4387
4388 switch (QNNS->getKind()) {
4392 ObjectType);
4393 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false,
4394 SS, FirstQualifierInScope, false))
4395 return NestedNameSpecifierLoc();
4396 break;
4397 }
4398
4400 NamespaceDecl *NS =
4401 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4402 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4403 SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
4404 break;
4405 }
4406
4408 NamespaceAliasDecl *Alias =
4409 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4411 SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
4412 Q.getLocalEndLoc());
4413 break;
4414 }
4415
4417 // There is no meaningful transformation that one could perform on the
4418 // global scope.
4419 SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
4420 break;
4421
4423 CXXRecordDecl *RD =
4424 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4425 SourceLocation(), QNNS->getAsRecordDecl()));
4426 SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc());
4427 break;
4428 }
4429
4432 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4433 FirstQualifierInScope, SS);
4434
4435 if (!TL)
4436 return NestedNameSpecifierLoc();
4437
4438 QualType T = TL.getType();
4439 if (T->isDependentType() || T->isRecordType() ||
4440 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4441 if (T->isEnumeralType())
4442 SemaRef.Diag(TL.getBeginLoc(),
4443 diag::warn_cxx98_compat_enum_nested_name_spec);
4444
4445 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4446 SS.Adopt(ETL.getQualifierLoc());
4447 TL = ETL.getNamedTypeLoc();
4448 }
4449
4450 SS.Extend(SemaRef.Context, TL.getTemplateKeywordLoc(), TL,
4451 Q.getLocalEndLoc());
4452 break;
4453 }
4454 // If the nested-name-specifier is an invalid type def, don't emit an
4455 // error because a previous error should have already been emitted.
4457 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4458 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
4459 << T << SS.getRange();
4460 }
4461 return NestedNameSpecifierLoc();
4462 }
4463 }
4464
4465 // The qualifier-in-scope and object type only apply to the leftmost entity.
4466 FirstQualifierInScope = nullptr;
4467 ObjectType = QualType();
4468 }
4469
4470 // Don't rebuild the nested-name-specifier if we don't have to.
4471 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4472 !getDerived().AlwaysRebuild())
4473 return NNS;
4474
4475 // If we can re-use the source-location data from the original
4476 // nested-name-specifier, do so.
4477 if (SS.location_size() == NNS.getDataLength() &&
4478 memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)
4480
4481 // Allocate new nested-name-specifier location information.
4482 return SS.getWithLocInContext(SemaRef.Context);
4483}
4484
4485template<typename Derived>
4489 DeclarationName Name = NameInfo.getName();
4490 if (!Name)
4491 return DeclarationNameInfo();
4492
4493 switch (Name.getNameKind()) {
4501 return NameInfo;
4502
4504 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4505 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4506 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4507 if (!NewTemplate)
4508 return DeclarationNameInfo();
4509
4510 DeclarationNameInfo NewNameInfo(NameInfo);
4511 NewNameInfo.setName(
4513 return NewNameInfo;
4514 }
4515
4519 TypeSourceInfo *NewTInfo;
4520 CanQualType NewCanTy;
4521 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4522 NewTInfo = getDerived().TransformType(OldTInfo);
4523 if (!NewTInfo)
4524 return DeclarationNameInfo();
4525 NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
4526 }
4527 else {
4528 NewTInfo = nullptr;
4529 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4530 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4531 if (NewT.isNull())
4532 return DeclarationNameInfo();
4533 NewCanTy = SemaRef.Context.getCanonicalType(NewT);
4534 }
4535
4536 DeclarationName NewName
4537 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
4538 NewCanTy);
4539 DeclarationNameInfo NewNameInfo(NameInfo);
4540 NewNameInfo.setName(NewName);
4541 NewNameInfo.setNamedTypeInfo(NewTInfo);
4542 return NewNameInfo;
4543 }
4544 }
4545
4546 llvm_unreachable("Unknown name kind.");
4547}
4548
4549template<typename Derived>
4552 TemplateName Name,
4553 SourceLocation NameLoc,
4554 QualType ObjectType,
4555 NamedDecl *FirstQualifierInScope,
4556 bool AllowInjectedClassName) {
4557 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4558 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4559 assert(Template && "qualified template name must refer to a template");
4560
4561 TemplateDecl *TransTemplate
4562 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4563 Template));
4564 if (!TransTemplate)
4565 return TemplateName();
4566
4567 if (!getDerived().AlwaysRebuild() &&
4568 SS.getScopeRep() == QTN->getQualifier() &&
4569 TransTemplate == Template)
4570 return Name;
4571
4572 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4573 TransTemplate);
4574 }
4575
4576 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4577 if (SS.getScopeRep()) {
4578 // These apply to the scope specifier, not the template.
4579 ObjectType = QualType();
4580 FirstQualifierInScope = nullptr;
4581 }
4582
4583 if (!getDerived().AlwaysRebuild() &&
4584 SS.getScopeRep() == DTN->getQualifier() &&
4585 ObjectType.isNull())
4586 return Name;
4587
4588 // FIXME: Preserve the location of the "template" keyword.
4589 SourceLocation TemplateKWLoc = NameLoc;
4590
4591 if (DTN->isIdentifier()) {
4592 return getDerived().RebuildTemplateName(SS,
4593 TemplateKWLoc,
4594 *DTN->getIdentifier(),
4595 NameLoc,
4596 ObjectType,
4597 FirstQualifierInScope,
4598 AllowInjectedClassName);
4599 }
4600
4601 return getDerived().RebuildTemplateName(SS, TemplateKWLoc,
4602 DTN->getOperator(), NameLoc,
4603 ObjectType, AllowInjectedClassName);
4604 }
4605
4606 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4607 TemplateDecl *TransTemplate
4608 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4609 Template));
4610 if (!TransTemplate)
4611 return TemplateName();
4612
4613 if (!getDerived().AlwaysRebuild() &&
4614 TransTemplate == Template)
4615 return Name;
4616
4617 return TemplateName(TransTemplate);
4618 }
4619
4621 = Name.getAsSubstTemplateTemplateParmPack()) {
4622 return getDerived().RebuildTemplateName(
4623 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4624 SubstPack->getIndex(), SubstPack->getFinal());
4625 }
4626
4627 // These should be getting filtered out before they reach the AST.
4628 llvm_unreachable("overloaded function decl survived to here");
4629}
4630
4631template<typename Derived>
4633 const TemplateArgument &Arg,
4634 TemplateArgumentLoc &Output) {
4635 Output = getSema().getTrivialTemplateArgumentLoc(
4636 Arg, QualType(), getDerived().getBaseLocation());
4637}
4638
4639template <typename Derived>
4641 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4642 bool Uneval) {
4643 const TemplateArgument &Arg = Input.getArgument();
4644 switch (Arg.getKind()) {
4647 llvm_unreachable("Unexpected TemplateArgument");
4648
4653 // Transform a resolved template argument straight to a resolved template
4654 // argument. We get here when substituting into an already-substituted
4655 // template type argument during concept satisfaction checking.
4657 QualType NewT = getDerived().TransformType(T);
4658 if (NewT.isNull())
4659 return true;
4660
4662 ? Arg.getAsDecl()
4663 : nullptr;
4664 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4665 getDerived().getBaseLocation(), D))
4666 : nullptr;
4667 if (D && !NewD)
4668 return true;
4669
4670 if (NewT == T && D == NewD)
4671 Output = Input;
4672 else if (Arg.getKind() == TemplateArgument::Integral)
4673 Output = TemplateArgumentLoc(
4674 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4676 else if (Arg.getKind() == TemplateArgument::NullPtr)
4677 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4679 else if (Arg.getKind() == TemplateArgument::Declaration)
4680 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4683 Output = TemplateArgumentLoc(
4684 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
4686 else
4687 llvm_unreachable("unexpected template argument kind");
4688
4689 return false;
4690 }
4691
4693 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4694 if (!DI)
4695 DI = InventTypeSourceInfo(Input.getArgument().getAsType());
4696
4697 DI = getDerived().TransformType(DI);
4698 if (!DI)
4699 return true;
4700
4701 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4702 return false;
4703 }
4704
4706 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4707 if (QualifierLoc) {
4708 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4709 if (!QualifierLoc)
4710 return true;
4711 }
4712
4713 CXXScopeSpec SS;
4714 SS.Adopt(QualifierLoc);
4715 TemplateName Template = getDerived().TransformTemplateName(
4716 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4717 if (Template.isNull())
4718 return true;
4719
4720 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4721 QualifierLoc, Input.getTemplateNameLoc());
4722 return false;
4723 }
4724
4726 llvm_unreachable("Caller should expand pack expansions");
4727
4729 // Template argument expressions are constant expressions.
4731 getSema(),
4734 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4736
4737 Expr *InputExpr = Input.getSourceExpression();
4738 if (!InputExpr)
4739 InputExpr = Input.getArgument().getAsExpr();
4740
4741 ExprResult E = getDerived().TransformExpr(InputExpr);
4742 E = SemaRef.ActOnConstantExpression(E);
4743 if (E.isInvalid())
4744 return true;
4745 Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get());
4746 return false;
4747 }
4748 }
4749
4750 // Work around bogus GCC warning
4751 return true;
4752}
4753
4754/// Iterator adaptor that invents template argument location information
4755/// for each of the template arguments in its underlying iterator.
4756template<typename Derived, typename InputIterator>
4759 InputIterator Iter;
4760
4761public:
4764 typedef typename std::iterator_traits<InputIterator>::difference_type
4766 typedef std::input_iterator_tag iterator_category;
4767
4768 class pointer {
4770
4771 public:
4772 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4773
4774 const TemplateArgumentLoc *operator->() const { return &Arg; }
4775 };
4776
4778 InputIterator Iter)
4779 : Self(Self), Iter(Iter) { }
4780
4782 ++Iter;
4783 return *this;
4784 }
4785
4788 ++(*this);
4789 return Old;
4790 }
4791
4794 Self.InventTemplateArgumentLoc(*Iter, Result);
4795 return Result;
4796 }
4797
4798 pointer operator->() const { return pointer(**this); }
4799
4802 return X.Iter == Y.Iter;
4803 }
4804
4807 return X.Iter != Y.Iter;
4808 }
4809};
4810
4811template<typename Derived>
4812template<typename InputIterator>
4814 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
4815 bool Uneval) {
4816 for (; First != Last; ++First) {
4819
4820 if (In.getArgument().getKind() == TemplateArgument::Pack) {
4821 // Unpack argument packs, which we translate them into separate
4822 // arguments.
4823 // FIXME: We could do much better if we could guarantee that the
4824 // TemplateArgumentLocInfo for the pack expansion would be usable for
4825 // all of the template arguments in the argument pack.
4826 typedef TemplateArgumentLocInventIterator<Derived,
4828 PackLocIterator;
4829 if (TransformTemplateArguments(PackLocIterator(*this,
4830 In.getArgument().pack_begin()),
4831 PackLocIterator(*this,
4832 In.getArgument().pack_end()),
4833 Outputs, Uneval))
4834 return true;
4835
4836 continue;
4837 }
4838
4839 if (In.getArgument().isPackExpansion()) {
4840 // We have a pack expansion, for which we will be substituting into
4841 // the pattern.
4842 SourceLocation Ellipsis;
4843 std::optional<unsigned> OrigNumExpansions;
4844 TemplateArgumentLoc Pattern
4845 = getSema().getTemplateArgumentPackExpansionPattern(
4846 In, Ellipsis, OrigNumExpansions);
4847
4849 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4850 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4851
4852 // Determine whether the set of unexpanded parameter packs can and should
4853 // be expanded.
4854 bool Expand = true;
4855 bool RetainExpansion = false;
4856 std::optional<unsigned> NumExpansions = OrigNumExpansions;
4857 if (getDerived().TryExpandParameterPacks(Ellipsis,
4858 Pattern.getSourceRange(),
4859 Unexpanded,
4860 Expand,
4861 RetainExpansion,
4862 NumExpansions))
4863 return true;
4864
4865 if (!Expand) {
4866 // The transform has determined that we should perform a simple
4867 // transformation on the pack expansion, producing another pack
4868 // expansion.
4869 TemplateArgumentLoc OutPattern;
4870 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4871 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
4872 return true;
4873
4874 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
4875 NumExpansions);
4876 if (Out.getArgument().isNull())
4877 return true;
4878
4879 Outputs.addArgument(Out);
4880 continue;
4881 }
4882
4883 // The transform has determined that we should perform an elementwise
4884 // expansion of the pattern. Do so.
4885 for (unsigned I = 0; I != *NumExpansions; ++I) {
4886 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4887
4888 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4889 return true;
4890
4891 if (Out.getArgument().containsUnexpandedParameterPack()) {
4892 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4893 OrigNumExpansions);
4894 if (Out.getArgument().isNull())
4895 return true;
4896 }
4897
4898 Outputs.addArgument(Out);
4899 }
4900
4901 // If we're supposed to retain a pack expansion, do so by temporarily
4902 // forgetting the partially-substituted parameter pack.
4903 if (RetainExpansion) {
4904 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4905
4906 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
4907 return true;
4908
4909 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
4910 OrigNumExpansions);
4911 if (Out.getArgument().isNull())
4912 return true;
4913
4914 Outputs.addArgument(Out);
4915 }
4916
4917 continue;
4918 }
4919
4920 // The simple case:
4921 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
4922 return true;
4923
4924 Outputs.addArgument(Out);
4925 }
4926
4927 return false;
4928
4929}
4930
4931//===----------------------------------------------------------------------===//
4932// Type transformation
4933//===----------------------------------------------------------------------===//
4934
4935template<typename Derived>
4937 if (getDerived().AlreadyTransformed(T))
4938 return T;
4939
4940 // Temporary workaround. All of these transformations should
4941 // eventually turn into transformations on TypeLocs.
4942 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4943 getDerived().getBaseLocation());
4944
4945 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
4946
4947 if (!NewDI)
4948 return QualType();
4949
4950 return NewDI->getType();
4951}
4952
4953template<typename Derived>
4955 // Refine the base location to the type's location.
4956 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
4957 getDerived().getBaseEntity());
4958 if (getDerived().AlreadyTransformed(DI->getType()))
4959 return DI;
4960
4961 TypeLocBuilder TLB;
4962
4963 TypeLoc TL = DI->getTypeLoc();
4964 TLB.reserve(TL.getFullDataSize());
4965
4966 QualType Result = getDerived().TransformType(TLB, TL);
4967 if (Result.isNull())
4968 return nullptr;
4969
4970 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
4971}
4972
4973template<typename Derived>
4976 switch (T.getTypeLocClass()) {
4977#define ABSTRACT_TYPELOC(CLASS, PARENT)
4978#define TYPELOC(CLASS, PARENT) \
4979 case TypeLoc::CLASS: \
4980 return getDerived().Transform##CLASS##Type(TLB, \
4981 T.castAs<CLASS##TypeLoc>());
4982#include "clang/AST/TypeLocNodes.def"
4983 }
4984
4985 llvm_unreachable("unhandled type loc!");
4986}
4987
4988template<typename Derived>
4990 if (!isa<DependentNameType>(T))
4991 return TransformType(T);
4992
4993 if (getDerived().AlreadyTransformed(T))
4994 return T;
4995 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
4996 getDerived().getBaseLocation());
4997 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
4998 return NewDI ? NewDI->getType() : QualType();
4999}
5000
5001template<typename Derived>
5004 if (!isa<DependentNameType>(DI->getType()))
5005 return TransformType(DI);
5006
5007 // Refine the base location to the type's location.
5008 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5009 getDerived().getBaseEntity());
5010 if (getDerived().AlreadyTransformed(DI->getType()))
5011 return DI;
5012
5013 TypeLocBuilder TLB;
5014
5015 TypeLoc TL = DI->getTypeLoc();
5016 TLB.reserve(TL.getFullDataSize());
5017
5018 auto QTL = TL.getAs<QualifiedTypeLoc>();
5019 if (QTL)
5020 TL = QTL.getUnqualifiedLoc();
5021
5022 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5023
5024 QualType Result = getDerived().TransformDependentNameType(
5025 TLB, DNTL, /*DeducedTSTContext*/true);
5026 if (Result.isNull())
5027 return nullptr;
5028
5029 if (QTL) {
5030 Result = getDerived().RebuildQualifiedType(Result, QTL);
5031 if (Result.isNull())
5032 return nullptr;
5034 }
5035
5036 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5037}
5038
5039template<typename Derived>
5044 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5045 auto SuppressObjCLifetime =
5046 T.getType().getLocalQualifiers().hasObjCLifetime();
5047 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5048 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5049 SuppressObjCLifetime);
5050 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5051 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5052 TLB, STTP, SuppressObjCLifetime);
5053 } else {
5054 Result = getDerived().TransformType(TLB, UnqualTL);
5055 }
5056
5057 if (Result.isNull())
5058 return QualType();
5059
5060 Result = getDerived().RebuildQualifiedType(Result, T);
5061
5062 if (Result.isNull())
5063 return QualType();
5064
5065 // RebuildQualifiedType might have updated the type, but not in a way
5066 // that invalidates the TypeLoc. (There's no location information for
5067 // qualifiers.)
5069
5070 return Result;
5071}
5072
5073template <typename Derived>
5075 QualifiedTypeLoc TL) {
5076
5078 Qualifiers Quals = TL.getType().getLocalQualifiers();
5079
5080 if ((T.getAddressSpace() != LangAS::Default &&
5081 Quals.getAddressSpace() != LangAS::Default) &&
5082 T.getAddressSpace() != Quals.getAddressSpace()) {
5083 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)
5084 << TL.getType() << T;
5085 return QualType();
5086 }
5087
5088 // C++ [dcl.fct]p7:
5089 // [When] adding cv-qualifications on top of the function type [...] the
5090 // cv-qualifiers are ignored.
5091 if (T->isFunctionType()) {
5093 Quals.getAddressSpace());
5094 return T;
5095 }
5096
5097 // C++ [dcl.ref]p1:
5098 // when the cv-qualifiers are introduced through the use of a typedef-name
5099 // or decltype-specifier [...] the cv-qualifiers are ignored.
5100 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5101 // applied to a reference type.
5102 if (T->isReferenceType()) {
5103 // The only qualifier that applies to a reference type is restrict.
5104 if (!Quals.hasRestrict())
5105 return T;
5107 }
5108
5109 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5110 // resulting type.
5111 if (Quals.hasObjCLifetime()) {
5112 if (!T->isObjCLifetimeType() && !T->isDependentType())
5113 Quals.removeObjCLifetime();
5114 else if (T.getObjCLifetime()) {
5115 // Objective-C ARC:
5116 // A lifetime qualifier applied to a substituted template parameter
5117 // overrides the lifetime qualifier from the template argument.
5118 const AutoType *AutoTy;
5119 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
5120 // 'auto' types behave the same way as template parameters.
5121 QualType Deduced = AutoTy->getDeducedType();
5122 Qualifiers Qs = Deduced.getQualifiers();
5123 Qs.removeObjCLifetime();
5124 Deduced =
5125 SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);
5126 T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),
5127 AutoTy->isDependentType(),
5128 /*isPack=*/false,
5129 AutoTy->getTypeConstraintConcept(),
5130 AutoTy->getTypeConstraintArguments());
5131 } else {
5132 // Otherwise, complain about the addition of a qualifier to an
5133 // already-qualified type.
5134 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5135 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
5136 Quals.removeObjCLifetime();
5137 }
5138 }
5139 }
5140
5141 return SemaRef.BuildQualifiedType(T, Loc, Quals);
5142}
5143
5144template<typename Derived>
5145TypeLoc
5147 QualType ObjectType,
5148 NamedDecl *UnqualLookup,
5149 CXXScopeSpec &SS) {
5150 if (getDerived().AlreadyTransformed(TL.getType()))
5151 return TL;
5152
5153 TypeSourceInfo *TSI =
5154 TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS);
5155 if (TSI)
5156 return TSI->getTypeLoc();
5157 return TypeLoc();
5158}
5159
5160template<typename Derived>
5161TypeSourceInfo *
5162TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5163 QualType ObjectType,
5164 NamedDecl *UnqualLookup,
5165 CXXScopeSpec &SS) {
5166 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5167 return TSInfo;
5168
5169 return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType,
5170 UnqualLookup, SS);
5171}
5172
5173template <typename Derived>
5174TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5175 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5176 CXXScopeSpec &SS) {
5177 QualType T = TL.getType();
5178 assert(!getDerived().AlreadyTransformed(T));
5179
5180 TypeLocBuilder TLB;
5181 QualType Result;
5182
5183 if (isa<TemplateSpecializationType>(T)) {
5184 TemplateSpecializationTypeLoc SpecTL =
5185 TL.castAs<TemplateSpecializationTypeLoc>();
5186
5187 TemplateName Template = getDerived().TransformTemplateName(
5188 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5189 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5190 if (Template.isNull())
5191 return nullptr;
5192
5193 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5194 Template);
5195 } else if (isa<DependentTemplateSpecializationType>(T)) {
5196 DependentTemplateSpecializationTypeLoc SpecTL =
5197 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5198
5199 TemplateName Template
5200 = getDerived().RebuildTemplateName(SS,
5201 SpecTL.getTemplateKeywordLoc(),
5202 *SpecTL.getTypePtr()->getIdentifier(),
5203 SpecTL.getTemplateNameLoc(),
5204 ObjectType, UnqualLookup,
5205 /*AllowInjectedClassName*/true);
5206 if (Template.isNull())
5207 return nullptr;
5208
5209 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5210 SpecTL,
5211 Template,
5212 SS);
5213 } else {
5214 // Nothing special needs to be done for these.
5215 Result = getDerived().TransformType(TLB, TL);
5216 }
5217
5218 if (Result.isNull())
5219 return nullptr;
5220
5221 return TLB.getTypeSourceInfo(SemaRef.Context, Result);
5222}
5223
5224template <class TyLoc> static inline
5226 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5227 NewT.setNameLoc(T.getNameLoc());
5228 return T.getType();
5229}
5230
5231template<typename Derived>
5232QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5233 BuiltinTypeLoc T) {
5234 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
5235 NewT.setBuiltinLoc(T.getBuiltinLoc());
5236 if (T.needsExtraLocalData())
5237 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5238 return T.getType();
5239}
5240
5241template<typename Derived>
5242QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5243 ComplexTypeLoc T) {
5244 // FIXME: recurse?
5245 return TransformTypeSpecType(TLB, T);
5246}
5247
5248template <typename Derived>
5249QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5250 AdjustedTypeLoc TL) {
5251 // Adjustments applied during transformation are handled elsewhere.
5252 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5253}
5254
5255template<typename Derived>
5256QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5257 DecayedTypeLoc TL) {
5258 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5259 if (OriginalType.isNull())
5260 return QualType();
5261
5262 QualType Result = TL.getType();
5263 if (getDerived().AlwaysRebuild() ||
5264 OriginalType != TL.getOriginalLoc().getType())
5265 Result = SemaRef.Context.getDecayedType(OriginalType);
5266 TLB.push<DecayedTypeLoc>(Result);
5267 // Nothing to set for DecayedTypeLoc.
5268 return Result;
5269}
5270
5271template <typename Derived>
5272QualType
5273TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5274 ArrayParameterTypeLoc TL) {
5275 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5276 if (OriginalType.isNull())
5277 return QualType();
5278
5279 QualType Result = TL.getType();
5280 if (getDerived().AlwaysRebuild() ||
5281 OriginalType != TL.getElementLoc().getType())
5282 Result = SemaRef.Context.getArrayParameterType(OriginalType);
5283 TLB.push<ArrayParameterTypeLoc>(Result);
5284 // Nothing to set for ArrayParameterTypeLoc.
5285 return Result;
5286}
5287
5288template<typename Derived>
5289QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5290 PointerTypeLoc TL) {
5291 QualType PointeeType
5292 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5293 if (PointeeType.isNull())
5294 return QualType();
5295
5296 QualType Result = TL.getType();
5297 if (PointeeType->getAs<ObjCObjectType>()) {
5298 // A dependent pointer type 'T *' has is being transformed such
5299 // that an Objective-C class type is being replaced for 'T'. The
5300 // resulting pointer type is an ObjCObjectPointerType, not a
5301 // PointerType.
5302 Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
5303
5304 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
5305 NewT.setStarLoc(TL.getStarLoc());
5306 return Result;
5307 }
5308
5309 if (getDerived().AlwaysRebuild() ||
5310 PointeeType != TL.getPointeeLoc().getType()) {
5311 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5312 if (Result.isNull())
5313 return QualType();
5314 }
5315
5316 // Objective-C ARC can add lifetime qualifiers to the type that we're
5317 // pointing to.
5318 TLB.TypeWasModifiedSafely(Result->getPointeeType());
5319
5320 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
5321 NewT.setSigilLoc(TL.getSigilLoc());
5322 return Result;
5323}
5324
5325template<typename Derived>
5326QualType
5327TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5328 BlockPointerTypeLoc TL) {
5329 QualType PointeeType
5330 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5331 if (PointeeType.isNull())
5332 return QualType();
5333
5334 QualType Result = TL.getType();
5335 if (getDerived().AlwaysRebuild() ||
5336 PointeeType != TL.getPointeeLoc().getType()) {
5337 Result = getDerived().RebuildBlockPointerType(PointeeType,
5338 TL.getSigilLoc());
5339 if (Result.isNull())
5340 return QualType();
5341 }
5342
5343 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
5344 NewT.setSigilLoc(TL.getSigilLoc());
5345 return Result;
5346}
5347
5348/// Transforms a reference type. Note that somewhat paradoxically we
5349/// don't care whether the type itself is an l-value type or an r-value
5350/// type; we only care if the type was *written* as an l-value type
5351/// or an r-value type.
5352template<typename Derived>
5353QualType
5355 ReferenceTypeLoc TL) {
5356 const ReferenceType *T = TL.getTypePtr();
5357
5358 // Note that this works with the pointee-as-written.
5359 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5360 if (PointeeType.isNull())
5361 return QualType();
5362
5363 QualType Result = TL.getType();
5364 if (getDerived().AlwaysRebuild() ||
5365 PointeeType != T->getPointeeTypeAsWritten()) {
5366 Result = getDerived().RebuildReferenceType(PointeeType,
5367 T->isSpelledAsLValue(),
5368 TL.getSigilLoc());
5369 if (Result.isNull())
5370 return QualType();
5371 }
5372
5373 // Objective-C ARC can add lifetime qualifiers to the type that we're
5374 // referring to.
5377
5378 // r-value references can be rebuilt as l-value references.
5379 ReferenceTypeLoc NewTL;
5380 if (isa<LValueReferenceType>(Result))
5381 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
5382 else
5383 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
5384 NewTL.setSigilLoc(TL.getSigilLoc());
5385
5386 return Result;
5387}
5388
5389template<typename Derived>
5393 return TransformReferenceType(TLB, TL);
5394}
5395
5396template<typename Derived>
5397QualType
5398TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5399 RValueReferenceTypeLoc TL) {
5400 return TransformReferenceType(TLB, TL);
5401}
5402
5403template<typename Derived>
5404QualType
5405TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5406 MemberPointerTypeLoc TL) {
5407 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5408 if (PointeeType.isNull())
5409 return QualType();
5410
5411 TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
5412 TypeSourceInfo *NewClsTInfo = nullptr;
5413 if (OldClsTInfo) {
5414 NewClsTInfo = getDerived().TransformType(OldClsTInfo);
5415 if (!NewClsTInfo)
5416 return QualType();
5417 }
5418
5419 const MemberPointerType *T = TL.getTypePtr();
5420 QualType OldClsType = QualType(T->getClass(), 0);
5421 QualType NewClsType;
5422 if (NewClsTInfo)
5423 NewClsType = NewClsTInfo->getType();
5424 else {
5425 NewClsType = getDerived().TransformType(OldClsType);
5426 if (NewClsType.isNull())
5427 return QualType();
5428 }
5429
5430 QualType Result = TL.getType();
5431 if (getDerived().AlwaysRebuild() ||
5432 PointeeType != T->getPointeeType() ||
5433 NewClsType != OldClsType) {
5434 Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
5435 TL.getStarLoc());
5436 if (Result.isNull())
5437 return QualType();
5438 }
5439
5440 // If we had to adjust the pointee type when building a member pointer, make
5441 // sure to push TypeLoc info for it.
5442 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5443 if (MPT && PointeeType != MPT->getPointeeType()) {
5444 assert(isa<AdjustedType>(MPT->getPointeeType()));
5445 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
5446 }
5447
5448 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
5449 NewTL.setSigilLoc(TL.getSigilLoc());
5450 NewTL.setClassTInfo(NewClsTInfo);
5451
5452 return Result;
5453}
5454
5455template<typename Derived>
5456QualType
5457TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5458 ConstantArrayTypeLoc TL) {
5459 const ConstantArrayType *T = TL.getTypePtr();
5460 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5461 if (ElementType.isNull())
5462 return QualType();
5463
5464 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5465 Expr *OldSize = TL.getSizeExpr();
5466 if (!OldSize)
5467 OldSize = const_cast<Expr*>(T->getSizeExpr());
5468 Expr *NewSize = nullptr;
5469 if (OldSize) {
5470 EnterExpressionEvaluationContext Unevaluated(
5472 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5473 NewSize = SemaRef.ActOnConstantExpression(NewSize).get();
5474 }
5475
5476 QualType Result = TL.getType();
5477 if (getDerived().AlwaysRebuild() ||
5478 ElementType != T->getElementType() ||
5479 (T->getSizeExpr() && NewSize != OldSize)) {
5480 Result = getDerived().RebuildConstantArrayType(ElementType,
5481 T->getSizeModifier(),
5482 T->getSize(), NewSize,
5483 T->getIndexTypeCVRQualifiers(),
5484 TL.getBracketsRange());
5485 if (Result.isNull())
5486 return QualType();
5487 }
5488
5489 // We might have either a ConstantArrayType or a VariableArrayType now:
5490 // a ConstantArrayType is allowed to have an element type which is a
5491 // VariableArrayType if the type is dependent. Fortunately, all array
5492 // types have the same location layout.
5493 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5494 NewTL.setLBracketLoc(TL.getLBracketLoc());
5495 NewTL.setRBracketLoc(TL.getRBracketLoc());
5496 NewTL.setSizeExpr(NewSize);
5497
5498 return Result;
5499}
5500
5501template<typename Derived>
5502QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5503 TypeLocBuilder &TLB,
5504 IncompleteArrayTypeLoc TL) {
5505 const IncompleteArrayType *T = TL.getTypePtr();
5506 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5507 if (ElementType.isNull())
5508 return QualType();
5509
5510 QualType Result = TL.getType();
5511 if (getDerived().AlwaysRebuild() ||
5512 ElementType != T->getElementType()) {
5513 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5514 T->getSizeModifier(),
5515 T->getIndexTypeCVRQualifiers(),
5516 TL.getBracketsRange());
5517 if (Result.isNull())
5518 return QualType();
5519 }
5520
5521 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
5522 NewTL.setLBracketLoc(TL.getLBracketLoc());
5523 NewTL.setRBracketLoc(TL.getRBracketLoc());
5524 NewTL.setSizeExpr(nullptr);
5525
5526 return Result;
5527}
5528
5529template<typename Derived>
5530QualType
5531TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5532 VariableArrayTypeLoc TL) {
5533 const VariableArrayType *T = TL.getTypePtr();
5534 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5535 if (ElementType.isNull())
5536 return QualType();
5537
5538 ExprResult SizeResult;
5539 {
5540 EnterExpressionEvaluationContext Context(
5542 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5543 }
5544 if (SizeResult.isInvalid())
5545 return QualType();
5546 SizeResult =
5547 SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);
5548 if (SizeResult.isInvalid())
5549 return QualType();
5550
5551 Expr *Size = SizeResult.get();
5552
5553 QualType Result = TL.getType();
5554 if (getDerived().AlwaysRebuild() ||
5555 ElementType != T->getElementType() ||
5556 Size != T->getSizeExpr()) {
5557 Result = getDerived().RebuildVariableArrayType(ElementType,
5558 T->getSizeModifier(),
5559 Size,
5560 T->getIndexTypeCVRQualifiers(),
5561 TL.getBracketsRange());
5562 if (Result.isNull())
5563 return QualType();
5564 }
5565
5566 // We might have constant size array now, but fortunately it has the same
5567 // location layout.
5568 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5569 NewTL.setLBracketLoc(TL.getLBracketLoc());
5570 NewTL.setRBracketLoc(TL.getRBracketLoc());
5571 NewTL.setSizeExpr(Size);
5572
5573 return Result;
5574}
5575
5576template<typename Derived>
5577QualType
5578TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5579 DependentSizedArrayTypeLoc TL) {
5580 const DependentSizedArrayType *T = TL.getTypePtr();
5581 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5582 if (ElementType.isNull())
5583 return QualType();
5584
5585 // Array bounds are constant expressions.
5586 EnterExpressionEvaluationContext Unevaluated(
5588
5589 // If we have a VLA then it won't be a constant.
5590 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5591
5592 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5593 Expr *origSize = TL.getSizeExpr();
5594 if (!origSize) origSize = T->getSizeExpr();
5595
5596 ExprResult sizeResult
5597 = getDerived().TransformExpr(origSize);
5598 sizeResult = SemaRef.ActOnConstantExpression(sizeResult);
5599 if (sizeResult.isInvalid())
5600 return QualType();
5601
5602 Expr *size = sizeResult.get();
5603
5604 QualType Result = TL.getType();
5605 if (getDerived().AlwaysRebuild() ||
5606 ElementType != T->getElementType() ||
5607 size != origSize) {
5608 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5609 T->getSizeModifier(),
5610 size,
5611 T->getIndexTypeCVRQualifiers(),
5612 TL.getBracketsRange());
5613 if (Result.isNull())
5614 return QualType();
5615 }
5616
5617 // We might have any sort of array type now, but fortunately they
5618 // all have the same location layout.
5619 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5620 NewTL.setLBracketLoc(TL.getLBracketLoc());
5621 NewTL.setRBracketLoc(TL.getRBracketLoc());
5622 NewTL.setSizeExpr(size);
5623
5624 return Result;
5625}
5626
5627template <typename Derived>
5628QualType TreeTransform<Derived>::TransformDependentVectorType(
5629 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5630 const DependentVectorType *T = TL.getTypePtr();
5631 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5632 if (ElementType.isNull())
5633 return QualType();
5634
5635 EnterExpressionEvaluationContext Unevaluated(
5637
5638 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5639 Size = SemaRef.ActOnConstantExpression(Size);
5640 if (Size.isInvalid())
5641 return QualType();
5642
5643 QualType Result = TL.getType();
5644 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5645 Size.get() != T->getSizeExpr()) {
5646 Result = getDerived().RebuildDependentVectorType(
5647 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5648 if (Result.isNull())
5649 return QualType();
5650 }
5651
5652 // Result might be dependent or not.
5653 if (isa<DependentVectorType>(Result)) {
5654 DependentVectorTypeLoc NewTL =
5655 TLB.push<DependentVectorTypeLoc>(Result);
5656 NewTL.setNameLoc(TL.getNameLoc());
5657 } else {
5658 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5659 NewTL.setNameLoc(TL.getNameLoc());
5660 }
5661
5662 return Result;
5663}
5664
5665template<typename Derived>
5666QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5667 TypeLocBuilder &TLB,
5668 DependentSizedExtVectorTypeLoc TL) {
5669 const DependentSizedExtVectorType *T = TL.getTypePtr();
5670
5671 // FIXME: ext vector locs should be nested
5672 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5673 if (ElementType.isNull())
5674 return QualType();
5675
5676 // Vector sizes are constant expressions.
5677 EnterExpressionEvaluationContext Unevaluated(
5679
5680 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5681 Size = SemaRef.ActOnConstantExpression(Size);
5682 if (Size.isInvalid())
5683 return QualType();
5684
5685 QualType Result = TL.getType();
5686 if (getDerived().AlwaysRebuild() ||
5687 ElementType != T->getElementType() ||
5688 Size.get() != T->getSizeExpr()) {
5689 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5690 Size.get(),
5691 T->getAttributeLoc());
5692 if (Result.isNull())
5693 return QualType();
5694 }
5695
5696 // Result might be dependent or not.
5697 if (isa<DependentSizedExtVectorType>(Result)) {
5698 DependentSizedExtVectorTypeLoc NewTL
5699 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
5700 NewTL.setNameLoc(TL.getNameLoc());
5701 } else {
5702 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5703 NewTL.setNameLoc(TL.getNameLoc());
5704 }
5705
5706 return Result;
5707}
5708
5709template <typename Derived>
5710QualType
5711TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5712 ConstantMatrixTypeLoc TL) {
5713 const ConstantMatrixType *T = TL.getTypePtr();
5714 QualType ElementType = getDerived().TransformType(T->getElementType());
5715 if (ElementType.isNull())
5716 return QualType();
5717
5718 QualType Result = TL.getType();
5719 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5720 Result = getDerived().RebuildConstantMatrixType(
5721 ElementType, T->getNumRows(), T->getNumColumns());
5722 if (Result.isNull())
5723 return QualType();
5724 }
5725
5726 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);
5727 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5728 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5729 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5730 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5731
5732 return Result;
5733}
5734
5735template <typename Derived>
5736QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5737 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5738 const DependentSizedMatrixType *T = TL.getTypePtr();
5739
5740 QualType ElementType = getDerived().TransformType(T->getElementType());
5741 if (ElementType.isNull()) {
5742 return QualType();
5743 }
5744
5745 // Matrix dimensions are constant expressions.
5746 EnterExpressionEvaluationContext Unevaluated(
5748
5749 Expr *origRows = TL.getAttrRowOperand();
5750 if (!origRows)
5751 origRows = T->getRowExpr();
5752 Expr *origColumns = TL.getAttrColumnOperand();
5753 if (!origColumns)
5754 origColumns = T->getColumnExpr();
5755
5756 ExprResult rowResult = getDerived().TransformExpr(origRows);
5757 rowResult = SemaRef.ActOnConstantExpression(rowResult);
5758 if (rowResult.isInvalid())
5759 return QualType();
5760
5761 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5762 columnResult = SemaRef.ActOnConstantExpression(columnResult);
5763 if (columnResult.isInvalid())
5764 return QualType();
5765
5766 Expr *rows = rowResult.get();
5767 Expr *columns = columnResult.get();
5768
5769 QualType Result = TL.getType();
5770 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5771 rows != origRows || columns != origColumns) {
5772 Result = getDerived().RebuildDependentSizedMatrixType(
5773 ElementType, rows, columns, T->getAttributeLoc());
5774
5775 if (Result.isNull())
5776 return QualType();
5777 }
5778
5779 // We might have any sort of matrix type now, but fortunately they
5780 // all have the same location layout.
5781 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);
5782 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5783 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5784 NewTL.setAttrRowOperand(rows);
5785 NewTL.setAttrColumnOperand(columns);
5786 return Result;
5787}
5788
5789template <typename Derived>
5790QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
5791 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
5792 const DependentAddressSpaceType *T = TL.getTypePtr();
5793
5794 QualType pointeeType = getDerived().TransformType(T->getPointeeType());
5795
5796 if (pointeeType.isNull())
5797 return QualType();
5798
5799 // Address spaces are constant expressions.
5800 EnterExpressionEvaluationContext Unevaluated(
5802
5803 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
5804 AddrSpace = SemaRef.ActOnConstantExpression(AddrSpace);
5805 if (AddrSpace.isInvalid())
5806 return QualType();
5807
5808 QualType Result = TL.getType();
5809 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
5810 AddrSpace.get() != T->getAddrSpaceExpr()) {
5811 Result = getDerived().RebuildDependentAddressSpaceType(
5812 pointeeType, AddrSpace.get(), T->getAttributeLoc());
5813 if (Result.isNull())
5814 return QualType();
5815 }
5816
5817 // Result might be dependent or not.
5818 if (isa<DependentAddressSpaceType>(Result)) {
5819 DependentAddressSpaceTypeLoc NewTL =
5820 TLB.push<DependentAddressSpaceTypeLoc>(Result);
5821
5822 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5823 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
5824 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5825
5826 } else {
5827 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(
5828 Result, getDerived().getBaseLocation());
5829 TransformType(TLB, DI->getTypeLoc());
5830 }
5831
5832 return Result;
5833}
5834
5835template <typename Derived>
5836QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
5837 VectorTypeLoc TL) {
5838 const VectorType *T = TL.getTypePtr();
5839 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5840 if (ElementType.isNull())
5841 return QualType();
5842
5843 QualType Result = TL.getType();
5844 if (getDerived().AlwaysRebuild() ||
5845 ElementType != T->getElementType()) {
5846 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
5847 T->getVectorKind());
5848 if (Result.isNull())
5849 return QualType();
5850 }
5851
5852 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5853 NewTL.setNameLoc(TL.getNameLoc());
5854
5855 return Result;
5856}
5857
5858template<typename Derived>
5859QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
5860 ExtVectorTypeLoc TL) {
5861 const VectorType *T = TL.getTypePtr();
5862 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5863 if (ElementType.isNull())
5864 return QualType();
5865
5866 QualType Result = TL.getType();
5867 if (getDerived().AlwaysRebuild() ||
5868 ElementType != T->getElementType()) {
5869 Result = getDerived().RebuildExtVectorType(ElementType,
5870 T->getNumElements(),
5871 /*FIXME*/ SourceLocation());
5872 if (Result.isNull())
5873 return QualType();
5874 }
5875
5876 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5877 NewTL.setNameLoc(TL.getNameLoc());
5878
5879 return Result;
5880}
5881
5882template <typename Derived>
5884 ParmVarDecl *OldParm, int indexAdjustment,
5885 std::optional<unsigned> NumExpansions, bool ExpectParameterPack) {
5886 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
5887 TypeSourceInfo *NewDI = nullptr;
5888
5889 if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
5890 // If we're substituting into a pack expansion type and we know the
5891 // length we want to expand to, just substitute for the pattern.
5892 TypeLoc OldTL = OldDI->getTypeLoc();
5893 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
5894
5895 TypeLocBuilder TLB;
5896 TypeLoc NewTL = OldDI->getTypeLoc();
5897 TLB.reserve(NewTL.getFullDataSize());
5898
5899 QualType Result = getDerived().TransformType(TLB,
5900 OldExpansionTL.getPatternLoc());
5901 if (Result.isNull())
5902 return nullptr;
5903
5904 Result = RebuildPackExpansionType(Result,
5905 OldExpansionTL.getPatternLoc().getSourceRange(),
5906 OldExpansionTL.getEllipsisLoc(),
5907 NumExpansions);
5908 if (Result.isNull())
5909 return nullptr;
5910
5911 PackExpansionTypeLoc NewExpansionTL
5912 = TLB.push<PackExpansionTypeLoc>(Result);
5913 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
5914 NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result);
5915 } else
5916 NewDI = getDerived().TransformType(OldDI);
5917 if (!NewDI)
5918 return nullptr;
5919
5920 if (NewDI == OldDI && indexAdjustment == 0)
5921 return OldParm;
5922
5923 ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context,
5924 OldParm->getDeclContext(),
5925 OldParm->getInnerLocStart(),
5926 OldParm->getLocation(),
5927 OldParm->getIdentifier(),
5928 NewDI->getType(),
5929 NewDI,
5930 OldParm->getStorageClass(),
5931 /* DefArg */ nullptr);
5932 newParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
5933 OldParm->getFunctionScopeIndex() + indexAdjustment);
5934 transformedLocalDecl(OldParm, {newParm});
5935 return newParm;
5936}
5937
5938template <typename Derived>
5941 const QualType *ParamTypes,
5942 const FunctionProtoType::ExtParameterInfo *ParamInfos,
5943 SmallVectorImpl<QualType> &OutParamTypes,
5946 unsigned *LastParamTransformed) {
5947 int indexAdjustment = 0;
5948
5949 unsigned NumParams = Params.size();
5950 for (unsigned i = 0; i != NumParams; ++i) {
5951 if (LastParamTransformed)
5952 *LastParamTransformed = i;
5953 if (ParmVarDecl *OldParm = Params[i]) {
5954 assert(OldParm->getFunctionScopeIndex() == i);
5955
5956 std::optional<unsigned> NumExpansions;
5957 ParmVarDecl *NewParm = nullptr;
5958 if (OldParm->isParameterPack()) {
5959 // We have a function parameter pack that may need to be expanded.
5961
5962 // Find the parameter packs that could be expanded.
5963 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
5965 TypeLoc Pattern = ExpansionTL.getPatternLoc();
5966 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
5967
5968 // Determine whether we should expand the parameter packs.
5969 bool ShouldExpand = false;
5970 bool RetainExpansion = false;
5971 std::optional<unsigned> OrigNumExpansions;
5972 if (Unexpanded.size() > 0) {
5973 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
5974 NumExpansions = OrigNumExpansions;
5975 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
5976 Pattern.getSourceRange(),
5977 Unexpanded,
5978 ShouldExpand,
5979 RetainExpansion,
5980 NumExpansions)) {
5981 return true;
5982 }
5983 } else {
5984#ifndef NDEBUG
5985 const AutoType *AT =
5986 Pattern.getType().getTypePtr()->getContainedAutoType();
5987 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
5988 "Could not find parameter packs or undeduced auto type!");
5989#endif
5990 }
5991
5992 if (ShouldExpand) {
5993 // Expand the function parameter pack into multiple, separate
5994 // parameters.
5995 getDerived().ExpandingFunctionParameterPack(OldParm);
5996 for (unsigned I = 0; I != *NumExpansions; ++I) {
5997 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
5998 ParmVarDecl *NewParm
5999 = getDerived().TransformFunctionTypeParam(OldParm,
6000 indexAdjustment++,
6001 OrigNumExpansions,
6002 /*ExpectParameterPack=*/false);
6003 if (!NewParm)
6004 return true;
6005
6006 if (ParamInfos)
6007 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6008 OutParamTypes.push_back(NewParm->getType());
6009 if (PVars)
6010 PVars->push_back(NewParm);
6011 }
6012
6013 // If we're supposed to retain a pack expansion, do so by temporarily
6014 // forgetting the partially-substituted parameter pack.
6015 if (RetainExpansion) {
6016 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6017 ParmVarDecl *NewParm
6018 = getDerived().TransformFunctionTypeParam(OldParm,
6019 indexAdjustment++,
6020 OrigNumExpansions,
6021 /*ExpectParameterPack=*/false);
6022 if (!NewParm)
6023 return true;
6024
6025 if (ParamInfos)
6026 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6027 OutParamTypes.push_back(NewParm->getType());
6028 if (PVars)
6029 PVars->push_back(NewParm);
6030 }
6031
6032 // The next parameter should have the same adjustment as the
6033 // last thing we pushed, but we post-incremented indexAdjustment
6034 // on every push. Also, if we push nothing, the adjustment should
6035 // go down by one.
6036 indexAdjustment--;
6037
6038 // We're done with the pack expansion.
6039 continue;
6040 }
6041
6042 // We'll substitute the parameter now without expanding the pack
6043 // expansion.
6044 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6045 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6046 indexAdjustment,
6047 NumExpansions,
6048 /*ExpectParameterPack=*/true);
6049 assert(NewParm->isParameterPack() &&
6050 "Parameter pack no longer a parameter pack after "
6051 "transformation.");
6052 } else {
6053 NewParm = getDerived().TransformFunctionTypeParam(
6054 OldParm, indexAdjustment, std::nullopt,
6055 /*ExpectParameterPack=*/false);
6056 }
6057
6058 if (!NewParm)
6059 return true;
6060
6061 if (ParamInfos)
6062 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6063 OutParamTypes.push_back(NewParm->getType());
6064 if (PVars)
6065 PVars->push_back(NewParm);
6066 continue;
6067 }
6068
6069 // Deal with the possibility that we don't have a parameter
6070 // declaration for this parameter.
6071 assert(ParamTypes);
6072 QualType OldType = ParamTypes[i];
6073 bool IsPackExpansion = false;
6074 std::optional<unsigned> NumExpansions;
6075 QualType NewType;
6076 if (const PackExpansionType *Expansion
6077 = dyn_cast<PackExpansionType>(OldType)) {
6078 // We have a function parameter pack that may need to be expanded.
6079 QualType Pattern = Expansion->getPattern();
6081 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6082
6083 // Determine whether we should expand the parameter packs.
6084 bool ShouldExpand = false;
6085 bool RetainExpansion = false;
6086 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
6087 Unexpanded,
6088 ShouldExpand,
6089 RetainExpansion,
6090 NumExpansions)) {
6091 return true;
6092 }
6093
6094 if (ShouldExpand) {
6095 // Expand the function parameter pack into multiple, separate
6096 // parameters.
6097 for (unsigned I = 0; I != *NumExpansions; ++I) {
6098 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6099 QualType NewType = getDerived().TransformType(Pattern);
6100 if (NewType.isNull())
6101 return true;
6102
6103 if (NewType->containsUnexpandedParameterPack()) {
6104 NewType = getSema().getASTContext().getPackExpansionType(
6105 NewType, std::nullopt);
6106
6107 if (NewType.isNull())
6108 return true;
6109 }
6110
6111 if (ParamInfos)
6112 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6113 OutParamTypes.push_back(NewType);
6114 if (PVars)
6115 PVars->push_back(nullptr);
6116 }
6117
6118 // We're done with the pack expansion.
6119 continue;
6120 }
6121
6122 // If we're supposed to retain a pack expansion, do so by temporarily
6123 // forgetting the partially-substituted parameter pack.
6124 if (RetainExpansion) {
6125 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6126 QualType NewType = getDerived().TransformType(Pattern);
6127 if (NewType.isNull())
6128 return true;
6129
6130 if (ParamInfos)
6131 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6132 OutParamTypes.push_back(NewType);
6133 if (PVars)
6134 PVars->push_back(nullptr);
6135 }
6136
6137 // We'll substitute the parameter now without expanding the pack
6138 // expansion.
6139 OldType = Expansion->getPattern();
6140 IsPackExpansion = true;
6141 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6142 NewType = getDerived().TransformType(OldType);
6143 } else {
6144 NewType = getDerived().TransformType(OldType);
6145 }
6146
6147 if (NewType.isNull())
6148 return true;
6149
6150 if (IsPackExpansion)
6151 NewType = getSema().Context.getPackExpansionType(NewType,
6152 NumExpansions);
6153
6154 if (ParamInfos)
6155 PInfos.set(OutParamTypes.size(), ParamInfos[i]);
6156 OutParamTypes.push_back(NewType);
6157 if (PVars)
6158 PVars->push_back(nullptr);
6159 }
6160
6161#ifndef NDEBUG
6162 if (PVars) {
6163 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6164 if (ParmVarDecl *parm = (*PVars)[i])
6165 assert(parm->getFunctionScopeIndex() == i);
6166 }
6167#endif
6168
6169 return false;
6170}
6171
6172template<typename Derived>
6176 SmallVector<QualType, 4> ExceptionStorage;
6177 return getDerived().TransformFunctionProtoType(
6178 TLB, TL, nullptr, Qualifiers(),
6179 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6180 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6181 ExceptionStorage, Changed);
6182 });
6183}
6184
6185template<typename Derived> template<typename Fn>
6187 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6188 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6189
6190 // Transform the parameters and return type.
6191 //
6192 // We are required to instantiate the params and return type in source order.
6193 // When the function has a trailing return type, we instantiate the
6194 // parameters before the return type, since the return type can then refer
6195 // to the parameters themselves (via decltype, sizeof, etc.).
6196 //
6197 SmallVector<QualType, 4> ParamTypes;
6199 Sema::ExtParameterInfoBuilder ExtParamInfos;
6200 const FunctionProtoType *T = TL.getTypePtr();
6201
6202 QualType ResultType;
6203
6204 if (T->hasTrailingReturn()) {
6205 if (getDerived().TransformFunctionTypeParams(
6206 TL.getBeginLoc(), TL.getParams(),
6209 ParamTypes, &ParamDecls, ExtParamInfos))
6210 return QualType();
6211
6212 {
6213 // C++11 [expr.prim.general]p3:
6214 // If a declaration declares a member function or member function
6215 // template of a class X, the expression this is a prvalue of type
6216 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6217 // and the end of the function-definition, member-declarator, or
6218 // declarator.
6219 auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.getCurLexicalContext());
6220 Sema::CXXThisScopeRAII ThisScope(
6221 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6222
6223 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6224 if (ResultType.isNull())
6225 return QualType();
6226 }
6227 }
6228 else {
6229 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6230 if (ResultType.isNull())
6231 return QualType();
6232
6233 if (getDerived().TransformFunctionTypeParams(
6234 TL.getBeginLoc(), TL.getParams(),
6237 ParamTypes, &ParamDecls, ExtParamInfos))
6238 return QualType();
6239 }
6240
6242
6243 bool EPIChanged = false;
6244 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6245 return QualType();
6246
6247 // Handle extended parameter information.
6248 if (auto NewExtParamInfos =
6249 ExtParamInfos.getPointerOrNull(ParamTypes.size())) {
6250 if (!EPI.ExtParameterInfos ||
6252 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6253 EPIChanged = true;
6254 }
6255 EPI.ExtParameterInfos = NewExtParamInfos;
6256 } else if (EPI.ExtParameterInfos) {
6257 EPIChanged = true;
6258 EPI.ExtParameterInfos = nullptr;
6259 }
6260
6261 QualType Result = TL.getType();
6262 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6263 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6264 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6265 if (Result.isNull())
6266 return QualType();
6267 }
6268
6271 NewTL.setLParenLoc(TL.getLParenLoc());
6272 NewTL.setRParenLoc(TL.getRParenLoc());
6275 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6276 NewTL.setParam(i, ParamDecls[i]);
6277
6278 return Result;
6279}
6280
6281template<typename Derived>
6284 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6285 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6286
6287 // Instantiate a dynamic noexcept expression, if any.
6288 if (isComputedNoexcept(ESI.Type)) {
6289 // Update this scrope because ContextDecl in Sema will be used in
6290 // TransformExpr.
6291 auto *Method = dyn_cast_if_present<CXXMethodDecl>(ESI.SourceTemplate);
6292 Sema::CXXThisScopeRAII ThisScope(
6293 SemaRef, Method ? Method->getParent() : nullptr,
6294 Method ? Method->getMethodQualifiers() : Qualifiers{},
6295 Method != nullptr);
6298 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6299 if (NoexceptExpr.isInvalid())
6300 return true;
6301
6303 NoexceptExpr =
6304 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6305 if (NoexceptExpr.isInvalid())
6306 return true;
6307
6308 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6309 Changed = true;
6310 ESI.NoexceptExpr = NoexceptExpr.get();
6311 ESI.Type = EST;
6312 }
6313
6314 if (ESI.Type != EST_Dynamic)
6315 return false;
6316
6317 // Instantiate a dynamic exception specification's type.
6318 for (QualType T : ESI.Exceptions) {
6319 if (const PackExpansionType *PackExpansion =
6321 Changed = true;
6322
6323 // We have a pack expansion. Instantiate it.
6325 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
6326 Unexpanded);
6327 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6328
6329 // Determine whether the set of unexpanded parameter packs can and
6330 // should
6331 // be expanded.
6332 bool Expand = false;
6333 bool RetainExpansion = false;
6334 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
6335 // FIXME: Track the location of the ellipsis (and track source location
6336 // information for the types in the exception specification in general).
6337 if (getDerived().TryExpandParameterPacks(
6338 Loc, SourceRange(), Unexpanded, Expand,
6339 RetainExpansion, NumExpansions))
6340 return true;
6341
6342 if (!Expand) {
6343 // We can't expand this pack expansion into separate arguments yet;
6344 // just substitute into the pattern and create a new pack expansion
6345 // type.
6346 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6347 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6348 if (U.isNull())
6349 return true;
6350
6351 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
6352 Exceptions.push_back(U);
6353 continue;
6354 }
6355
6356 // Substitute into the pack expansion pattern for each slice of the
6357 // pack.
6358 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6359 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
6360
6361 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6362 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6363 return true;
6364
6365 Exceptions.push_back(U);
6366 }
6367 } else {
6368 QualType U = getDerived().TransformType(T);
6369 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6370 return true;
6371 if (T != U)
6372 Changed = true;
6373
6374 Exceptions.push_back(U);
6375 }
6376 }
6377
6378 ESI.Exceptions = Exceptions;
6379 if (ESI.Exceptions.empty())
6380 ESI.Type = EST_DynamicNone;
6381 return false;
6382}
6383
6384template<typename Derived>
6386 TypeLocBuilder &TLB,
6388 const FunctionNoProtoType *T = TL.getTypePtr();
6389 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6390 if (ResultType.isNull())
6391 return QualType();
6392
6393 QualType Result = TL.getType();
6394 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6395 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6396
6399 NewTL.setLParenLoc(TL.getLParenLoc());
6400 NewTL.setRParenLoc(TL.getRParenLoc());
6402
6403 return Result;
6404}
6405
6406template <typename Derived>
6407QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6408 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6409 const UnresolvedUsingType *T = TL.getTypePtr();
6410 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6411 if (!D)
6412 return QualType();
6413
6414 QualType Result = TL.getType();
6415 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6416 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6417 if (Result.isNull())
6418 return QualType();
6419 }
6420
6421 // We might get an arbitrary type spec type back. We should at
6422 // least always get a type spec type, though.
6423 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result);
6424 NewTL.setNameLoc(TL.getNameLoc());
6425
6426 return Result;
6427}
6428
6429template <typename Derived>
6430QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6431 UsingTypeLoc TL) {
6432 const UsingType *T = TL.getTypePtr();
6433
6434 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6435 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6436 if (!Found)
6437 return QualType();
6438
6439 QualType Underlying = getDerived().TransformType(T->desugar());
6440 if (Underlying.isNull())
6441 return QualType();
6442
6443 QualType Result = TL.getType();
6444 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6445 Underlying != T->getUnderlyingType()) {
6446 Result = getDerived().RebuildUsingType(Found, Underlying);
6447 if (Result.isNull())
6448 return QualType();
6449 }
6450
6451 TLB.pushTypeSpec(Result).setNameLoc(TL.getNameLoc());
6452 return Result;
6453}
6454
6455template<typename Derived>
6456QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6457 TypedefTypeLoc TL) {
6458 const TypedefType *T = TL.getTypePtr();
6459 TypedefNameDecl *Typedef
6460 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6461 T->getDecl()));
6462 if (!Typedef)
6463 return QualType();
6464
6465 QualType Result = TL.getType();
6466 if (getDerived().AlwaysRebuild() ||
6467 Typedef != T->getDecl()) {
6468 Result = getDerived().RebuildTypedefType(Typedef);
6469 if (Result.isNull())
6470 return QualType();
6471 }
6472
6473 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
6474 NewTL.setNameLoc(TL.getNameLoc());
6475
6476 return Result;
6477}
6478
6479template<typename Derived>
6480QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6481 TypeOfExprTypeLoc TL) {
6482 // typeof expressions are not potentially evaluated contexts
6483 EnterExpressionEvaluationContext Unevaluated(
6486
6487 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6488 if (E.isInvalid())
6489 return QualType();
6490
6491 E = SemaRef.HandleExprEvaluationContextForTypeof(E.get());
6492 if (E.isInvalid())
6493 return QualType();
6494
6495 QualType Result = TL.getType();
6496 TypeOfKind Kind = Result->getAs<TypeOfExprType>()->getKind();
6497 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6498 Result =
6499 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6500 if (Result.isNull())
6501 return QualType();
6502 }
6503
6504 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
6505 NewTL.setTypeofLoc(TL.getTypeofLoc());
6506 NewTL.setLParenLoc(TL.getLParenLoc());
6507 NewTL.setRParenLoc(TL.getRParenLoc());
6508
6509 return Result;
6510}
6511
6512template<typename Derived>
6513QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6514 TypeOfTypeLoc TL) {
6515 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6516 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6517 if (!New_Under_TI)
6518 return QualType();
6519
6520 QualType Result = TL.getType();
6521 TypeOfKind Kind = Result->getAs<TypeOfType>()->getKind();
6522 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6523 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6524 if (Result.isNull())
6525 return QualType();
6526 }
6527
6528 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
6529 NewTL.setTypeofLoc(TL.getTypeofLoc());
6530 NewTL.setLParenLoc(TL.getLParenLoc());
6531 NewTL.setRParenLoc(TL.getRParenLoc());
6532 NewTL.setUnmodifiedTInfo(New_Under_TI);
6533
6534 return Result;
6535}
6536
6537template<typename Derived>
6538QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6539 DecltypeTypeLoc TL) {
6540 const DecltypeType *T = TL.getTypePtr();
6541
6542 // decltype expressions are not potentially evaluated contexts
6543 EnterExpressionEvaluationContext Unevaluated(
6546
6547 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6548 if (E.isInvalid())
6549 return QualType();
6550
6551 E = getSema().ActOnDecltypeExpression(E.get());
6552 if (E.isInvalid())
6553 return QualType();
6554
6555 QualType Result = TL.getType();
6556 if (getDerived().AlwaysRebuild() ||
6557 E.get() != T->getUnderlyingExpr()) {
6558 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6559 if (Result.isNull())
6560 return QualType();
6561 }
6562 else E.get();
6563
6564 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
6565 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6566 NewTL.setRParenLoc(TL.getRParenLoc());
6567 return Result;
6568}
6569
6570template <typename Derived>
6571QualType
6572TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
6573 PackIndexingTypeLoc TL) {
6574 // Transform the index
6575 ExprResult IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
6576 if (IndexExpr.isInvalid())
6577 return QualType();
6578 QualType Pattern = TL.getPattern();
6579
6580 const PackIndexingType *PIT = TL.getTypePtr();
6581 SmallVector<QualType, 5> SubtitutedTypes;
6582 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
6583
6584 bool NotYetExpanded = Types.empty();
6585 bool FullySubstituted = true;
6586
6587 if (Types.empty())
6588 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
6589
6590 for (const QualType &T : Types) {
6592 QualType Transformed = getDerived().TransformType(T);
6593 if (Transformed.isNull())
6594 return QualType();
6595 SubtitutedTypes.push_back(Transformed);
6596 continue;
6597 }
6598
6600 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
6601 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6602 // Determine whether the set of unexpanded parameter packs can and should
6603 // be expanded.
6604 bool ShouldExpand = true;
6605 bool RetainExpansion = false;
6606 std::optional<unsigned> OrigNumExpansions;
6607 std::optional<unsigned> NumExpansions = OrigNumExpansions;
6608 if (getDerived().TryExpandParameterPacks(TL.getEllipsisLoc(), SourceRange(),
6609 Unexpanded, ShouldExpand,
6610 RetainExpansion, NumExpansions))
6611 return QualType();
6612 if (!ShouldExpand) {
6613 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6614 // FIXME: should we keep TypeLoc for individual expansions in
6615 // PackIndexingTypeLoc?
6616 TypeSourceInfo *TI =
6617 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, TL.getBeginLoc());
6618 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
6619 if (Pack.isNull())
6620 return QualType();
6621 if (NotYetExpanded) {
6622 FullySubstituted = false;
6623 QualType Out = getDerived().RebuildPackIndexingType(
6624 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6625 FullySubstituted);
6626 if (Out.isNull())
6627 return QualType();
6628
6629 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6630 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6631 return Out;
6632 }
6633 SubtitutedTypes.push_back(Pack);
6634 continue;
6635 }
6636 for (unsigned I = 0; I != *NumExpansions; ++I) {
6637 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
6638 QualType Out = getDerived().TransformType(T);
6639 if (Out.isNull())
6640 return QualType();
6641 SubtitutedTypes.push_back(Out);
6642 }
6643 // If we're supposed to retain a pack expansion, do so by temporarily
6644 // forgetting the partially-substituted parameter pack.
6645 if (RetainExpansion) {
6646 FullySubstituted = false;
6647 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6648 QualType Out = getDerived().TransformType(T);
6649 if (Out.isNull())
6650 return QualType();
6651 SubtitutedTypes.push_back(Out);
6652 }
6653 }
6654
6655 // A pack indexing type can appear in a larger pack expansion,
6656 // e.g. `Pack...[pack_of_indexes]...`
6657 // so we need to temporarily disable substitution of pack elements
6658 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
6659 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
6660
6661 QualType Out = getDerived().RebuildPackIndexingType(
6662 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6663 FullySubstituted, SubtitutedTypes);
6664 if (Out.isNull())
6665 return Out;
6666
6667 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6668 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6669 return Out;
6670}
6671
6672template<typename Derived>
6673QualType TreeTransform<Derived>::TransformUnaryTransformType(
6674 TypeLocBuilder &TLB,
6675 UnaryTransformTypeLoc TL) {
6676 QualType Result = TL.getType();
6677 if (Result->isDependentType()) {
6678 const UnaryTransformType *T = TL.getTypePtr();
6679 QualType NewBase =
6680 getDerived().TransformType(TL.getUnderlyingTInfo())->getType();
6681 Result = getDerived().RebuildUnaryTransformType(NewBase,
6682 T->getUTTKind(),
6683 TL.getKWLoc());
6684 if (Result.isNull())
6685 return QualType();
6686 }
6687
6688 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
6689 NewTL.setKWLoc(TL.getKWLoc());
6690 NewTL.setParensRange(TL.getParensRange());
6691 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6692 return Result;
6693}
6694
6695template<typename Derived>
6696QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6697 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6698 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6699
6700 CXXScopeSpec SS;
6701 TemplateName TemplateName = getDerived().TransformTemplateName(
6702 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6703 if (TemplateName.isNull())
6704 return QualType();
6705
6706 QualType OldDeduced = T->getDeducedType();
6707 QualType NewDeduced;
6708 if (!OldDeduced.isNull()) {
6709 NewDeduced = getDerived().TransformType(OldDeduced);
6710 if (NewDeduced.isNull())
6711 return QualType();
6712 }
6713
6714 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
6715 TemplateName, NewDeduced);
6716 if (Result.isNull())
6717 return QualType();
6718
6719 DeducedTemplateSpecializationTypeLoc NewTL =
6720 TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
6721 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
6722
6723 return Result;
6724}
6725
6726template<typename Derived>
6727QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
6728 RecordTypeLoc TL) {
6729 const RecordType *T = TL.getTypePtr();
6730 RecordDecl *Record
6731 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6732 T->getDecl()));
6733 if (!Record)
6734 return QualType();
6735
6736 QualType Result = TL.getType();
6737 if (getDerived().AlwaysRebuild() ||
6738 Record != T->getDecl()) {
6739 Result = getDerived().RebuildRecordType(Record);
6740 if (Result.isNull())
6741 return QualType();
6742 }
6743
6744 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
6745 NewTL.setNameLoc(TL.getNameLoc());
6746
6747 return Result;
6748}
6749
6750template<typename Derived>
6751QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
6752 EnumTypeLoc TL) {
6753 const EnumType *T = TL.getTypePtr();
6754 EnumDecl *Enum
6755 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6756 T->getDecl()));
6757 if (!Enum)
6758 return QualType();
6759
6760 QualType Result = TL.getType();
6761 if (getDerived().AlwaysRebuild() ||
6762 Enum != T->getDecl()) {
6763 Result = getDerived().RebuildEnumType(Enum);
6764 if (Result.isNull())
6765 return QualType();
6766 }
6767
6768 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
6769 NewTL.setNameLoc(TL.getNameLoc());
6770
6771 return Result;
6772}
6773
6774template<typename Derived>
6775QualType TreeTransform<Derived>::TransformInjectedClassNameType(
6776 TypeLocBuilder &TLB,
6777 InjectedClassNameTypeLoc TL) {
6778 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
6779 TL.getTypePtr()->getDecl());
6780 if (!D) return QualType();
6781
6782 QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
6783 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
6784 return T;
6785}
6786
6787template<typename Derived>
6789 TypeLocBuilder &TLB,
6791 return getDerived().TransformTemplateTypeParmType(
6792 TLB, TL,
6793 /*SuppressObjCLifetime=*/false);
6794}
6795
6796template <typename Derived>
6798 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
6799 return TransformTypeSpecType(TLB, TL);
6800}
6801
6802template<typename Derived>
6803QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
6804 TypeLocBuilder &TLB,
6805 SubstTemplateTypeParmTypeLoc TL) {
6806 const SubstTemplateTypeParmType *T = TL.getTypePtr();
6807
6808 Decl *NewReplaced =
6809 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
6810
6811 // Substitute into the replacement type, which itself might involve something
6812 // that needs to be transformed. This only tends to occur with default
6813 // template arguments of template template parameters.
6814 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
6815 QualType Replacement = getDerived().TransformType(T->getReplacementType());
6816 if (Replacement.isNull())
6817 return QualType();
6818
6819 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
6820 Replacement, NewReplaced, T->getIndex(), T->getPackIndex());
6821
6822 // Propagate type-source information.
6823 SubstTemplateTypeParmTypeLoc NewTL
6824 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
6825 NewTL.setNameLoc(TL.getNameLoc());
6826 return Result;
6827
6828}
6829
6830template<typename Derived>
6832 TypeLocBuilder &TLB,
6834 return getDerived().TransformSubstTemplateTypeParmPackType(
6835 TLB, TL, /*SuppressObjCLifetime=*/false);
6836}
6837
6838template <typename Derived>
6841 return TransformTypeSpecType(TLB, TL);
6842}
6843
6844template<typename Derived>
6846 TypeLocBuilder &TLB,
6849
6850 // The nested-name-specifier never matters in a TemplateSpecializationType,
6851 // because we can't have a dependent nested-name-specifier anyway.
6852 CXXScopeSpec SS;
6853 TemplateName Template
6854 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
6855 TL.getTemplateNameLoc());
6856 if (Template.isNull())
6857 return QualType();
6858
6859 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
6860}
6861
6862template<typename Derived>
6864 AtomicTypeLoc TL) {
6865 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6866 if (ValueType.isNull())
6867 return QualType();
6868
6869 QualType Result = TL.getType();
6870 if (getDerived().AlwaysRebuild() ||
6871 ValueType != TL.getValueLoc().getType()) {
6872 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
6873 if (Result.isNull())
6874 return QualType();
6875 }
6876
6877 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
6878 NewTL.setKWLoc(TL.getKWLoc());
6879 NewTL.setLParenLoc(TL.getLParenLoc());
6880 NewTL.setRParenLoc(TL.getRParenLoc());
6881
6882 return Result;
6883}
6884
6885template <typename Derived>
6886QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
6887 PipeTypeLoc TL) {
6888 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
6889 if (ValueType.isNull())
6890 return QualType();
6891
6892 QualType Result = TL.getType();
6893 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
6894 const PipeType *PT = Result->castAs<PipeType>();
6895 bool isReadPipe = PT->isReadOnly();
6896 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
6897 if (Result.isNull())
6898 return QualType();
6899 }
6900
6901 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);
6902 NewTL.setKWLoc(TL.getKWLoc());
6903
6904 return Result;
6905}
6906
6907template <typename Derived>
6908QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
6909 BitIntTypeLoc TL) {
6910 const BitIntType *EIT = TL.getTypePtr();
6911 QualType Result = TL.getType();
6912
6913 if (getDerived().AlwaysRebuild()) {
6914 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
6915 EIT->getNumBits(), TL.getNameLoc());
6916 if (Result.isNull())
6917 return QualType();
6918 }
6919
6920 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6921 NewTL.setNameLoc(TL.getNameLoc());
6922 return Result;
6923}
6924
6925template <typename Derived>
6926QualType TreeTransform<Derived>::TransformDependentBitIntType(
6927 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
6928 const DependentBitIntType *EIT = TL.getTypePtr();
6929
6930 EnterExpressionEvaluationContext Unevaluated(
6932 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
6933 BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr);
6934
6935 if (BitsExpr.isInvalid())
6936 return QualType();
6937
6938 QualType Result = TL.getType();
6939
6940 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
6941 Result = getDerived().RebuildDependentBitIntType(
6942 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
6943
6944 if (Result.isNull())
6945 return QualType();
6946 }
6947
6948 if (isa<DependentBitIntType>(Result)) {
6949 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);
6950 NewTL.setNameLoc(TL.getNameLoc());
6951 } else {
6952 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
6953 NewTL.setNameLoc(TL.getNameLoc());
6954 }
6955 return Result;
6956}
6957
6958 /// Simple iterator that traverses the template arguments in a
6959 /// container that provides a \c getArgLoc() member function.
6960 ///
6961 /// This iterator is intended to be used with the iterator form of
6962 /// \c TreeTransform<Derived>::TransformTemplateArguments().
6963 template<typename ArgLocContainer>
6965 ArgLocContainer *Container;
6966 unsigned Index;
6967
6968 public:
6971 typedef int difference_type;
6972 typedef std::input_iterator_tag iterator_category;
6973
6974 class pointer {
6976
6977 public:
6978 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
6979
6981 return &Arg;
6982 }
6983 };
6984
6985
6987
6988 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
6989 unsigned Index)
6990 : Container(&Container), Index(Index) { }
6991
6993 ++Index;
6994 return *this;
6995 }
6996
6999 ++(*this);
7000 return Old;
7001 }
7002
7004 return Container->getArgLoc(Index);
7005 }
7006
7008 return pointer(Container->getArgLoc(Index));
7009 }
7010
7013 return X.Container == Y.Container && X.Index == Y.Index;
7014 }
7015
7018 return !(X == Y);
7019 }
7020 };
7021
7022template<typename Derived>
7023QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7024 AutoTypeLoc TL) {
7025 const AutoType *T = TL.getTypePtr();
7026 QualType OldDeduced = T->getDeducedType();
7027 QualType NewDeduced;
7028 if (!OldDeduced.isNull()) {
7029 NewDeduced = getDerived().TransformType(OldDeduced);
7030 if (NewDeduced.isNull())
7031 return QualType();
7032 }
7033
7034 ConceptDecl *NewCD = nullptr;
7035 TemplateArgumentListInfo NewTemplateArgs;
7036 NestedNameSpecifierLoc NewNestedNameSpec;
7037 if (T->isConstrained()) {
7038 assert(TL.getConceptReference());
7039 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7040 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7041
7042 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7043 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7044 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7045 if (getDerived().TransformTemplateArguments(
7046 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7047 NewTemplateArgs))
7048 return QualType();
7049
7050 if (TL.getNestedNameSpecifierLoc()) {
7051 NewNestedNameSpec
7052 = getDerived().TransformNestedNameSpecifierLoc(
7053 TL.getNestedNameSpecifierLoc());
7054 if (!NewNestedNameSpec)
7055 return QualType();
7056 }
7057 }
7058
7059 QualType Result = TL.getType();
7060 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7061 T->isDependentType() || T->isConstrained()) {
7062 // FIXME: Maybe don't rebuild if all template arguments are the same.
7064 NewArgList.reserve(NewTemplateArgs.size());
7065 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7066 NewArgList.push_back(ArgLoc.getArgument());
7067 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7068 NewArgList);
7069 if (Result.isNull())
7070 return QualType();
7071 }
7072
7073 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
7074 NewTL.setNameLoc(TL.getNameLoc());
7075 NewTL.setRParenLoc(TL.getRParenLoc());
7076 NewTL.setConceptReference(nullptr);
7077
7078 if (T->isConstrained()) {
7079 DeclarationNameInfo DNI = DeclarationNameInfo(
7080 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7081 TL.getConceptNameLoc(),
7082 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7083 auto *CR = ConceptReference::Create(
7084 SemaRef.Context, NewNestedNameSpec, TL.getTemplateKWLoc(), DNI,
7085 TL.getFoundDecl(), TL.getTypePtr()->getTypeConstraintConcept(),
7086 ASTTemplateArgumentListInfo::Create(SemaRef.Context, NewTemplateArgs));
7087 NewTL.setConceptReference(CR);
7088 }
7089
7090 return Result;
7091}
7092
7093template <typename Derived>
7095 TypeLocBuilder &TLB,
7096 TemplateSpecializationTypeLoc TL,
7097 TemplateName Template) {
7098 TemplateArgumentListInfo NewTemplateArgs;
7099 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7100 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7101 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7102 ArgIterator;
7103 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7104 ArgIterator(TL, TL.getNumArgs()),
7105 NewTemplateArgs))
7106 return QualType();
7107
7108 // FIXME: maybe don't rebuild if all the template arguments are the same.
7109
7110 QualType Result =
7111 getDerived().RebuildTemplateSpecializationType(Template,
7112 TL.getTemplateNameLoc(),
7113 NewTemplateArgs);
7114
7115 if (!Result.isNull()) {
7116 // Specializations of template template parameters are represented as
7117 // TemplateSpecializationTypes, and substitution of type alias templates
7118 // within a dependent context can transform them into
7119 // DependentTemplateSpecializationTypes.
7120 if (isa<DependentTemplateSpecializationType>(Result)) {
7121 DependentTemplateSpecializationTypeLoc NewTL
7122 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7123 NewTL.setElaboratedKeywordLoc(SourceLocation());
7124 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
7125 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7126 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7127 NewTL.setLAngleLoc(TL.getLAngleLoc());
7128 NewTL.setRAngleLoc(TL.getRAngleLoc());
7129 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7130 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7131 return Result;
7132 }
7133
7134 TemplateSpecializationTypeLoc NewTL
7135 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7136 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7137 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7138 NewTL.setLAngleLoc(TL.getLAngleLoc());
7139 NewTL.setRAngleLoc(TL.getRAngleLoc());
7140 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7141 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7142 }
7143
7144 return Result;
7145}
7146
7147template <typename Derived>
7149 TypeLocBuilder &TLB,
7151 TemplateName Template,
7152 CXXScopeSpec &SS) {
7153 TemplateArgumentListInfo NewTemplateArgs;
7154 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7155 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7158 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7159 ArgIterator(TL, TL.getNumArgs()),
7160 NewTemplateArgs))
7161 return QualType();
7162
7163 // FIXME: maybe don't rebuild if all the template arguments are the same.
7164
7165 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
7166 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
7167 TL.getTypePtr()->getKeyword(), DTN->getQualifier(),
7168 DTN->getIdentifier(), NewTemplateArgs.arguments());
7169
7173 NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
7176 NewTL.setLAngleLoc(TL.getLAngleLoc());
7177 NewTL.setRAngleLoc(TL.getRAngleLoc());
7178 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7179 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7180 return Result;
7181 }
7182
7184 = getDerived().RebuildTemplateSpecializationType(Template,
7185 TL.getTemplateNameLoc(),
7186 NewTemplateArgs);
7187
7188 if (!Result.isNull()) {
7189 /// FIXME: Wrap this in an elaborated-type-specifier?
7194 NewTL.setLAngleLoc(TL.getLAngleLoc());
7195 NewTL.setRAngleLoc(TL.getRAngleLoc());
7196 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7197 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
7198 }
7199
7200 return Result;
7201}
7202
7203template<typename Derived>
7206 ElaboratedTypeLoc TL) {
7207 const ElaboratedType *T = TL.getTypePtr();
7208
7209 NestedNameSpecifierLoc QualifierLoc;
7210 // NOTE: the qualifier in an ElaboratedType is optional.
7211 if (TL.getQualifierLoc()) {
7212 QualifierLoc
7213 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7214 if (!QualifierLoc)
7215 return QualType();
7216 }
7217
7218 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7219 if (NamedT.isNull())
7220 return QualType();
7221
7222 // C++0x [dcl.type.elab]p2:
7223 // If the identifier resolves to a typedef-name or the simple-template-id
7224 // resolves to an alias template specialization, the
7225 // elaborated-type-specifier is ill-formed.
7226 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7227 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7228 if (const TemplateSpecializationType *TST =
7229 NamedT->getAs<TemplateSpecializationType>()) {
7230 TemplateName Template = TST->getTemplateName();
7231 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7232 Template.getAsTemplateDecl())) {
7233 SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
7234 diag::err_tag_reference_non_tag)
7236 << llvm::to_underlying(
7238 SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
7239 }
7240 }
7241 }
7242
7243 QualType Result = TL.getType();
7244 if (getDerived().AlwaysRebuild() ||
7245 QualifierLoc != TL.getQualifierLoc() ||
7246 NamedT != T->getNamedType()) {
7247 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7248 T->getKeyword(),
7249 QualifierLoc, NamedT);
7250 if (Result.isNull())
7251 return QualType();
7252 }
7253
7254 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7255 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7256 NewTL.setQualifierLoc(QualifierLoc);
7257 return Result;
7258}
7259
7260template <typename Derived>
7261template <typename Fn>
7263 TypeLocBuilder &TLB, AttributedTypeLoc TL, Fn TransformModifiedTypeFn) {
7264 const AttributedType *oldType = TL.getTypePtr();
7265 QualType modifiedType = TransformModifiedTypeFn(TLB, TL.getModifiedLoc());
7266 if (modifiedType.isNull())
7267 return QualType();
7268
7269 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7270 const Attr *oldAttr = TL.getAttr();
7271 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7272 if (oldAttr && !newAttr)
7273 return QualType();
7274
7275 QualType result = TL.getType();
7276
7277 // FIXME: dependent operand expressions?
7278 if (getDerived().AlwaysRebuild() ||
7279 modifiedType != oldType->getModifiedType()) {
7280 TypeLocBuilder AuxiliaryTLB;
7281 AuxiliaryTLB.reserve(TL.getFullDataSize());
7282 QualType equivalentType =
7283 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7284 if (equivalentType.isNull())
7285 return QualType();
7286
7287 // Check whether we can add nullability; it is only represented as
7288 // type sugar, and therefore cannot be diagnosed in any other way.
7289 if (auto nullability = oldType->getImmediateNullability()) {
7290 if (!modifiedType->canHaveNullability()) {
7291 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
7292 : TL.getModifiedLoc().getBeginLoc()),
7293 diag::err_nullability_nonpointer)
7294 << DiagNullabilityKind(*nullability, false) << modifiedType;
7295 return QualType();
7296 }
7297 }
7298
7299 result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
7300 modifiedType,
7301 equivalentType);
7302 }
7303
7304 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
7305 newTL.setAttr(newAttr);
7306 return result;
7307}
7308
7309template <typename Derived>
7311 AttributedTypeLoc TL) {
7312 return getDerived().TransformAttributedType(
7313 TLB, TL, [&](TypeLocBuilder &TLB, TypeLoc ModifiedLoc) -> QualType {
7314 return getDerived().TransformType(TLB, ModifiedLoc);
7315 });
7316}
7317
7318template <typename Derived>
7321 const CountAttributedType *OldTy = TL.getTypePtr();
7322 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7323 if (InnerTy.isNull())
7324 return QualType();
7325
7326 Expr *OldCount = TL.getCountExpr();
7327 Expr *NewCount = nullptr;
7328 if (OldCount) {
7329 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7330 if (CountResult.isInvalid())
7331 return QualType();
7332 NewCount = CountResult.get();
7333 }
7334
7335 QualType Result = TL.getType();
7336 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7337 OldCount != NewCount) {
7338 // Currently, CountAttributedType can only wrap incomplete array types.
7339 Result = SemaRef.BuildCountAttributedArrayType(InnerTy, NewCount);
7340 }
7341
7342 TLB.push<CountAttributedTypeLoc>(Result);
7343 return Result;
7344}
7345
7346template <typename Derived>
7347QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7348 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7349 // The BTFTagAttributedType is available for C only.
7350 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7351}
7352
7353template<typename Derived>
7354QualType
7355TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7356 ParenTypeLoc TL) {
7357 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7358 if (Inner.isNull())
7359 return QualType();
7360
7361 QualType Result = TL.getType();
7362 if (getDerived().AlwaysRebuild() ||
7363 Inner != TL.getInnerLoc().getType()) {
7364 Result = getDerived().RebuildParenType(Inner);
7365 if (Result.isNull())
7366 return QualType();
7367 }
7368
7369 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
7370 NewTL.setLParenLoc(TL.getLParenLoc());
7371 NewTL.setRParenLoc(TL.getRParenLoc());
7372 return Result;
7373}
7374
7375template <typename Derived>
7376QualType
7377TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7378 MacroQualifiedTypeLoc TL) {
7379 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7380 if (Inner.isNull())
7381 return QualType();
7382
7383 QualType Result = TL.getType();
7384 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7385 Result =
7386 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7387 if (Result.isNull())
7388 return QualType();
7389 }
7390
7391 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
7392 NewTL.setExpansionLoc(TL.getExpansionLoc());
7393 return Result;
7394}
7395
7396template<typename Derived>
7397QualType TreeTransform<Derived>::TransformDependentNameType(
7398 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7399 return TransformDependentNameType(TLB, TL, false);
7400}
7401
7402template<typename Derived>
7403QualType TreeTransform<Derived>::TransformDependentNameType(
7404 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7405 const DependentNameType *T = TL.getTypePtr();
7406
7407 NestedNameSpecifierLoc QualifierLoc
7408 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7409 if (!QualifierLoc)
7410 return QualType();
7411
7412 QualType Result
7413 = getDerived().RebuildDependentNameType(T->getKeyword(),
7414 TL.getElaboratedKeywordLoc(),
7415 QualifierLoc,
7416 T->getIdentifier(),
7417 TL.getNameLoc(),
7418 DeducedTSTContext);
7419 if (Result.isNull())
7420 return QualType();
7421
7422 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7423 QualType NamedT = ElabT->getNamedType();
7424 TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
7425
7426 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7427 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7428 NewTL.setQualifierLoc(QualifierLoc);
7429 } else {
7430 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
7431 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7432 NewTL.setQualifierLoc(QualifierLoc);
7433 NewTL.setNameLoc(TL.getNameLoc());
7434 }
7435 return Result;
7436}
7437
7438template<typename Derived>
7441 DependentTemplateSpecializationTypeLoc TL) {
7442 NestedNameSpecifierLoc QualifierLoc;
7443 if (TL.getQualifierLoc()) {
7444 QualifierLoc
7445 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7446 if (!QualifierLoc)
7447 return QualType();
7448 }
7449
7450 return getDerived()
7451 .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
7452}
7453
7454template<typename Derived>
7458 NestedNameSpecifierLoc QualifierLoc) {
7460
7461 TemplateArgumentListInfo NewTemplateArgs;
7462 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7463 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7464
7467 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7468 ArgIterator(TL, TL.getNumArgs()),
7469 NewTemplateArgs))
7470 return QualType();
7471
7472 QualType Result = getDerived().RebuildDependentTemplateSpecializationType(
7473 T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(),
7474 T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs,
7475 /*AllowInjectedClassName*/ false);
7476 if (Result.isNull())
7477 return QualType();
7478
7479 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
7480 QualType NamedT = ElabT->getNamedType();
7481
7482 // Copy information relevant to the template specialization.
7484 = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
7487 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7488 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7489 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7490 NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7491
7492 // Copy information relevant to the elaborated type.
7495 NewTL.setQualifierLoc(QualifierLoc);
7496 } else if (isa<DependentTemplateSpecializationType>(Result)) {
7500 SpecTL.setQualifierLoc(QualifierLoc);
7503 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7504 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7505 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7506 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7507 } else {
7512 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7513 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7514 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7515 SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
7516 }
7517 return Result;
7518}
7519
7520template<typename Derived>
7523 QualType Pattern
7524 = getDerived().TransformType(TLB, TL.getPatternLoc());
7525 if (Pattern.isNull())
7526 return QualType();
7527
7528 QualType Result = TL.getType();
7529 if (getDerived().AlwaysRebuild() ||
7530 Pattern != TL.getPatternLoc().getType()) {
7531 Result = getDerived().RebuildPackExpansionType(Pattern,
7533 TL.getEllipsisLoc(),
7535 if (Result.isNull())
7536 return QualType();
7537 }
7538
7539 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
7540 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7541 return Result;
7542}
7543
7544template<typename Derived>
7545QualType
7546TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7547 ObjCInterfaceTypeLoc TL) {
7548 // ObjCInterfaceType is never dependent.
7549 TLB.pushFullCopy(TL);
7550 return TL.getType();
7551}
7552
7553template<typename Derived>
7554QualType
7555TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7556 ObjCTypeParamTypeLoc TL) {
7557 const ObjCTypeParamType *T = TL.getTypePtr();
7558 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7559 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7560 if (!OTP)
7561 return QualType();
7562
7563 QualType Result = TL.getType();
7564 if (getDerived().AlwaysRebuild() ||
7565 OTP != T->getDecl()) {
7566 Result = getDerived().RebuildObjCTypeParamType(
7567 OTP, TL.getProtocolLAngleLoc(),
7568 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7569 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7570 if (Result.isNull())
7571 return QualType();
7572 }
7573
7574 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
7575 if (TL.getNumProtocols()) {
7576 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7577 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7578 NewTL.setProtocolLoc(i, TL.getProtocolLoc(i));
7579 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7580 }
7581 return Result;
7582}
7583
7584template<typename Derived>
7585QualType
7586TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7587 ObjCObjectTypeLoc TL) {
7588 // Transform base type.
7589 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7590 if (BaseType.isNull())
7591 return QualType();
7592
7593 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7594
7595 // Transform type arguments.
7596 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7597 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7598 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7599 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7600 QualType TypeArg = TypeArgInfo->getType();
7601 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7602 AnyChanged = true;
7603
7604 // We have a pack expansion. Instantiate it.
7605 const auto *PackExpansion = PackExpansionLoc.getType()
7606 ->castAs<PackExpansionType>();
7608 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
7609 Unexpanded);
7610 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7611
7612 // Determine whether the set of unexpanded parameter packs can
7613 // and should be expanded.
7614 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7615 bool Expand = false;
7616 bool RetainExpansion = false;
7617 std::optional<unsigned> NumExpansions = PackExpansion->getNumExpansions();
7618 if (getDerived().TryExpandParameterPacks(
7619 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7620 Unexpanded, Expand, RetainExpansion, NumExpansions))
7621 return QualType();
7622
7623 if (!Expand) {
7624 // We can't expand this pack expansion into separate arguments yet;
7625 // just substitute into the pattern and create a new pack expansion
7626 // type.
7627 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
7628
7629 TypeLocBuilder TypeArgBuilder;
7630 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7631 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7632 PatternLoc);
7633 if (NewPatternType.isNull())
7634 return QualType();
7635
7636 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7637 NewPatternType, NumExpansions);
7638 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);
7639 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7640 NewTypeArgInfos.push_back(
7641 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewExpansionType));
7642 continue;
7643 }
7644
7645 // Substitute into the pack expansion pattern for each slice of the
7646 // pack.
7647 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
7648 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx);
7649
7650 TypeLocBuilder TypeArgBuilder;
7651 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());
7652
7653 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
7654 PatternLoc);
7655 if (NewTypeArg.isNull())
7656 return QualType();
7657
7658 NewTypeArgInfos.push_back(
7659 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7660 }
7661
7662 continue;
7663 }
7664
7665 TypeLocBuilder TypeArgBuilder;
7666 TypeArgBuilder.reserve(TypeArgLoc.getFullDataSize());
7667 QualType NewTypeArg =
7668 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
7669 if (NewTypeArg.isNull())
7670 return QualType();
7671
7672 // If nothing changed, just keep the old TypeSourceInfo.
7673 if (NewTypeArg == TypeArg) {
7674 NewTypeArgInfos.push_back(TypeArgInfo);
7675 continue;
7676 }
7677
7678 NewTypeArgInfos.push_back(
7679 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));
7680 AnyChanged = true;
7681 }
7682
7683 QualType Result = TL.getType();
7684 if (getDerived().AlwaysRebuild() || AnyChanged) {
7685 // Rebuild the type.
7686 Result = getDerived().RebuildObjCObjectType(
7687 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
7688 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
7689 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7690 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7691
7692 if (Result.isNull())
7693 return QualType();
7694 }
7695
7696 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);
7697 NewT.setHasBaseTypeAsWritten(true);
7698 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
7699 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
7700 NewT.setTypeArgTInfo(i, NewTypeArgInfos[i]);
7701 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
7702 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7703 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7704 NewT.setProtocolLoc(i, TL.getProtocolLoc(i));
7705 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7706 return Result;
7707}
7708
7709template<typename Derived>
7710QualType
7711TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
7712 ObjCObjectPointerTypeLoc TL) {
7713 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
7714 if (PointeeType.isNull())
7715 return QualType();
7716
7717 QualType Result = TL.getType();
7718 if (getDerived().AlwaysRebuild() ||
7719 PointeeType != TL.getPointeeLoc().getType()) {
7720 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
7721 TL.getStarLoc());
7722 if (Result.isNull())
7723 return QualType();
7724 }
7725
7726 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
7727 NewT.setStarLoc(TL.getStarLoc());
7728 return Result;
7729}
7730
7731//===----------------------------------------------------------------------===//
7732// Statement transformation
7733//===----------------------------------------------------------------------===//
7734template<typename Derived>
7736TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
7737 return S;
7738}
7739
7740template<typename Derived>
7743 return getDerived().TransformCompoundStmt(S, false);
7744}
7745
7746template<typename Derived>
7749 bool IsStmtExpr) {
7750 Sema::CompoundScopeRAII CompoundScope(getSema());
7751 Sema::FPFeaturesStateRAII FPSave(getSema());
7752 if (S->hasStoredFPFeatures())
7753 getSema().resetFPOptions(
7754 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
7755
7756 const Stmt *ExprResult = S->getStmtExprResult();
7757 bool SubStmtInvalid = false;
7758 bool SubStmtChanged = false;
7759 SmallVector<Stmt*, 8> Statements;
7760 for (auto *B : S->body()) {
7761 StmtResult Result = getDerived().TransformStmt(
7762 B, IsStmtExpr && B == ExprResult ? SDK_StmtExprResult : SDK_Discarded);
7763
7764 if (Result.isInvalid()) {
7765 // Immediately fail if this was a DeclStmt, since it's very
7766 // likely that this will cause problems for future statements.
7767 if (isa<DeclStmt>(B))
7768 return StmtError();
7769
7770 // Otherwise, just keep processing substatements and fail later.
7771 SubStmtInvalid = true;
7772 continue;
7773 }
7774
7775 SubStmtChanged = SubStmtChanged || Result.get() != B;
7776 Statements.push_back(Result.getAs<Stmt>());
7777 }
7778
7779 if (SubStmtInvalid)
7780 return StmtError();
7781
7782 if (!getDerived().AlwaysRebuild() &&
7783 !SubStmtChanged)
7784 return S;
7785
7786 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
7787 Statements,
7788 S->getRBracLoc(),
7789 IsStmtExpr);
7790}
7791
7792template<typename Derived>
7794TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
7795 ExprResult LHS, RHS;
7796 {
7797 EnterExpressionEvaluationContext Unevaluated(
7799
7800 // Transform the left-hand case value.
7801 LHS = getDerived().TransformExpr(S->getLHS());
7802 LHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), LHS);
7803 if (LHS.isInvalid())
7804 return StmtError();
7805
7806 // Transform the right-hand case value (for the GNU case-range extension).
7807 RHS = getDerived().TransformExpr(S->getRHS());
7808 RHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), RHS);
7809 if (RHS.isInvalid())
7810 return StmtError();
7811 }
7812
7813 // Build the case statement.
7814 // Case statements are always rebuilt so that they will attached to their
7815 // transformed switch statement.
7816 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
7817 LHS.get(),
7818 S->getEllipsisLoc(),
7819 RHS.get(),
7820 S->getColonLoc());
7821 if (Case.isInvalid())
7822 return StmtError();
7823
7824 // Transform the statement following the case
7825 StmtResult SubStmt =
7826 getDerived().TransformStmt(S->getSubStmt());
7827 if (SubStmt.isInvalid())
7828 return StmtError();
7829
7830 // Attach the body to the case statement
7831 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
7832}
7833
7834template <typename Derived>
7835StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
7836 // Transform the statement following the default case
7837 StmtResult SubStmt =
7838 getDerived().TransformStmt(S->getSubStmt());
7839 if (SubStmt.isInvalid())
7840 return StmtError();
7841
7842 // Default statements are always rebuilt
7843 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
7844 SubStmt.get());
7845}
7846
7847template<typename Derived>
7849TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
7850 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7851 if (SubStmt.isInvalid())
7852 return StmtError();
7853
7854 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
7855 S->getDecl());
7856 if (!LD)
7857 return StmtError();
7858
7859 // If we're transforming "in-place" (we're not creating new local
7860 // declarations), assume we're replacing the old label statement
7861 // and clear out the reference to it.
7862 if (LD == S->getDecl())
7863 S->getDecl()->setStmt(nullptr);
7864
7865 // FIXME: Pass the real colon location in.
7866 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
7867 cast<LabelDecl>(LD), SourceLocation(),
7868 SubStmt.get());
7869}
7870
7871template <typename Derived>
7873 if (!R)
7874 return R;
7875
7876 switch (R->getKind()) {
7877// Transform attributes by calling TransformXXXAttr.
7878#define ATTR(X) \
7879 case attr::X: \
7880 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
7881#include "clang/Basic/AttrList.inc"
7882 }
7883 return R;
7884}
7885
7886template <typename Derived>
7888 const Stmt *InstS,
7889 const Attr *R) {
7890 if (!R)
7891 return R;
7892
7893 switch (R->getKind()) {
7894// Transform attributes by calling TransformStmtXXXAttr.
7895#define ATTR(X) \
7896 case attr::X: \
7897 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
7898#include "clang/Basic/AttrList.inc"
7899 }
7900 return TransformAttr(R);
7901}
7902
7903template <typename Derived>
7906 StmtDiscardKind SDK) {
7907 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
7908 if (SubStmt.isInvalid())
7909 return StmtError();
7910
7911 bool AttrsChanged = false;
7913
7914 // Visit attributes and keep track if any are transformed.
7915 for (const auto *I : S->getAttrs()) {
7916 const Attr *R =
7917 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
7918 AttrsChanged |= (I != R);
7919 if (R)
7920 Attrs.push_back(R);
7921 }
7922
7923 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
7924 return S;
7925
7926 // If transforming the attributes failed for all of the attributes in the
7927 // statement, don't make an AttributedStmt without attributes.
7928 if (Attrs.empty())
7929 return SubStmt;
7930
7931 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
7932 SubStmt.get());
7933}
7934
7935template<typename Derived>
7937TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
7938 // Transform the initialization statement
7939 StmtResult Init = getDerived().TransformStmt(S->getInit());
7940 if (Init.isInvalid())
7941 return StmtError();
7942
7943 Sema::ConditionResult Cond;
7944 if (!S->isConsteval()) {
7945 // Transform the condition
7946 Cond = getDerived().TransformCondition(
7947 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
7948 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
7950 if (Cond.isInvalid())
7951 return StmtError();
7952 }
7953
7954 // If this is a constexpr if, determine which arm we should instantiate.
7955 std::optional<bool> ConstexprConditionValue;
7956 if (S->isConstexpr())
7957 ConstexprConditionValue = Cond.getKnownValue();
7958
7959 // Transform the "then" branch.
7960 StmtResult Then;
7961 if (!ConstexprConditionValue || *ConstexprConditionValue) {
7962 EnterExpressionEvaluationContext Ctx(
7965 S->isNonNegatedConsteval());
7966
7967 Then = getDerived().TransformStmt(S->getThen());
7968 if (Then.isInvalid())
7969 return StmtError();
7970 } else {
7971 // Discarded branch is replaced with empty CompoundStmt so we can keep
7972 // proper source location for start and end of original branch, so
7973 // subsequent transformations like CoverageMapping work properly
7974 Then = new (getSema().Context)
7975 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
7976 }
7977
7978 // Transform the "else" branch.
7979 StmtResult Else;
7980 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
7981 EnterExpressionEvaluationContext Ctx(
7984 S->isNegatedConsteval());
7985
7986 Else = getDerived().TransformStmt(S->getElse());
7987 if (Else.isInvalid())
7988 return StmtError();
7989 } else if (S->getElse() && ConstexprConditionValue &&
7990 *ConstexprConditionValue) {
7991 // Same thing here as with <then> branch, we are discarding it, we can't
7992 // replace it with NULL nor NullStmt as we need to keep for source location
7993 // range, for CoverageMapping
7994 Else = new (getSema().Context)
7995 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
7996 }
7997
7998 if (!getDerived().AlwaysRebuild() &&
7999 Init.get() == S->getInit() &&
8000 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8001 Then.get() == S->getThen() &&
8002 Else.get() == S->getElse())
8003 return S;
8004
8005 return getDerived().RebuildIfStmt(
8006 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8007 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8008}
8009
8010template<typename Derived>
8012TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8013 // Transform the initialization statement
8014 StmtResult Init = getDerived().TransformStmt(S->getInit());
8015 if (Init.isInvalid())
8016 return StmtError();
8017
8018 // Transform the condition.
8019 Sema::ConditionResult Cond = getDerived().TransformCondition(
8020 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8022 if (Cond.isInvalid())
8023 return StmtError();
8024
8025 // Rebuild the switch statement.
8027 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8028 Init.get(), Cond, S->getRParenLoc());
8029 if (Switch.isInvalid())
8030 return StmtError();
8031
8032 // Transform the body of the switch statement.
8033 StmtResult Body = getDerived().TransformStmt(S->getBody());
8034 if (Body.isInvalid())
8035 return StmtError();
8036
8037 // Complete the switch statement.
8038 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8039 Body.get());
8040}
8041
8042template<typename Derived>
8044TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8045 // Transform the condition
8046 Sema::ConditionResult Cond = getDerived().TransformCondition(
8047 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8049 if (Cond.isInvalid())
8050 return StmtError();
8051
8052 // Transform the body
8053 StmtResult Body = getDerived().TransformStmt(S->getBody());
8054 if (Body.isInvalid())
8055 return StmtError();
8056
8057 if (!getDerived().AlwaysRebuild() &&
8058 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8059 Body.get() == S->getBody())
8060 return Owned(S);
8061
8062 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8063 Cond, S->getRParenLoc(), Body.get());
8064}
8065
8066template<typename Derived>
8068TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8069 // Transform the body
8070 StmtResult Body = getDerived().TransformStmt(S->getBody());
8071 if (Body.isInvalid())
8072 return StmtError();
8073
8074 // Transform the condition
8075 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8076 if (Cond.isInvalid())
8077 return StmtError();
8078
8079 if (!getDerived().AlwaysRebuild() &&
8080 Cond.get() == S->getCond() &&
8081 Body.get() == S->getBody())
8082 return S;
8083
8084 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8085 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8086 S->getRParenLoc());
8087}
8088
8089template<typename Derived>
8091TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8092 if (getSema().getLangOpts().OpenMP)
8093 getSema().OpenMP().startOpenMPLoop();
8094
8095 // Transform the initialization statement
8096 StmtResult Init = getDerived().TransformStmt(S->getInit());
8097 if (Init.isInvalid())
8098 return StmtError();
8099
8100 // In OpenMP loop region loop control variable must be captured and be
8101 // private. Perform analysis of first part (if any).
8102 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8103 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8104 Init.get());
8105
8106 // Transform the condition
8107 Sema::ConditionResult Cond = getDerived().TransformCondition(
8108 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8110 if (Cond.isInvalid())
8111 return StmtError();
8112
8113 // Transform the increment
8114 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8115 if (Inc.isInvalid())
8116 return StmtError();
8117
8118 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8119 if (S->getInc() && !FullInc.get())
8120 return StmtError();
8121
8122 // Transform the body
8123 StmtResult Body = getDerived().TransformStmt(S->getBody());
8124 if (Body.isInvalid())
8125 return StmtError();
8126
8127 if (!getDerived().AlwaysRebuild() &&
8128 Init.get() == S->getInit() &&
8129 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8130 Inc.get() == S->getInc() &&
8131 Body.get() == S->getBody())
8132 return S;
8133
8134 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8135 Init.get(), Cond, FullInc,
8136 S->getRParenLoc(), Body.get());
8137}
8138
8139template<typename Derived>
8141TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8142 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8143 S->getLabel());
8144 if (!LD)
8145 return StmtError();
8146
8147 // Goto statements must always be rebuilt, to resolve the label.
8148 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8149 cast<LabelDecl>(LD));
8150}
8151
8152template<typename Derived>
8154TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8155 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8156 if (Target.isInvalid())
8157 return StmtError();
8158 Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());
8159
8160 if (!getDerived().AlwaysRebuild() &&
8161 Target.get() == S->getTarget())
8162 return S;
8163
8164 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8165 Target.get());
8166}
8167
8168template<typename Derived>
8170TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8171 return S;
8172}
8173
8174template<typename Derived>
8176TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8177 return S;
8178}
8179
8180template<typename Derived>
8182TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8183 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8184 /*NotCopyInit*/false);
8185 if (Result.isInvalid())
8186 return StmtError();
8187
8188 // FIXME: We always rebuild the return statement because there is no way
8189 // to tell whether the return type of the function has changed.
8190 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8191}
8192
8193template<typename Derived>
8195TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8196 bool DeclChanged = false;
8198 for (auto *D : S->decls()) {
8199 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8200 if (!Transformed)
8201 return StmtError();
8202
8203 if (Transformed != D)
8204 DeclChanged = true;
8205
8206 Decls.push_back(Transformed);
8207 }
8208
8209 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8210 return S;
8211
8212 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8213}
8214
8215template<typename Derived>
8217TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8218
8219 SmallVector<Expr*, 8> Constraints;
8222
8223 ExprResult AsmString;
8224 SmallVector<Expr*, 8> Clobbers;
8225
8226 bool ExprsChanged = false;
8227
8228 // Go through the outputs.
8229 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8230 Names.push_back(S->getOutputIdentifier(I));
8231
8232 // No need to transform the constraint literal.
8233 Constraints.push_back(S->getOutputConstraintLiteral(I));
8234
8235 // Transform the output expr.
8236 Expr *OutputExpr = S->getOutputExpr(I);
8237 ExprResult Result = getDerived().TransformExpr(OutputExpr);
8238 if (Result.isInvalid())
8239 return StmtError();
8240
8241 ExprsChanged |= Result.get() != OutputExpr;
8242
8243 Exprs.push_back(Result.get());
8244 }
8245
8246 // Go through the inputs.
8247 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8248 Names.push_back(S->getInputIdentifier(I));
8249
8250 // No need to transform the constraint literal.
8251 Constraints.push_back(S->getInputConstraintLiteral(I));
8252
8253 // Transform the input expr.
8254 Expr *InputExpr = S->getInputExpr(I);
8255 ExprResult Result = getDerived().TransformExpr(InputExpr);
8256 if (Result.isInvalid())
8257 return StmtError();
8258
8259 ExprsChanged |= Result.get() != InputExpr;
8260
8261 Exprs.push_back(Result.get());
8262 }
8263
8264 // Go through the Labels.
8265 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8266 Names.push_back(S->getLabelIdentifier(I));
8267
8268 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(I));
8269 if (Result.isInvalid())
8270 return StmtError();
8271 ExprsChanged |= Result.get() != S->getLabelExpr(I);
8272 Exprs.push_back(Result.get());
8273 }
8274 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8275 return S;
8276
8277 // Go through the clobbers.
8278 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
8279 Clobbers.push_back(S->getClobberStringLiteral(I));
8280
8281 // No need to transform the asm string literal.
8282 AsmString = S->getAsmString();
8283 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8284 S->isVolatile(), S->getNumOutputs(),
8285 S->getNumInputs(), Names.data(),
8286 Constraints, Exprs, AsmString.get(),
8287 Clobbers, S->getNumLabels(),
8288 S->getRParenLoc());
8289}
8290
8291template<typename Derived>
8293TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8294 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8295
8296 bool HadError = false, HadChange = false;
8297
8298 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8299 SmallVector<Expr*, 8> TransformedExprs;
8300 TransformedExprs.reserve(SrcExprs.size());
8301 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8302 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8303 if (!Result.isUsable()) {
8304 HadError = true;
8305 } else {
8306 HadChange |= (Result.get() != SrcExprs[i]);
8307 TransformedExprs.push_back(Result.get());
8308 }
8309 }
8310
8311 if (HadError) return StmtError();
8312 if (!HadChange && !getDerived().AlwaysRebuild())
8313 return Owned(S);
8314
8315 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8316 AsmToks, S->getAsmString(),
8317 S->getNumOutputs(), S->getNumInputs(),
8318 S->getAllConstraints(), S->getClobbers(),
8319 TransformedExprs, S->getEndLoc());
8320}
8321
8322// C++ Coroutines
8323template<typename Derived>
8325TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8326 auto *ScopeInfo = SemaRef.getCurFunction();
8327 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
8328 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8329 ScopeInfo->NeedsCoroutineSuspends &&
8330 ScopeInfo->CoroutineSuspends.first == nullptr &&
8331 ScopeInfo->CoroutineSuspends.second == nullptr &&
8332 "expected clean scope info");
8333
8334 // Set that we have (possibly-invalid) suspend points before we do anything
8335 // that may fail.
8336 ScopeInfo->setNeedsCoroutineSuspends(false);
8337
8338 // We re-build the coroutine promise object (and the coroutine parameters its
8339 // type and constructor depend on) based on the types used in our current
8340 // function. We must do so, and set it on the current FunctionScopeInfo,
8341 // before attempting to transform the other parts of the coroutine body
8342 // statement, such as the implicit suspend statements (because those
8343 // statements reference the FunctionScopeInfo::CoroutinePromise).
8344 if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation()))
8345 return StmtError();
8346 auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());
8347 if (!Promise)
8348 return StmtError();
8349 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8350 ScopeInfo->CoroutinePromise = Promise;
8351
8352 // Transform the implicit coroutine statements constructed using dependent
8353 // types during the previous parse: initial and final suspensions, the return
8354 // object, and others. We also transform the coroutine function's body.
8355 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8356 if (InitSuspend.isInvalid())
8357 return StmtError();
8358 StmtResult FinalSuspend =
8359 getDerived().TransformStmt(S->getFinalSuspendStmt());
8360 if (FinalSuspend.isInvalid() ||
8361 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get()))
8362 return StmtError();
8363 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());
8364 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8365
8366 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8367 if (BodyRes.isInvalid())
8368 return StmtError();
8369
8370 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8371 if (Builder.isInvalid())
8372 return StmtError();
8373
8374 Expr *ReturnObject = S->getReturnValueInit();
8375 assert(ReturnObject && "the return object is expected to be valid");
8376 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8377 /*NoCopyInit*/ false);
8378 if (Res.isInvalid())
8379 return StmtError();
8380 Builder.ReturnValue = Res.get();
8381
8382 // If during the previous parse the coroutine still had a dependent promise
8383 // statement, we may need to build some implicit coroutine statements
8384 // (such as exception and fallthrough handlers) for the first time.
8385 if (S->hasDependentPromiseType()) {
8386 // We can only build these statements, however, if the current promise type
8387 // is not dependent.
8388 if (!Promise->getType()->isDependentType()) {
8389 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8390 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8391 "these nodes should not have been built yet");
8392 if (!Builder.buildDependentStatements())
8393 return StmtError();
8394 }
8395 } else {
8396 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8397 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8398 if (Res.isInvalid())
8399 return StmtError();
8400 Builder.OnFallthrough = Res.get();
8401 }
8402
8403 if (auto *OnException = S->getExceptionHandler()) {
8404 StmtResult Res = getDerived().TransformStmt(OnException);
8405 if (Res.isInvalid())
8406 return StmtError();
8407 Builder.OnException = Res.get();
8408 }
8409
8410 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8411 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8412 if (Res.isInvalid())
8413 return StmtError();
8414 Builder.ReturnStmtOnAllocFailure = Res.get();
8415 }
8416
8417 // Transform any additional statements we may have already built
8418 assert(S->getAllocate() && S->getDeallocate() &&
8419 "allocation and deallocation calls must already be built");
8420 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8421 if (AllocRes.isInvalid())
8422 return StmtError();
8423 Builder.Allocate = AllocRes.get();
8424
8425 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8426 if (DeallocRes.isInvalid())
8427 return StmtError();
8428 Builder.Deallocate = DeallocRes.get();
8429
8430 if (auto *ResultDecl = S->getResultDecl()) {
8431 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8432 if (Res.isInvalid())
8433 return StmtError();
8434 Builder.ResultDecl = Res.get();
8435 }
8436
8437 if (auto *ReturnStmt = S->getReturnStmt()) {
8438 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8439 if (Res.isInvalid())
8440 return StmtError();
8441 Builder.ReturnStmt = Res.get();
8442 }
8443 }
8444
8445 return getDerived().RebuildCoroutineBodyStmt(Builder);
8446}
8447
8448template<typename Derived>
8450TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8451 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8452 /*NotCopyInit*/false);
8453 if (Result.isInvalid())
8454 return StmtError();
8455
8456 // Always rebuild; we don't know if this needs to be injected into a new
8457 // context or if the promise type has changed.
8458 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8459 S->isImplicit());
8460}
8461
8462template <typename Derived>
8463ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8464 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8465 /*NotCopyInit*/ false);
8466 if (Operand.isInvalid())
8467 return ExprError();
8468
8469 // Rebuild the common-expr from the operand rather than transforming it
8470 // separately.
8471
8472 // FIXME: getCurScope() should not be used during template instantiation.
8473 // We should pick up the set of unqualified lookup results for operator
8474 // co_await during the initial parse.
8475 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8476 getSema().getCurScope(), E->getKeywordLoc());
8477
8478 // Always rebuild; we don't know if this needs to be injected into a new
8479 // context or if the promise type has changed.
8480 return getDerived().RebuildCoawaitExpr(
8481 E->getKeywordLoc(), Operand.get(),
8482 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());
8483}
8484
8485template <typename Derived>
8487TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8488 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8489 /*NotCopyInit*/ false);
8490 if (OperandResult.isInvalid())
8491 return ExprError();
8492
8493 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8494 E->getOperatorCoawaitLookup());
8495
8496 if (LookupResult.isInvalid())
8497 return ExprError();
8498
8499 // Always rebuild; we don't know if this needs to be injected into a new
8500 // context or if the promise type has changed.
8501 return getDerived().RebuildDependentCoawaitExpr(
8502 E->getKeywordLoc(), OperandResult.get(),
8503 cast<UnresolvedLookupExpr>(LookupResult.get()));
8504}
8505
8506template<typename Derived>
8508TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8509 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8510 /*NotCopyInit*/false);
8511 if (Result.isInvalid())
8512 return ExprError();
8513
8514 // Always rebuild; we don't know if this needs to be injected into a new
8515 // context or if the promise type has changed.
8516 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8517}
8518
8519// Objective-C Statements.
8520
8521template<typename Derived>
8523TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8524 // Transform the body of the @try.
8525 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8526 if (TryBody.isInvalid())
8527 return StmtError();
8528
8529 // Transform the @catch statements (if present).
8530 bool AnyCatchChanged = false;
8531 SmallVector<Stmt*, 8> CatchStmts;
8532 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8533 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8534 if (Catch.isInvalid())
8535 return StmtError();
8536 if (Catch.get() != S->getCatchStmt(I))
8537 AnyCatchChanged = true;
8538 CatchStmts.push_back(Catch.get());
8539 }
8540
8541 // Transform the @finally statement (if present).
8542 StmtResult Finally;
8543 if (S->getFinallyStmt()) {
8544 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8545 if (Finally.isInvalid())
8546 return StmtError();
8547 }
8548
8549 // If nothing changed, just retain this statement.
8550 if (!getDerived().AlwaysRebuild() &&
8551 TryBody.get() == S->getTryBody() &&
8552 !AnyCatchChanged &&
8553 Finally.get() == S->getFinallyStmt())
8554 return S;
8555
8556 // Build a new statement.
8557 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8558 CatchStmts, Finally.get());
8559}
8560
8561template<typename Derived>
8563TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8564 // Transform the @catch parameter, if there is one.
8565 VarDecl *Var = nullptr;
8566 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8567 TypeSourceInfo *TSInfo = nullptr;
8568 if (FromVar->getTypeSourceInfo()) {
8569 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8570 if (!TSInfo)
8571 return StmtError();
8572 }
8573
8574 QualType T;
8575 if (TSInfo)
8576 T = TSInfo->getType();
8577 else {
8578 T = getDerived().TransformType(FromVar->getType());
8579 if (T.isNull())
8580 return StmtError();
8581 }
8582
8583 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8584 if (!Var)
8585 return StmtError();
8586 }
8587
8588 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8589 if (Body.isInvalid())
8590 return StmtError();
8591
8592 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
8593 S->getRParenLoc(),
8594 Var, Body.get());
8595}
8596
8597template<typename Derived>
8599TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
8600 // Transform the body.
8601 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
8602 if (Body.isInvalid())
8603 return StmtError();
8604
8605 // If nothing changed, just retain this statement.
8606 if (!getDerived().AlwaysRebuild() &&
8607 Body.get() == S->getFinallyBody())
8608 return S;
8609
8610 // Build a new statement.
8611 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
8612 Body.get());
8613}
8614
8615template<typename Derived>
8617TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
8619 if (S->getThrowExpr()) {
8620 Operand = getDerived().TransformExpr(S->getThrowExpr());
8621 if (Operand.isInvalid())
8622 return StmtError();
8623 }
8624
8625 if (!getDerived().AlwaysRebuild() &&
8626 Operand.get() == S->getThrowExpr())
8627 return S;
8628
8629 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
8630}
8631
8632template<typename Derived>
8634TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
8635 ObjCAtSynchronizedStmt *S) {
8636 // Transform the object we are locking.
8637 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
8638 if (Object.isInvalid())
8639 return StmtError();
8640 Object =
8641 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
8642 Object.get());
8643 if (Object.isInvalid())
8644 return StmtError();
8645
8646 // Transform the body.
8647 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
8648 if (Body.isInvalid())
8649 return StmtError();
8650
8651 // If nothing change, just retain the current statement.
8652 if (!getDerived().AlwaysRebuild() &&
8653 Object.get() == S->getSynchExpr() &&
8654 Body.get() == S->getSynchBody())
8655 return S;
8656
8657 // Build a new statement.
8658 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
8659 Object.get(), Body.get());
8660}
8661
8662template<typename Derived>
8664TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
8665 ObjCAutoreleasePoolStmt *S) {
8666 // Transform the body.
8667 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
8668 if (Body.isInvalid())
8669 return StmtError();
8670
8671 // If nothing changed, just retain this statement.
8672 if (!getDerived().AlwaysRebuild() &&
8673 Body.get() == S->getSubStmt())
8674 return S;
8675
8676 // Build a new statement.
8677 return getDerived().RebuildObjCAutoreleasePoolStmt(
8678 S->getAtLoc(), Body.get());
8679}
8680
8681template<typename Derived>
8683TreeTransform<Derived>::TransformObjCForCollectionStmt(
8684 ObjCForCollectionStmt *S) {
8685 // Transform the element statement.
8686 StmtResult Element =
8687 getDerived().TransformStmt(S->getElement(), SDK_NotDiscarded);
8688 if (Element.isInvalid())
8689 return StmtError();
8690
8691 // Transform the collection expression.
8692 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
8693 if (Collection.isInvalid())
8694 return StmtError();
8695
8696 // Transform the body.
8697 StmtResult Body = getDerived().TransformStmt(S->getBody());
8698 if (Body.isInvalid())
8699 return StmtError();
8700
8701 // If nothing changed, just retain this statement.
8702 if (!getDerived().AlwaysRebuild() &&
8703 Element.get() == S->getElement() &&
8704 Collection.get() == S->getCollection() &&
8705 Body.get() == S->getBody())
8706 return S;
8707
8708 // Build a new statement.
8709 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
8710 Element.get(),
8711 Collection.get(),
8712 S->getRParenLoc(),
8713 Body.get());
8714}
8715
8716template <typename Derived>
8717StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
8718 // Transform the exception declaration, if any.
8719 VarDecl *Var = nullptr;
8720 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
8721 TypeSourceInfo *T =
8722 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
8723 if (!T)
8724 return StmtError();
8725
8726 Var = getDerived().RebuildExceptionDecl(
8727 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
8728 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
8729 if (!Var || Var->isInvalidDecl())
8730 return StmtError();
8731 }
8732
8733 // Transform the actual exception handler.
8734 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
8735 if (Handler.isInvalid())
8736 return StmtError();
8737
8738 if (!getDerived().AlwaysRebuild() && !Var &&
8739 Handler.get() == S->getHandlerBlock())
8740 return S;
8741
8742 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
8743}
8744
8745template <typename Derived>
8746StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
8747 // Transform the try block itself.
8748 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8749 if (TryBlock.isInvalid())
8750 return StmtError();
8751
8752 // Transform the handlers.
8753 bool HandlerChanged = false;
8754 SmallVector<Stmt *, 8> Handlers;
8755 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
8756 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I));
8757 if (Handler.isInvalid())
8758 return StmtError();
8759
8760 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
8761 Handlers.push_back(Handler.getAs<Stmt>());
8762 }
8763
8764 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8765 !HandlerChanged)
8766 return S;
8767
8768 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
8769 Handlers);
8770}
8771
8772template<typename Derived>
8774TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
8775 EnterExpressionEvaluationContext ForRangeInitContext(
8777 /*LambdaContextDecl=*/nullptr,
8779 getSema().getLangOpts().CPlusPlus23);
8780
8781 // P2718R0 - Lifetime extension in range-based for loops.
8782 if (getSema().getLangOpts().CPlusPlus23) {
8783 auto &LastRecord = getSema().ExprEvalContexts.back();
8784 LastRecord.InLifetimeExtendingContext = true;
8785 }
8787 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
8788 if (Init.isInvalid())
8789 return StmtError();
8790
8791 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
8792 if (Range.isInvalid())
8793 return StmtError();
8794
8795 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
8796 assert(getSema().getLangOpts().CPlusPlus23 ||
8797 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
8798 auto ForRangeLifetimeExtendTemps =
8799 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
8800
8801 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
8802 if (Begin.isInvalid())
8803 return StmtError();
8804 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
8805 if (End.isInvalid())
8806 return StmtError();
8807
8808 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8809 if (Cond.isInvalid())
8810 return StmtError();
8811 if (Cond.get())
8812 Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());
8813 if (Cond.isInvalid())
8814 return StmtError();
8815 if (Cond.get())
8816 Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());
8817
8818 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8819 if (Inc.isInvalid())
8820 return StmtError();
8821 if (Inc.get())
8822 Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());
8823
8824 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
8825 if (LoopVar.isInvalid())
8826 return StmtError();
8827
8828 StmtResult NewStmt = S;
8829 if (getDerived().AlwaysRebuild() ||
8830 Init.get() != S->getInit() ||
8831 Range.get() != S->getRangeStmt() ||
8832 Begin.get() != S->getBeginStmt() ||
8833 End.get() != S->getEndStmt() ||
8834 Cond.get() != S->getCond() ||
8835 Inc.get() != S->getInc() ||
8836 LoopVar.get() != S->getLoopVarStmt()) {
8837 NewStmt = getDerived().RebuildCXXForRangeStmt(
8838 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
8839 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
8840 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
8841 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
8842 // Might not have attached any initializer to the loop variable.
8843 getSema().ActOnInitializerError(
8844 cast<DeclStmt>(LoopVar.get())->getSingleDecl());
8845 return StmtError();
8846 }
8847 }
8848
8849 StmtResult Body = getDerived().TransformStmt(S->getBody());
8850 if (Body.isInvalid())
8851 return StmtError();
8852
8853 // Body has changed but we didn't rebuild the for-range statement. Rebuild
8854 // it now so we have a new statement to attach the body to.
8855 if (Body.get() != S->getBody() && NewStmt.get() == S) {
8856 NewStmt = getDerived().RebuildCXXForRangeStmt(
8857 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
8858 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
8859 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
8860 if (NewStmt.isInvalid())
8861 return StmtError();
8862 }
8863
8864 if (NewStmt.get() == S)
8865 return S;
8866
8867 return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
8868}
8869
8870template<typename Derived>
8872TreeTransform<Derived>::TransformMSDependentExistsStmt(
8873 MSDependentExistsStmt *S) {
8874 // Transform the nested-name-specifier, if any.
8875 NestedNameSpecifierLoc QualifierLoc;
8876 if (S->getQualifierLoc()) {
8877 QualifierLoc
8878 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
8879 if (!QualifierLoc)
8880 return StmtError();
8881 }
8882
8883 // Transform the declaration name.
8884 DeclarationNameInfo NameInfo = S->getNameInfo();
8885 if (NameInfo.getName()) {
8886 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
8887 if (!NameInfo.getName())
8888 return StmtError();
8889 }
8890
8891 // Check whether anything changed.
8892 if (!getDerived().AlwaysRebuild() &&
8893 QualifierLoc == S->getQualifierLoc() &&
8894 NameInfo.getName() == S->getNameInfo().getName())
8895 return S;
8896
8897 // Determine whether this name exists, if we can.
8898 CXXScopeSpec SS;
8899 SS.Adopt(QualifierLoc);
8900 bool Dependent = false;
8901 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
8902 case Sema::IER_Exists:
8903 if (S->isIfExists())
8904 break;
8905
8906 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8907
8909 if (S->isIfNotExists())
8910 break;
8911
8912 return new (getSema().Context) NullStmt(S->getKeywordLoc());
8913
8915 Dependent = true;
8916 break;
8917
8918 case Sema::IER_Error:
8919 return StmtError();
8920 }
8921
8922 // We need to continue with the instantiation, so do so now.
8923 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
8924 if (SubStmt.isInvalid())
8925 return StmtError();
8926
8927 // If we have resolved the name, just transform to the substatement.
8928 if (!Dependent)
8929 return SubStmt;
8930
8931 // The name is still dependent, so build a dependent expression again.
8932 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
8933 S->isIfExists(),
8934 QualifierLoc,
8935 NameInfo,
8936 SubStmt.get());
8937}
8938
8939template<typename Derived>
8941TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
8942 NestedNameSpecifierLoc QualifierLoc;
8943 if (E->getQualifierLoc()) {
8944 QualifierLoc
8945 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
8946 if (!QualifierLoc)
8947 return ExprError();
8948 }
8949
8950 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
8951 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
8952 if (!PD)
8953 return ExprError();
8954
8955 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
8956 if (Base.isInvalid())
8957 return ExprError();
8958
8959 return new (SemaRef.getASTContext())
8960 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
8962 QualifierLoc, E->getMemberLoc());
8963}
8964
8965template <typename Derived>
8966ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
8967 MSPropertySubscriptExpr *E) {
8968 auto BaseRes = getDerived().TransformExpr(E->getBase());
8969 if (BaseRes.isInvalid())
8970 return ExprError();
8971 auto IdxRes = getDerived().TransformExpr(E->getIdx());
8972 if (IdxRes.isInvalid())
8973 return ExprError();
8974
8975 if (!getDerived().AlwaysRebuild() &&
8976 BaseRes.get() == E->getBase() &&
8977 IdxRes.get() == E->getIdx())
8978 return E;
8979
8980 return getDerived().RebuildArraySubscriptExpr(
8981 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
8982}
8983
8984template <typename Derived>
8985StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
8986 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
8987 if (TryBlock.isInvalid())
8988 return StmtError();
8989
8990 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
8991 if (Handler.isInvalid())
8992 return StmtError();
8993
8994 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
8995 Handler.get() == S->getHandler())
8996 return S;
8997
8998 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
8999 TryBlock.get(), Handler.get());
9000}
9001
9002template <typename Derived>
9003StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9004 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9005 if (Block.isInvalid())
9006 return StmtError();
9007
9008 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9009}
9010
9011template <typename Derived>
9012StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9013 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9014 if (FilterExpr.isInvalid())
9015 return StmtError();
9016
9017 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9018 if (Block.isInvalid())
9019 return StmtError();
9020
9021 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9022 Block.get());
9023}
9024
9025template <typename Derived>
9027 if (isa<SEHFinallyStmt>(Handler))
9028 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
9029 else
9030 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
9031}
9032
9033template<typename Derived>
9036 return S;
9037}
9038
9039//===----------------------------------------------------------------------===//
9040// OpenMP directive transformation
9041//===----------------------------------------------------------------------===//
9042
9043template <typename Derived>
9045TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9046 // OMPCanonicalLoops are eliminated during transformation, since they will be
9047 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9048 // after transformation.
9049 return getDerived().TransformStmt(L->getLoopStmt());
9050}
9051
9052template <typename Derived>
9055
9056 // Transform the clauses
9058 ArrayRef<OMPClause *> Clauses = D->clauses();
9059 TClauses.reserve(Clauses.size());
9060 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9061 I != E; ++I) {
9062 if (*I) {
9063 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9064 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9065 getDerived().getSema().OpenMP().EndOpenMPClause();
9066 if (Clause)
9067 TClauses.push_back(Clause);
9068 } else {
9069 TClauses.push_back(nullptr);
9070 }
9071 }
9072 StmtResult AssociatedStmt;
9073 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9074 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9075 D->getDirectiveKind(),
9076 /*CurScope=*/nullptr);
9077 StmtResult Body;
9078 {
9079 Sema::CompoundScopeRAII CompoundScope(getSema());
9080 Stmt *CS;
9081 if (D->getDirectiveKind() == OMPD_atomic ||
9082 D->getDirectiveKind() == OMPD_critical ||
9083 D->getDirectiveKind() == OMPD_section ||
9084 D->getDirectiveKind() == OMPD_master)
9085 CS = D->getAssociatedStmt();
9086 else
9087 CS = D->getRawStmt();
9088 Body = getDerived().TransformStmt(CS);
9089 if (Body.isUsable() && isOpenMPLoopDirective(D->getDirectiveKind()) &&
9090 getSema().getLangOpts().OpenMPIRBuilder)
9091 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9092 }
9093 AssociatedStmt =
9094 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9095 if (AssociatedStmt.isInvalid()) {
9096 return StmtError();
9097 }
9098 }
9099 if (TClauses.size() != Clauses.size()) {
9100 return StmtError();
9101 }
9102
9103 // Transform directive name for 'omp critical' directive.
9104 DeclarationNameInfo DirName;
9105 if (D->getDirectiveKind() == OMPD_critical) {
9106 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
9107 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9108 }
9109 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9110 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9111 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();
9112 } else if (D->getDirectiveKind() == OMPD_cancel) {
9113 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();
9114 }
9115
9116 return getDerived().RebuildOMPExecutableDirective(
9117 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9118 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc(),
9119 D->getMappedDirective());
9120}
9121
9122template <typename Derived>
9125 // TODO: Fix This
9126 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)
9127 << getOpenMPDirectiveName(D->getDirectiveKind());
9128 return StmtError();
9129}
9130
9131template <typename Derived>
9133TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9134 DeclarationNameInfo DirName;
9135 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9136 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9137 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9138 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9139 return Res;
9140}
9141
9142template <typename Derived>
9144TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9145 DeclarationNameInfo DirName;
9146 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9147 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9148 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9149 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9150 return Res;
9151}
9152
9153template <typename Derived>
9155TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9156 DeclarationNameInfo DirName;
9157 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9158 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9159 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9160 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9161 return Res;
9162}
9163
9164template <typename Derived>
9166TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9167 DeclarationNameInfo DirName;
9168 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9169 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9170 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9171 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9172 return Res;
9173}
9174
9175template <typename Derived>
9177TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9178 DeclarationNameInfo DirName;
9179 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9180 OMPD_for, DirName, nullptr, D->getBeginLoc());
9181 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9182 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9183 return Res;
9184}
9185
9186template <typename Derived>
9188TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9189 DeclarationNameInfo DirName;
9190 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9191 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9192 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9193 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9194 return Res;
9195}
9196
9197template <typename Derived>
9199TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9200 DeclarationNameInfo DirName;
9201 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9202 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9203 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9204 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9205 return Res;
9206}
9207
9208template <typename Derived>
9210TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9211 DeclarationNameInfo DirName;
9212 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9213 OMPD_section, DirName, nullptr, D->getBeginLoc());
9214 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9215 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9216 return Res;
9217}
9218
9219template <typename Derived>
9221TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9222 DeclarationNameInfo DirName;
9223 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9224 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9225 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9226 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9227 return Res;
9228}
9229
9230template <typename Derived>
9232TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9233 DeclarationNameInfo DirName;
9234 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9235 OMPD_single, DirName, nullptr, D->getBeginLoc());
9236 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9237 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9238 return Res;
9239}
9240
9241template <typename Derived>
9243TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9244 DeclarationNameInfo DirName;
9245 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9246 OMPD_master, DirName, nullptr, D->getBeginLoc());
9247 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9248 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9249 return Res;
9250}
9251
9252template <typename Derived>
9254TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9255 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9256 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9257 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9258 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9259 return Res;
9260}
9261
9262template <typename Derived>
9263StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9264 OMPParallelForDirective *D) {
9265 DeclarationNameInfo DirName;
9266 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9267 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9268 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9269 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9270 return Res;
9271}
9272
9273template <typename Derived>
9274StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9275 OMPParallelForSimdDirective *D) {
9276 DeclarationNameInfo DirName;
9277 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9278 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9279 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9280 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9281 return Res;
9282}
9283
9284template <typename Derived>
9285StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9286 OMPParallelMasterDirective *D) {
9287 DeclarationNameInfo DirName;
9288 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9289 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
9290 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9291 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9292 return Res;
9293}
9294
9295template <typename Derived>
9296StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9297 OMPParallelMaskedDirective *D) {
9298 DeclarationNameInfo DirName;
9299 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9300 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
9301 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9302 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9303 return Res;
9304}
9305
9306template <typename Derived>
9307StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9308 OMPParallelSectionsDirective *D) {
9309 DeclarationNameInfo DirName;
9310 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9311 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
9312 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9313 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9314 return Res;
9315}
9316
9317template <typename Derived>
9319TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9320 DeclarationNameInfo DirName;
9321 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9322 OMPD_task, DirName, nullptr, D->getBeginLoc());
9323 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9324 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9325 return Res;
9326}
9327
9328template <typename Derived>
9329StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9330 OMPTaskyieldDirective *D) {
9331 DeclarationNameInfo DirName;
9332 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9333 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
9334 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9335 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9336 return Res;
9337}
9338
9339template <typename Derived>
9341TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9342 DeclarationNameInfo DirName;
9343 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9344 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
9345 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9346 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9347 return Res;
9348}
9349
9350template <typename Derived>
9352TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9353 DeclarationNameInfo DirName;
9354 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9355 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
9356 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9357 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9358 return Res;
9359}
9360
9361template <typename Derived>
9363TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9364 DeclarationNameInfo DirName;
9365 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9366 OMPD_error, DirName, nullptr, D->getBeginLoc());
9367 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9368 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9369 return Res;
9370}
9371
9372template <typename Derived>
9373StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9374 OMPTaskgroupDirective *D) {
9375 DeclarationNameInfo DirName;
9376 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9377 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
9378 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9379 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9380 return Res;
9381}
9382
9383template <typename Derived>
9385TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9386 DeclarationNameInfo DirName;
9387 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9388 OMPD_flush, DirName, nullptr, D->getBeginLoc());
9389 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9390 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9391 return Res;
9392}
9393
9394template <typename Derived>
9396TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9397 DeclarationNameInfo DirName;
9398 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9399 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
9400 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9401 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9402 return Res;
9403}
9404
9405template <typename Derived>
9407TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9408 DeclarationNameInfo DirName;
9409 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9410 OMPD_scan, DirName, nullptr, D->getBeginLoc());
9411 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9412 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9413 return Res;
9414}
9415
9416template <typename Derived>
9418TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9419 DeclarationNameInfo DirName;
9420 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9421 OMPD_ordered, DirName, nullptr, D->getBeginLoc());
9422 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9423 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9424 return Res;
9425}
9426
9427template <typename Derived>
9429TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9430 DeclarationNameInfo DirName;
9431 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9432 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
9433 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9434 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9435 return Res;
9436}
9437
9438template <typename Derived>
9440TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9441 DeclarationNameInfo DirName;
9442 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9443 OMPD_target, DirName, nullptr, D->getBeginLoc());
9444 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9445 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9446 return Res;
9447}
9448
9449template <typename Derived>
9450StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9451 OMPTargetDataDirective *D) {
9452 DeclarationNameInfo DirName;
9453 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9454 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
9455 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9456 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9457 return Res;
9458}
9459
9460template <typename Derived>
9461StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9462 OMPTargetEnterDataDirective *D) {
9463 DeclarationNameInfo DirName;
9464 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9465 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
9466 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9467 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9468 return Res;
9469}
9470
9471template <typename Derived>
9472StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9473 OMPTargetExitDataDirective *D) {
9474 DeclarationNameInfo DirName;
9475 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9476 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
9477 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9478 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9479 return Res;
9480}
9481
9482template <typename Derived>
9483StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
9484 OMPTargetParallelDirective *D) {
9485 DeclarationNameInfo DirName;
9486 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9487 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
9488 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9489 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9490 return Res;
9491}
9492
9493template <typename Derived>
9494StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
9495 OMPTargetParallelForDirective *D) {
9496 DeclarationNameInfo DirName;
9497 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9498 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
9499 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9500 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9501 return Res;
9502}
9503
9504template <typename Derived>
9505StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
9506 OMPTargetUpdateDirective *D) {
9507 DeclarationNameInfo DirName;
9508 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9509 OMPD_target_update, 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>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
9518 DeclarationNameInfo DirName;
9519 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9520 OMPD_teams, 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>
9527StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
9528 OMPCancellationPointDirective *D) {
9529 DeclarationNameInfo DirName;
9530 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9531 OMPD_cancellation_point, 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>::TransformOMPCancelDirective(OMPCancelDirective *D) {
9540 DeclarationNameInfo DirName;
9541 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9542 OMPD_cancel, 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>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
9551 DeclarationNameInfo DirName;
9552 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9553 OMPD_taskloop, 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>::TransformOMPTaskLoopSimdDirective(
9561 OMPTaskLoopSimdDirective *D) {
9562 DeclarationNameInfo DirName;
9563 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9564 OMPD_taskloop_simd, 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>
9571StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
9572 OMPMasterTaskLoopDirective *D) {
9573 DeclarationNameInfo DirName;
9574 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9575 OMPD_master_taskloop, 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>
9582StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
9583 OMPMaskedTaskLoopDirective *D) {
9584 DeclarationNameInfo DirName;
9585 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9586 OMPD_masked_taskloop, 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>
9593StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
9594 OMPMasterTaskLoopSimdDirective *D) {
9595 DeclarationNameInfo DirName;
9596 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9597 OMPD_master_taskloop_simd, 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>
9604StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
9605 OMPMaskedTaskLoopSimdDirective *D) {
9606 DeclarationNameInfo DirName;
9607 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9608 OMPD_masked_taskloop_simd, 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>
9615StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
9616 OMPParallelMasterTaskLoopDirective *D) {
9617 DeclarationNameInfo DirName;
9618 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9619 OMPD_parallel_master_taskloop, 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>
9626StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
9627 OMPParallelMaskedTaskLoopDirective *D) {
9628 DeclarationNameInfo DirName;
9629 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9630 OMPD_parallel_masked_taskloop, 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>::TransformOMPParallelMasterTaskLoopSimdDirective(
9639 OMPParallelMasterTaskLoopSimdDirective *D) {
9640 DeclarationNameInfo DirName;
9641 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9642 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9643 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9644 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9645 return Res;
9646}
9647
9648template <typename Derived>
9650TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
9651 OMPParallelMaskedTaskLoopSimdDirective *D) {
9652 DeclarationNameInfo DirName;
9653 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9654 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
9655 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9656 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9657 return Res;
9658}
9659
9660template <typename Derived>
9661StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
9662 OMPDistributeDirective *D) {
9663 DeclarationNameInfo DirName;
9664 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9665 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
9666 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9667 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9668 return Res;
9669}
9670
9671template <typename Derived>
9672StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
9673 OMPDistributeParallelForDirective *D) {
9674 DeclarationNameInfo DirName;
9675 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9676 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9677 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9678 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9679 return Res;
9680}
9681
9682template <typename Derived>
9684TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
9685 OMPDistributeParallelForSimdDirective *D) {
9686 DeclarationNameInfo DirName;
9687 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9688 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9689 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9690 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9691 return Res;
9692}
9693
9694template <typename Derived>
9695StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
9696 OMPDistributeSimdDirective *D) {
9697 DeclarationNameInfo DirName;
9698 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9699 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
9700 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9701 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9702 return Res;
9703}
9704
9705template <typename Derived>
9706StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
9707 OMPTargetParallelForSimdDirective *D) {
9708 DeclarationNameInfo DirName;
9709 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9710 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9711 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9712 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9713 return Res;
9714}
9715
9716template <typename Derived>
9717StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
9718 OMPTargetSimdDirective *D) {
9719 DeclarationNameInfo DirName;
9720 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9721 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
9722 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9723 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9724 return Res;
9725}
9726
9727template <typename Derived>
9728StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
9729 OMPTeamsDistributeDirective *D) {
9730 DeclarationNameInfo DirName;
9731 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9732 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
9733 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9734 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9735 return Res;
9736}
9737
9738template <typename Derived>
9739StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
9740 OMPTeamsDistributeSimdDirective *D) {
9741 DeclarationNameInfo DirName;
9742 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9743 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9744 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9745 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9746 return Res;
9747}
9748
9749template <typename Derived>
9750StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
9751 OMPTeamsDistributeParallelForSimdDirective *D) {
9752 DeclarationNameInfo DirName;
9753 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9754 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
9755 D->getBeginLoc());
9756 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9757 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9758 return Res;
9759}
9760
9761template <typename Derived>
9762StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
9763 OMPTeamsDistributeParallelForDirective *D) {
9764 DeclarationNameInfo DirName;
9765 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9766 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
9767 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9768 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9769 return Res;
9770}
9771
9772template <typename Derived>
9773StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
9774 OMPTargetTeamsDirective *D) {
9775 DeclarationNameInfo DirName;
9776 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9777 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
9778 auto Res = getDerived().TransformOMPExecutableDirective(D);
9779 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9780 return Res;
9781}
9782
9783template <typename Derived>
9784StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
9785 OMPTargetTeamsDistributeDirective *D) {
9786 DeclarationNameInfo DirName;
9787 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9788 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
9789 auto Res = getDerived().TransformOMPExecutableDirective(D);
9790 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9791 return Res;
9792}
9793
9794template <typename Derived>
9796TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
9797 OMPTargetTeamsDistributeParallelForDirective *D) {
9798 DeclarationNameInfo DirName;
9799 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9800 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
9801 D->getBeginLoc());
9802 auto Res = getDerived().TransformOMPExecutableDirective(D);
9803 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9804 return Res;
9805}
9806
9807template <typename Derived>
9808StmtResult TreeTransform<Derived>::
9809 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
9810 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
9811 DeclarationNameInfo DirName;
9812 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9813 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
9814 D->getBeginLoc());
9815 auto Res = getDerived().TransformOMPExecutableDirective(D);
9816 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9817 return Res;
9818}
9819
9820template <typename Derived>
9822TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
9823 OMPTargetTeamsDistributeSimdDirective *D) {
9824 DeclarationNameInfo DirName;
9825 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9826 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
9827 auto Res = getDerived().TransformOMPExecutableDirective(D);
9828 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9829 return Res;
9830}
9831
9832template <typename Derived>
9834TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
9835 DeclarationNameInfo DirName;
9836 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9837 OMPD_interop, DirName, nullptr, D->getBeginLoc());
9838 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9839 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9840 return Res;
9841}
9842
9843template <typename Derived>
9845TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
9846 DeclarationNameInfo DirName;
9847 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9848 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
9849 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9850 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9851 return Res;
9852}
9853
9854template <typename Derived>
9856TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
9857 DeclarationNameInfo DirName;
9858 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9859 OMPD_masked, DirName, nullptr, D->getBeginLoc());
9860 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9861 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9862 return Res;
9863}
9864
9865template <typename Derived>
9866StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
9867 OMPGenericLoopDirective *D) {
9868 DeclarationNameInfo DirName;
9869 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9870 OMPD_loop, DirName, nullptr, D->getBeginLoc());
9871 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9872 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9873 return Res;
9874}
9875
9876template <typename Derived>
9877StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
9878 OMPTeamsGenericLoopDirective *D) {
9879 DeclarationNameInfo DirName;
9880 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9881 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
9882 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9883 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9884 return Res;
9885}
9886
9887template <typename Derived>
9888StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
9889 OMPTargetTeamsGenericLoopDirective *D) {
9890 DeclarationNameInfo DirName;
9891 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9892 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
9893 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9894 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9895 return Res;
9896}
9897
9898template <typename Derived>
9899StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
9900 OMPParallelGenericLoopDirective *D) {
9901 DeclarationNameInfo DirName;
9902 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9903 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
9904 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9905 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9906 return Res;
9907}
9908
9909template <typename Derived>
9911TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
9912 OMPTargetParallelGenericLoopDirective *D) {
9913 DeclarationNameInfo DirName;
9914 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9915 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
9916 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9917 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9918 return Res;
9919}
9920
9921//===----------------------------------------------------------------------===//
9922// OpenMP clause transformation
9923//===----------------------------------------------------------------------===//
9924template <typename Derived>
9925OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
9926 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9927 if (Cond.isInvalid())
9928 return nullptr;
9929 return getDerived().RebuildOMPIfClause(
9930 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
9931 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
9932}
9933
9934template <typename Derived>
9935OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
9936 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
9937 if (Cond.isInvalid())
9938 return nullptr;
9939 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
9940 C->getLParenLoc(), C->getEndLoc());
9941}
9942
9943template <typename Derived>
9944OMPClause *
9945TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
9946 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
9947 if (NumThreads.isInvalid())
9948 return nullptr;
9949 return getDerived().RebuildOMPNumThreadsClause(
9950 NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9951}
9952
9953template <typename Derived>
9954OMPClause *
9955TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
9956 ExprResult E = getDerived().TransformExpr(C->getSafelen());
9957 if (E.isInvalid())
9958 return nullptr;
9959 return getDerived().RebuildOMPSafelenClause(
9960 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9961}
9962
9963template <typename Derived>
9964OMPClause *
9965TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
9966 ExprResult E = getDerived().TransformExpr(C->getAllocator());
9967 if (E.isInvalid())
9968 return nullptr;
9969 return getDerived().RebuildOMPAllocatorClause(
9970 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9971}
9972
9973template <typename Derived>
9974OMPClause *
9975TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
9976 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
9977 if (E.isInvalid())
9978 return nullptr;
9979 return getDerived().RebuildOMPSimdlenClause(
9980 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
9981}
9982
9983template <typename Derived>
9984OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
9985 SmallVector<Expr *, 4> TransformedSizes;
9986 TransformedSizes.reserve(C->getNumSizes());
9987 bool Changed = false;
9988 for (Expr *E : C->getSizesRefs()) {
9989 if (!E) {
9990 TransformedSizes.push_back(nullptr);
9991 continue;
9992 }
9993
9994 ExprResult T = getDerived().TransformExpr(E);
9995 if (T.isInvalid())
9996 return nullptr;
9997 if (E != T.get())
9998 Changed = true;
9999 TransformedSizes.push_back(T.get());
10000 }
10001
10002 if (!Changed && !getDerived().AlwaysRebuild())
10003 return C;
10004 return RebuildOMPSizesClause(TransformedSizes, C->getBeginLoc(),
10005 C->getLParenLoc(), C->getEndLoc());
10006}
10007
10008template <typename Derived>
10009OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10010 if (!getDerived().AlwaysRebuild())
10011 return C;
10012 return RebuildOMPFullClause(C->getBeginLoc(), C->getEndLoc());
10013}
10014
10015template <typename Derived>
10016OMPClause *
10017TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10018 ExprResult T = getDerived().TransformExpr(C->getFactor());
10019 if (T.isInvalid())
10020 return nullptr;
10021 Expr *Factor = T.get();
10022 bool Changed = Factor != C->getFactor();
10023
10024 if (!Changed && !getDerived().AlwaysRebuild())
10025 return C;
10026 return RebuildOMPPartialClause(Factor, C->getBeginLoc(), C->getLParenLoc(),
10027 C->getEndLoc());
10028}
10029
10030template <typename Derived>
10031OMPClause *
10032TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10033 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10034 if (E.isInvalid())
10035 return nullptr;
10036 return getDerived().RebuildOMPCollapseClause(
10037 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10038}
10039
10040template <typename Derived>
10041OMPClause *
10042TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10043 return getDerived().RebuildOMPDefaultClause(
10044 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
10045 C->getLParenLoc(), C->getEndLoc());
10046}
10047
10048template <typename Derived>
10049OMPClause *
10050TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10051 return getDerived().RebuildOMPProcBindClause(
10052 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10053 C->getLParenLoc(), C->getEndLoc());
10054}
10055
10056template <typename Derived>
10057OMPClause *
10058TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10059 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10060 if (E.isInvalid())
10061 return nullptr;
10062 return getDerived().RebuildOMPScheduleClause(
10063 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10064 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10065 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10066 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10067}
10068
10069template <typename Derived>
10070OMPClause *
10071TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10072 ExprResult E;
10073 if (auto *Num = C->getNumForLoops()) {
10074 E = getDerived().TransformExpr(Num);
10075 if (E.isInvalid())
10076 return nullptr;
10077 }
10078 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10079 C->getLParenLoc(), E.get());
10080}
10081
10082template <typename Derived>
10083OMPClause *
10084TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10085 ExprResult E;
10086 if (Expr *Evt = C->getEventHandler()) {
10087 E = getDerived().TransformExpr(Evt);
10088 if (E.isInvalid())
10089 return nullptr;
10090 }
10091 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10092 C->getLParenLoc(), C->getEndLoc());
10093}
10094
10095template <typename Derived>
10096OMPClause *
10097TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10098 // No need to rebuild this clause, no template-dependent parameters.
10099 return C;
10100}
10101
10102template <typename Derived>
10103OMPClause *
10104TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10105 // No need to rebuild this clause, no template-dependent parameters.
10106 return C;
10107}
10108
10109template <typename Derived>
10110OMPClause *
10111TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10112 // No need to rebuild this clause, no template-dependent parameters.
10113 return C;
10114}
10115
10116template <typename Derived>
10117OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10118 // No need to rebuild this clause, no template-dependent parameters.
10119 return C;
10120}
10121
10122template <typename Derived>
10123OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10124 // No need to rebuild this clause, no template-dependent parameters.
10125 return C;
10126}
10127
10128template <typename Derived>
10129OMPClause *
10130TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10131 // No need to rebuild this clause, no template-dependent parameters.
10132 return C;
10133}
10134
10135template <typename Derived>
10136OMPClause *
10137TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10138 // No need to rebuild this clause, no template-dependent parameters.
10139 return C;
10140}
10141
10142template <typename Derived>
10143OMPClause *
10144TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10145 // No need to rebuild this clause, no template-dependent parameters.
10146 return C;
10147}
10148
10149template <typename Derived>
10150OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10151 // No need to rebuild this clause, no template-dependent parameters.
10152 return C;
10153}
10154
10155template <typename Derived>
10156OMPClause *
10157TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10158 // No need to rebuild this clause, no template-dependent parameters.
10159 return C;
10160}
10161
10162template <typename Derived>
10163OMPClause *
10164TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10165 // No need to rebuild this clause, no template-dependent parameters.
10166 return C;
10167}
10168
10169template <typename Derived>
10170OMPClause *
10171TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10172 // No need to rebuild this clause, no template-dependent parameters.
10173 return C;
10174}
10175
10176template <typename Derived>
10177OMPClause *
10178TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10179 // No need to rebuild this clause, no template-dependent parameters.
10180 return C;
10181}
10182
10183template <typename Derived>
10184OMPClause *
10185TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10186 // No need to rebuild this clause, no template-dependent parameters.
10187 return C;
10188}
10189
10190template <typename Derived>
10191OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10192 // No need to rebuild this clause, no template-dependent parameters.
10193 return C;
10194}
10195
10196template <typename Derived>
10197OMPClause *
10198TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10199 // No need to rebuild this clause, no template-dependent parameters.
10200 return C;
10201}
10202
10203template <typename Derived>
10204OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10205 // No need to rebuild this clause, no template-dependent parameters.
10206 return C;
10207}
10208
10209template <typename Derived>
10210OMPClause *
10211TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10212 // No need to rebuild this clause, no template-dependent parameters.
10213 return C;
10214}
10215
10216template <typename Derived>
10217OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10218 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10219 if (IVR.isInvalid())
10220 return nullptr;
10221
10222 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10223 InteropInfo.PreferTypes.reserve(C->varlist_size() - 1);
10224 for (Expr *E : llvm::drop_begin(C->varlists())) {
10225 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
10226 if (ER.isInvalid())
10227 return nullptr;
10228 InteropInfo.PreferTypes.push_back(ER.get());
10229 }
10230 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10231 C->getBeginLoc(), C->getLParenLoc(),
10232 C->getVarLoc(), C->getEndLoc());
10233}
10234
10235template <typename Derived>
10236OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10237 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10238 if (ER.isInvalid())
10239 return nullptr;
10240 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10241 C->getLParenLoc(), C->getVarLoc(),
10242 C->getEndLoc());
10243}
10244
10245template <typename Derived>
10246OMPClause *
10247TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10248 ExprResult ER;
10249 if (Expr *IV = C->getInteropVar()) {
10250 ER = getDerived().TransformExpr(IV);
10251 if (ER.isInvalid())
10252 return nullptr;
10253 }
10254 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10255 C->getLParenLoc(), C->getVarLoc(),
10256 C->getEndLoc());
10257}
10258
10259template <typename Derived>
10260OMPClause *
10261TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10262 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10263 if (Cond.isInvalid())
10264 return nullptr;
10265 return getDerived().RebuildOMPNovariantsClause(
10266 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10267}
10268
10269template <typename Derived>
10270OMPClause *
10271TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
10272 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10273 if (Cond.isInvalid())
10274 return nullptr;
10275 return getDerived().RebuildOMPNocontextClause(
10276 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10277}
10278
10279template <typename Derived>
10280OMPClause *
10281TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
10282 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
10283 if (ThreadID.isInvalid())
10284 return nullptr;
10285 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10286 C->getLParenLoc(), C->getEndLoc());
10287}
10288
10289template <typename Derived>
10290OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10291 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10292 if (E.isInvalid())
10293 return nullptr;
10294 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10295 C->getLParenLoc(), C->getEndLoc());
10296}
10297
10298template <typename Derived>
10299OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10300 OMPUnifiedAddressClause *C) {
10301 llvm_unreachable("unified_address clause cannot appear in dependent context");
10302}
10303
10304template <typename Derived>
10305OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10306 OMPUnifiedSharedMemoryClause *C) {
10307 llvm_unreachable(
10308 "unified_shared_memory clause cannot appear in dependent context");
10309}
10310
10311template <typename Derived>
10312OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10313 OMPReverseOffloadClause *C) {
10314 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10315}
10316
10317template <typename Derived>
10318OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10319 OMPDynamicAllocatorsClause *C) {
10320 llvm_unreachable(
10321 "dynamic_allocators clause cannot appear in dependent context");
10322}
10323
10324template <typename Derived>
10325OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10326 OMPAtomicDefaultMemOrderClause *C) {
10327 llvm_unreachable(
10328 "atomic_default_mem_order clause cannot appear in dependent context");
10329}
10330
10331template <typename Derived>
10332OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10333 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10334 C->getBeginLoc(), C->getLParenLoc(),
10335 C->getEndLoc());
10336}
10337
10338template <typename Derived>
10339OMPClause *
10340TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10341 return getDerived().RebuildOMPSeverityClause(
10342 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10343 C->getLParenLoc(), C->getEndLoc());
10344}
10345
10346template <typename Derived>
10347OMPClause *
10348TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10349 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10350 if (E.isInvalid())
10351 return nullptr;
10352 return getDerived().RebuildOMPMessageClause(
10353 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10354 C->getEndLoc());
10355}
10356
10357template <typename Derived>
10358OMPClause *
10359TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10361 Vars.reserve(C->varlist_size());
10362 for (auto *VE : C->varlists()) {
10363 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10364 if (EVar.isInvalid())
10365 return nullptr;
10366 Vars.push_back(EVar.get());
10367 }
10368 return getDerived().RebuildOMPPrivateClause(
10369 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10370}
10371
10372template <typename Derived>
10373OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10374 OMPFirstprivateClause *C) {
10376 Vars.reserve(C->varlist_size());
10377 for (auto *VE : C->varlists()) {
10378 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10379 if (EVar.isInvalid())
10380 return nullptr;
10381 Vars.push_back(EVar.get());
10382 }
10383 return getDerived().RebuildOMPFirstprivateClause(
10384 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10385}
10386
10387template <typename Derived>
10388OMPClause *
10389TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10391 Vars.reserve(C->varlist_size());
10392 for (auto *VE : C->varlists()) {
10393 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10394 if (EVar.isInvalid())
10395 return nullptr;
10396 Vars.push_back(EVar.get());
10397 }
10398 return getDerived().RebuildOMPLastprivateClause(
10399 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10400 C->getLParenLoc(), C->getEndLoc());
10401}
10402
10403template <typename Derived>
10404OMPClause *
10405TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
10407 Vars.reserve(C->varlist_size());
10408 for (auto *VE : C->varlists()) {
10409 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10410 if (EVar.isInvalid())
10411 return nullptr;
10412 Vars.push_back(EVar.get());
10413 }
10414 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
10415 C->getLParenLoc(), C->getEndLoc());
10416}
10417
10418template <typename Derived>
10419OMPClause *
10420TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
10422 Vars.reserve(C->varlist_size());
10423 for (auto *VE : C->varlists()) {
10424 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10425 if (EVar.isInvalid())
10426 return nullptr;
10427 Vars.push_back(EVar.get());
10428 }
10429 CXXScopeSpec ReductionIdScopeSpec;
10430 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10431
10432 DeclarationNameInfo NameInfo = C->getNameInfo();
10433 if (NameInfo.getName()) {
10434 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10435 if (!NameInfo.getName())
10436 return nullptr;
10437 }
10438 // Build a list of all UDR decls with the same names ranged by the Scopes.
10439 // The Scope boundary is a duplication of the previous decl.
10440 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10441 for (auto *E : C->reduction_ops()) {
10442 // Transform all the decls.
10443 if (E) {
10444 auto *ULE = cast<UnresolvedLookupExpr>(E);
10445 UnresolvedSet<8> Decls;
10446 for (auto *D : ULE->decls()) {
10447 NamedDecl *InstD =
10448 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10449 Decls.addDecl(InstD, InstD->getAccess());
10450 }
10451 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10452 SemaRef.Context, /*NamingClass=*/nullptr,
10453 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10454 /*ADL=*/true, Decls.begin(), Decls.end(),
10455 /*KnownDependent=*/false));
10456 } else
10457 UnresolvedReductions.push_back(nullptr);
10458 }
10459 return getDerived().RebuildOMPReductionClause(
10460 Vars, C->getModifier(), C->getBeginLoc(), C->getLParenLoc(),
10461 C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
10462 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10463}
10464
10465template <typename Derived>
10466OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
10467 OMPTaskReductionClause *C) {
10469 Vars.reserve(C->varlist_size());
10470 for (auto *VE : C->varlists()) {
10471 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10472 if (EVar.isInvalid())
10473 return nullptr;
10474 Vars.push_back(EVar.get());
10475 }
10476 CXXScopeSpec ReductionIdScopeSpec;
10477 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10478
10479 DeclarationNameInfo NameInfo = C->getNameInfo();
10480 if (NameInfo.getName()) {
10481 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10482 if (!NameInfo.getName())
10483 return nullptr;
10484 }
10485 // Build a list of all UDR decls with the same names ranged by the Scopes.
10486 // The Scope boundary is a duplication of the previous decl.
10487 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10488 for (auto *E : C->reduction_ops()) {
10489 // Transform all the decls.
10490 if (E) {
10491 auto *ULE = cast<UnresolvedLookupExpr>(E);
10492 UnresolvedSet<8> Decls;
10493 for (auto *D : ULE->decls()) {
10494 NamedDecl *InstD =
10495 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10496 Decls.addDecl(InstD, InstD->getAccess());
10497 }
10498 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10499 SemaRef.Context, /*NamingClass=*/nullptr,
10500 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10501 /*ADL=*/true, Decls.begin(), Decls.end(),
10502 /*KnownDependent=*/false));
10503 } else
10504 UnresolvedReductions.push_back(nullptr);
10505 }
10506 return getDerived().RebuildOMPTaskReductionClause(
10507 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10508 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10509}
10510
10511template <typename Derived>
10512OMPClause *
10513TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
10515 Vars.reserve(C->varlist_size());
10516 for (auto *VE : C->varlists()) {
10517 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10518 if (EVar.isInvalid())
10519 return nullptr;
10520 Vars.push_back(EVar.get());
10521 }
10522 CXXScopeSpec ReductionIdScopeSpec;
10523 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
10524
10525 DeclarationNameInfo NameInfo = C->getNameInfo();
10526 if (NameInfo.getName()) {
10527 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
10528 if (!NameInfo.getName())
10529 return nullptr;
10530 }
10531 // Build a list of all UDR decls with the same names ranged by the Scopes.
10532 // The Scope boundary is a duplication of the previous decl.
10533 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
10534 for (auto *E : C->reduction_ops()) {
10535 // Transform all the decls.
10536 if (E) {
10537 auto *ULE = cast<UnresolvedLookupExpr>(E);
10538 UnresolvedSet<8> Decls;
10539 for (auto *D : ULE->decls()) {
10540 NamedDecl *InstD =
10541 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
10542 Decls.addDecl(InstD, InstD->getAccess());
10543 }
10544 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
10545 SemaRef.Context, /*NamingClass=*/nullptr,
10546 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
10547 /*ADL=*/true, Decls.begin(), Decls.end(),
10548 /*KnownDependent=*/false));
10549 } else
10550 UnresolvedReductions.push_back(nullptr);
10551 }
10552 return getDerived().RebuildOMPInReductionClause(
10553 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10554 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
10555}
10556
10557template <typename Derived>
10558OMPClause *
10559TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
10561 Vars.reserve(C->varlist_size());
10562 for (auto *VE : C->varlists()) {
10563 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10564 if (EVar.isInvalid())
10565 return nullptr;
10566 Vars.push_back(EVar.get());
10567 }
10568 ExprResult Step = getDerived().TransformExpr(C->getStep());
10569 if (Step.isInvalid())
10570 return nullptr;
10571 return getDerived().RebuildOMPLinearClause(
10572 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
10573 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
10574 C->getEndLoc());
10575}
10576
10577template <typename Derived>
10578OMPClause *
10579TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
10581 Vars.reserve(C->varlist_size());
10582 for (auto *VE : C->varlists()) {
10583 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10584 if (EVar.isInvalid())
10585 return nullptr;
10586 Vars.push_back(EVar.get());
10587 }
10588 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
10589 if (Alignment.isInvalid())
10590 return nullptr;
10591 return getDerived().RebuildOMPAlignedClause(
10592 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
10593 C->getColonLoc(), C->getEndLoc());
10594}
10595
10596template <typename Derived>
10597OMPClause *
10598TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
10600 Vars.reserve(C->varlist_size());
10601 for (auto *VE : C->varlists()) {
10602 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10603 if (EVar.isInvalid())
10604 return nullptr;
10605 Vars.push_back(EVar.get());
10606 }
10607 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
10608 C->getLParenLoc(), C->getEndLoc());
10609}
10610
10611template <typename Derived>
10612OMPClause *
10613TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
10615 Vars.reserve(C->varlist_size());
10616 for (auto *VE : C->varlists()) {
10617 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10618 if (EVar.isInvalid())
10619 return nullptr;
10620 Vars.push_back(EVar.get());
10621 }
10622 return getDerived().RebuildOMPCopyprivateClause(
10623 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10624}
10625
10626template <typename Derived>
10627OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
10629 Vars.reserve(C->varlist_size());
10630 for (auto *VE : C->varlists()) {
10631 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10632 if (EVar.isInvalid())
10633 return nullptr;
10634 Vars.push_back(EVar.get());
10635 }
10636 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
10637 C->getLParenLoc(), C->getEndLoc());
10638}
10639
10640template <typename Derived>
10641OMPClause *
10642TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
10643 ExprResult E = getDerived().TransformExpr(C->getDepobj());
10644 if (E.isInvalid())
10645 return nullptr;
10646 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
10647 C->getLParenLoc(), C->getEndLoc());
10648}
10649
10650template <typename Derived>
10651OMPClause *
10652TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
10654 Expr *DepModifier = C->getModifier();
10655 if (DepModifier) {
10656 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
10657 if (DepModRes.isInvalid())
10658 return nullptr;
10659 DepModifier = DepModRes.get();
10660 }
10661 Vars.reserve(C->varlist_size());
10662 for (auto *VE : C->varlists()) {
10663 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10664 if (EVar.isInvalid())
10665 return nullptr;
10666 Vars.push_back(EVar.get());
10667 }
10668 return getDerived().RebuildOMPDependClause(
10669 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
10670 C->getOmpAllMemoryLoc()},
10671 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10672}
10673
10674template <typename Derived>
10675OMPClause *
10676TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
10677 ExprResult E = getDerived().TransformExpr(C->getDevice());
10678 if (E.isInvalid())
10679 return nullptr;
10680 return getDerived().RebuildOMPDeviceClause(
10681 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10682 C->getModifierLoc(), C->getEndLoc());
10683}
10684
10685template <typename Derived, class T>
10688 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
10689 DeclarationNameInfo &MapperIdInfo,
10690 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
10691 // Transform expressions in the list.
10692 Vars.reserve(C->varlist_size());
10693 for (auto *VE : C->varlists()) {
10694 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
10695 if (EVar.isInvalid())
10696 return true;
10697 Vars.push_back(EVar.get());
10698 }
10699 // Transform mapper scope specifier and identifier.
10700 NestedNameSpecifierLoc QualifierLoc;
10701 if (C->getMapperQualifierLoc()) {
10702 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
10703 C->getMapperQualifierLoc());
10704 if (!QualifierLoc)
10705 return true;
10706 }
10707 MapperIdScopeSpec.Adopt(QualifierLoc);
10708 MapperIdInfo = C->getMapperIdInfo();
10709 if (MapperIdInfo.getName()) {
10710 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
10711 if (!MapperIdInfo.getName())
10712 return true;
10713 }
10714 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
10715 // the previous user-defined mapper lookup in dependent environment.
10716 for (auto *E : C->mapperlists()) {
10717 // Transform all the decls.
10718 if (E) {
10719 auto *ULE = cast<UnresolvedLookupExpr>(E);
10720 UnresolvedSet<8> Decls;
10721 for (auto *D : ULE->decls()) {
10722 NamedDecl *InstD =
10723 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
10724 Decls.addDecl(InstD, InstD->getAccess());
10725 }
10726 UnresolvedMappers.push_back(UnresolvedLookupExpr::Create(
10727 TT.getSema().Context, /*NamingClass=*/nullptr,
10728 MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),
10729 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
10730 /*KnownDependent=*/false));
10731 } else {
10732 UnresolvedMappers.push_back(nullptr);
10733 }
10734 }
10735 return false;
10736}
10737
10738template <typename Derived>
10739OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
10740 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10742 Expr *IteratorModifier = C->getIteratorModifier();
10743 if (IteratorModifier) {
10744 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
10745 if (MapModRes.isInvalid())
10746 return nullptr;
10747 IteratorModifier = MapModRes.get();
10748 }
10749 CXXScopeSpec MapperIdScopeSpec;
10750 DeclarationNameInfo MapperIdInfo;
10751 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10752 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
10753 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10754 return nullptr;
10755 return getDerived().RebuildOMPMapClause(
10756 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
10757 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
10758 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10759}
10760
10761template <typename Derived>
10762OMPClause *
10763TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
10764 Expr *Allocator = C->getAllocator();
10765 if (Allocator) {
10766 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
10767 if (AllocatorRes.isInvalid())
10768 return nullptr;
10769 Allocator = AllocatorRes.get();
10770 }
10772 Vars.reserve(C->varlist_size());
10773 for (auto *VE : C->varlists()) {
10774 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10775 if (EVar.isInvalid())
10776 return nullptr;
10777 Vars.push_back(EVar.get());
10778 }
10779 return getDerived().RebuildOMPAllocateClause(
10780 Allocator, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
10781 C->getEndLoc());
10782}
10783
10784template <typename Derived>
10785OMPClause *
10786TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
10787 ExprResult E = getDerived().TransformExpr(C->getNumTeams());
10788 if (E.isInvalid())
10789 return nullptr;
10790 return getDerived().RebuildOMPNumTeamsClause(
10791 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10792}
10793
10794template <typename Derived>
10795OMPClause *
10796TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
10797 ExprResult E = getDerived().TransformExpr(C->getThreadLimit());
10798 if (E.isInvalid())
10799 return nullptr;
10800 return getDerived().RebuildOMPThreadLimitClause(
10801 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10802}
10803
10804template <typename Derived>
10805OMPClause *
10806TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
10807 ExprResult E = getDerived().TransformExpr(C->getPriority());
10808 if (E.isInvalid())
10809 return nullptr;
10810 return getDerived().RebuildOMPPriorityClause(
10811 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10812}
10813
10814template <typename Derived>
10815OMPClause *
10816TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
10817 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
10818 if (E.isInvalid())
10819 return nullptr;
10820 return getDerived().RebuildOMPGrainsizeClause(
10821 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10822 C->getModifierLoc(), C->getEndLoc());
10823}
10824
10825template <typename Derived>
10826OMPClause *
10827TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
10828 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
10829 if (E.isInvalid())
10830 return nullptr;
10831 return getDerived().RebuildOMPNumTasksClause(
10832 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10833 C->getModifierLoc(), C->getEndLoc());
10834}
10835
10836template <typename Derived>
10837OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
10838 ExprResult E = getDerived().TransformExpr(C->getHint());
10839 if (E.isInvalid())
10840 return nullptr;
10841 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
10842 C->getLParenLoc(), C->getEndLoc());
10843}
10844
10845template <typename Derived>
10846OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
10847 OMPDistScheduleClause *C) {
10848 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10849 if (E.isInvalid())
10850 return nullptr;
10851 return getDerived().RebuildOMPDistScheduleClause(
10852 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10853 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10854}
10855
10856template <typename Derived>
10857OMPClause *
10858TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
10859 // Rebuild Defaultmap Clause since we need to invoke the checking of
10860 // defaultmap(none:variable-category) after template initialization.
10861 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
10862 C->getDefaultmapKind(),
10863 C->getBeginLoc(),
10864 C->getLParenLoc(),
10865 C->getDefaultmapModifierLoc(),
10866 C->getDefaultmapKindLoc(),
10867 C->getEndLoc());
10868}
10869
10870template <typename Derived>
10871OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
10872 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10874 CXXScopeSpec MapperIdScopeSpec;
10875 DeclarationNameInfo MapperIdInfo;
10876 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10877 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
10878 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10879 return nullptr;
10880 return getDerived().RebuildOMPToClause(
10881 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10882 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10883}
10884
10885template <typename Derived>
10886OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
10887 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10889 CXXScopeSpec MapperIdScopeSpec;
10890 DeclarationNameInfo MapperIdInfo;
10891 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
10892 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
10893 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
10894 return nullptr;
10895 return getDerived().RebuildOMPFromClause(
10896 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
10897 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
10898}
10899
10900template <typename Derived>
10901OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
10902 OMPUseDevicePtrClause *C) {
10904 Vars.reserve(C->varlist_size());
10905 for (auto *VE : C->varlists()) {
10906 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10907 if (EVar.isInvalid())
10908 return nullptr;
10909 Vars.push_back(EVar.get());
10910 }
10911 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10912 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
10913}
10914
10915template <typename Derived>
10916OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
10917 OMPUseDeviceAddrClause *C) {
10919 Vars.reserve(C->varlist_size());
10920 for (auto *VE : C->varlists()) {
10921 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10922 if (EVar.isInvalid())
10923 return nullptr;
10924 Vars.push_back(EVar.get());
10925 }
10926 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10927 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
10928}
10929
10930template <typename Derived>
10931OMPClause *
10932TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
10934 Vars.reserve(C->varlist_size());
10935 for (auto *VE : C->varlists()) {
10936 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10937 if (EVar.isInvalid())
10938 return nullptr;
10939 Vars.push_back(EVar.get());
10940 }
10941 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10942 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
10943}
10944
10945template <typename Derived>
10946OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
10947 OMPHasDeviceAddrClause *C) {
10949 Vars.reserve(C->varlist_size());
10950 for (auto *VE : C->varlists()) {
10951 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10952 if (EVar.isInvalid())
10953 return nullptr;
10954 Vars.push_back(EVar.get());
10955 }
10956 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10957 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
10958}
10959
10960template <typename Derived>
10961OMPClause *
10962TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
10964 Vars.reserve(C->varlist_size());
10965 for (auto *VE : C->varlists()) {
10966 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10967 if (EVar.isInvalid())
10968 return nullptr;
10969 Vars.push_back(EVar.get());
10970 }
10971 return getDerived().RebuildOMPNontemporalClause(
10972 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10973}
10974
10975template <typename Derived>
10976OMPClause *
10977TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
10979 Vars.reserve(C->varlist_size());
10980 for (auto *VE : C->varlists()) {
10981 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10982 if (EVar.isInvalid())
10983 return nullptr;
10984 Vars.push_back(EVar.get());
10985 }
10986 return getDerived().RebuildOMPInclusiveClause(
10987 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10988}
10989
10990template <typename Derived>
10991OMPClause *
10992TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
10994 Vars.reserve(C->varlist_size());
10995 for (auto *VE : C->varlists()) {
10996 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10997 if (EVar.isInvalid())
10998 return nullptr;
10999 Vars.push_back(EVar.get());
11000 }
11001 return getDerived().RebuildOMPExclusiveClause(
11002 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11003}
11004
11005template <typename Derived>
11006OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11007 OMPUsesAllocatorsClause *C) {
11009 Data.reserve(C->getNumberOfAllocators());
11010 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11011 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11012 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11013 if (Allocator.isInvalid())
11014 continue;
11015 ExprResult AllocatorTraits;
11016 if (Expr *AT = D.AllocatorTraits) {
11017 AllocatorTraits = getDerived().TransformExpr(AT);
11018 if (AllocatorTraits.isInvalid())
11019 continue;
11020 }
11021 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11022 NewD.Allocator = Allocator.get();
11023 NewD.AllocatorTraits = AllocatorTraits.get();
11024 NewD.LParenLoc = D.LParenLoc;
11025 NewD.RParenLoc = D.RParenLoc;
11026 }
11027 return getDerived().RebuildOMPUsesAllocatorsClause(
11028 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11029}
11030
11031template <typename Derived>
11032OMPClause *
11033TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11034 SmallVector<Expr *, 4> Locators;
11035 Locators.reserve(C->varlist_size());
11036 ExprResult ModifierRes;
11037 if (Expr *Modifier = C->getModifier()) {
11038 ModifierRes = getDerived().TransformExpr(Modifier);
11039 if (ModifierRes.isInvalid())
11040 return nullptr;
11041 }
11042 for (Expr *E : C->varlists()) {
11043 ExprResult Locator = getDerived().TransformExpr(E);
11044 if (Locator.isInvalid())
11045 continue;
11046 Locators.push_back(Locator.get());
11047 }
11048 return getDerived().RebuildOMPAffinityClause(
11049 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11050 ModifierRes.get(), Locators);
11051}
11052
11053template <typename Derived>
11054OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11055 return getDerived().RebuildOMPOrderClause(
11056 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11057 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11058}
11059
11060template <typename Derived>
11061OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11062 return getDerived().RebuildOMPBindClause(
11063 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11064 C->getLParenLoc(), C->getEndLoc());
11065}
11066
11067template <typename Derived>
11068OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11069 OMPXDynCGroupMemClause *C) {
11070 ExprResult Size = getDerived().TransformExpr(C->getSize());
11071 if (Size.isInvalid())
11072 return nullptr;
11073 return getDerived().RebuildOMPXDynCGroupMemClause(
11074 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11075}
11076
11077template <typename Derived>
11078OMPClause *
11079TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11081 Vars.reserve(C->varlist_size());
11082 for (auto *VE : C->varlists()) {
11083 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11084 if (EVar.isInvalid())
11085 return nullptr;
11086 Vars.push_back(EVar.get());
11087 }
11088 return getDerived().RebuildOMPDoacrossClause(
11089 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11090 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11091}
11092
11093template <typename Derived>
11094OMPClause *
11095TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11097 for (auto *A : C->getAttrs())
11098 NewAttrs.push_back(getDerived().TransformAttr(A));
11099 return getDerived().RebuildOMPXAttributeClause(
11100 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11101}
11102
11103template <typename Derived>
11104OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11105 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11106}
11107
11108//===----------------------------------------------------------------------===//
11109// OpenACC transformation
11110//===----------------------------------------------------------------------===//
11111namespace {
11112template <typename Derived>
11113class OpenACCClauseTransform final
11114 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11115 TreeTransform<Derived> &Self;
11116 ArrayRef<const OpenACCClause *> ExistingClauses;
11117 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11118 OpenACCClause *NewClause = nullptr;
11119
11120 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11121 llvm::SmallVector<Expr *> InstantiatedVarList;
11122 for (Expr *CurVar : VarList) {
11123 ExprResult Res = Self.TransformExpr(CurVar);
11124
11125 if (!Res.isUsable())
11126 continue;
11127
11128 Res = Self.getSema().OpenACC().ActOnVar(Res.get());
11129
11130 if (Res.isUsable())
11131 InstantiatedVarList.push_back(Res.get());
11132 }
11133
11134 return InstantiatedVarList;
11135 }
11136
11137public:
11138 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11139 ArrayRef<const OpenACCClause *> ExistingClauses,
11140 SemaOpenACC::OpenACCParsedClause &PC)
11141 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
11142
11143 OpenACCClause *CreatedClause() const { return NewClause; }
11144
11145#define VISIT_CLAUSE(CLAUSE_NAME) \
11146 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11147#include "clang/Basic/OpenACCClauses.def"
11148};
11149
11150template <typename Derived>
11151void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11152 const OpenACCDefaultClause &C) {
11153 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11154
11155 NewClause = OpenACCDefaultClause::Create(
11156 Self.getSema().getASTContext(), ParsedClause.getDefaultClauseKind(),
11157 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11158 ParsedClause.getEndLoc());
11159}
11160
11161template <typename Derived>
11162void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11163 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11164 assert(Cond && "If constructed with invalid Condition");
11165 Sema::ConditionResult Res = Self.TransformCondition(
11166 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11167
11168 if (Res.isInvalid() || !Res.get().second)
11169 return;
11170
11171 ParsedClause.setConditionDetails(Res.get().second);
11172
11173 NewClause = OpenACCIfClause::Create(
11174 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11175 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11176 ParsedClause.getEndLoc());
11177}
11178
11179template <typename Derived>
11180void OpenACCClauseTransform<Derived>::VisitSelfClause(
11181 const OpenACCSelfClause &C) {
11182
11183 if (C.hasConditionExpr()) {
11184 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11185 Sema::ConditionResult Res =
11186 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
11188
11189 if (Res.isInvalid() || !Res.get().second)
11190 return;
11191
11192 ParsedClause.setConditionDetails(Res.get().second);
11193 }
11194
11195 NewClause = OpenACCSelfClause::Create(
11196 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11197 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11198 ParsedClause.getEndLoc());
11199}
11200
11201template <typename Derived>
11202void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
11203 const OpenACCNumGangsClause &C) {
11204 llvm::SmallVector<Expr *> InstantiatedIntExprs;
11205
11206 for (Expr *CurIntExpr : C.getIntExprs()) {
11207 ExprResult Res = Self.TransformExpr(CurIntExpr);
11208
11209 if (!Res.isUsable())
11210 return;
11211
11212 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11213 C.getClauseKind(),
11214 C.getBeginLoc(), Res.get());
11215 if (!Res.isUsable())
11216 return;
11217
11218 InstantiatedIntExprs.push_back(Res.get());
11219 }
11220
11221 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
11223 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11224 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs(),
11225 ParsedClause.getEndLoc());
11226}
11227
11228template <typename Derived>
11229void OpenACCClauseTransform<Derived>::VisitPrivateClause(
11230 const OpenACCPrivateClause &C) {
11231 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11232 /*IsReadOnly=*/false, /*IsZero=*/false);
11233
11234 NewClause = OpenACCPrivateClause::Create(
11235 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11236 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11237 ParsedClause.getEndLoc());
11238}
11239
11240template <typename Derived>
11241void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
11242 const OpenACCFirstPrivateClause &C) {
11243 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11244 /*IsReadOnly=*/false, /*IsZero=*/false);
11245
11247 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11248 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11249 ParsedClause.getEndLoc());
11250}
11251
11252template <typename Derived>
11253void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
11254 const OpenACCNoCreateClause &C) {
11255 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11256 /*IsReadOnly=*/false, /*IsZero=*/false);
11257
11259 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11260 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11261 ParsedClause.getEndLoc());
11262}
11263
11264template <typename Derived>
11265void OpenACCClauseTransform<Derived>::VisitPresentClause(
11266 const OpenACCPresentClause &C) {
11267 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11268 /*IsReadOnly=*/false, /*IsZero=*/false);
11269
11270 NewClause = OpenACCPresentClause::Create(
11271 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11272 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11273 ParsedClause.getEndLoc());
11274}
11275
11276template <typename Derived>
11277void OpenACCClauseTransform<Derived>::VisitCopyClause(
11278 const OpenACCCopyClause &C) {
11279 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11280 /*IsReadOnly=*/false, /*IsZero=*/false);
11281
11282 NewClause = OpenACCCopyClause::Create(
11283 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11284 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11285 ParsedClause.getVarList(), ParsedClause.getEndLoc());
11286}
11287
11288template <typename Derived>
11289void OpenACCClauseTransform<Derived>::VisitCopyInClause(
11290 const OpenACCCopyInClause &C) {
11291 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()), C.isReadOnly(),
11292 /*IsZero=*/false);
11293
11294 NewClause = OpenACCCopyInClause::Create(
11295 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11296 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11297 ParsedClause.isReadOnly(), ParsedClause.getVarList(),
11298 ParsedClause.getEndLoc());
11299}
11300
11301template <typename Derived>
11302void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
11303 const OpenACCCopyOutClause &C) {
11304 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11305 /*IsReadOnly=*/false, C.isZero());
11306
11307 NewClause = OpenACCCopyOutClause::Create(
11308 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11309 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11310 ParsedClause.isZero(), ParsedClause.getVarList(),
11311 ParsedClause.getEndLoc());
11312}
11313
11314template <typename Derived>
11315void OpenACCClauseTransform<Derived>::VisitCreateClause(
11316 const OpenACCCreateClause &C) {
11317 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11318 /*IsReadOnly=*/false, C.isZero());
11319
11320 NewClause = OpenACCCreateClause::Create(
11321 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),
11322 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11323 ParsedClause.isZero(), ParsedClause.getVarList(),
11324 ParsedClause.getEndLoc());
11325}
11326template <typename Derived>
11327void OpenACCClauseTransform<Derived>::VisitAttachClause(
11328 const OpenACCAttachClause &C) {
11329 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
11330
11331 // Ensure each var is a pointer type.
11332 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
11333 return Self.getSema().OpenACC().CheckVarIsPointerType(
11334 OpenACCClauseKind::Attach, E);
11335 }), VarList.end());
11336
11337 ParsedClause.setVarListDetails(VarList,
11338 /*IsReadOnly=*/false, /*IsZero=*/false);
11339 NewClause = OpenACCAttachClause::Create(
11340 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11341 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11342 ParsedClause.getEndLoc());
11343}
11344
11345template <typename Derived>
11346void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
11347 const OpenACCDevicePtrClause &C) {
11348 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
11349
11350 // Ensure each var is a pointer type.
11351 VarList.erase(std::remove_if(VarList.begin(), VarList.end(), [&](Expr *E) {
11352 return Self.getSema().OpenACC().CheckVarIsPointerType(
11353 OpenACCClauseKind::DevicePtr, E);
11354 }), VarList.end());
11355
11356 ParsedClause.setVarListDetails(VarList,
11357 /*IsReadOnly=*/false, /*IsZero=*/false);
11359 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11360 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11361 ParsedClause.getEndLoc());
11362}
11363
11364template <typename Derived>
11365void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
11366 const OpenACCNumWorkersClause &C) {
11367 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11368 assert(IntExpr && "num_workers clause constructed with invalid int expr");
11369
11370 ExprResult Res = Self.TransformExpr(IntExpr);
11371 if (!Res.isUsable())
11372 return;
11373
11374 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11375 C.getClauseKind(),
11376 C.getBeginLoc(), Res.get());
11377 if (!Res.isUsable())
11378 return;
11379
11380 ParsedClause.setIntExprDetails(Res.get());
11382 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11383 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
11384 ParsedClause.getEndLoc());
11385}
11386
11387template <typename Derived>
11388void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
11389 const OpenACCVectorLengthClause &C) {
11390 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
11391 assert(IntExpr && "vector_length clause constructed with invalid int expr");
11392
11393 ExprResult Res = Self.TransformExpr(IntExpr);
11394 if (!Res.isUsable())
11395 return;
11396
11397 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11398 C.getClauseKind(),
11399 C.getBeginLoc(), Res.get());
11400 if (!Res.isUsable())
11401 return;
11402
11403 ParsedClause.setIntExprDetails(Res.get());
11405 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11406 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],
11407 ParsedClause.getEndLoc());
11408}
11409
11410template <typename Derived>
11411void OpenACCClauseTransform<Derived>::VisitAsyncClause(
11412 const OpenACCAsyncClause &C) {
11413 if (C.hasIntExpr()) {
11414 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
11415 if (!Res.isUsable())
11416 return;
11417
11418 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11419 C.getClauseKind(),
11420 C.getBeginLoc(), Res.get());
11421 if (!Res.isUsable())
11422 return;
11423 ParsedClause.setIntExprDetails(Res.get());
11424 }
11425
11426 NewClause = OpenACCAsyncClause::Create(
11427 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11428 ParsedClause.getLParenLoc(),
11429 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
11430 : nullptr,
11431 ParsedClause.getEndLoc());
11432}
11433template <typename Derived>
11434void OpenACCClauseTransform<Derived>::VisitWaitClause(
11435 const OpenACCWaitClause &C) {
11436 if (!C.getLParenLoc().isInvalid()) {
11437 Expr *DevNumExpr = nullptr;
11438 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
11439
11440 // Instantiate devnum expr if it exists.
11441 if (C.getDevNumExpr()) {
11442 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
11443 if (!Res.isUsable())
11444 return;
11445 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11446 C.getClauseKind(),
11447 C.getBeginLoc(), Res.get());
11448 if (!Res.isUsable())
11449 return;
11450
11451 DevNumExpr = Res.get();
11452 }
11453
11454 // Instantiate queue ids.
11455 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
11456 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
11457 if (!Res.isUsable())
11458 return;
11459 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11460 C.getClauseKind(),
11461 C.getBeginLoc(), Res.get());
11462 if (!Res.isUsable())
11463 return;
11464
11465 InstantiatedQueueIdExprs.push_back(Res.get());
11466 }
11467
11468 ParsedClause.setWaitDetails(DevNumExpr, C.getQueuesLoc(),
11469 std::move(InstantiatedQueueIdExprs));
11470 }
11471
11472 NewClause = OpenACCWaitClause::Create(
11473 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11474 ParsedClause.getLParenLoc(), ParsedClause.getDevNumExpr(),
11475 ParsedClause.getQueuesLoc(), ParsedClause.getQueueIdExprs(),
11476 ParsedClause.getEndLoc());
11477}
11478
11479template <typename Derived>
11480void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
11481 const OpenACCDeviceTypeClause &C) {
11482 // Nothing to transform here, just create a new version of 'C'.
11484 Self.getSema().getASTContext(), C.getClauseKind(),
11485 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
11486 C.getArchitectures(), ParsedClause.getEndLoc());
11487}
11488} // namespace
11489template <typename Derived>
11490OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
11491 ArrayRef<const OpenACCClause *> ExistingClauses,
11492 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
11493
11494 SemaOpenACC::OpenACCParsedClause ParsedClause(
11495 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
11496 ParsedClause.setEndLoc(OldClause->getEndLoc());
11497
11498 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(OldClause))
11499 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
11500
11501 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
11502 ParsedClause};
11503 Transform.Visit(OldClause);
11504
11505 return Transform.CreatedClause();
11506}
11507
11508template <typename Derived>
11510TreeTransform<Derived>::TransformOpenACCClauseList(
11512 llvm::SmallVector<OpenACCClause *> TransformedClauses;
11513 for (const auto *Clause : OldClauses) {
11514 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
11515 TransformedClauses, DirKind, Clause))
11516 TransformedClauses.push_back(TransformedClause);
11517 }
11518 return TransformedClauses;
11519}
11520
11521template <typename Derived>
11522StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
11523 OpenACCComputeConstruct *C) {
11524 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
11525 // FIXME: When implementing this for constructs that can take arguments, we
11526 // should do Sema for them here.
11527
11528 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
11529 C->getBeginLoc()))
11530 return StmtError();
11531
11532 llvm::SmallVector<OpenACCClause *> TransformedClauses =
11533 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
11534 C->clauses());
11535
11536 // Transform Structured Block.
11537 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
11538 StrBlock =
11539 getSema().OpenACC().ActOnAssociatedStmt(C->getDirectiveKind(), StrBlock);
11540
11541 return getDerived().RebuildOpenACCComputeConstruct(
11542 C->getDirectiveKind(), C->getBeginLoc(), C->getEndLoc(),
11543 TransformedClauses, StrBlock);
11544}
11545
11546//===----------------------------------------------------------------------===//
11547// Expression transformation
11548//===----------------------------------------------------------------------===//
11549template<typename Derived>
11551TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
11552 return TransformExpr(E->getSubExpr());
11553}
11554
11555template <typename Derived>
11556ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
11557 SYCLUniqueStableNameExpr *E) {
11558 if (!E->isTypeDependent())
11559 return E;
11560
11561 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
11562
11563 if (!NewT)
11564 return ExprError();
11565
11566 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
11567 return E;
11568
11569 return getDerived().RebuildSYCLUniqueStableNameExpr(
11570 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
11571}
11572
11573template<typename Derived>
11575TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
11576 if (!E->isTypeDependent())
11577 return E;
11578
11579 return getDerived().RebuildPredefinedExpr(E->getLocation(),
11580 E->getIdentKind());
11581}
11582
11583template<typename Derived>
11585TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
11586 NestedNameSpecifierLoc QualifierLoc;
11587 if (E->getQualifierLoc()) {
11588 QualifierLoc
11589 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
11590 if (!QualifierLoc)
11591 return ExprError();
11592 }
11593
11594 ValueDecl *ND
11595 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
11596 E->getDecl()));
11597 if (!ND)
11598 return ExprError();
11599
11600 NamedDecl *Found = ND;
11601 if (E->getFoundDecl() != E->getDecl()) {
11602 Found = cast_or_null<NamedDecl>(
11603 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
11604 if (!Found)
11605 return ExprError();
11606 }
11607
11608 DeclarationNameInfo NameInfo = E->getNameInfo();
11609 if (NameInfo.getName()) {
11610 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11611 if (!NameInfo.getName())
11612 return ExprError();
11613 }
11614
11615 if (!getDerived().AlwaysRebuild() &&
11616 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
11617 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
11618 Found == E->getFoundDecl() &&
11619 NameInfo.getName() == E->getDecl()->getDeclName() &&
11620 !E->hasExplicitTemplateArgs()) {
11621
11622 // Mark it referenced in the new context regardless.
11623 // FIXME: this is a bit instantiation-specific.
11624 SemaRef.MarkDeclRefReferenced(E);
11625
11626 return E;
11627 }
11628
11629 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
11630 if (E->hasExplicitTemplateArgs()) {
11631 TemplateArgs = &TransArgs;
11632 TransArgs.setLAngleLoc(E->getLAngleLoc());
11633 TransArgs.setRAngleLoc(E->getRAngleLoc());
11634 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
11635 E->getNumTemplateArgs(),
11636 TransArgs))
11637 return ExprError();
11638 }
11639
11640 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
11641 Found, TemplateArgs);
11642}
11643
11644template<typename Derived>
11646TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
11647 return E;
11648}
11649
11650template <typename Derived>
11651ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
11652 FixedPointLiteral *E) {
11653 return E;
11654}
11655
11656template<typename Derived>
11658TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
11659 return E;
11660}
11661
11662template<typename Derived>
11664TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
11665 return E;
11666}
11667
11668template<typename Derived>
11670TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
11671 return E;
11672}
11673
11674template<typename Derived>
11676TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
11677 return E;
11678}
11679
11680template<typename Derived>
11682TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
11683 return getDerived().TransformCallExpr(E);
11684}
11685
11686template<typename Derived>
11688TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
11689 ExprResult ControllingExpr;
11690 TypeSourceInfo *ControllingType = nullptr;
11691 if (E->isExprPredicate())
11692 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
11693 else
11694 ControllingType = getDerived().TransformType(E->getControllingType());
11695
11696 if (ControllingExpr.isInvalid() && !ControllingType)
11697 return ExprError();
11698
11699 SmallVector<Expr *, 4> AssocExprs;
11701 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
11702 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
11703 if (TSI) {
11704 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
11705 if (!AssocType)
11706 return ExprError();
11707 AssocTypes.push_back(AssocType);
11708 } else {
11709 AssocTypes.push_back(nullptr);
11710 }
11711
11712 ExprResult AssocExpr =
11713 getDerived().TransformExpr(Assoc.getAssociationExpr());
11714 if (AssocExpr.isInvalid())
11715 return ExprError();
11716 AssocExprs.push_back(AssocExpr.get());
11717 }
11718
11719 if (!ControllingType)
11720 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
11721 E->getDefaultLoc(),
11722 E->getRParenLoc(),
11723 ControllingExpr.get(),
11724 AssocTypes,
11725 AssocExprs);
11726 return getDerived().RebuildGenericSelectionExpr(
11727 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
11728 ControllingType, AssocTypes, AssocExprs);
11729}
11730
11731template<typename Derived>
11733TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
11734 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
11735 if (SubExpr.isInvalid())
11736 return ExprError();
11737
11738 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11739 return E;
11740
11741 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
11742 E->getRParen());
11743}
11744
11745/// The operand of a unary address-of operator has special rules: it's
11746/// allowed to refer to a non-static member of a class even if there's no 'this'
11747/// object available.
11748template<typename Derived>
11751 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
11752 return getDerived().TransformDependentScopeDeclRefExpr(
11753 DRE, /*IsAddressOfOperand=*/true, nullptr);
11754 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E))
11755 return getDerived().TransformUnresolvedLookupExpr(
11756 ULE, /*IsAddressOfOperand=*/true);
11757 else
11758 return getDerived().TransformExpr(E);
11759}
11760
11761template<typename Derived>
11764 ExprResult SubExpr;
11765 if (E->getOpcode() == UO_AddrOf)
11766 SubExpr = TransformAddressOfOperand(E->getSubExpr());
11767 else
11768 SubExpr = TransformExpr(E->getSubExpr());
11769 if (SubExpr.isInvalid())
11770 return ExprError();
11771
11772 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
11773 return E;
11774
11775 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
11776 E->getOpcode(),
11777 SubExpr.get());
11778}
11779
11780template<typename Derived>
11782TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
11783 // Transform the type.
11784 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
11785 if (!Type)
11786 return ExprError();
11787
11788 // Transform all of the components into components similar to what the
11789 // parser uses.
11790 // FIXME: It would be slightly more efficient in the non-dependent case to
11791 // just map FieldDecls, rather than requiring the rebuilder to look for
11792 // the fields again. However, __builtin_offsetof is rare enough in
11793 // template code that we don't care.
11794 bool ExprChanged = false;
11795 typedef Sema::OffsetOfComponent Component;
11796 SmallVector<Component, 4> Components;
11797 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
11798 const OffsetOfNode &ON = E->getComponent(I);
11799 Component Comp;
11800 Comp.isBrackets = true;
11801 Comp.LocStart = ON.getSourceRange().getBegin();
11802 Comp.LocEnd = ON.getSourceRange().getEnd();
11803 switch (ON.getKind()) {
11804 case OffsetOfNode::Array: {
11805 Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
11806 ExprResult Index = getDerived().TransformExpr(FromIndex);
11807 if (Index.isInvalid())
11808 return ExprError();
11809
11810 ExprChanged = ExprChanged || Index.get() != FromIndex;
11811 Comp.isBrackets = true;
11812 Comp.U.E = Index.get();
11813 break;
11814 }
11815
11818 Comp.isBrackets = false;
11819 Comp.U.IdentInfo = ON.getFieldName();
11820 if (!Comp.U.IdentInfo)
11821 continue;
11822
11823 break;
11824
11825 case OffsetOfNode::Base:
11826 // Will be recomputed during the rebuild.
11827 continue;
11828 }
11829
11830 Components.push_back(Comp);
11831 }
11832
11833 // If nothing changed, retain the existing expression.
11834 if (!getDerived().AlwaysRebuild() &&
11835 Type == E->getTypeSourceInfo() &&
11836 !ExprChanged)
11837 return E;
11838
11839 // Build a new offsetof expression.
11840 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
11841 Components, E->getRParenLoc());
11842}
11843
11844template<typename Derived>
11846TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
11847 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
11848 "opaque value expression requires transformation");
11849 return E;
11850}
11851
11852template<typename Derived>
11854TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
11855 return E;
11856}
11857
11858template <typename Derived>
11859ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
11861 bool Changed = false;
11862 for (Expr *C : E->subExpressions()) {
11863 ExprResult NewC = getDerived().TransformExpr(C);
11864 if (NewC.isInvalid())
11865 return ExprError();
11866 Children.push_back(NewC.get());
11867
11868 Changed |= NewC.get() != C;
11869 }
11870 if (!getDerived().AlwaysRebuild() && !Changed)
11871 return E;
11872 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
11873 Children, E->getType());
11874}
11875
11876template<typename Derived>
11878TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
11879 // Rebuild the syntactic form. The original syntactic form has
11880 // opaque-value expressions in it, so strip those away and rebuild
11881 // the result. This is a really awful way of doing this, but the
11882 // better solution (rebuilding the semantic expressions and
11883 // rebinding OVEs as necessary) doesn't work; we'd need
11884 // TreeTransform to not strip away implicit conversions.
11885 Expr *newSyntacticForm = SemaRef.recreateSyntacticForm(E);
11886 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
11887 if (result.isInvalid()) return ExprError();
11888
11889 // If that gives us a pseudo-object result back, the pseudo-object
11890 // expression must have been an lvalue-to-rvalue conversion which we
11891 // should reapply.
11892 if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
11893 result = SemaRef.checkPseudoObjectRValue(result.get());
11894
11895 return result;
11896}
11897
11898template<typename Derived>
11900TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
11901 UnaryExprOrTypeTraitExpr *E) {
11902 if (E->isArgumentType()) {
11903 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
11904
11905 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
11906 if (!NewT)
11907 return ExprError();
11908
11909 if (!getDerived().AlwaysRebuild() && OldT == NewT)
11910 return E;
11911
11912 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
11913 E->getKind(),
11914 E->getSourceRange());
11915 }
11916
11917 // C++0x [expr.sizeof]p1:
11918 // The operand is either an expression, which is an unevaluated operand
11919 // [...]
11920 EnterExpressionEvaluationContext Unevaluated(
11923
11924 // Try to recover if we have something like sizeof(T::X) where X is a type.
11925 // Notably, there must be *exactly* one set of parens if X is a type.
11926 TypeSourceInfo *RecoveryTSI = nullptr;
11927 ExprResult SubExpr;
11928 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
11929 if (auto *DRE =
11930 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
11931 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
11932 PE, DRE, false, &RecoveryTSI);
11933 else
11934 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
11935
11936 if (RecoveryTSI) {
11937 return getDerived().RebuildUnaryExprOrTypeTrait(
11938 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
11939 } else if (SubExpr.isInvalid())
11940 return ExprError();
11941
11942 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
11943 return E;
11944
11945 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
11946 E->getOperatorLoc(),
11947 E->getKind(),
11948 E->getSourceRange());
11949}
11950
11951template<typename Derived>
11953TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
11954 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
11955 if (LHS.isInvalid())
11956 return ExprError();
11957
11958 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
11959 if (RHS.isInvalid())
11960 return ExprError();
11961
11962
11963 if (!getDerived().AlwaysRebuild() &&
11964 LHS.get() == E->getLHS() &&
11965 RHS.get() == E->getRHS())
11966 return E;
11967
11968 return getDerived().RebuildArraySubscriptExpr(
11969 LHS.get(),
11970 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
11971}
11972
11973template <typename Derived>
11975TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
11976 ExprResult Base = getDerived().TransformExpr(E->getBase());
11977 if (Base.isInvalid())
11978 return ExprError();
11979
11980 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
11981 if (RowIdx.isInvalid())
11982 return ExprError();
11983
11984 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
11985 if (ColumnIdx.isInvalid())
11986 return ExprError();
11987
11988 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
11989 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
11990 return E;
11991
11992 return getDerived().RebuildMatrixSubscriptExpr(
11993 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
11994}
11995
11996template <typename Derived>
11998TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
11999 ExprResult Base = getDerived().TransformExpr(E->getBase());
12000 if (Base.isInvalid())
12001 return ExprError();
12002
12003 ExprResult LowerBound;
12004 if (E->getLowerBound()) {
12005 LowerBound = getDerived().TransformExpr(E->getLowerBound());
12006 if (LowerBound.isInvalid())
12007 return ExprError();
12008 }
12009
12010 ExprResult Length;
12011 if (E->getLength()) {
12012 Length = getDerived().TransformExpr(E->getLength());
12013 if (Length.isInvalid())
12014 return ExprError();
12015 }
12016
12017 ExprResult Stride;
12018 if (E->isOMPArraySection()) {
12019 if (Expr *Str = E->getStride()) {
12020 Stride = getDerived().TransformExpr(Str);
12021 if (Stride.isInvalid())
12022 return ExprError();
12023 }
12024 }
12025
12026 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
12027 LowerBound.get() == E->getLowerBound() &&
12028 Length.get() == E->getLength() &&
12029 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
12030 return E;
12031
12032 return getDerived().RebuildArraySectionExpr(
12033 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
12034 LowerBound.get(), E->getColonLocFirst(),
12035 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
12036 Length.get(), Stride.get(), E->getRBracketLoc());
12037}
12038
12039template <typename Derived>
12041TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
12042 ExprResult Base = getDerived().TransformExpr(E->getBase());
12043 if (Base.isInvalid())
12044 return ExprError();
12045
12047 bool ErrorFound = false;
12048 for (Expr *Dim : E->getDimensions()) {
12049 ExprResult DimRes = getDerived().TransformExpr(Dim);
12050 if (DimRes.isInvalid()) {
12051 ErrorFound = true;
12052 continue;
12053 }
12054 Dims.push_back(DimRes.get());
12055 }
12056
12057 if (ErrorFound)
12058 return ExprError();
12059 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
12060 E->getRParenLoc(), Dims,
12061 E->getBracketsRanges());
12062}
12063
12064template <typename Derived>
12066TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
12067 unsigned NumIterators = E->numOfIterators();
12069
12070 bool ErrorFound = false;
12071 bool NeedToRebuild = getDerived().AlwaysRebuild();
12072 for (unsigned I = 0; I < NumIterators; ++I) {
12073 auto *D = cast<VarDecl>(E->getIteratorDecl(I));
12074 Data[I].DeclIdent = D->getIdentifier();
12075 Data[I].DeclIdentLoc = D->getLocation();
12076 if (D->getLocation() == D->getBeginLoc()) {
12077 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
12078 "Implicit type must be int.");
12079 } else {
12080 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
12081 QualType DeclTy = getDerived().TransformType(D->getType());
12082 Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI);
12083 }
12084 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
12085 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
12086 ExprResult End = getDerived().TransformExpr(Range.End);
12087 ExprResult Step = getDerived().TransformExpr(Range.Step);
12088 ErrorFound = ErrorFound ||
12089 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
12090 !Data[I].Type.get().isNull())) ||
12091 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
12092 if (ErrorFound)
12093 continue;
12094 Data[I].Range.Begin = Begin.get();
12095 Data[I].Range.End = End.get();
12096 Data[I].Range.Step = Step.get();
12097 Data[I].AssignLoc = E->getAssignLoc(I);
12098 Data[I].ColonLoc = E->getColonLoc(I);
12099 Data[I].SecColonLoc = E->getSecondColonLoc(I);
12100 NeedToRebuild =
12101 NeedToRebuild ||
12102 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
12103 D->getType().getTypePtrOrNull()) ||
12104 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
12105 Range.Step != Data[I].Range.Step;
12106 }
12107 if (ErrorFound)
12108 return ExprError();
12109 if (!NeedToRebuild)
12110 return E;
12111
12112 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
12113 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
12114 if (!Res.isUsable())
12115 return Res;
12116 auto *IE = cast<OMPIteratorExpr>(Res.get());
12117 for (unsigned I = 0; I < NumIterators; ++I)
12118 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
12119 IE->getIteratorDecl(I));
12120 return Res;
12121}
12122
12123template<typename Derived>
12125TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
12126 // Transform the callee.
12127 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
12128 if (Callee.isInvalid())
12129 return ExprError();
12130
12131 // Transform arguments.
12132 bool ArgChanged = false;
12134 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
12135 &ArgChanged))
12136 return ExprError();
12137
12138 if (!getDerived().AlwaysRebuild() &&
12139 Callee.get() == E->getCallee() &&
12140 !ArgChanged)
12141 return SemaRef.MaybeBindToTemporary(E);
12142
12143 // FIXME: Wrong source location information for the '('.
12144 SourceLocation FakeLParenLoc
12145 = ((Expr *)Callee.get())->getSourceRange().getBegin();
12146
12147 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12148 if (E->hasStoredFPFeatures()) {
12149 FPOptionsOverride NewOverrides = E->getFPFeatures();
12150 getSema().CurFPFeatures =
12151 NewOverrides.applyOverrides(getSema().getLangOpts());
12152 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12153 }
12154
12155 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
12156 Args,
12157 E->getRParenLoc());
12158}
12159
12160template<typename Derived>
12162TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
12163 ExprResult Base = getDerived().TransformExpr(E->getBase());
12164 if (Base.isInvalid())
12165 return ExprError();
12166
12167 NestedNameSpecifierLoc QualifierLoc;
12168 if (E->hasQualifier()) {
12169 QualifierLoc
12170 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
12171
12172 if (!QualifierLoc)
12173 return ExprError();
12174 }
12175 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
12176
12177 ValueDecl *Member
12178 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
12179 E->getMemberDecl()));
12180 if (!Member)
12181 return ExprError();
12182
12183 NamedDecl *FoundDecl = E->getFoundDecl();
12184 if (FoundDecl == E->getMemberDecl()) {
12185 FoundDecl = Member;
12186 } else {
12187 FoundDecl = cast_or_null<NamedDecl>(
12188 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
12189 if (!FoundDecl)
12190 return ExprError();
12191 }
12192
12193 if (!getDerived().AlwaysRebuild() &&
12194 Base.get() == E->getBase() &&
12195 QualifierLoc == E->getQualifierLoc() &&
12196 Member == E->getMemberDecl() &&
12197 FoundDecl == E->getFoundDecl() &&
12198 !E->hasExplicitTemplateArgs()) {
12199
12200 // Skip for member expression of (this->f), rebuilt thisi->f is needed
12201 // for Openmp where the field need to be privatizized in the case.
12202 if (!(isa<CXXThisExpr>(E->getBase()) &&
12203 getSema().OpenMP().isOpenMPRebuildMemberExpr(
12204 cast<ValueDecl>(Member)))) {
12205 // Mark it referenced in the new context regardless.
12206 // FIXME: this is a bit instantiation-specific.
12207 SemaRef.MarkMemberReferenced(E);
12208 return E;
12209 }
12210 }
12211
12212 TemplateArgumentListInfo TransArgs;
12213 if (E->hasExplicitTemplateArgs()) {
12214 TransArgs.setLAngleLoc(E->getLAngleLoc());
12215 TransArgs.setRAngleLoc(E->getRAngleLoc());
12216 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
12217 E->getNumTemplateArgs(),
12218 TransArgs))
12219 return ExprError();
12220 }
12221
12222 // FIXME: Bogus source location for the operator
12223 SourceLocation FakeOperatorLoc =
12224 SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
12225
12226 // FIXME: to do this check properly, we will need to preserve the
12227 // first-qualifier-in-scope here, just in case we had a dependent
12228 // base (and therefore couldn't do the check) and a
12229 // nested-name-qualifier (and therefore could do the lookup).
12230 NamedDecl *FirstQualifierInScope = nullptr;
12231 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
12232 if (MemberNameInfo.getName()) {
12233 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
12234 if (!MemberNameInfo.getName())
12235 return ExprError();
12236 }
12237
12238 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
12239 E->isArrow(),
12240 QualifierLoc,
12241 TemplateKWLoc,
12242 MemberNameInfo,
12243 Member,
12244 FoundDecl,
12245 (E->hasExplicitTemplateArgs()
12246 ? &TransArgs : nullptr),
12247 FirstQualifierInScope);
12248}
12249
12250template<typename Derived>
12252TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
12253 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12254 if (LHS.isInvalid())
12255 return ExprError();
12256
12257 ExprResult RHS =
12258 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
12259 if (RHS.isInvalid())
12260 return ExprError();
12261
12262 if (!getDerived().AlwaysRebuild() &&
12263 LHS.get() == E->getLHS() &&
12264 RHS.get() == E->getRHS())
12265 return E;
12266
12267 if (E->isCompoundAssignmentOp())
12268 // FPFeatures has already been established from trailing storage
12269 return getDerived().RebuildBinaryOperator(
12270 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
12271 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12272 FPOptionsOverride NewOverrides(E->getFPFeatures());
12273 getSema().CurFPFeatures =
12274 NewOverrides.applyOverrides(getSema().getLangOpts());
12275 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12276 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
12277 LHS.get(), RHS.get());
12278}
12279
12280template <typename Derived>
12281ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
12282 CXXRewrittenBinaryOperator *E) {
12283 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
12284
12285 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
12286 if (LHS.isInvalid())
12287 return ExprError();
12288
12289 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
12290 if (RHS.isInvalid())
12291 return ExprError();
12292
12293 // Extract the already-resolved callee declarations so that we can restrict
12294 // ourselves to using them as the unqualified lookup results when rebuilding.
12295 UnresolvedSet<2> UnqualLookups;
12296 bool ChangedAnyLookups = false;
12297 Expr *PossibleBinOps[] = {E->getSemanticForm(),
12298 const_cast<Expr *>(Decomp.InnerBinOp)};
12299 for (Expr *PossibleBinOp : PossibleBinOps) {
12300 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());
12301 if (!Op)
12302 continue;
12303 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());
12304 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))
12305 continue;
12306
12307 // Transform the callee in case we built a call to a local extern
12308 // declaration.
12309 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
12310 E->getOperatorLoc(), Callee->getFoundDecl()));
12311 if (!Found)
12312 return ExprError();
12313 if (Found != Callee->getFoundDecl())
12314 ChangedAnyLookups = true;
12315 UnqualLookups.addDecl(Found);
12316 }
12317
12318 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
12319 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
12320 // Mark all functions used in the rewrite as referenced. Note that when
12321 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
12322 // function calls, and/or there might be a user-defined conversion sequence
12323 // applied to the operands of the <.
12324 // FIXME: this is a bit instantiation-specific.
12325 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
12326 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);
12327 return E;
12328 }
12329
12330 return getDerived().RebuildCXXRewrittenBinaryOperator(
12331 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
12332}
12333
12334template<typename Derived>
12336TreeTransform<Derived>::TransformCompoundAssignOperator(
12337 CompoundAssignOperator *E) {
12338 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12339 FPOptionsOverride NewOverrides(E->getFPFeatures());
12340 getSema().CurFPFeatures =
12341 NewOverrides.applyOverrides(getSema().getLangOpts());
12342 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12343 return getDerived().TransformBinaryOperator(E);
12344}
12345
12346template<typename Derived>
12347ExprResult TreeTransform<Derived>::
12348TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
12349 // Just rebuild the common and RHS expressions and see whether we
12350 // get any changes.
12351
12352 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
12353 if (commonExpr.isInvalid())
12354 return ExprError();
12355
12356 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
12357 if (rhs.isInvalid())
12358 return ExprError();
12359
12360 if (!getDerived().AlwaysRebuild() &&
12361 commonExpr.get() == e->getCommon() &&
12362 rhs.get() == e->getFalseExpr())
12363 return e;
12364
12365 return getDerived().RebuildConditionalOperator(commonExpr.get(),
12366 e->getQuestionLoc(),
12367 nullptr,
12368 e->getColonLoc(),
12369 rhs.get());
12370}
12371
12372template<typename Derived>
12374TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
12375 ExprResult Cond = getDerived().TransformExpr(E->getCond());
12376 if (Cond.isInvalid())
12377 return ExprError();
12378
12379 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12380 if (LHS.isInvalid())
12381 return ExprError();
12382
12383 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
12384 if (RHS.isInvalid())
12385 return ExprError();
12386
12387 if (!getDerived().AlwaysRebuild() &&
12388 Cond.get() == E->getCond() &&
12389 LHS.get() == E->getLHS() &&
12390 RHS.get() == E->getRHS())
12391 return E;
12392
12393 return getDerived().RebuildConditionalOperator(Cond.get(),
12394 E->getQuestionLoc(),
12395 LHS.get(),
12396 E->getColonLoc(),
12397 RHS.get());
12398}
12399
12400template<typename Derived>
12402TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
12403 // Implicit casts are eliminated during transformation, since they
12404 // will be recomputed by semantic analysis after transformation.
12405 return getDerived().TransformExpr(E->getSubExprAsWritten());
12406}
12407
12408template<typename Derived>
12410TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
12411 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
12412 if (!Type)
12413 return ExprError();
12414
12415 ExprResult SubExpr
12416 = getDerived().TransformExpr(E->getSubExprAsWritten());
12417 if (SubExpr.isInvalid())
12418 return ExprError();
12419
12420 if (!getDerived().AlwaysRebuild() &&
12421 Type == E->getTypeInfoAsWritten() &&
12422 SubExpr.get() == E->getSubExpr())
12423 return E;
12424
12425 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
12426 Type,
12427 E->getRParenLoc(),
12428 SubExpr.get());
12429}
12430
12431template<typename Derived>
12433TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
12434 TypeSourceInfo *OldT = E->getTypeSourceInfo();
12435 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
12436 if (!NewT)
12437 return ExprError();
12438
12439 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
12440 if (Init.isInvalid())
12441 return ExprError();
12442
12443 if (!getDerived().AlwaysRebuild() &&
12444 OldT == NewT &&
12445 Init.get() == E->getInitializer())
12446 return SemaRef.MaybeBindToTemporary(E);
12447
12448 // Note: the expression type doesn't necessarily match the
12449 // type-as-written, but that's okay, because it should always be
12450 // derivable from the initializer.
12451
12452 return getDerived().RebuildCompoundLiteralExpr(
12453 E->getLParenLoc(), NewT,
12454 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
12455}
12456
12457template<typename Derived>
12459TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
12460 ExprResult Base = getDerived().TransformExpr(E->getBase());
12461 if (Base.isInvalid())
12462 return ExprError();
12463
12464 if (!getDerived().AlwaysRebuild() &&
12465 Base.get() == E->getBase())
12466 return E;
12467
12468 // FIXME: Bad source location
12469 SourceLocation FakeOperatorLoc =
12470 SemaRef.getLocForEndOfToken(E->getBase()->getEndLoc());
12471 return getDerived().RebuildExtVectorElementExpr(
12472 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
12473 E->getAccessor());
12474}
12475
12476template<typename Derived>
12478TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
12479 if (InitListExpr *Syntactic = E->getSyntacticForm())
12480 E = Syntactic;
12481
12482 bool InitChanged = false;
12483
12484 EnterExpressionEvaluationContext Context(
12486
12488 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
12489 Inits, &InitChanged))
12490 return ExprError();
12491
12492 if (!getDerived().AlwaysRebuild() && !InitChanged) {
12493 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
12494 // in some cases. We can't reuse it in general, because the syntactic and
12495 // semantic forms are linked, and we can't know that semantic form will
12496 // match even if the syntactic form does.
12497 }
12498
12499 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
12500 E->getRBraceLoc());
12501}
12502
12503template<typename Derived>
12505TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
12506 Designation Desig;
12507
12508 // transform the initializer value
12509 ExprResult Init = getDerived().TransformExpr(E->getInit());
12510 if (Init.isInvalid())
12511 return ExprError();
12512
12513 // transform the designators.
12514 SmallVector<Expr*, 4> ArrayExprs;
12515 bool ExprChanged = false;
12516 for (const DesignatedInitExpr::Designator &D : E->designators()) {
12517 if (D.isFieldDesignator()) {
12518 if (D.getFieldDecl()) {
12519 FieldDecl *Field = cast_or_null<FieldDecl>(
12520 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
12521 if (Field != D.getFieldDecl())
12522 // Rebuild the expression when the transformed FieldDecl is
12523 // different to the already assigned FieldDecl.
12524 ExprChanged = true;
12525 if (Field->isAnonymousStructOrUnion())
12526 continue;
12527 } else {
12528 // Ensure that the designator expression is rebuilt when there isn't
12529 // a resolved FieldDecl in the designator as we don't want to assign
12530 // a FieldDecl to a pattern designator that will be instantiated again.
12531 ExprChanged = true;
12532 }
12533 Desig.AddDesignator(Designator::CreateFieldDesignator(
12534 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
12535 continue;
12536 }
12537
12538 if (D.isArrayDesignator()) {
12539 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
12540 if (Index.isInvalid())
12541 return ExprError();
12542
12543 Desig.AddDesignator(
12544 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
12545
12546 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D);
12547 ArrayExprs.push_back(Index.get());
12548 continue;
12549 }
12550
12551 assert(D.isArrayRangeDesignator() && "New kind of designator?");
12552 ExprResult Start
12553 = getDerived().TransformExpr(E->getArrayRangeStart(D));
12554 if (Start.isInvalid())
12555 return ExprError();
12556
12557 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
12558 if (End.isInvalid())
12559 return ExprError();
12560
12561 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
12562 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
12563
12564 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
12565 End.get() != E->getArrayRangeEnd(D);
12566
12567 ArrayExprs.push_back(Start.get());
12568 ArrayExprs.push_back(End.get());
12569 }
12570
12571 if (!getDerived().AlwaysRebuild() &&
12572 Init.get() == E->getInit() &&
12573 !ExprChanged)
12574 return E;
12575
12576 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
12577 E->getEqualOrColonLoc(),
12578 E->usesGNUSyntax(), Init.get());
12579}
12580
12581// Seems that if TransformInitListExpr() only works on the syntactic form of an
12582// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
12583template<typename Derived>
12585TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
12586 DesignatedInitUpdateExpr *E) {
12587 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
12588 "initializer");
12589 return ExprError();
12590}
12591
12592template<typename Derived>
12594TreeTransform<Derived>::TransformNoInitExpr(
12595 NoInitExpr *E) {
12596 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
12597 return ExprError();
12598}
12599
12600template<typename Derived>
12602TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
12603 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
12604 return ExprError();
12605}
12606
12607template<typename Derived>
12609TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
12610 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
12611 return ExprError();
12612}
12613
12614template<typename Derived>
12616TreeTransform<Derived>::TransformImplicitValueInitExpr(
12617 ImplicitValueInitExpr *E) {
12618 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
12619
12620 // FIXME: Will we ever have proper type location here? Will we actually
12621 // need to transform the type?
12622 QualType T = getDerived().TransformType(E->getType());
12623 if (T.isNull())
12624 return ExprError();
12625
12626 if (!getDerived().AlwaysRebuild() &&
12627 T == E->getType())
12628 return E;
12629
12630 return getDerived().RebuildImplicitValueInitExpr(T);
12631}
12632
12633template<typename Derived>
12635TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
12636 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
12637 if (!TInfo)
12638 return ExprError();
12639
12640 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
12641 if (SubExpr.isInvalid())
12642 return ExprError();
12643
12644 if (!getDerived().AlwaysRebuild() &&
12645 TInfo == E->getWrittenTypeInfo() &&
12646 SubExpr.get() == E->getSubExpr())
12647 return E;
12648
12649 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
12650 TInfo, E->getRParenLoc());
12651}
12652
12653template<typename Derived>
12655TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
12656 bool ArgumentChanged = false;
12658 if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits,
12659 &ArgumentChanged))
12660 return ExprError();
12661
12662 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
12663 Inits,
12664 E->getRParenLoc());
12665}
12666
12667/// Transform an address-of-label expression.
12668///
12669/// By default, the transformation of an address-of-label expression always
12670/// rebuilds the expression, so that the label identifier can be resolved to
12671/// the corresponding label statement by semantic analysis.
12672template<typename Derived>
12674TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
12675 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
12676 E->getLabel());
12677 if (!LD)
12678 return ExprError();
12679
12680 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
12681 cast<LabelDecl>(LD));
12682}
12683
12684template<typename Derived>
12686TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
12687 SemaRef.ActOnStartStmtExpr();
12688 StmtResult SubStmt
12689 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
12690 if (SubStmt.isInvalid()) {
12691 SemaRef.ActOnStmtExprError();
12692 return ExprError();
12693 }
12694
12695 unsigned OldDepth = E->getTemplateDepth();
12696 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
12697
12698 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
12699 SubStmt.get() == E->getSubStmt()) {
12700 // Calling this an 'error' is unintuitive, but it does the right thing.
12701 SemaRef.ActOnStmtExprError();
12702 return SemaRef.MaybeBindToTemporary(E);
12703 }
12704
12705 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
12706 E->getRParenLoc(), NewDepth);
12707}
12708
12709template<typename Derived>
12711TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
12712 ExprResult Cond = getDerived().TransformExpr(E->getCond());
12713 if (Cond.isInvalid())
12714 return ExprError();
12715
12716 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
12717 if (LHS.isInvalid())
12718 return ExprError();
12719
12720 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
12721 if (RHS.isInvalid())
12722 return ExprError();
12723
12724 if (!getDerived().AlwaysRebuild() &&
12725 Cond.get() == E->getCond() &&
12726 LHS.get() == E->getLHS() &&
12727 RHS.get() == E->getRHS())
12728 return E;
12729
12730 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
12731 Cond.get(), LHS.get(), RHS.get(),
12732 E->getRParenLoc());
12733}
12734
12735template<typename Derived>
12737TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
12738 return E;
12739}
12740
12741template<typename Derived>
12743TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
12744 switch (E->getOperator()) {
12745 case OO_New:
12746 case OO_Delete:
12747 case OO_Array_New:
12748 case OO_Array_Delete:
12749 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
12750
12751 case OO_Subscript:
12752 case OO_Call: {
12753 // This is a call to an object's operator().
12754 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
12755
12756 // Transform the object itself.
12757 ExprResult Object = getDerived().TransformExpr(E->getArg(0));
12758 if (Object.isInvalid())
12759 return ExprError();
12760
12761 // FIXME: Poor location information
12762 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
12763 static_cast<Expr *>(Object.get())->getEndLoc());
12764
12765 // Transform the call arguments.
12767 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
12768 Args))
12769 return ExprError();
12770
12771 if (E->getOperator() == OO_Subscript)
12772 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
12773 Args, E->getEndLoc());
12774
12775 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
12776 E->getEndLoc());
12777 }
12778
12779#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
12780 case OO_##Name: \
12781 break;
12782
12783#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
12784#include "clang/Basic/OperatorKinds.def"
12785
12786 case OO_Conditional:
12787 llvm_unreachable("conditional operator is not actually overloadable");
12788
12789 case OO_None:
12791 llvm_unreachable("not an overloaded operator?");
12792 }
12793
12795 if (E->getOperator() == OO_Amp)
12796 First = getDerived().TransformAddressOfOperand(E->getArg(0));
12797 else
12798 First = getDerived().TransformExpr(E->getArg(0));
12799 if (First.isInvalid())
12800 return ExprError();
12801
12802 ExprResult Second;
12803 if (E->getNumArgs() == 2) {
12804 Second =
12805 getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);
12806 if (Second.isInvalid())
12807 return ExprError();
12808 }
12809
12810 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
12811 FPOptionsOverride NewOverrides(E->getFPFeatures());
12812 getSema().CurFPFeatures =
12813 NewOverrides.applyOverrides(getSema().getLangOpts());
12814 getSema().FpPragmaStack.CurrentValue = NewOverrides;
12815
12816 Expr *Callee = E->getCallee();
12817 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
12818 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
12820 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
12821 return ExprError();
12822
12823 return getDerived().RebuildCXXOperatorCallExpr(
12824 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
12825 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
12826 }
12827
12828 UnresolvedSet<1> Functions;
12829 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
12830 Callee = ICE->getSubExprAsWritten();
12831 NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();
12832 ValueDecl *VD = cast_or_null<ValueDecl>(
12833 getDerived().TransformDecl(DR->getLocation(), DR));
12834 if (!VD)
12835 return ExprError();
12836
12837 if (!isa<CXXMethodDecl>(VD))
12838 Functions.addDecl(VD);
12839
12840 return getDerived().RebuildCXXOperatorCallExpr(
12841 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
12842 /*RequiresADL=*/false, Functions, First.get(), Second.get());
12843}
12844
12845template<typename Derived>
12847TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
12848 return getDerived().TransformCallExpr(E);
12849}
12850
12851template <typename Derived>
12852ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
12853 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(E->getIdentKind()) &&
12854 getSema().CurContext != E->getParentContext();
12855
12856 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
12857 return E;
12858
12859 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
12860 E->getBeginLoc(), E->getEndLoc(),
12861 getSema().CurContext);
12862}
12863
12864template<typename Derived>
12866TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
12867 // Transform the callee.
12868 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
12869 if (Callee.isInvalid())
12870 return ExprError();
12871
12872 // Transform exec config.
12873 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
12874 if (EC.isInvalid())
12875 return ExprError();
12876
12877 // Transform arguments.
12878 bool ArgChanged = false;
12880 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
12881 &ArgChanged))
12882 return ExprError();
12883
12884 if (!getDerived().AlwaysRebuild() &&
12885 Callee.get() == E->getCallee() &&
12886 !ArgChanged)
12887 return SemaRef.MaybeBindToTemporary(E);
12888
12889 // FIXME: Wrong source location information for the '('.
12890 SourceLocation FakeLParenLoc
12891 = ((Expr *)Callee.get())->getSourceRange().getBegin();
12892 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
12893 Args,
12894 E->getRParenLoc(), EC.get());
12895}
12896
12897template<typename Derived>
12900 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
12901 if (!Type)
12902 return ExprError();
12903
12904 ExprResult SubExpr
12905 = getDerived().TransformExpr(E->getSubExprAsWritten());
12906 if (SubExpr.isInvalid())
12907 return ExprError();
12908
12909 if (!getDerived().AlwaysRebuild() &&
12910 Type == E->getTypeInfoAsWritten() &&
12911 SubExpr.get() == E->getSubExpr())
12912 return E;
12913 return getDerived().RebuildCXXNamedCastExpr(
12916 // FIXME. this should be '(' location
12917 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
12918}
12919
12920template<typename Derived>
12923 TypeSourceInfo *TSI =
12924 getDerived().TransformType(BCE->getTypeInfoAsWritten());
12925 if (!TSI)
12926 return ExprError();
12927
12928 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
12929 if (Sub.isInvalid())
12930 return ExprError();
12931
12932 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
12933 Sub.get(), BCE->getEndLoc());
12934}
12935
12936template<typename Derived>
12938TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
12939 return getDerived().TransformCXXNamedCastExpr(E);
12940}
12941
12942template<typename Derived>
12944TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
12945 return getDerived().TransformCXXNamedCastExpr(E);
12946}
12947
12948template<typename Derived>
12950TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
12951 CXXReinterpretCastExpr *E) {
12952 return getDerived().TransformCXXNamedCastExpr(E);
12953}
12954
12955template<typename Derived>
12957TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
12958 return getDerived().TransformCXXNamedCastExpr(E);
12959}
12960
12961template<typename Derived>
12963TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
12964 return getDerived().TransformCXXNamedCastExpr(E);
12965}
12966
12967template<typename Derived>
12969TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
12970 CXXFunctionalCastExpr *E) {
12971 TypeSourceInfo *Type =
12972 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
12973 if (!Type)
12974 return ExprError();
12975
12976 ExprResult SubExpr
12977 = getDerived().TransformExpr(E->getSubExprAsWritten());
12978 if (SubExpr.isInvalid())
12979 return ExprError();
12980
12981 if (!getDerived().AlwaysRebuild() &&
12982 Type == E->getTypeInfoAsWritten() &&
12983 SubExpr.get() == E->getSubExpr())
12984 return E;
12985
12986 return getDerived().RebuildCXXFunctionalCastExpr(Type,
12987 E->getLParenLoc(),
12988 SubExpr.get(),
12989 E->getRParenLoc(),
12990 E->isListInitialization());
12991}
12992
12993template<typename Derived>
12995TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
12996 if (E->isTypeOperand()) {
12997 TypeSourceInfo *TInfo
12998 = getDerived().TransformType(E->getTypeOperandSourceInfo());
12999 if (!TInfo)
13000 return ExprError();
13001
13002 if (!getDerived().AlwaysRebuild() &&
13003 TInfo == E->getTypeOperandSourceInfo())
13004 return E;
13005
13006 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
13007 TInfo, E->getEndLoc());
13008 }
13009
13010 // Typeid's operand is an unevaluated context, unless it's a polymorphic
13011 // type. We must not unilaterally enter unevaluated context here, as then
13012 // semantic processing can re-transform an already transformed operand.
13013 Expr *Op = E->getExprOperand();
13015 if (E->isGLValue())
13016 if (auto *RecordT = Op->getType()->getAs<RecordType>())
13017 if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
13018 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
13019
13020 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
13022
13023 ExprResult SubExpr = getDerived().TransformExpr(Op);
13024 if (SubExpr.isInvalid())
13025 return ExprError();
13026
13027 if (!getDerived().AlwaysRebuild() &&
13028 SubExpr.get() == E->getExprOperand())
13029 return E;
13030
13031 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
13032 SubExpr.get(), E->getEndLoc());
13033}
13034
13035template<typename Derived>
13037TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
13038 if (E->isTypeOperand()) {
13039 TypeSourceInfo *TInfo
13040 = getDerived().TransformType(E->getTypeOperandSourceInfo());
13041 if (!TInfo)
13042 return ExprError();
13043
13044 if (!getDerived().AlwaysRebuild() &&
13045 TInfo == E->getTypeOperandSourceInfo())
13046 return E;
13047
13048 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
13049 TInfo, E->getEndLoc());
13050 }
13051
13052 EnterExpressionEvaluationContext Unevaluated(
13054
13055 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
13056 if (SubExpr.isInvalid())
13057 return ExprError();
13058
13059 if (!getDerived().AlwaysRebuild() &&
13060 SubExpr.get() == E->getExprOperand())
13061 return E;
13062
13063 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
13064 SubExpr.get(), E->getEndLoc());
13065}
13066
13067template<typename Derived>
13069TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
13070 return E;
13071}
13072
13073template<typename Derived>
13075TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
13076 CXXNullPtrLiteralExpr *E) {
13077 return E;
13078}
13079
13080template<typename Derived>
13082TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
13083
13084 // In lambdas, the qualifiers of the type depends of where in
13085 // the call operator `this` appear, and we do not have a good way to
13086 // rebuild this information, so we transform the type.
13087 //
13088 // In other contexts, the type of `this` may be overrided
13089 // for type deduction, so we need to recompute it.
13090 //
13091 // Always recompute the type if we're in the body of a lambda, and
13092 // 'this' is dependent on a lambda's explicit object parameter.
13093 QualType T = [&]() {
13094 auto &S = getSema();
13095 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
13096 return S.getCurrentThisType();
13097 if (S.getCurLambda())
13098 return getDerived().TransformType(E->getType());
13099 return S.getCurrentThisType();
13100 }();
13101
13102 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
13103 // Mark it referenced in the new context regardless.
13104 // FIXME: this is a bit instantiation-specific.
13105 getSema().MarkThisReferenced(E);
13106 return E;
13107 }
13108
13109 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
13110}
13111
13112template<typename Derived>
13114TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
13115 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13116 if (SubExpr.isInvalid())
13117 return ExprError();
13118
13119 if (!getDerived().AlwaysRebuild() &&
13120 SubExpr.get() == E->getSubExpr())
13121 return E;
13122
13123 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
13124 E->isThrownVariableInScope());
13125}
13126
13127template<typename Derived>
13129TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
13130 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
13131 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
13132 if (!Param)
13133 return ExprError();
13134
13135 ExprResult InitRes;
13136 if (E->hasRewrittenInit()) {
13137 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
13138 if (InitRes.isInvalid())
13139 return ExprError();
13140 }
13141
13142 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
13143 E->getUsedContext() == SemaRef.CurContext &&
13144 InitRes.get() == E->getRewrittenExpr())
13145 return E;
13146
13147 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
13148 InitRes.get());
13149}
13150
13151template<typename Derived>
13153TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
13154 FieldDecl *Field = cast_or_null<FieldDecl>(
13155 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
13156 if (!Field)
13157 return ExprError();
13158
13159 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
13160 E->getUsedContext() == SemaRef.CurContext)
13161 return E;
13162
13163 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
13164}
13165
13166template<typename Derived>
13168TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
13169 CXXScalarValueInitExpr *E) {
13170 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
13171 if (!T)
13172 return ExprError();
13173
13174 if (!getDerived().AlwaysRebuild() &&
13175 T == E->getTypeSourceInfo())
13176 return E;
13177
13178 return getDerived().RebuildCXXScalarValueInitExpr(T,
13179 /*FIXME:*/T->getTypeLoc().getEndLoc(),
13180 E->getRParenLoc());
13181}
13182
13183template<typename Derived>
13185TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
13186 // Transform the type that we're allocating
13187 TypeSourceInfo *AllocTypeInfo =
13188 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
13189 if (!AllocTypeInfo)
13190 return ExprError();
13191
13192 // Transform the size of the array we're allocating (if any).
13193 std::optional<Expr *> ArraySize;
13194 if (E->isArray()) {
13195 ExprResult NewArraySize;
13196 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
13197 NewArraySize = getDerived().TransformExpr(*OldArraySize);
13198 if (NewArraySize.isInvalid())
13199 return ExprError();
13200 }
13201 ArraySize = NewArraySize.get();
13202 }
13203
13204 // Transform the placement arguments (if any).
13205 bool ArgumentChanged = false;
13206 SmallVector<Expr*, 8> PlacementArgs;
13207 if (getDerived().TransformExprs(E->getPlacementArgs(),
13208 E->getNumPlacementArgs(), true,
13209 PlacementArgs, &ArgumentChanged))
13210 return ExprError();
13211
13212 // Transform the initializer (if any).
13213 Expr *OldInit = E->getInitializer();
13214 ExprResult NewInit;
13215 if (OldInit)
13216 NewInit = getDerived().TransformInitializer(OldInit, true);
13217 if (NewInit.isInvalid())
13218 return ExprError();
13219
13220 // Transform new operator and delete operator.
13221 FunctionDecl *OperatorNew = nullptr;
13222 if (E->getOperatorNew()) {
13223 OperatorNew = cast_or_null<FunctionDecl>(
13224 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
13225 if (!OperatorNew)
13226 return ExprError();
13227 }
13228
13229 FunctionDecl *OperatorDelete = nullptr;
13230 if (E->getOperatorDelete()) {
13231 OperatorDelete = cast_or_null<FunctionDecl>(
13232 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
13233 if (!OperatorDelete)
13234 return ExprError();
13235 }
13236
13237 if (!getDerived().AlwaysRebuild() &&
13238 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
13239 ArraySize == E->getArraySize() &&
13240 NewInit.get() == OldInit &&
13241 OperatorNew == E->getOperatorNew() &&
13242 OperatorDelete == E->getOperatorDelete() &&
13243 !ArgumentChanged) {
13244 // Mark any declarations we need as referenced.
13245 // FIXME: instantiation-specific.
13246 if (OperatorNew)
13247 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorNew);
13248 if (OperatorDelete)
13249 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
13250
13251 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
13252 QualType ElementType
13253 = SemaRef.Context.getBaseElementType(E->getAllocatedType());
13254 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
13255 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
13256 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
13257 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor);
13258 }
13259 }
13260 }
13261
13262 return E;
13263 }
13264
13265 QualType AllocType = AllocTypeInfo->getType();
13266 if (!ArraySize) {
13267 // If no array size was specified, but the new expression was
13268 // instantiated with an array type (e.g., "new T" where T is
13269 // instantiated with "int[4]"), extract the outer bound from the
13270 // array type as our array size. We do this with constant and
13271 // dependently-sized array types.
13272 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);
13273 if (!ArrayT) {
13274 // Do nothing
13275 } else if (const ConstantArrayType *ConsArrayT
13276 = dyn_cast<ConstantArrayType>(ArrayT)) {
13277 ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),
13278 SemaRef.Context.getSizeType(),
13279 /*FIXME:*/ E->getBeginLoc());
13280 AllocType = ConsArrayT->getElementType();
13281 } else if (const DependentSizedArrayType *DepArrayT
13282 = dyn_cast<DependentSizedArrayType>(ArrayT)) {
13283 if (DepArrayT->getSizeExpr()) {
13284 ArraySize = DepArrayT->getSizeExpr();
13285 AllocType = DepArrayT->getElementType();
13286 }
13287 }
13288 }
13289
13290 return getDerived().RebuildCXXNewExpr(
13291 E->getBeginLoc(), E->isGlobalNew(),
13292 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
13293 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
13294 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
13295}
13296
13297template<typename Derived>
13299TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
13300 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
13301 if (Operand.isInvalid())
13302 return ExprError();
13303
13304 // Transform the delete operator, if known.
13305 FunctionDecl *OperatorDelete = nullptr;
13306 if (E->getOperatorDelete()) {
13307 OperatorDelete = cast_or_null<FunctionDecl>(
13308 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
13309 if (!OperatorDelete)
13310 return ExprError();
13311 }
13312
13313 if (!getDerived().AlwaysRebuild() &&
13314 Operand.get() == E->getArgument() &&
13315 OperatorDelete == E->getOperatorDelete()) {
13316 // Mark any declarations we need as referenced.
13317 // FIXME: instantiation-specific.
13318 if (OperatorDelete)
13319 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);
13320
13321 if (!E->getArgument()->isTypeDependent()) {
13322 QualType Destroyed = SemaRef.Context.getBaseElementType(
13323 E->getDestroyedType());
13324 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
13325 CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
13326 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
13327 SemaRef.LookupDestructor(Record));
13328 }
13329 }
13330
13331 return E;
13332 }
13333
13334 return getDerived().RebuildCXXDeleteExpr(
13335 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
13336}
13337
13338template<typename Derived>
13340TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
13341 CXXPseudoDestructorExpr *E) {
13342 ExprResult Base = getDerived().TransformExpr(E->getBase());
13343 if (Base.isInvalid())
13344 return ExprError();
13345
13346 ParsedType ObjectTypePtr;
13347 bool MayBePseudoDestructor = false;
13348 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
13349 E->getOperatorLoc(),
13350 E->isArrow()? tok::arrow : tok::period,
13351 ObjectTypePtr,
13352 MayBePseudoDestructor);
13353 if (Base.isInvalid())
13354 return ExprError();
13355
13356 QualType ObjectType = ObjectTypePtr.get();
13357 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
13358 if (QualifierLoc) {
13359 QualifierLoc
13360 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
13361 if (!QualifierLoc)
13362 return ExprError();
13363 }
13364 CXXScopeSpec SS;
13365 SS.Adopt(QualifierLoc);
13366
13367 PseudoDestructorTypeStorage Destroyed;
13368 if (E->getDestroyedTypeInfo()) {
13369 TypeSourceInfo *DestroyedTypeInfo
13370 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
13371 ObjectType, nullptr, SS);
13372 if (!DestroyedTypeInfo)
13373 return ExprError();
13374 Destroyed = DestroyedTypeInfo;
13375 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
13376 // We aren't likely to be able to resolve the identifier down to a type
13377 // now anyway, so just retain the identifier.
13378 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
13379 E->getDestroyedTypeLoc());
13380 } else {
13381 // Look for a destructor known with the given name.
13382 ParsedType T = SemaRef.getDestructorName(
13383 *E->getDestroyedTypeIdentifier(), E->getDestroyedTypeLoc(),
13384 /*Scope=*/nullptr, SS, ObjectTypePtr, false);
13385 if (!T)
13386 return ExprError();
13387
13388 Destroyed
13390 E->getDestroyedTypeLoc());
13391 }
13392
13393 TypeSourceInfo *ScopeTypeInfo = nullptr;
13394 if (E->getScopeTypeInfo()) {
13395 CXXScopeSpec EmptySS;
13396 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
13397 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
13398 if (!ScopeTypeInfo)
13399 return ExprError();
13400 }
13401
13402 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
13403 E->getOperatorLoc(),
13404 E->isArrow(),
13405 SS,
13406 ScopeTypeInfo,
13407 E->getColonColonLoc(),
13408 E->getTildeLoc(),
13409 Destroyed);
13410}
13411
13412template <typename Derived>
13414 bool RequiresADL,
13415 LookupResult &R) {
13416 // Transform all the decls.
13417 bool AllEmptyPacks = true;
13418 for (auto *OldD : Old->decls()) {
13419 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
13420 if (!InstD) {
13421 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
13422 // This can happen because of dependent hiding.
13423 if (isa<UsingShadowDecl>(OldD))
13424 continue;
13425 else {
13426 R.clear();
13427 return true;
13428 }
13429 }
13430
13431 // Expand using pack declarations.
13432 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
13433 ArrayRef<NamedDecl*> Decls = SingleDecl;
13434 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
13435 Decls = UPD->expansions();
13436
13437 // Expand using declarations.
13438 for (auto *D : Decls) {
13439 if (auto *UD = dyn_cast<UsingDecl>(D)) {
13440 for (auto *SD : UD->shadows())
13441 R.addDecl(SD);
13442 } else {
13443 R.addDecl(D);
13444 }
13445 }
13446
13447 AllEmptyPacks &= Decls.empty();
13448 };
13449
13450 // C++ [temp.res]/8.4.2:
13451 // The program is ill-formed, no diagnostic required, if [...] lookup for
13452 // a name in the template definition found a using-declaration, but the
13453 // lookup in the corresponding scope in the instantiation odoes not find
13454 // any declarations because the using-declaration was a pack expansion and
13455 // the corresponding pack is empty
13456 if (AllEmptyPacks && !RequiresADL) {
13457 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
13458 << isa<UnresolvedMemberExpr>(Old) << Old->getName();
13459 return true;
13460 }
13461
13462 // Resolve a kind, but don't do any further analysis. If it's
13463 // ambiguous, the callee needs to deal with it.
13464 R.resolveKind();
13465
13466 if (Old->hasTemplateKeyword() && !R.empty()) {
13468 getSema().FilterAcceptableTemplateNames(R,
13469 /*AllowFunctionTemplates=*/true,
13470 /*AllowDependent=*/true);
13471 if (R.empty()) {
13472 // If a 'template' keyword was used, a lookup that finds only non-template
13473 // names is an error.
13474 getSema().Diag(R.getNameLoc(),
13475 diag::err_template_kw_refers_to_non_template)
13477 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
13478 getSema().Diag(FoundDecl->getLocation(),
13479 diag::note_template_kw_refers_to_non_template)
13480 << R.getLookupName();
13481 return true;
13482 }
13483 }
13484
13485 return false;
13486}
13487
13488template <typename Derived>
13490 UnresolvedLookupExpr *Old) {
13491 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
13492}
13493
13494template <typename Derived>
13497 bool IsAddressOfOperand) {
13498 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
13500
13501 // Transform the declaration set.
13502 if (TransformOverloadExprDecls(Old, Old->requiresADL(), R))
13503 return ExprError();
13504
13505 // Rebuild the nested-name qualifier, if present.
13506 CXXScopeSpec SS;
13507 if (Old->getQualifierLoc()) {
13508 NestedNameSpecifierLoc QualifierLoc
13509 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
13510 if (!QualifierLoc)
13511 return ExprError();
13512
13513 SS.Adopt(QualifierLoc);
13514 }
13515
13516 if (Old->getNamingClass()) {
13517 CXXRecordDecl *NamingClass
13518 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
13519 Old->getNameLoc(),
13520 Old->getNamingClass()));
13521 if (!NamingClass) {
13522 R.clear();
13523 return ExprError();
13524 }
13525
13526 R.setNamingClass(NamingClass);
13527 }
13528
13529 // Rebuild the template arguments, if any.
13530 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
13531 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
13532 if (Old->hasExplicitTemplateArgs() &&
13533 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
13534 Old->getNumTemplateArgs(),
13535 TransArgs)) {
13536 R.clear();
13537 return ExprError();
13538 }
13539
13540 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
13541 // a non-static data member is named in an unevaluated operand, or when
13542 // a member is named in a dependent class scope function template explicit
13543 // specialization that is neither declared static nor with an explicit object
13544 // parameter.
13545 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
13546 return SemaRef.BuildPossibleImplicitMemberExpr(
13547 SS, TemplateKWLoc, R,
13548 Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
13549 /*S=*/nullptr);
13550
13551 // If we have neither explicit template arguments, nor the template keyword,
13552 // it's a normal declaration name or member reference.
13553 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
13554 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
13555
13556 // If we have template arguments, then rebuild the template-id expression.
13557 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
13558 Old->requiresADL(), &TransArgs);
13559}
13560
13561template<typename Derived>
13563TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
13564 bool ArgChanged = false;
13566 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
13567 TypeSourceInfo *From = E->getArg(I);
13568 TypeLoc FromTL = From->getTypeLoc();
13569 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
13570 TypeLocBuilder TLB;
13571 TLB.reserve(FromTL.getFullDataSize());
13572 QualType To = getDerived().TransformType(TLB, FromTL);
13573 if (To.isNull())
13574 return ExprError();
13575
13576 if (To == From->getType())
13577 Args.push_back(From);
13578 else {
13579 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
13580 ArgChanged = true;
13581 }
13582 continue;
13583 }
13584
13585 ArgChanged = true;
13586
13587 // We have a pack expansion. Instantiate it.
13588 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
13589 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
13591 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
13592
13593 // Determine whether the set of unexpanded parameter packs can and should
13594 // be expanded.
13595 bool Expand = true;
13596 bool RetainExpansion = false;
13597 std::optional<unsigned> OrigNumExpansions =
13598 ExpansionTL.getTypePtr()->getNumExpansions();
13599 std::optional<unsigned> NumExpansions = OrigNumExpansions;
13600 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
13601 PatternTL.getSourceRange(),
13602 Unexpanded,
13603 Expand, RetainExpansion,
13604 NumExpansions))
13605 return ExprError();
13606
13607 if (!Expand) {
13608 // The transform has determined that we should perform a simple
13609 // transformation on the pack expansion, producing another pack
13610 // expansion.
13611 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
13612
13613 TypeLocBuilder TLB;
13614 TLB.reserve(From->getTypeLoc().getFullDataSize());
13615
13616 QualType To = getDerived().TransformType(TLB, PatternTL);
13617 if (To.isNull())
13618 return ExprError();
13619
13620 To = getDerived().RebuildPackExpansionType(To,
13621 PatternTL.getSourceRange(),
13622 ExpansionTL.getEllipsisLoc(),
13623 NumExpansions);
13624 if (To.isNull())
13625 return ExprError();
13626
13627 PackExpansionTypeLoc ToExpansionTL
13628 = TLB.push<PackExpansionTypeLoc>(To);
13629 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13630 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
13631 continue;
13632 }
13633
13634 // Expand the pack expansion by substituting for each argument in the
13635 // pack(s).
13636 for (unsigned I = 0; I != *NumExpansions; ++I) {
13637 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
13638 TypeLocBuilder TLB;
13639 TLB.reserve(PatternTL.getFullDataSize());
13640 QualType To = getDerived().TransformType(TLB, PatternTL);
13641 if (To.isNull())
13642 return ExprError();
13643
13644 if (To->containsUnexpandedParameterPack()) {
13645 To = getDerived().RebuildPackExpansionType(To,
13646 PatternTL.getSourceRange(),
13647 ExpansionTL.getEllipsisLoc(),
13648 NumExpansions);
13649 if (To.isNull())
13650 return ExprError();
13651
13652 PackExpansionTypeLoc ToExpansionTL
13653 = TLB.push<PackExpansionTypeLoc>(To);
13654 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13655 }
13656
13657 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
13658 }
13659
13660 if (!RetainExpansion)
13661 continue;
13662
13663 // If we're supposed to retain a pack expansion, do so by temporarily
13664 // forgetting the partially-substituted parameter pack.
13665 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
13666
13667 TypeLocBuilder TLB;
13668 TLB.reserve(From->getTypeLoc().getFullDataSize());
13669
13670 QualType To = getDerived().TransformType(TLB, PatternTL);
13671 if (To.isNull())
13672 return ExprError();
13673
13674 To = getDerived().RebuildPackExpansionType(To,
13675 PatternTL.getSourceRange(),
13676 ExpansionTL.getEllipsisLoc(),
13677 NumExpansions);
13678 if (To.isNull())
13679 return ExprError();
13680
13681 PackExpansionTypeLoc ToExpansionTL
13682 = TLB.push<PackExpansionTypeLoc>(To);
13683 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
13684 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
13685 }
13686
13687 if (!getDerived().AlwaysRebuild() && !ArgChanged)
13688 return E;
13689
13690 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
13691 E->getEndLoc());
13692}
13693
13694template<typename Derived>
13696TreeTransform<Derived>::TransformConceptSpecializationExpr(
13697 ConceptSpecializationExpr *E) {
13698 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
13699 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
13700 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
13701 Old->NumTemplateArgs, TransArgs))
13702 return ExprError();
13703
13704 return getDerived().RebuildConceptSpecializationExpr(
13705 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
13706 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
13707 &TransArgs);
13708}
13709
13710template<typename Derived>
13712TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
13713 SmallVector<ParmVarDecl*, 4> TransParams;
13714 SmallVector<QualType, 4> TransParamTypes;
13715 Sema::ExtParameterInfoBuilder ExtParamInfos;
13716
13717 // C++2a [expr.prim.req]p2
13718 // Expressions appearing within a requirement-body are unevaluated operands.
13719 EnterExpressionEvaluationContext Ctx(
13722
13723 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
13724 getSema().Context, getSema().CurContext,
13725 E->getBody()->getBeginLoc());
13726
13727 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
13728
13729 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
13730 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
13731 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
13732
13733 for (ParmVarDecl *Param : TransParams)
13734 if (Param)
13735 Param->setDeclContext(Body);
13736
13737 // On failure to transform, TransformRequiresTypeParams returns an expression
13738 // in the event that the transformation of the type params failed in some way.
13739 // It is expected that this will result in a 'not satisfied' Requires clause
13740 // when instantiating.
13741 if (!TypeParamResult.isUnset())
13742 return TypeParamResult;
13743
13745 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
13746 TransReqs))
13747 return ExprError();
13748
13749 for (concepts::Requirement *Req : TransReqs) {
13750 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
13751 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
13752 ER->getReturnTypeRequirement()
13753 .getTypeConstraintTemplateParameterList()->getParam(0)
13754 ->setDeclContext(Body);
13755 }
13756 }
13757 }
13758
13759 return getDerived().RebuildRequiresExpr(
13760 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
13761 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
13762}
13763
13764template<typename Derived>
13768 for (concepts::Requirement *Req : Reqs) {
13769 concepts::Requirement *TransReq = nullptr;
13770 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
13771 TransReq = getDerived().TransformTypeRequirement(TypeReq);
13772 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
13773 TransReq = getDerived().TransformExprRequirement(ExprReq);
13774 else
13775 TransReq = getDerived().TransformNestedRequirement(
13776 cast<concepts::NestedRequirement>(Req));
13777 if (!TransReq)
13778 return true;
13779 Transformed.push_back(TransReq);
13780 }
13781 return false;
13782}
13783
13784template<typename Derived>
13788 if (Req->isSubstitutionFailure()) {
13789 if (getDerived().AlwaysRebuild())
13790 return getDerived().RebuildTypeRequirement(
13792 return Req;
13793 }
13794 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
13795 if (!TransType)
13796 return nullptr;
13797 return getDerived().RebuildTypeRequirement(TransType);
13798}
13799
13800template<typename Derived>
13803 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
13804 if (Req->isExprSubstitutionFailure())
13805 TransExpr = Req->getExprSubstitutionDiagnostic();
13806 else {
13807 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
13808 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
13809 TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());
13810 if (TransExprRes.isInvalid())
13811 return nullptr;
13812 TransExpr = TransExprRes.get();
13813 }
13814
13815 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
13816 const auto &RetReq = Req->getReturnTypeRequirement();
13817 if (RetReq.isEmpty())
13818 TransRetReq.emplace();
13819 else if (RetReq.isSubstitutionFailure())
13820 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
13821 else if (RetReq.isTypeConstraint()) {
13822 TemplateParameterList *OrigTPL =
13823 RetReq.getTypeConstraintTemplateParameterList();
13825 getDerived().TransformTemplateParameterList(OrigTPL);
13826 if (!TPL)
13827 return nullptr;
13828 TransRetReq.emplace(TPL);
13829 }
13830 assert(TransRetReq && "All code paths leading here must set TransRetReq");
13831 if (Expr *E = TransExpr.dyn_cast<Expr *>())
13832 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
13833 Req->getNoexceptLoc(),
13834 std::move(*TransRetReq));
13835 return getDerived().RebuildExprRequirement(
13837 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
13838}
13839
13840template<typename Derived>
13844 if (Req->hasInvalidConstraint()) {
13845 if (getDerived().AlwaysRebuild())
13846 return getDerived().RebuildNestedRequirement(
13848 return Req;
13849 }
13850 ExprResult TransConstraint =
13851 getDerived().TransformExpr(Req->getConstraintExpr());
13852 if (TransConstraint.isInvalid())
13853 return nullptr;
13854 return getDerived().RebuildNestedRequirement(TransConstraint.get());
13855}
13856
13857template<typename Derived>
13860 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
13861 if (!T)
13862 return ExprError();
13863
13864 if (!getDerived().AlwaysRebuild() &&
13866 return E;
13867
13868 ExprResult SubExpr;
13869 {
13872 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
13873 if (SubExpr.isInvalid())
13874 return ExprError();
13875
13876 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
13877 return E;
13878 }
13879
13880 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
13881 SubExpr.get(), E->getEndLoc());
13882}
13883
13884template<typename Derived>
13886TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
13887 ExprResult SubExpr;
13888 {
13889 EnterExpressionEvaluationContext Unevaluated(
13891 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
13892 if (SubExpr.isInvalid())
13893 return ExprError();
13894
13895 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
13896 return E;
13897 }
13898
13899 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
13900 SubExpr.get(), E->getEndLoc());
13901}
13902
13903template <typename Derived>
13905 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
13906 TypeSourceInfo **RecoveryTSI) {
13907 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
13908 DRE, AddrTaken, RecoveryTSI);
13909
13910 // Propagate both errors and recovered types, which return ExprEmpty.
13911 if (!NewDRE.isUsable())
13912 return NewDRE;
13913
13914 // We got an expr, wrap it up in parens.
13915 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
13916 return PE;
13917 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
13918 PE->getRParen());
13919}
13920
13921template <typename Derived>
13924 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
13925 nullptr);
13926}
13927
13928template <typename Derived>
13930 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
13931 TypeSourceInfo **RecoveryTSI) {
13932 assert(E->getQualifierLoc());
13933 NestedNameSpecifierLoc QualifierLoc =
13934 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13935 if (!QualifierLoc)
13936 return ExprError();
13937 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13938
13939 // TODO: If this is a conversion-function-id, verify that the
13940 // destination type name (if present) resolves the same way after
13941 // instantiation as it did in the local scope.
13942
13943 DeclarationNameInfo NameInfo =
13944 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
13945 if (!NameInfo.getName())
13946 return ExprError();
13947
13948 if (!E->hasExplicitTemplateArgs()) {
13949 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
13950 // Note: it is sufficient to compare the Name component of NameInfo:
13951 // if name has not changed, DNLoc has not changed either.
13952 NameInfo.getName() == E->getDeclName())
13953 return E;
13954
13955 return getDerived().RebuildDependentScopeDeclRefExpr(
13956 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
13957 IsAddressOfOperand, RecoveryTSI);
13958 }
13959
13960 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
13961 if (getDerived().TransformTemplateArguments(
13962 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
13963 return ExprError();
13964
13965 return getDerived().RebuildDependentScopeDeclRefExpr(
13966 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
13967 RecoveryTSI);
13968}
13969
13970template<typename Derived>
13972TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
13973 // CXXConstructExprs other than for list-initialization and
13974 // CXXTemporaryObjectExpr are always implicit, so when we have
13975 // a 1-argument construction we just transform that argument.
13976 if (getDerived().AllowSkippingCXXConstructExpr() &&
13977 ((E->getNumArgs() == 1 ||
13978 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) &&
13979 (!getDerived().DropCallArgument(E->getArg(0))) &&
13980 !E->isListInitialization()))
13981 return getDerived().TransformInitializer(E->getArg(0),
13982 /*DirectInit*/ false);
13983
13984 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
13985
13986 QualType T = getDerived().TransformType(E->getType());
13987 if (T.isNull())
13988 return ExprError();
13989
13990 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
13991 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
13992 if (!Constructor)
13993 return ExprError();
13994
13995 bool ArgumentChanged = false;
13997 {
13998 EnterExpressionEvaluationContext Context(
14000 E->isListInitialization());
14001 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14002 &ArgumentChanged))
14003 return ExprError();
14004 }
14005
14006 if (!getDerived().AlwaysRebuild() &&
14007 T == E->getType() &&
14008 Constructor == E->getConstructor() &&
14009 !ArgumentChanged) {
14010 // Mark the constructor as referenced.
14011 // FIXME: Instantiation-specific
14012 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
14013 return E;
14014 }
14015
14016 return getDerived().RebuildCXXConstructExpr(
14017 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
14018 E->hadMultipleCandidates(), E->isListInitialization(),
14019 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
14020 E->getConstructionKind(), E->getParenOrBraceRange());
14021}
14022
14023template<typename Derived>
14024ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
14025 CXXInheritedCtorInitExpr *E) {
14026 QualType T = getDerived().TransformType(E->getType());
14027 if (T.isNull())
14028 return ExprError();
14029
14030 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
14031 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
14032 if (!Constructor)
14033 return ExprError();
14034
14035 if (!getDerived().AlwaysRebuild() &&
14036 T == E->getType() &&
14037 Constructor == E->getConstructor()) {
14038 // Mark the constructor as referenced.
14039 // FIXME: Instantiation-specific
14040 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
14041 return E;
14042 }
14043
14044 return getDerived().RebuildCXXInheritedCtorInitExpr(
14045 T, E->getLocation(), Constructor,
14046 E->constructsVBase(), E->inheritedFromVBase());
14047}
14048
14049/// Transform a C++ temporary-binding expression.
14050///
14051/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
14052/// transform the subexpression and return that.
14053template<typename Derived>
14055TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
14056 if (auto *Dtor = E->getTemporary()->getDestructor())
14057 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
14058 const_cast<CXXDestructorDecl *>(Dtor));
14059 return getDerived().TransformExpr(E->getSubExpr());
14060}
14061
14062/// Transform a C++ expression that contains cleanups that should
14063/// be run after the expression is evaluated.
14064///
14065/// Since ExprWithCleanups nodes are implicitly generated, we
14066/// just transform the subexpression and return that.
14067template<typename Derived>
14069TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
14070 return getDerived().TransformExpr(E->getSubExpr());
14071}
14072
14073template<typename Derived>
14075TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
14076 CXXTemporaryObjectExpr *E) {
14077 TypeSourceInfo *T =
14078 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
14079 if (!T)
14080 return ExprError();
14081
14082 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
14083 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
14084 if (!Constructor)
14085 return ExprError();
14086
14087 bool ArgumentChanged = false;
14089 Args.reserve(E->getNumArgs());
14090 {
14091 EnterExpressionEvaluationContext Context(
14093 E->isListInitialization());
14094 if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14095 &ArgumentChanged))
14096 return ExprError();
14097 }
14098
14099 if (!getDerived().AlwaysRebuild() &&
14100 T == E->getTypeSourceInfo() &&
14101 Constructor == E->getConstructor() &&
14102 !ArgumentChanged) {
14103 // FIXME: Instantiation-specific
14104 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
14105 return SemaRef.MaybeBindToTemporary(E);
14106 }
14107
14108 // FIXME: We should just pass E->isListInitialization(), but we're not
14109 // prepared to handle list-initialization without a child InitListExpr.
14110 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
14111 return getDerived().RebuildCXXTemporaryObjectExpr(
14112 T, LParenLoc, Args, E->getEndLoc(),
14113 /*ListInitialization=*/LParenLoc.isInvalid());
14114}
14115
14116template<typename Derived>
14118TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
14119 // Transform any init-capture expressions before entering the scope of the
14120 // lambda body, because they are not semantically within that scope.
14121 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
14122 struct TransformedInitCapture {
14123 // The location of the ... if the result is retaining a pack expansion.
14124 SourceLocation EllipsisLoc;
14125 // Zero or more expansions of the init-capture.
14127 };
14129 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
14130 for (LambdaExpr::capture_iterator C = E->capture_begin(),
14131 CEnd = E->capture_end();
14132 C != CEnd; ++C) {
14133 if (!E->isInitCapture(C))
14134 continue;
14135
14136 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
14137 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
14138
14139 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
14140 std::optional<unsigned> NumExpansions) {
14141 ExprResult NewExprInitResult = getDerived().TransformInitializer(
14142 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
14143
14144 if (NewExprInitResult.isInvalid()) {
14145 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
14146 return;
14147 }
14148 Expr *NewExprInit = NewExprInitResult.get();
14149
14150 QualType NewInitCaptureType =
14151 getSema().buildLambdaInitCaptureInitialization(
14152 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
14153 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
14154 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=
14156 NewExprInit);
14157 Result.Expansions.push_back(
14158 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
14159 };
14160
14161 // If this is an init-capture pack, consider expanding the pack now.
14162 if (OldVD->isParameterPack()) {
14163 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
14164 ->getTypeLoc()
14165 .castAs<PackExpansionTypeLoc>();
14167 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
14168
14169 // Determine whether the set of unexpanded parameter packs can and should
14170 // be expanded.
14171 bool Expand = true;
14172 bool RetainExpansion = false;
14173 std::optional<unsigned> OrigNumExpansions =
14174 ExpansionTL.getTypePtr()->getNumExpansions();
14175 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14176 if (getDerived().TryExpandParameterPacks(
14177 ExpansionTL.getEllipsisLoc(),
14178 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
14179 RetainExpansion, NumExpansions))
14180 return ExprError();
14181 if (Expand) {
14182 for (unsigned I = 0; I != *NumExpansions; ++I) {
14183 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14184 SubstInitCapture(SourceLocation(), std::nullopt);
14185 }
14186 }
14187 if (!Expand || RetainExpansion) {
14188 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14189 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
14190 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
14191 }
14192 } else {
14193 SubstInitCapture(SourceLocation(), std::nullopt);
14194 }
14195 }
14196
14197 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
14198 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
14199
14200 // Create the local class that will describe the lambda.
14201
14202 // FIXME: DependencyKind below is wrong when substituting inside a templated
14203 // context that isn't a DeclContext (such as a variable template), or when
14204 // substituting an unevaluated lambda inside of a function's parameter's type
14205 // - as parameter types are not instantiated from within a function's DC. We
14206 // use evaluation contexts to distinguish the function parameter case.
14209 DeclContext *DC = getSema().CurContext;
14210 // A RequiresExprBodyDecl is not interesting for dependencies.
14211 // For the following case,
14212 //
14213 // template <typename>
14214 // concept C = requires { [] {}; };
14215 //
14216 // template <class F>
14217 // struct Widget;
14218 //
14219 // template <C F>
14220 // struct Widget<F> {};
14221 //
14222 // While we are substituting Widget<F>, the parent of DC would be
14223 // the template specialization itself. Thus, the lambda expression
14224 // will be deemed as dependent even if there are no dependent template
14225 // arguments.
14226 // (A ClassTemplateSpecializationDecl is always a dependent context.)
14227 while (DC->getDeclKind() == Decl::Kind::RequiresExprBody)
14228 DC = DC->getParent();
14229 if ((getSema().isUnevaluatedContext() ||
14230 getSema().isConstantEvaluatedContext()) &&
14231 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
14232 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
14233
14234 CXXRecordDecl *OldClass = E->getLambdaClass();
14235 CXXRecordDecl *Class = getSema().createLambdaClosureType(
14236 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
14237 E->getCaptureDefault());
14238 getDerived().transformedLocalDecl(OldClass, {Class});
14239
14240 CXXMethodDecl *NewCallOperator =
14241 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
14242 NewCallOperator->setLexicalDeclContext(getSema().CurContext);
14243
14244 // Enter the scope of the lambda.
14245 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
14246 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
14247 E->hasExplicitParameters(), E->isMutable());
14248
14249 // Introduce the context of the call operator.
14250 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
14251 /*NewThisContext*/false);
14252
14253 bool Invalid = false;
14254
14255 // Transform captures.
14256 for (LambdaExpr::capture_iterator C = E->capture_begin(),
14257 CEnd = E->capture_end();
14258 C != CEnd; ++C) {
14259 // When we hit the first implicit capture, tell Sema that we've finished
14260 // the list of explicit captures.
14261 if (C->isImplicit())
14262 break;
14263
14264 // Capturing 'this' is trivial.
14265 if (C->capturesThis()) {
14266 // If this is a lambda that is part of a default member initialiser
14267 // and which we're instantiating outside the class that 'this' is
14268 // supposed to refer to, adjust the type of 'this' accordingly.
14269 //
14270 // Otherwise, leave the type of 'this' as-is.
14271 Sema::CXXThisScopeRAII ThisScope(
14272 getSema(),
14273 dyn_cast_if_present<CXXRecordDecl>(
14274 getSema().getFunctionLevelDeclContext()),
14275 Qualifiers());
14276 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
14277 /*BuildAndDiagnose*/ true, nullptr,
14278 C->getCaptureKind() == LCK_StarThis);
14279 continue;
14280 }
14281 // Captured expression will be recaptured during captured variables
14282 // rebuilding.
14283 if (C->capturesVLAType())
14284 continue;
14285
14286 // Rebuild init-captures, including the implied field declaration.
14287 if (E->isInitCapture(C)) {
14288 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
14289
14290 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
14292
14293 for (InitCaptureInfoTy &Info : NewC.Expansions) {
14294 ExprResult Init = Info.first;
14295 QualType InitQualType = Info.second;
14296 if (Init.isInvalid() || InitQualType.isNull()) {
14297 Invalid = true;
14298 break;
14299 }
14300 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
14301 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
14302 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
14303 getSema().CurContext);
14304 if (!NewVD) {
14305 Invalid = true;
14306 break;
14307 }
14308 NewVDs.push_back(NewVD);
14309 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
14310 }
14311
14312 if (Invalid)
14313 break;
14314
14315 getDerived().transformedLocalDecl(OldVD, NewVDs);
14316 continue;
14317 }
14318
14319 assert(C->capturesVariable() && "unexpected kind of lambda capture");
14320
14321 // Determine the capture kind for Sema.
14323 = C->isImplicit()? Sema::TryCapture_Implicit
14324 : C->getCaptureKind() == LCK_ByCopy
14327 SourceLocation EllipsisLoc;
14328 if (C->isPackExpansion()) {
14329 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
14330 bool ShouldExpand = false;
14331 bool RetainExpansion = false;
14332 std::optional<unsigned> NumExpansions;
14333 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
14334 C->getLocation(),
14335 Unexpanded,
14336 ShouldExpand, RetainExpansion,
14337 NumExpansions)) {
14338 Invalid = true;
14339 continue;
14340 }
14341
14342 if (ShouldExpand) {
14343 // The transform has determined that we should perform an expansion;
14344 // transform and capture each of the arguments.
14345 // expansion of the pattern. Do so.
14346 auto *Pack = cast<VarDecl>(C->getCapturedVar());
14347 for (unsigned I = 0; I != *NumExpansions; ++I) {
14348 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14349 VarDecl *CapturedVar
14350 = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
14351 Pack));
14352 if (!CapturedVar) {
14353 Invalid = true;
14354 continue;
14355 }
14356
14357 // Capture the transformed variable.
14358 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
14359 }
14360
14361 // FIXME: Retain a pack expansion if RetainExpansion is true.
14362
14363 continue;
14364 }
14365
14366 EllipsisLoc = C->getEllipsisLoc();
14367 }
14368
14369 // Transform the captured variable.
14370 auto *CapturedVar = cast_or_null<ValueDecl>(
14371 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
14372 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
14373 Invalid = true;
14374 continue;
14375 }
14376
14377 // Capture the transformed variable.
14378 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
14379 EllipsisLoc);
14380 }
14381 getSema().finishLambdaExplicitCaptures(LSI);
14382
14383 // Transform the template parameters, and add them to the current
14384 // instantiation scope. The null case is handled correctly.
14385 auto TPL = getDerived().TransformTemplateParameterList(
14386 E->getTemplateParameterList());
14387 LSI->GLTemplateParameterList = TPL;
14388 if (TPL)
14389 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
14390 TPL);
14391
14392 // Transform the type of the original lambda's call operator.
14393 // The transformation MUST be done in the CurrentInstantiationScope since
14394 // it introduces a mapping of the original to the newly created
14395 // transformed parameters.
14396 TypeSourceInfo *NewCallOpTSI = nullptr;
14397 {
14398 auto OldCallOpTypeLoc =
14399 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
14400
14401 auto TransformFunctionProtoTypeLoc =
14402 [this](TypeLocBuilder &TLB, FunctionProtoTypeLoc FPTL) -> QualType {
14403 SmallVector<QualType, 4> ExceptionStorage;
14404 return this->TransformFunctionProtoType(
14405 TLB, FPTL, nullptr, Qualifiers(),
14406 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
14407 return TransformExceptionSpec(FPTL.getBeginLoc(), ESI,
14408 ExceptionStorage, Changed);
14409 });
14410 };
14411
14412 QualType NewCallOpType;
14413 TypeLocBuilder NewCallOpTLBuilder;
14414
14415 if (auto ATL = OldCallOpTypeLoc.getAs<AttributedTypeLoc>()) {
14416 NewCallOpType = this->TransformAttributedType(
14417 NewCallOpTLBuilder, ATL,
14418 [&](TypeLocBuilder &TLB, TypeLoc TL) -> QualType {
14419 return TransformFunctionProtoTypeLoc(
14420 TLB, TL.castAs<FunctionProtoTypeLoc>());
14421 });
14422 } else {
14423 auto FPTL = OldCallOpTypeLoc.castAs<FunctionProtoTypeLoc>();
14424 NewCallOpType = TransformFunctionProtoTypeLoc(NewCallOpTLBuilder, FPTL);
14425 }
14426
14427 if (NewCallOpType.isNull())
14428 return ExprError();
14429 NewCallOpTSI =
14430 NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
14431 }
14432
14434 if (auto ATL = NewCallOpTSI->getTypeLoc().getAs<AttributedTypeLoc>()) {
14435 Params = ATL.getModifiedLoc().castAs<FunctionProtoTypeLoc>().getParams();
14436 } else {
14437 auto FPTL = NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>();
14438 Params = FPTL.getParams();
14439 }
14440
14441 getSema().CompleteLambdaCallOperator(
14442 NewCallOperator, E->getCallOperator()->getLocation(),
14443 E->getCallOperator()->getInnerLocStart(),
14444 E->getCallOperator()->getTrailingRequiresClause(), NewCallOpTSI,
14445 E->getCallOperator()->getConstexprKind(),
14446 E->getCallOperator()->getStorageClass(), Params,
14447 E->hasExplicitResultType());
14448
14449 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
14450 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
14451
14452 {
14453 // Number the lambda for linkage purposes if necessary.
14454 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
14455
14456 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
14457 if (getDerived().ReplacingOriginal()) {
14458 Numbering = OldClass->getLambdaNumbering();
14459 }
14460
14461 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
14462 }
14463
14464 // FIXME: Sema's lambda-building mechanism expects us to push an expression
14465 // evaluation context even if we're not transforming the function body.
14466 getSema().PushExpressionEvaluationContext(
14467 E->getCallOperator()->isConsteval() ?
14470
14471 Sema::CodeSynthesisContext C;
14473 C.PointOfInstantiation = E->getBody()->getBeginLoc();
14474 getSema().pushCodeSynthesisContext(C);
14475
14476 // Instantiate the body of the lambda expression.
14477 StmtResult Body =
14478 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
14479
14480 getSema().popCodeSynthesisContext();
14481
14482 // ActOnLambda* will pop the function scope for us.
14483 FuncScopeCleanup.disable();
14484
14485 if (Body.isInvalid()) {
14486 SavedContext.pop();
14487 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
14488 /*IsInstantiation=*/true);
14489 return ExprError();
14490 }
14491
14492 // Copy the LSI before ActOnFinishFunctionBody removes it.
14493 // FIXME: This is dumb. Store the lambda information somewhere that outlives
14494 // the call operator.
14495 auto LSICopy = *LSI;
14496 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
14497 /*IsInstantiation*/ true);
14498 SavedContext.pop();
14499
14500 // Recompute the dependency of the lambda so that we can defer the lambda call
14501 // construction until after we have all the necessary template arguments. For
14502 // example, given
14503 //
14504 // template <class> struct S {
14505 // template <class U>
14506 // using Type = decltype([](U){}(42.0));
14507 // };
14508 // void foo() {
14509 // using T = S<int>::Type<float>;
14510 // ^~~~~~
14511 // }
14512 //
14513 // We would end up here from instantiating S<int> when ensuring its
14514 // completeness. That would transform the lambda call expression regardless of
14515 // the absence of the corresponding argument for U.
14516 //
14517 // Going ahead with unsubstituted type U makes things worse: we would soon
14518 // compare the argument type (which is float) against the parameter U
14519 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
14520 // error suggesting unmatched types 'U' and 'float'!
14521 //
14522 // That said, everything will be fine if we defer that semantic checking.
14523 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
14524 // dependent. Since the CallExpr's dependency boils down to the lambda's
14525 // dependency in this case, we can harness that by recomputing the dependency
14526 // from the instantiation arguments.
14527 //
14528 // FIXME: Creating the type of a lambda requires us to have a dependency
14529 // value, which happens before its substitution. We update its dependency
14530 // *after* the substitution in case we can't decide the dependency
14531 // so early, e.g. because we want to see if any of the *substituted*
14532 // parameters are dependent.
14533 DependencyKind = getDerived().ComputeLambdaDependency(&LSICopy);
14534 Class->setLambdaDependencyKind(DependencyKind);
14535 // Clean up the type cache created previously. Then, we re-create a type for
14536 // such Decl with the new DependencyKind.
14537 Class->setTypeForDecl(nullptr);
14538 getSema().Context.getTypeDeclType(Class);
14539
14540 return getSema().BuildLambdaExpr(E->getBeginLoc(), Body.get()->getEndLoc(),
14541 &LSICopy);
14542}
14543
14544template<typename Derived>
14547 return TransformStmt(S);
14548}
14549
14550template<typename Derived>
14553 // Transform captures.
14555 CEnd = E->capture_end();
14556 C != CEnd; ++C) {
14557 // When we hit the first implicit capture, tell Sema that we've finished
14558 // the list of explicit captures.
14559 if (!C->isImplicit())
14560 continue;
14561
14562 // Capturing 'this' is trivial.
14563 if (C->capturesThis()) {
14564 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
14565 /*BuildAndDiagnose*/ true, nullptr,
14566 C->getCaptureKind() == LCK_StarThis);
14567 continue;
14568 }
14569 // Captured expression will be recaptured during captured variables
14570 // rebuilding.
14571 if (C->capturesVLAType())
14572 continue;
14573
14574 assert(C->capturesVariable() && "unexpected kind of lambda capture");
14575 assert(!E->isInitCapture(C) && "implicit init-capture?");
14576
14577 // Transform the captured variable.
14578 VarDecl *CapturedVar = cast_or_null<VarDecl>(
14579 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
14580 if (!CapturedVar || CapturedVar->isInvalidDecl())
14581 return StmtError();
14582
14583 // Capture the transformed variable.
14584 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
14585 }
14586
14587 return S;
14588}
14589
14590template<typename Derived>
14594 TypeSourceInfo *T =
14595 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
14596 if (!T)
14597 return ExprError();
14598
14599 bool ArgumentChanged = false;
14601 Args.reserve(E->getNumArgs());
14602 {
14606 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
14607 &ArgumentChanged))
14608 return ExprError();
14609 }
14610
14611 if (!getDerived().AlwaysRebuild() &&
14612 T == E->getTypeSourceInfo() &&
14613 !ArgumentChanged)
14614 return E;
14615
14616 // FIXME: we're faking the locations of the commas
14617 return getDerived().RebuildCXXUnresolvedConstructExpr(
14618 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
14619}
14620
14621template<typename Derived>
14623TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
14624 CXXDependentScopeMemberExpr *E) {
14625 // Transform the base of the expression.
14626 ExprResult Base((Expr*) nullptr);
14627 Expr *OldBase;
14628 QualType BaseType;
14629 QualType ObjectType;
14630 if (!E->isImplicitAccess()) {
14631 OldBase = E->getBase();
14632 Base = getDerived().TransformExpr(OldBase);
14633 if (Base.isInvalid())
14634 return ExprError();
14635
14636 // Start the member reference and compute the object's type.
14637 ParsedType ObjectTy;
14638 bool MayBePseudoDestructor = false;
14639 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),
14640 E->getOperatorLoc(),
14641 E->isArrow()? tok::arrow : tok::period,
14642 ObjectTy,
14643 MayBePseudoDestructor);
14644 if (Base.isInvalid())
14645 return ExprError();
14646
14647 ObjectType = ObjectTy.get();
14648 BaseType = ((Expr*) Base.get())->getType();
14649 } else {
14650 OldBase = nullptr;
14651 BaseType = getDerived().TransformType(E->getBaseType());
14652 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
14653 }
14654
14655 // Transform the first part of the nested-name-specifier that qualifies
14656 // the member name.
14657 NamedDecl *FirstQualifierInScope
14658 = getDerived().TransformFirstQualifierInScope(
14659 E->getFirstQualifierFoundInScope(),
14660 E->getQualifierLoc().getBeginLoc());
14661
14662 NestedNameSpecifierLoc QualifierLoc;
14663 if (E->getQualifier()) {
14664 QualifierLoc
14665 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
14666 ObjectType,
14667 FirstQualifierInScope);
14668 if (!QualifierLoc)
14669 return ExprError();
14670 }
14671
14672 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
14673
14674 // TODO: If this is a conversion-function-id, verify that the
14675 // destination type name (if present) resolves the same way after
14676 // instantiation as it did in the local scope.
14677
14678 DeclarationNameInfo NameInfo
14679 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
14680 if (!NameInfo.getName())
14681 return ExprError();
14682
14683 if (!E->hasExplicitTemplateArgs()) {
14684 // This is a reference to a member without an explicitly-specified
14685 // template argument list. Optimize for this common case.
14686 if (!getDerived().AlwaysRebuild() &&
14687 Base.get() == OldBase &&
14688 BaseType == E->getBaseType() &&
14689 QualifierLoc == E->getQualifierLoc() &&
14690 NameInfo.getName() == E->getMember() &&
14691 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
14692 return E;
14693
14694 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
14695 BaseType,
14696 E->isArrow(),
14697 E->getOperatorLoc(),
14698 QualifierLoc,
14699 TemplateKWLoc,
14700 FirstQualifierInScope,
14701 NameInfo,
14702 /*TemplateArgs*/nullptr);
14703 }
14704
14705 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
14706 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
14707 E->getNumTemplateArgs(),
14708 TransArgs))
14709 return ExprError();
14710
14711 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
14712 BaseType,
14713 E->isArrow(),
14714 E->getOperatorLoc(),
14715 QualifierLoc,
14716 TemplateKWLoc,
14717 FirstQualifierInScope,
14718 NameInfo,
14719 &TransArgs);
14720}
14721
14722template <typename Derived>
14723ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
14724 UnresolvedMemberExpr *Old) {
14725 // Transform the base of the expression.
14726 ExprResult Base((Expr *)nullptr);
14727 QualType BaseType;
14728 if (!Old->isImplicitAccess()) {
14729 Base = getDerived().TransformExpr(Old->getBase());
14730 if (Base.isInvalid())
14731 return ExprError();
14732 Base =
14733 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
14734 if (Base.isInvalid())
14735 return ExprError();
14736 BaseType = Base.get()->getType();
14737 } else {
14738 BaseType = getDerived().TransformType(Old->getBaseType());
14739 }
14740
14741 NestedNameSpecifierLoc QualifierLoc;
14742 if (Old->getQualifierLoc()) {
14743 QualifierLoc =
14744 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
14745 if (!QualifierLoc)
14746 return ExprError();
14747 }
14748
14749 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
14750
14751 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
14752
14753 // Transform the declaration set.
14754 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ false, R))
14755 return ExprError();
14756
14757 // Determine the naming class.
14758 if (Old->getNamingClass()) {
14759 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
14760 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
14761 if (!NamingClass)
14762 return ExprError();
14763
14764 R.setNamingClass(NamingClass);
14765 }
14766
14767 TemplateArgumentListInfo TransArgs;
14768 if (Old->hasExplicitTemplateArgs()) {
14769 TransArgs.setLAngleLoc(Old->getLAngleLoc());
14770 TransArgs.setRAngleLoc(Old->getRAngleLoc());
14771 if (getDerived().TransformTemplateArguments(
14772 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
14773 return ExprError();
14774 }
14775
14776 // FIXME: to do this check properly, we will need to preserve the
14777 // first-qualifier-in-scope here, just in case we had a dependent
14778 // base (and therefore couldn't do the check) and a
14779 // nested-name-qualifier (and therefore could do the lookup).
14780 NamedDecl *FirstQualifierInScope = nullptr;
14781
14782 return getDerived().RebuildUnresolvedMemberExpr(
14783 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
14784 TemplateKWLoc, FirstQualifierInScope, R,
14785 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
14786}
14787
14788template<typename Derived>
14790TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
14791 EnterExpressionEvaluationContext Unevaluated(
14793 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
14794 if (SubExpr.isInvalid())
14795 return ExprError();
14796
14797 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
14798 return E;
14799
14800 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
14801}
14802
14803template<typename Derived>
14805TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
14806 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
14807 if (Pattern.isInvalid())
14808 return ExprError();
14809
14810 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
14811 return E;
14812
14813 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
14814 E->getNumExpansions());
14815}
14816
14817template<typename Derived>
14819TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
14820 // If E is not value-dependent, then nothing will change when we transform it.
14821 // Note: This is an instantiation-centric view.
14822 if (!E->isValueDependent())
14823 return E;
14824
14825 EnterExpressionEvaluationContext Unevaluated(
14827
14829 TemplateArgument ArgStorage;
14830
14831 // Find the argument list to transform.
14832 if (E->isPartiallySubstituted()) {
14833 PackArgs = E->getPartialArguments();
14834 } else if (E->isValueDependent()) {
14835 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
14836 bool ShouldExpand = false;
14837 bool RetainExpansion = false;
14838 std::optional<unsigned> NumExpansions;
14839 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
14840 Unexpanded,
14841 ShouldExpand, RetainExpansion,
14842 NumExpansions))
14843 return ExprError();
14844
14845 // If we need to expand the pack, build a template argument from it and
14846 // expand that.
14847 if (ShouldExpand) {
14848 auto *Pack = E->getPack();
14849 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) {
14850 ArgStorage = getSema().Context.getPackExpansionType(
14851 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
14852 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {
14853 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
14854 } else {
14855 auto *VD = cast<ValueDecl>(Pack);
14856 ExprResult DRE = getSema().BuildDeclRefExpr(
14857 VD, VD->getType().getNonLValueExprType(getSema().Context),
14858 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
14859 E->getPackLoc());
14860 if (DRE.isInvalid())
14861 return ExprError();
14862 ArgStorage = new (getSema().Context)
14863 PackExpansionExpr(getSema().Context.DependentTy, DRE.get(),
14864 E->getPackLoc(), std::nullopt);
14865 }
14866 PackArgs = ArgStorage;
14867 }
14868 }
14869
14870 // If we're not expanding the pack, just transform the decl.
14871 if (!PackArgs.size()) {
14872 auto *Pack = cast_or_null<NamedDecl>(
14873 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
14874 if (!Pack)
14875 return ExprError();
14876 return getDerived().RebuildSizeOfPackExpr(
14877 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
14878 std::nullopt, std::nullopt);
14879 }
14880
14881 // Try to compute the result without performing a partial substitution.
14882 std::optional<unsigned> Result = 0;
14883 for (const TemplateArgument &Arg : PackArgs) {
14884 if (!Arg.isPackExpansion()) {
14885 Result = *Result + 1;
14886 continue;
14887 }
14888
14889 TemplateArgumentLoc ArgLoc;
14890 InventTemplateArgumentLoc(Arg, ArgLoc);
14891
14892 // Find the pattern of the pack expansion.
14893 SourceLocation Ellipsis;
14894 std::optional<unsigned> OrigNumExpansions;
14895 TemplateArgumentLoc Pattern =
14896 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
14897 OrigNumExpansions);
14898
14899 // Substitute under the pack expansion. Do not expand the pack (yet).
14900 TemplateArgumentLoc OutPattern;
14901 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14902 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
14903 /*Uneval*/ true))
14904 return true;
14905
14906 // See if we can determine the number of arguments from the result.
14907 std::optional<unsigned> NumExpansions =
14908 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
14909 if (!NumExpansions) {
14910 // No: we must be in an alias template expansion, and we're going to need
14911 // to actually expand the packs.
14912 Result = std::nullopt;
14913 break;
14914 }
14915
14916 Result = *Result + *NumExpansions;
14917 }
14918
14919 // Common case: we could determine the number of expansions without
14920 // substituting.
14921 if (Result)
14922 return getDerived().RebuildSizeOfPackExpr(
14923 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
14924 *Result, std::nullopt);
14925
14926 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
14927 E->getPackLoc());
14928 {
14929 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
14930 typedef TemplateArgumentLocInventIterator<
14931 Derived, const TemplateArgument*> PackLocIterator;
14932 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
14933 PackLocIterator(*this, PackArgs.end()),
14934 TransformedPackArgs, /*Uneval*/true))
14935 return ExprError();
14936 }
14937
14938 // Check whether we managed to fully-expand the pack.
14939 // FIXME: Is it possible for us to do so and not hit the early exit path?
14941 bool PartialSubstitution = false;
14942 for (auto &Loc : TransformedPackArgs.arguments()) {
14943 Args.push_back(Loc.getArgument());
14944 if (Loc.getArgument().isPackExpansion())
14945 PartialSubstitution = true;
14946 }
14947
14948 if (PartialSubstitution)
14949 return getDerived().RebuildSizeOfPackExpr(
14950 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
14951 std::nullopt, Args);
14952
14953 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
14954 E->getPackLoc(), E->getRParenLoc(),
14955 Args.size(), std::nullopt);
14956}
14957
14958template <typename Derived>
14960TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
14961 if (!E->isValueDependent())
14962 return E;
14963
14964 // Transform the index
14965 ExprResult IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
14966 if (IndexExpr.isInvalid())
14967 return ExprError();
14968
14969 SmallVector<Expr *, 5> ExpandedExprs;
14970 if (E->getExpressions().empty()) {
14971 Expr *Pattern = E->getPackIdExpression();
14973 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
14974 Unexpanded);
14975 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
14976
14977 // Determine whether the set of unexpanded parameter packs can and should
14978 // be expanded.
14979 bool ShouldExpand = true;
14980 bool RetainExpansion = false;
14981 std::optional<unsigned> OrigNumExpansions;
14982 std::optional<unsigned> NumExpansions = OrigNumExpansions;
14983 if (getDerived().TryExpandParameterPacks(
14984 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
14985 ShouldExpand, RetainExpansion, NumExpansions))
14986 return true;
14987 if (!ShouldExpand) {
14988 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
14989 ExprResult Pack = getDerived().TransformExpr(Pattern);
14990 if (Pack.isInvalid())
14991 return ExprError();
14992 return getDerived().RebuildPackIndexingExpr(
14993 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
14994 std::nullopt);
14995 }
14996 for (unsigned I = 0; I != *NumExpansions; ++I) {
14997 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
14998 ExprResult Out = getDerived().TransformExpr(Pattern);
14999 if (Out.isInvalid())
15000 return true;
15001 if (Out.get()->containsUnexpandedParameterPack()) {
15002 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
15003 OrigNumExpansions);
15004 if (Out.isInvalid())
15005 return true;
15006 }
15007 ExpandedExprs.push_back(Out.get());
15008 }
15009 // If we're supposed to retain a pack expansion, do so by temporarily
15010 // forgetting the partially-substituted parameter pack.
15011 if (RetainExpansion) {
15012 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15013
15014 ExprResult Out = getDerived().TransformExpr(Pattern);
15015 if (Out.isInvalid())
15016 return true;
15017
15018 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
15019 OrigNumExpansions);
15020 if (Out.isInvalid())
15021 return true;
15022 ExpandedExprs.push_back(Out.get());
15023 }
15024 }
15025
15026 else {
15027 if (getDerived().TransformExprs(E->getExpressions().data(),
15028 E->getExpressions().size(), false,
15029 ExpandedExprs))
15030 return ExprError();
15031 }
15032
15033 return getDerived().RebuildPackIndexingExpr(
15034 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
15035 IndexExpr.get(), ExpandedExprs,
15036 /*EmptyPack=*/ExpandedExprs.size() == 0);
15037}
15038
15039template<typename Derived>
15041TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
15042 SubstNonTypeTemplateParmPackExpr *E) {
15043 // Default behavior is to do nothing with this transformation.
15044 return E;
15045}
15046
15047template<typename Derived>
15049TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
15050 SubstNonTypeTemplateParmExpr *E) {
15051 // Default behavior is to do nothing with this transformation.
15052 return E;
15053}
15054
15055template<typename Derived>
15057TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
15058 // Default behavior is to do nothing with this transformation.
15059 return E;
15060}
15061
15062template<typename Derived>
15064TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
15065 MaterializeTemporaryExpr *E) {
15066 return getDerived().TransformExpr(E->getSubExpr());
15067}
15068
15069template<typename Derived>
15071TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
15072 UnresolvedLookupExpr *Callee = nullptr;
15073 if (Expr *OldCallee = E->getCallee()) {
15074 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
15075 if (CalleeResult.isInvalid())
15076 return ExprError();
15077 Callee = cast<UnresolvedLookupExpr>(CalleeResult.get());
15078 }
15079
15080 Expr *Pattern = E->getPattern();
15081
15083 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
15084 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
15085
15086 // Determine whether the set of unexpanded parameter packs can and should
15087 // be expanded.
15088 bool Expand = true;
15089 bool RetainExpansion = false;
15090 std::optional<unsigned> OrigNumExpansions = E->getNumExpansions(),
15091 NumExpansions = OrigNumExpansions;
15092 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
15093 Pattern->getSourceRange(),
15094 Unexpanded,
15095 Expand, RetainExpansion,
15096 NumExpansions))
15097 return true;
15098
15099 if (!Expand) {
15100 // Do not expand any packs here, just transform and rebuild a fold
15101 // expression.
15102 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15103
15104 ExprResult LHS =
15105 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
15106 if (LHS.isInvalid())
15107 return true;
15108
15109 ExprResult RHS =
15110 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
15111 if (RHS.isInvalid())
15112 return true;
15113
15114 if (!getDerived().AlwaysRebuild() &&
15115 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
15116 return E;
15117
15118 return getDerived().RebuildCXXFoldExpr(
15119 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
15120 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
15121 }
15122
15123 // Formally a fold expression expands to nested parenthesized expressions.
15124 // Enforce this limit to avoid creating trees so deep we can't safely traverse
15125 // them.
15126 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < NumExpansions) {
15127 SemaRef.Diag(E->getEllipsisLoc(),
15128 clang::diag::err_fold_expression_limit_exceeded)
15129 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
15130 << E->getSourceRange();
15131 SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);
15132 return ExprError();
15133 }
15134
15135 // The transform has determined that we should perform an elementwise
15136 // expansion of the pattern. Do so.
15137 ExprResult Result = getDerived().TransformExpr(E->getInit());
15138 if (Result.isInvalid())
15139 return true;
15140 bool LeftFold = E->isLeftFold();
15141
15142 // If we're retaining an expansion for a right fold, it is the innermost
15143 // component and takes the init (if any).
15144 if (!LeftFold && RetainExpansion) {
15145 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15146
15147 ExprResult Out = getDerived().TransformExpr(Pattern);
15148 if (Out.isInvalid())
15149 return true;
15150
15151 Result = getDerived().RebuildCXXFoldExpr(
15152 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
15153 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
15154 if (Result.isInvalid())
15155 return true;
15156 }
15157
15158 for (unsigned I = 0; I != *NumExpansions; ++I) {
15159 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(
15160 getSema(), LeftFold ? I : *NumExpansions - I - 1);
15161 ExprResult Out = getDerived().TransformExpr(Pattern);
15162 if (Out.isInvalid())
15163 return true;
15164
15165 if (Out.get()->containsUnexpandedParameterPack()) {
15166 // We still have a pack; retain a pack expansion for this slice.
15167 Result = getDerived().RebuildCXXFoldExpr(
15168 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
15169 E->getOperator(), E->getEllipsisLoc(),
15170 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
15171 OrigNumExpansions);
15172 } else if (Result.isUsable()) {
15173 // We've got down to a single element; build a binary operator.
15174 Expr *LHS = LeftFold ? Result.get() : Out.get();
15175 Expr *RHS = LeftFold ? Out.get() : Result.get();
15176 if (Callee) {
15177 UnresolvedSet<16> Functions;
15178 Functions.append(Callee->decls_begin(), Callee->decls_end());
15179 Result = getDerived().RebuildCXXOperatorCallExpr(
15180 BinaryOperator::getOverloadedOperator(E->getOperator()),
15181 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
15182 Functions, LHS, RHS);
15183 } else {
15184 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
15185 E->getOperator(), LHS, RHS);
15186 }
15187 } else
15188 Result = Out;
15189
15190 if (Result.isInvalid())
15191 return true;
15192 }
15193
15194 // If we're retaining an expansion for a left fold, it is the outermost
15195 // component and takes the complete expansion so far as its init (if any).
15196 if (LeftFold && RetainExpansion) {
15197 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15198
15199 ExprResult Out = getDerived().TransformExpr(Pattern);
15200 if (Out.isInvalid())
15201 return true;
15202
15203 Result = getDerived().RebuildCXXFoldExpr(
15204 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
15205 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
15206 if (Result.isInvalid())
15207 return true;
15208 }
15209
15210 // If we had no init and an empty pack, and we're not retaining an expansion,
15211 // then produce a fallback value or error.
15212 if (Result.isUnset())
15213 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
15214 E->getOperator());
15215
15216 return Result;
15217}
15218
15219template <typename Derived>
15221TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
15222 SmallVector<Expr *, 4> TransformedInits;
15223 ArrayRef<Expr *> InitExprs = E->getInitExprs();
15224 if (TransformExprs(InitExprs.data(), InitExprs.size(), true,
15225 TransformedInits))
15226 return ExprError();
15227
15228 return getDerived().RebuildParenListExpr(E->getBeginLoc(), TransformedInits,
15229 E->getEndLoc());
15230}
15231
15232template<typename Derived>
15234TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
15235 CXXStdInitializerListExpr *E) {
15236 return getDerived().TransformExpr(E->getSubExpr());
15237}
15238
15239template<typename Derived>
15241TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
15242 return SemaRef.MaybeBindToTemporary(E);
15243}
15244
15245template<typename Derived>
15247TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
15248 return E;
15249}
15250
15251template<typename Derived>
15253TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
15254 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
15255 if (SubExpr.isInvalid())
15256 return ExprError();
15257
15258 if (!getDerived().AlwaysRebuild() &&
15259 SubExpr.get() == E->getSubExpr())
15260 return E;
15261
15262 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
15263}
15264
15265template<typename Derived>
15267TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
15268 // Transform each of the elements.
15269 SmallVector<Expr *, 8> Elements;
15270 bool ArgChanged = false;
15271 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
15272 /*IsCall=*/false, Elements, &ArgChanged))
15273 return ExprError();
15274
15275 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15276 return SemaRef.MaybeBindToTemporary(E);
15277
15278 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
15279 Elements.data(),
15280 Elements.size());
15281}
15282
15283template<typename Derived>
15285TreeTransform<Derived>::TransformObjCDictionaryLiteral(
15286 ObjCDictionaryLiteral *E) {
15287 // Transform each of the elements.
15289 bool ArgChanged = false;
15290 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
15291 ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);
15292
15293 if (OrigElement.isPackExpansion()) {
15294 // This key/value element is a pack expansion.
15296 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
15297 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
15298 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
15299
15300 // Determine whether the set of unexpanded parameter packs can
15301 // and should be expanded.
15302 bool Expand = true;
15303 bool RetainExpansion = false;
15304 std::optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
15305 std::optional<unsigned> NumExpansions = OrigNumExpansions;
15306 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
15307 OrigElement.Value->getEndLoc());
15308 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
15309 PatternRange, Unexpanded, Expand,
15310 RetainExpansion, NumExpansions))
15311 return ExprError();
15312
15313 if (!Expand) {
15314 // The transform has determined that we should perform a simple
15315 // transformation on the pack expansion, producing another pack
15316 // expansion.
15317 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
15318 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15319 if (Key.isInvalid())
15320 return ExprError();
15321
15322 if (Key.get() != OrigElement.Key)
15323 ArgChanged = true;
15324
15325 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
15326 if (Value.isInvalid())
15327 return ExprError();
15328
15329 if (Value.get() != OrigElement.Value)
15330 ArgChanged = true;
15331
15332 ObjCDictionaryElement Expansion = {
15333 Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions
15334 };
15335 Elements.push_back(Expansion);
15336 continue;
15337 }
15338
15339 // Record right away that the argument was changed. This needs
15340 // to happen even if the array expands to nothing.
15341 ArgChanged = true;
15342
15343 // The transform has determined that we should perform an elementwise
15344 // expansion of the pattern. Do so.
15345 for (unsigned I = 0; I != *NumExpansions; ++I) {
15346 Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
15347 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15348 if (Key.isInvalid())
15349 return ExprError();
15350
15351 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
15352 if (Value.isInvalid())
15353 return ExprError();
15354
15355 ObjCDictionaryElement Element = {
15356 Key.get(), Value.get(), SourceLocation(), NumExpansions
15357 };
15358
15359 // If any unexpanded parameter packs remain, we still have a
15360 // pack expansion.
15361 // FIXME: Can this really happen?
15362 if (Key.get()->containsUnexpandedParameterPack() ||
15363 Value.get()->containsUnexpandedParameterPack())
15364 Element.EllipsisLoc = OrigElement.EllipsisLoc;
15365
15366 Elements.push_back(Element);
15367 }
15368
15369 // FIXME: Retain a pack expansion if RetainExpansion is true.
15370
15371 // We've finished with this pack expansion.
15372 continue;
15373 }
15374
15375 // Transform and check key.
15376 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
15377 if (Key.isInvalid())
15378 return ExprError();
15379
15380 if (Key.get() != OrigElement.Key)
15381 ArgChanged = true;
15382
15383 // Transform and check value.
15385 = getDerived().TransformExpr(OrigElement.Value);
15386 if (Value.isInvalid())
15387 return ExprError();
15388
15389 if (Value.get() != OrigElement.Value)
15390 ArgChanged = true;
15391
15392 ObjCDictionaryElement Element = {Key.get(), Value.get(), SourceLocation(),
15393 std::nullopt};
15394 Elements.push_back(Element);
15395 }
15396
15397 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15398 return SemaRef.MaybeBindToTemporary(E);
15399
15400 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
15401 Elements);
15402}
15403
15404template<typename Derived>
15406TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
15407 TypeSourceInfo *EncodedTypeInfo
15408 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
15409 if (!EncodedTypeInfo)
15410 return ExprError();
15411
15412 if (!getDerived().AlwaysRebuild() &&
15413 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
15414 return E;
15415
15416 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
15417 EncodedTypeInfo,
15418 E->getRParenLoc());
15419}
15420
15421template<typename Derived>
15422ExprResult TreeTransform<Derived>::
15423TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
15424 // This is a kind of implicit conversion, and it needs to get dropped
15425 // and recomputed for the same general reasons that ImplicitCastExprs
15426 // do, as well a more specific one: this expression is only valid when
15427 // it appears *immediately* as an argument expression.
15428 return getDerived().TransformExpr(E->getSubExpr());
15429}
15430
15431template<typename Derived>
15432ExprResult TreeTransform<Derived>::
15433TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
15434 TypeSourceInfo *TSInfo
15435 = getDerived().TransformType(E->getTypeInfoAsWritten());
15436 if (!TSInfo)
15437 return ExprError();
15438
15439 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
15440 if (Result.isInvalid())
15441 return ExprError();
15442
15443 if (!getDerived().AlwaysRebuild() &&
15444 TSInfo == E->getTypeInfoAsWritten() &&
15445 Result.get() == E->getSubExpr())
15446 return E;
15447
15448 return SemaRef.ObjC().BuildObjCBridgedCast(
15449 E->getLParenLoc(), E->getBridgeKind(), E->getBridgeKeywordLoc(), TSInfo,
15450 Result.get());
15451}
15452
15453template <typename Derived>
15454ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
15455 ObjCAvailabilityCheckExpr *E) {
15456 return E;
15457}
15458
15459template<typename Derived>
15461TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
15462 // Transform arguments.
15463 bool ArgChanged = false;
15465 Args.reserve(E->getNumArgs());
15466 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
15467 &ArgChanged))
15468 return ExprError();
15469
15470 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
15471 // Class message: transform the receiver type.
15472 TypeSourceInfo *ReceiverTypeInfo
15473 = getDerived().TransformType(E->getClassReceiverTypeInfo());
15474 if (!ReceiverTypeInfo)
15475 return ExprError();
15476
15477 // If nothing changed, just retain the existing message send.
15478 if (!getDerived().AlwaysRebuild() &&
15479 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
15480 return SemaRef.MaybeBindToTemporary(E);
15481
15482 // Build a new class message send.
15484 E->getSelectorLocs(SelLocs);
15485 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
15486 E->getSelector(),
15487 SelLocs,
15488 E->getMethodDecl(),
15489 E->getLeftLoc(),
15490 Args,
15491 E->getRightLoc());
15492 }
15493 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
15494 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
15495 if (!E->getMethodDecl())
15496 return ExprError();
15497
15498 // Build a new class message send to 'super'.
15500 E->getSelectorLocs(SelLocs);
15501 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
15502 E->getSelector(),
15503 SelLocs,
15504 E->getReceiverType(),
15505 E->getMethodDecl(),
15506 E->getLeftLoc(),
15507 Args,
15508 E->getRightLoc());
15509 }
15510
15511 // Instance message: transform the receiver
15512 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
15513 "Only class and instance messages may be instantiated");
15514 ExprResult Receiver
15515 = getDerived().TransformExpr(E->getInstanceReceiver());
15516 if (Receiver.isInvalid())
15517 return ExprError();
15518
15519 // If nothing changed, just retain the existing message send.
15520 if (!getDerived().AlwaysRebuild() &&
15521 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
15522 return SemaRef.MaybeBindToTemporary(E);
15523
15524 // Build a new instance message send.
15526 E->getSelectorLocs(SelLocs);
15527 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
15528 E->getSelector(),
15529 SelLocs,
15530 E->getMethodDecl(),
15531 E->getLeftLoc(),
15532 Args,
15533 E->getRightLoc());
15534}
15535
15536template<typename Derived>
15538TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
15539 return E;
15540}
15541
15542template<typename Derived>
15544TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
15545 return E;
15546}
15547
15548template<typename Derived>
15550TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
15551 // Transform the base expression.
15552 ExprResult Base = getDerived().TransformExpr(E->getBase());
15553 if (Base.isInvalid())
15554 return ExprError();
15555
15556 // We don't need to transform the ivar; it will never change.
15557
15558 // If nothing changed, just retain the existing expression.
15559 if (!getDerived().AlwaysRebuild() &&
15560 Base.get() == E->getBase())
15561 return E;
15562
15563 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
15564 E->getLocation(),
15565 E->isArrow(), E->isFreeIvar());
15566}
15567
15568template<typename Derived>
15570TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
15571 // 'super' and types never change. Property never changes. Just
15572 // retain the existing expression.
15573 if (!E->isObjectReceiver())
15574 return E;
15575
15576 // Transform the base expression.
15577 ExprResult Base = getDerived().TransformExpr(E->getBase());
15578 if (Base.isInvalid())
15579 return ExprError();
15580
15581 // We don't need to transform the property; it will never change.
15582
15583 // If nothing changed, just retain the existing expression.
15584 if (!getDerived().AlwaysRebuild() &&
15585 Base.get() == E->getBase())
15586 return E;
15587
15588 if (E->isExplicitProperty())
15589 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
15590 E->getExplicitProperty(),
15591 E->getLocation());
15592
15593 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
15594 SemaRef.Context.PseudoObjectTy,
15595 E->getImplicitPropertyGetter(),
15596 E->getImplicitPropertySetter(),
15597 E->getLocation());
15598}
15599
15600template<typename Derived>
15602TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
15603 // Transform the base expression.
15604 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
15605 if (Base.isInvalid())
15606 return ExprError();
15607
15608 // Transform the key expression.
15609 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
15610 if (Key.isInvalid())
15611 return ExprError();
15612
15613 // If nothing changed, just retain the existing expression.
15614 if (!getDerived().AlwaysRebuild() &&
15615 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
15616 return E;
15617
15618 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
15619 Base.get(), Key.get(),
15620 E->getAtIndexMethodDecl(),
15621 E->setAtIndexMethodDecl());
15622}
15623
15624template<typename Derived>
15626TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
15627 // Transform the base expression.
15628 ExprResult Base = getDerived().TransformExpr(E->getBase());
15629 if (Base.isInvalid())
15630 return ExprError();
15631
15632 // If nothing changed, just retain the existing expression.
15633 if (!getDerived().AlwaysRebuild() &&
15634 Base.get() == E->getBase())
15635 return E;
15636
15637 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
15638 E->getOpLoc(),
15639 E->isArrow());
15640}
15641
15642template<typename Derived>
15644TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
15645 bool ArgumentChanged = false;
15646 SmallVector<Expr*, 8> SubExprs;
15647 SubExprs.reserve(E->getNumSubExprs());
15648 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
15649 SubExprs, &ArgumentChanged))
15650 return ExprError();
15651
15652 if (!getDerived().AlwaysRebuild() &&
15653 !ArgumentChanged)
15654 return E;
15655
15656 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
15657 SubExprs,
15658 E->getRParenLoc());
15659}
15660
15661template<typename Derived>
15663TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
15664 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
15665 if (SrcExpr.isInvalid())
15666 return ExprError();
15667
15668 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
15669 if (!Type)
15670 return ExprError();
15671
15672 if (!getDerived().AlwaysRebuild() &&
15673 Type == E->getTypeSourceInfo() &&
15674 SrcExpr.get() == E->getSrcExpr())
15675 return E;
15676
15677 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
15678 SrcExpr.get(), Type,
15679 E->getRParenLoc());
15680}
15681
15682template<typename Derived>
15684TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
15685 BlockDecl *oldBlock = E->getBlockDecl();
15686
15687 SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr);
15688 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
15689
15690 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
15691 blockScope->TheDecl->setBlockMissingReturnType(
15692 oldBlock->blockMissingReturnType());
15693
15695 SmallVector<QualType, 4> paramTypes;
15696
15697 const FunctionProtoType *exprFunctionType = E->getFunctionType();
15698
15699 // Parameter substitution.
15700 Sema::ExtParameterInfoBuilder extParamInfos;
15701 if (getDerived().TransformFunctionTypeParams(
15702 E->getCaretLocation(), oldBlock->parameters(), nullptr,
15703 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
15704 extParamInfos)) {
15705 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
15706 return ExprError();
15707 }
15708
15709 QualType exprResultType =
15710 getDerived().TransformType(exprFunctionType->getReturnType());
15711
15712 auto epi = exprFunctionType->getExtProtoInfo();
15713 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size());
15714
15715 QualType functionType =
15716 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
15717 blockScope->FunctionType = functionType;
15718
15719 // Set the parameters on the block decl.
15720 if (!params.empty())
15721 blockScope->TheDecl->setParams(params);
15722
15723 if (!oldBlock->blockMissingReturnType()) {
15724 blockScope->HasImplicitReturnType = false;
15725 blockScope->ReturnType = exprResultType;
15726 }
15727
15728 // Transform the body
15729 StmtResult body = getDerived().TransformStmt(E->getBody());
15730 if (body.isInvalid()) {
15731 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
15732 return ExprError();
15733 }
15734
15735#ifndef NDEBUG
15736 // In builds with assertions, make sure that we captured everything we
15737 // captured before.
15738 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
15739 for (const auto &I : oldBlock->captures()) {
15740 VarDecl *oldCapture = I.getVariable();
15741
15742 // Ignore parameter packs.
15743 if (oldCapture->isParameterPack())
15744 continue;
15745
15746 VarDecl *newCapture =
15747 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
15748 oldCapture));
15749 assert(blockScope->CaptureMap.count(newCapture));
15750 }
15751
15752 // The this pointer may not be captured by the instantiated block, even when
15753 // it's captured by the original block, if the expression causing the
15754 // capture is in the discarded branch of a constexpr if statement.
15755 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
15756 "this pointer isn't captured in the old block");
15757 }
15758#endif
15759
15760 return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(),
15761 /*Scope=*/nullptr);
15762}
15763
15764template<typename Derived>
15766TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
15767 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
15768 if (SrcExpr.isInvalid())
15769 return ExprError();
15770
15771 QualType Type = getDerived().TransformType(E->getType());
15772
15773 return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(),
15774 E->getRParenLoc());
15775}
15776
15777template<typename Derived>
15779TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
15780 bool ArgumentChanged = false;
15781 SmallVector<Expr*, 8> SubExprs;
15782 SubExprs.reserve(E->getNumSubExprs());
15783 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
15784 SubExprs, &ArgumentChanged))
15785 return ExprError();
15786
15787 if (!getDerived().AlwaysRebuild() &&
15788 !ArgumentChanged)
15789 return E;
15790
15791 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
15792 E->getOp(), E->getRParenLoc());
15793}
15794
15795//===----------------------------------------------------------------------===//
15796// Type reconstruction
15797//===----------------------------------------------------------------------===//
15798
15799template<typename Derived>
15802 return SemaRef.BuildPointerType(PointeeType, Star,
15803 getDerived().getBaseEntity());
15804}
15805
15806template<typename Derived>
15809 return SemaRef.BuildBlockPointerType(PointeeType, Star,
15810 getDerived().getBaseEntity());
15811}
15812
15813template<typename Derived>
15816 bool WrittenAsLValue,
15817 SourceLocation Sigil) {
15818 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue,
15819 Sigil, getDerived().getBaseEntity());
15820}
15821
15822template<typename Derived>
15825 QualType ClassType,
15826 SourceLocation Sigil) {
15827 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil,
15828 getDerived().getBaseEntity());
15829}
15830
15831template<typename Derived>
15833 const ObjCTypeParamDecl *Decl,
15834 SourceLocation ProtocolLAngleLoc,
15836 ArrayRef<SourceLocation> ProtocolLocs,
15837 SourceLocation ProtocolRAngleLoc) {
15838 return SemaRef.ObjC().BuildObjCTypeParamType(
15839 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
15840 /*FailOnError=*/true);
15841}
15842
15843template<typename Derived>
15845 QualType BaseType,
15847 SourceLocation TypeArgsLAngleLoc,
15849 SourceLocation TypeArgsRAngleLoc,
15850 SourceLocation ProtocolLAngleLoc,
15852 ArrayRef<SourceLocation> ProtocolLocs,
15853 SourceLocation ProtocolRAngleLoc) {
15854 return SemaRef.ObjC().BuildObjCObjectType(
15855 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
15856 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
15857 /*FailOnError=*/true,
15858 /*Rebuilding=*/true);
15859}
15860
15861template<typename Derived>
15863 QualType PointeeType,
15865 return SemaRef.Context.getObjCObjectPointerType(PointeeType);
15866}
15867
15868template <typename Derived>
15870 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
15871 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
15872 if (SizeExpr || !Size)
15873 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
15874 IndexTypeQuals, BracketsRange,
15875 getDerived().getBaseEntity());
15876
15877 QualType Types[] = {
15881 };
15882 QualType SizeType;
15883 for (const auto &T : Types)
15884 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
15885 SizeType = T;
15886 break;
15887 }
15888
15889 // Note that we can return a VariableArrayType here in the case where
15890 // the element type was a dependent VariableArrayType.
15891 IntegerLiteral *ArraySize
15892 = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType,
15893 /*FIXME*/BracketsRange.getBegin());
15894 return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize,
15895 IndexTypeQuals, BracketsRange,
15896 getDerived().getBaseEntity());
15897}
15898
15899template <typename Derived>
15901 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
15902 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
15903 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
15904 IndexTypeQuals, BracketsRange);
15905}
15906
15907template <typename Derived>
15909 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
15910 SourceRange BracketsRange) {
15911 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
15912 IndexTypeQuals, BracketsRange);
15913}
15914
15915template <typename Derived>
15917 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
15918 unsigned IndexTypeQuals, SourceRange BracketsRange) {
15919 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
15920 SizeExpr,
15921 IndexTypeQuals, BracketsRange);
15922}
15923
15924template <typename Derived>
15926 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
15927 unsigned IndexTypeQuals, SourceRange BracketsRange) {
15928 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
15929 SizeExpr,
15930 IndexTypeQuals, BracketsRange);
15931}
15932
15933template <typename Derived>
15935 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
15936 return SemaRef.BuildAddressSpaceAttr(PointeeType, AddrSpaceExpr,
15937 AttributeLoc);
15938}
15939
15940template <typename Derived>
15942 unsigned NumElements,
15943 VectorKind VecKind) {
15944 // FIXME: semantic checking!
15945 return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);
15946}
15947
15948template <typename Derived>
15950 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
15951 VectorKind VecKind) {
15952 return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc);
15953}
15954
15955template<typename Derived>
15957 unsigned NumElements,
15958 SourceLocation AttributeLoc) {
15959 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
15960 NumElements, true);
15961 IntegerLiteral *VectorSize
15962 = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
15963 AttributeLoc);
15964 return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
15965}
15966
15967template<typename Derived>
15970 Expr *SizeExpr,
15971 SourceLocation AttributeLoc) {
15972 return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
15973}
15974
15975template <typename Derived>
15977 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
15978 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
15979 NumColumns);
15980}
15981
15982template <typename Derived>
15984 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
15985 SourceLocation AttributeLoc) {
15986 return SemaRef.BuildMatrixType(ElementType, RowExpr, ColumnExpr,
15987 AttributeLoc);
15988}
15989
15990template<typename Derived>
15992 QualType T,
15993 MutableArrayRef<QualType> ParamTypes,
15995 return SemaRef.BuildFunctionType(T, ParamTypes,
15996 getDerived().getBaseLocation(),
15997 getDerived().getBaseEntity(),
15998 EPI);
15999}
16000
16001template<typename Derived>
16003 return SemaRef.Context.getFunctionNoProtoType(T);
16004}
16005
16006template<typename Derived>
16008 Decl *D) {
16009 assert(D && "no decl found");
16010 if (D->isInvalidDecl()) return QualType();
16011
16012 // FIXME: Doesn't account for ObjCInterfaceDecl!
16013 if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {
16014 // A valid resolved using typename pack expansion decl can have multiple
16015 // UsingDecls, but they must each have exactly one type, and it must be
16016 // the same type in every case. But we must have at least one expansion!
16017 if (UPD->expansions().empty()) {
16018 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
16019 << UPD->isCXXClassMember() << UPD;
16020 return QualType();
16021 }
16022
16023 // We might still have some unresolved types. Try to pick a resolved type
16024 // if we can. The final instantiation will check that the remaining
16025 // unresolved types instantiate to the type we pick.
16026 QualType FallbackT;
16027 QualType T;
16028 for (auto *E : UPD->expansions()) {
16029 QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
16030 if (ThisT.isNull())
16031 continue;
16032 else if (ThisT->getAs<UnresolvedUsingType>())
16033 FallbackT = ThisT;
16034 else if (T.isNull())
16035 T = ThisT;
16036 else
16037 assert(getSema().Context.hasSameType(ThisT, T) &&
16038 "mismatched resolved types in using pack expansion");
16039 }
16040 return T.isNull() ? FallbackT : T;
16041 } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
16042 assert(Using->hasTypename() &&
16043 "UnresolvedUsingTypenameDecl transformed to non-typename using");
16044
16045 // A valid resolved using typename decl points to exactly one type decl.
16046 assert(++Using->shadow_begin() == Using->shadow_end());
16047
16048 UsingShadowDecl *Shadow = *Using->shadow_begin();
16049 if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), Loc))
16050 return QualType();
16051 return SemaRef.Context.getUsingType(
16052 Shadow, SemaRef.Context.getTypeDeclType(
16053 cast<TypeDecl>(Shadow->getTargetDecl())));
16054 } else {
16055 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
16056 "UnresolvedUsingTypenameDecl transformed to non-using decl");
16057 return SemaRef.Context.getTypeDeclType(
16058 cast<UnresolvedUsingTypenameDecl>(D));
16059 }
16060}
16061
16062template <typename Derived>
16064 TypeOfKind Kind) {
16065 return SemaRef.BuildTypeofExprType(E, Kind);
16066}
16067
16068template<typename Derived>
16070 TypeOfKind Kind) {
16071 return SemaRef.Context.getTypeOfType(Underlying, Kind);
16072}
16073
16074template <typename Derived>
16076 return SemaRef.BuildDecltypeType(E);
16077}
16078
16079template <typename Derived>
16081 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
16082 SourceLocation EllipsisLoc, bool FullySubstituted,
16083 ArrayRef<QualType> Expansions) {
16084 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
16085 FullySubstituted, Expansions);
16086}
16087
16088template<typename Derived>
16092 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
16093}
16094
16095template<typename Derived>
16097 TemplateName Template,
16098 SourceLocation TemplateNameLoc,
16099 TemplateArgumentListInfo &TemplateArgs) {
16100 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
16101}
16102
16103template<typename Derived>
16105 SourceLocation KWLoc) {
16106 return SemaRef.BuildAtomicType(ValueType, KWLoc);
16107}
16108
16109template<typename Derived>
16111 SourceLocation KWLoc,
16112 bool isReadPipe) {
16113 return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc)
16114 : SemaRef.BuildWritePipeType(ValueType, KWLoc);
16115}
16116
16117template <typename Derived>
16119 unsigned NumBits,
16121 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
16122 NumBits, true);
16123 IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,
16124 SemaRef.Context.IntTy, Loc);
16125 return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc);
16126}
16127
16128template <typename Derived>
16130 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
16131 return SemaRef.BuildBitIntType(IsUnsigned, NumBitsExpr, Loc);
16132}
16133
16134template<typename Derived>
16137 bool TemplateKW,
16138 TemplateDecl *Template) {
16139 return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW,
16140 TemplateName(Template));
16141}
16142
16143template<typename Derived>
16146 SourceLocation TemplateKWLoc,
16147 const IdentifierInfo &Name,
16148 SourceLocation NameLoc,
16149 QualType ObjectType,
16150 NamedDecl *FirstQualifierInScope,
16151 bool AllowInjectedClassName) {
16153 TemplateName.setIdentifier(&Name, NameLoc);
16154 Sema::TemplateTy Template;
16155 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
16156 TemplateName, ParsedType::make(ObjectType),
16157 /*EnteringContext=*/false, Template,
16158 AllowInjectedClassName);
16159 return Template.get();
16160}
16161
16162template<typename Derived>
16165 SourceLocation TemplateKWLoc,
16166 OverloadedOperatorKind Operator,
16167 SourceLocation NameLoc,
16168 QualType ObjectType,
16169 bool AllowInjectedClassName) {
16170 UnqualifiedId Name;
16171 // FIXME: Bogus location information.
16172 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
16173 Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);
16174 Sema::TemplateTy Template;
16175 getSema().ActOnTemplateName(
16176 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(ObjectType),
16177 /*EnteringContext=*/false, Template, AllowInjectedClassName);
16178 return Template.get();
16179}
16180
16181template <typename Derived>
16184 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
16185 Expr *Second) {
16186 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
16187
16188 if (First->getObjectKind() == OK_ObjCProperty) {
16191 return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc, Opc,
16192 First, Second);
16194 if (Result.isInvalid())
16195 return ExprError();
16196 First = Result.get();
16197 }
16198
16199 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
16200 ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);
16201 if (Result.isInvalid())
16202 return ExprError();
16203 Second = Result.get();
16204 }
16205
16206 // Determine whether this should be a builtin operation.
16207 if (Op == OO_Subscript) {
16208 if (!First->getType()->isOverloadableType() &&
16209 !Second->getType()->isOverloadableType())
16210 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
16211 OpLoc);
16212 } else if (Op == OO_Arrow) {
16213 // It is possible that the type refers to a RecoveryExpr created earlier
16214 // in the tree transformation.
16215 if (First->getType()->isDependentType())
16216 return ExprError();
16217 // -> is never a builtin operation.
16218 return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);
16219 } else if (Second == nullptr || isPostIncDec) {
16220 if (!First->getType()->isOverloadableType() ||
16221 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
16222 // The argument is not of overloadable type, or this is an expression
16223 // of the form &Class::member, so try to create a built-in unary
16224 // operation.
16226 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
16227
16228 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
16229 }
16230 } else {
16231 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
16232 !First->getType()->isOverloadableType() &&
16233 !Second->getType()->isOverloadableType()) {
16234 // Neither of the arguments is type-dependent or has an overloadable
16235 // type, so try to create a built-in binary operation.
16238 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
16239 if (Result.isInvalid())
16240 return ExprError();
16241
16242 return Result;
16243 }
16244 }
16245
16246 // Create the overloaded operator invocation for unary operators.
16247 if (!Second || isPostIncDec) {
16249 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
16250 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First,
16251 RequiresADL);
16252 }
16253
16254 // Create the overloaded operator invocation for binary operators.
16256 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions,
16257 First, Second, RequiresADL);
16258 if (Result.isInvalid())
16259 return ExprError();
16260
16261 return Result;
16262}
16263
16264template<typename Derived>
16267 SourceLocation OperatorLoc,
16268 bool isArrow,
16269 CXXScopeSpec &SS,
16270 TypeSourceInfo *ScopeType,
16271 SourceLocation CCLoc,
16272 SourceLocation TildeLoc,
16273 PseudoDestructorTypeStorage Destroyed) {
16274 QualType BaseType = Base->getType();
16275 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
16276 (!isArrow && !BaseType->getAs<RecordType>()) ||
16277 (isArrow && BaseType->getAs<PointerType>() &&
16278 !BaseType->castAs<PointerType>()->getPointeeType()
16279 ->template getAs<RecordType>())){
16280 // This pseudo-destructor expression is still a pseudo-destructor.
16281 return SemaRef.BuildPseudoDestructorExpr(
16282 Base, OperatorLoc, isArrow ? tok::arrow : tok::period, SS, ScopeType,
16283 CCLoc, TildeLoc, Destroyed);
16284 }
16285
16286 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
16288 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
16289 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
16290 NameInfo.setNamedTypeInfo(DestroyedType);
16291
16292 // The scope type is now known to be a valid nested name specifier
16293 // component. Tack it on to the end of the nested name specifier.
16294 if (ScopeType) {
16295 if (!ScopeType->getType()->getAs<TagType>()) {
16296 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
16297 diag::err_expected_class_or_namespace)
16298 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
16299 return ExprError();
16300 }
16301 SS.Extend(SemaRef.Context, SourceLocation(), ScopeType->getTypeLoc(),
16302 CCLoc);
16303 }
16304
16305 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
16306 return getSema().BuildMemberReferenceExpr(Base, BaseType,
16307 OperatorLoc, isArrow,
16308 SS, TemplateKWLoc,
16309 /*FIXME: FirstQualifier*/ nullptr,
16310 NameInfo,
16311 /*TemplateArgs*/ nullptr,
16312 /*S*/nullptr);
16313}
16314
16315template<typename Derived>
16318 SourceLocation Loc = S->getBeginLoc();
16319 CapturedDecl *CD = S->getCapturedDecl();
16320 unsigned NumParams = CD->getNumParams();
16321 unsigned ContextParamPos = CD->getContextParamPosition();
16323 for (unsigned I = 0; I < NumParams; ++I) {
16324 if (I != ContextParamPos) {
16325 Params.push_back(
16326 std::make_pair(
16327 CD->getParam(I)->getName(),
16328 getDerived().TransformType(CD->getParam(I)->getType())));
16329 } else {
16330 Params.push_back(std::make_pair(StringRef(), QualType()));
16331 }
16332 }
16333 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
16334 S->getCapturedRegionKind(), Params);
16335 StmtResult Body;
16336 {
16337 Sema::CompoundScopeRAII CompoundScope(getSema());
16338 Body = getDerived().TransformStmt(S->getCapturedStmt());
16339 }
16340
16341 if (Body.isInvalid()) {
16342 getSema().ActOnCapturedRegionError();
16343 return StmtError();
16344 }
16345
16346 return getSema().ActOnCapturedRegionEnd(Body.get());
16347}
16348
16349} // end namespace clang
16350
16351#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
int Id
Definition: ASTDiff.cpp:190
MatchType Type
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:1125
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:2979
unsigned Iter
Definition: HTMLLogger.cpp:154
#define X(type, name)
Definition: Value.h:143
llvm::MachO::Target Target
Definition: MachO.h:50
llvm::MachO::Record Record
Definition: MachO.h:31
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
SourceRange Range
Definition: SemaObjC.cpp:754
SourceLocation Loc
Definition: SemaObjC.cpp:755
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 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.
SourceLocation Begin
std::string Label
QualType getUsingType(const UsingShadowDecl *Found, QualType Underlying) const
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1073
unsigned getIntWidth(QualType T) const
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType, QualType equivalentType) const
QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent, bool IsPack=false, ConceptDecl *TypeConstraintConcept=nullptr, ArrayRef< TemplateArgument > TypeConstraintArgs={}) const
C++11 deduced auto type.
QualType getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, ArrayRef< TemplateArgumentLoc > Args) const
DeclarationNameTable DeclarationNames
Definition: ASTContext.h:648
QualType getFunctionNoProtoType(QualType ResultTy, const FunctionType::ExtInfo &Info) const
Return a K&R style C function type like 'int()'.
QualType getArrayParameterType(QualType Ty) const
Return the uniqued reference to a specified array parameter type from the original array type.
QualType getPackExpansionType(QualType Pattern, std::optional< unsigned > NumExpansions, bool ExpectPackInType=true)
Form a pack expansion type with the given pattern.
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2575
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2591
TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, TemplateName Template) const
Retrieve the template name that represents a qualified template name such as std::vector.
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
Definition: ASTContext.h:1591
IdentifierTable & Idents
Definition: ASTContext.h:644
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:1101
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:1100
CanQualType PseudoObjectTy
Definition: ASTContext.h:1122
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
Definition: ASTContext.h:2157
QualType getElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, QualType NamedType, TagDecl *OwnedTagDecl=nullptr) const
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
CanQualType UnsignedInt128Ty
Definition: ASTContext.h:1102
CanQualType BuiltinFnTy
Definition: ASTContext.h:1121
CanQualType UnsignedCharTy
Definition: ASTContext.h:1101
CanQualType UnsignedIntTy
Definition: ASTContext.h:1101
CanQualType UnsignedLongLongTy
Definition: ASTContext.h:1102
CanQualType UnsignedShortTy
Definition: ASTContext.h:1101
QualType getDependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, const IdentifierInfo *Name, QualType Canon=QualType()) const
TemplateName getSubstTemplateTemplateParmPack(const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index, bool Final) const
QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const
Return the uniqued reference to the type for an address space qualified type with the specified type ...
QualType getTypeOfType(QualType QT, TypeOfKind Kind) const
getTypeOfType - Unlike many "get<Type>" functions, we don't unique TypeOfType nodes.
QualType getSubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl, unsigned Index, std::optional< unsigned > PackIndex) const
Retrieve a substitution-result type.
QualType getConstantMatrixType(QualType ElementType, unsigned NumRows, unsigned NumColumns) const
Return the unique reference to the matrix type of the specified element type and size.
PtrTy get() const
Definition: Ownership.h:170
bool isInvalid() const
Definition: Ownership.h:166
bool isUsable() const
Definition: Ownership.h:168
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition: ExprCXX.h:2848
SourceLocation getEndLoc() const LLVM_READONLY
Definition: ExprCXX.h:2886
ArrayTypeTrait getTrait() const
Definition: ExprCXX.h:2888
Expr * getDimensionExpression() const
Definition: ExprCXX.h:2896
TypeSourceInfo * getQueriedTypeSourceInfo() const
Definition: ExprCXX.h:2892
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprCXX.h:2885
SourceLocation getRParenLoc() const
Definition: TypeLoc.h:2634
TypeLoc getValueLoc() const
Definition: TypeLoc.h:2610
SourceLocation getKWLoc() const
Definition: TypeLoc.h:2618
SourceLocation getLParenLoc() const
Definition: TypeLoc.h:2626
Attr - This represents one attribute.
Definition: Attr.h:42
attr::Kind getKind() const
Definition: Attr.h:88
SourceLocation getLocation() const
Definition: Attr.h:95
Represents an attribute applied to a statement.
Definition: Stmt.h:2080
Type source information for an attributed type.
Definition: TypeLoc.h:875
const Attr * getAttr() const
The type attribute.
Definition: TypeLoc.h:898
TypeLoc getModifiedLoc() const
The modified type, which is generally canonically different from the attribute type.
Definition: TypeLoc.h:889
TypeLoc getEquivalentTypeLoc() const
Definition: TypeLoc.h:893
void setAttr(const Attr *A)
Definition: TypeLoc.h:901
attr::Kind getAttrKind() const
Definition: TypeLoc.h:877
An attributed type is a type to which a type attribute has been applied.
Definition: Type.h:5604
QualType getModifiedType() const
Definition: Type.h:5626
std::optional< NullabilityKind > getImmediateNullability() const
Definition: Type.cpp:4788
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:5981
ArrayRef< TemplateArgument > getTypeConstraintArguments() const
Definition: Type.h:5991
ConceptDecl * getTypeConstraintConcept() const
Definition: Type.h:5996
AutoTypeKeyword getKeyword() const
Definition: Type.h:6012
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:2181
bool isAssignmentOp() const
Definition: Expr.h:3978
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO)
Retrieve the binary opcode that corresponds to the given overloaded operator.
Definition: Expr.cpp:2143
void setIsVariadic(bool value)
Definition: Decl.h:4570
TypeLoc getInnerLoc() const
Definition: TypeLoc.h:1128
QualType desugar() const
Definition: Type.h:3209
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition: ExprCXX.h:5282
SourceLocation getEndLoc() const LLVM_READONLY
Definition: ExprCXX.h:5301
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprCXX.h:5300
Represents binding an expression to a temporary.
Definition: ExprCXX.h:1487
CXXCatchStmt - This represents a C++ catch block.
Definition: StmtCXX.h:28
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1542
SourceRange getParenOrBraceRange() const
Definition: ExprCXX.h:1710
Expr * getArg(unsigned Arg)
Return the specified argument.
Definition: ExprCXX.h:1685
bool isStdInitListInitialization() const
Whether this constructor call was written as list-initialization, but was interpreted as forming a st...
Definition: ExprCXX.h:1635
SourceLocation getEndLoc() const LLVM_READONLY
Definition: ExprCXX.cpp:519
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: ExprCXX.cpp:513
bool isListInitialization() const
Whether this constructor call was written as list-initialization.
Definition: ExprCXX.h:1624
unsigned getNumArgs() const
Return the number of arguments to the constructor call.
Definition: ExprCXX.h:1682
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2535
static CXXDefaultArgExpr * Create(const ASTContext &C, SourceLocation Loc, ParmVarDecl *Param, Expr *RewrittenExpr, DeclContext *UsedContext)
Definition: ExprCXX.cpp:969
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition: ExprCXX.h:1733
Abstract class common to all of the C++ "named"/"keyword" casts.
Definition: ExprCXX.h:372
SourceLocation getOperatorLoc() const
Retrieve the location of the cast operator keyword, e.g., static_cast.
Definition: ExprCXX.h:403
SourceRange getAngleBrackets() const LLVM_READONLY
Definition: ExprCXX.h:410
SourceLocation getRParenLoc() const
Retrieve the location of the closing parenthesis.
Definition: ExprCXX.h:406
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
unsigned getLambdaDependencyKind() const
Definition: DeclCXX.h:1856
An expression "T()" which creates a value-initialized rvalue of type T, which is a non-class type.
Definition: ExprCXX.h:2177
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:74
char * location_data() const
Retrieve the data associated with the source-location information.
Definition: DeclSpec.h:236
SourceRange getRange() const
Definition: DeclSpec.h:80
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc)
Turn this (empty) nested-name-specifier into the global nested-name-specifier '::'.
Definition: DeclSpec.cpp:104
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
Definition: DeclSpec.cpp:152
NestedNameSpecifier * getScopeRep() const
Retrieve the representation of the nested-name-specifier.
Definition: DeclSpec.h:95
unsigned location_size() const
Retrieve the size of the data associated with source-location information.
Definition: DeclSpec.h:240
void MakeSuper(ASTContext &Context, CXXRecordDecl *RD, SourceLocation SuperLoc, SourceLocation ColonColonLoc)
Turns this (empty) nested-name-specifier into '__super' nested-name-specifier.
Definition: DeclSpec.cpp:114
void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL, SourceLocation ColonColonLoc)
Extend the current nested-name-specifier by another nested-name-specifier component of the form 'type...
Definition: DeclSpec.cpp:54
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
Definition: DeclSpec.cpp:132
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Definition: ExprCXX.h:797
Describes an explicit type conversion that uses functional notion but could not be resolved because o...
Definition: ExprCXX.h:3550
SourceLocation getLParenLoc() const
Retrieve the location of the left parentheses ('(') that precedes the argument list.
Definition: ExprCXX.h:3594
bool isListInitialization() const
Determine whether this expression models list-initialization.
Definition: ExprCXX.h:3605
TypeSourceInfo * getTypeSourceInfo() const
Retrieve the type source information for the type being constructed.
Definition: ExprCXX.h:3588
SourceLocation getRParenLoc() const
Retrieve the location of the right parentheses (')') that follows the argument list.
Definition: ExprCXX.h:3599
unsigned getNumArgs() const
Retrieve the number of arguments.
Definition: ExprCXX.h:3608
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr * > Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, FPOptionsOverride FPFeatures, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
Definition: Expr.cpp:1494
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition: Decl.h:4686
unsigned getNumParams() const
Definition: Decl.h:4728
unsigned getContextParamPosition() const
Definition: Decl.h:4757
ImplicitParamDecl * getParam(unsigned i) const
Definition: Decl.h:4730
This captures a statement into a function.
Definition: Stmt.h:3757
Expr * getSubExprAsWritten()
Retrieve the cast subexpression as it was written in the source code, looking through any implicit ca...
Definition: Expr.cpp:1981
Expr * getSubExpr()
Definition: Expr.h:3533
SourceLocation getBegin() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition: Stmt.h:1606
Declaration of a C++20 concept.
static ConceptReference * Create(const ASTContext &C, NestedNameSpecifierLoc NNS, SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo, NamedDecl *FoundDecl, ConceptDecl *NamedConcept, const ASTTemplateArgumentListInfo *ArgsAsWritten)
Definition: ASTConcept.cpp:94
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:421
Expr * getCountExpr() const
Definition: TypeLoc.h:1142
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Definition: Type.h:3247
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1369
reference front() const
Definition: DeclBase.h:1392
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Definition: DeclBase.cpp:1802
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1716
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1260
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition: Stmt.h:1497
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
bool isInvalidDecl() const
Definition: DeclBase.h:594
SourceLocation getLocation() const
Definition: DeclBase.h:445
DeclContext * getDeclContext()
Definition: DeclBase.h:454
AccessSpecifier getAccess() const
Definition: DeclBase.h:513
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:813
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:799
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1900
QualType getDeducedType() const
Get the type deduced for this placeholder type, or null if it has not been deduced.
Definition: Type.h:5968
bool isDeduced() const
Definition: Type.h:5969
A qualified reference to a name whose declaration cannot yet be resolved.
Definition: ExprCXX.h:3316
SourceLocation getRAngleLoc() const
Retrieve the location of the right angle bracket ending the explicit template argument list following...
Definition: ExprCXX.h:3390
NestedNameSpecifierLoc getQualifierLoc() const
Retrieve the nested-name-specifier that qualifies the name, with source location information.
Definition: ExprCXX.h:3364
SourceLocation getLAngleLoc() const
Retrieve the location of the left angle bracket starting the explicit template argument list followin...
Definition: ExprCXX.h:3382
bool hasExplicitTemplateArgs() const
Determines whether this lookup had explicit template arguments.
Definition: ExprCXX.h:3400
SourceLocation getTemplateKeywordLoc() const
Retrieve the location of the template keyword preceding this name, if any.
Definition: ExprCXX.h:3374
unsigned getNumTemplateArgs() const
Definition: ExprCXX.h:3417
DeclarationName getDeclName() const
Retrieve the name that this expression refers to.
Definition: ExprCXX.h:3355
TemplateArgumentLoc const * getTemplateArgs() const
Definition: ExprCXX.h:3410
const DeclarationNameInfo & getNameInfo() const
Retrieve the name that this expression refers to.
Definition: ExprCXX.h:3352
Represents a dependent template name that cannot be resolved prior to template instantiation.
Definition: TemplateName.h:488
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc)
Definition: TypeLoc.h:2472
SourceLocation getTemplateNameLoc() const
Definition: TypeLoc.h:2496
void setTemplateKeywordLoc(SourceLocation Loc)
Definition: TypeLoc.h:2492
SourceLocation getTemplateKeywordLoc() const
Definition: TypeLoc.h:2488
void setElaboratedKeywordLoc(SourceLocation Loc)
Definition: TypeLoc.h:2460
void setRAngleLoc(SourceLocation Loc)
Definition: TypeLoc.h:2516
SourceLocation getElaboratedKeywordLoc() const
Definition: TypeLoc.h:2456
void setLAngleLoc(SourceLocation Loc)
Definition: TypeLoc.h:2508
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI)
Definition: TypeLoc.h:2524
void setTemplateNameLoc(SourceLocation Loc)
Definition: TypeLoc.h:2500
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: Type.h:6504
Designation - Represent a full designation, which is a sequence of designators.
Definition: Designator.h:208
static Designator CreateArrayRangeDesignator(Expr *Start, Expr *End, SourceLocation LBracketLoc, SourceLocation EllipsisLoc)
Creates a GNU array-range designator.
Definition: Designator.h:172
static Designator CreateArrayDesignator(Expr *Index, SourceLocation LBracketLoc)
Creates an array designator.
Definition: Designator.h:142
static Designator CreateFieldDesignator(const IdentifierInfo *FieldName, SourceLocation DotLoc, SourceLocation FieldLoc)
Creates a field designator.
Definition: Designator.h:115
bool hasErrorOccurred() const
Definition: Diagnostic.h:843
SourceLocation getElaboratedKeywordLoc() const
Definition: TypeLoc.h:2319
NestedNameSpecifierLoc getQualifierLoc() const
Definition: TypeLoc.h:2331
void setElaboratedKeywordLoc(SourceLocation Loc)
Definition: TypeLoc.h:2323
TypeLoc getNamedTypeLoc() const
Definition: TypeLoc.h:2361
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc)
Definition: TypeLoc.h:2337
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:6371
RAII object that enters a new expression evaluation context.
Represents an enum.
Definition: Decl.h:3867
TypeSourceInfo * getTypeInfoAsWritten() const
getTypeInfoAsWritten - Returns the type source info for the type that this expression is casting to.
Definition: Expr.h:3752
This represents one expression.
Definition: Expr.h:110
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
bool isDefaultArgument() const
Determine whether this expression is a default function argument.
Definition: Expr.cpp:3154
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:915
Represents a member of a struct/union/class.
Definition: Decl.h:3057
Represents a function declaration or definition.
Definition: Decl.h:1971
QualType getReturnType() const
Definition: Decl.h:2754
QualType getCallResultType() const
Determine the type of an expression that calls this function.
Definition: Decl.h:2790
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: Type.h:4611
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4656
QualType desugar() const
Definition: Type.h:5123
param_type_iterator param_type_begin() const
Definition: Type.h:5048
const ExtParameterInfo * getExtParameterInfosOrNull() const
Return a pointer to the beginning of the array of extra parameter information, if present,...
Definition: Type.h:5086
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition: Type.h:5028
ExtProtoInfo getExtProtoInfo() const
Definition: Type.h:4900
ArrayRef< QualType > getParamTypes() const
Definition: Type.h:4896
unsigned getNumParams() const
Definition: TypeLoc.h:1500
SourceLocation getLocalRangeEnd() const
Definition: TypeLoc.h:1452
void setLocalRangeBegin(SourceLocation L)
Definition: TypeLoc.h:1448
void setLParenLoc(SourceLocation Loc)
Definition: TypeLoc.h:1464
SourceRange getExceptionSpecRange() const
Definition: TypeLoc.h:1480
void setParam(unsigned i, ParmVarDecl *VD)
Definition: TypeLoc.h:1507
ArrayRef< ParmVarDecl * > getParams() const
Definition: TypeLoc.h:1491
void setRParenLoc(SourceLocation Loc)
Definition: TypeLoc.h:1472
void setLocalRangeEnd(SourceLocation L)
Definition: TypeLoc.h:1456
void setExceptionSpecRange(SourceRange R)
Definition: TypeLoc.h:1486
TypeLoc getReturnLoc() const
Definition: TypeLoc.h:1509
SourceLocation getLocalRangeBegin() const
Definition: TypeLoc.h:1444
SourceLocation getLParenLoc() const
Definition: TypeLoc.h:1460
SourceLocation getRParenLoc() const
Definition: TypeLoc.h:1468
Interesting information about a specific parameter that can't simply be reflected in parameter's type...
Definition: Type.h:4282
QualType getReturnType() const
Definition: Type.h:4573
AssociationTy< false > Association
Definition: Expr.h:5956
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:3655
Represents an implicitly-generated value initialization of an object of a given type.
Definition: Expr.h:5600
const TypeClass * getTypePtr() const
Definition: TypeLoc.h:514
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Definition: Expr.cpp:977
Represents the declaration of a label.
Definition: Decl.h:499
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1950
capture_iterator capture_begin() const
Retrieve an iterator pointing to the first lambda capture.
Definition: ExprCXX.cpp:1295
bool isInitCapture(const LambdaCapture *Capture) const
Determine whether one of this lambda's captures is an init-capture.
Definition: ExprCXX.cpp:1290
capture_iterator capture_end() const
Retrieve an iterator pointing past the end of the sequence of lambda captures.
Definition: ExprCXX.cpp:1299
const LambdaCapture * capture_iterator
An iterator that walks over the captures of the lambda, both implicit and explicit.
Definition: ExprCXX.h:2015
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:4710
This represents a decl that may have a name.
Definition: Decl.h:249
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
Definition: Decl.h:462
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
Represents a C++ namespace alias.
Definition: DeclCXX.h:3120
Represent a C++ namespace.
Definition: Decl.h:547
A C++ nested-name-specifier augmented with source location information.
SourceLocation getBeginLoc() const
Retrieve the location of the beginning of this nested-name-specifier.
SourceLocation getLocalEndLoc() const
Retrieve the location of the end of this component of the nested-name-specifier.
SourceLocation getEndLoc() const
Retrieve the location of the end of this nested-name-specifier.
TypeLoc getTypeLoc() const
For a nested-name-specifier that refers to a type, retrieve the type with source-location information...
void * getOpaqueData() const
Retrieve the opaque pointer that refers to source-location data.
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
SourceLocation getLocalBeginLoc() const
Retrieve the location of the beginning of this component of the nested-name-specifier.
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
CXXRecordDecl * getAsRecordDecl() const
Retrieve the record declaration stored in this nested name specifier.
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
NamespaceAliasDecl * getAsNamespaceAlias() const
Retrieve the namespace alias stored in this nested name specifier.
IdentifierInfo * getAsIdentifier() const
Retrieve the identifier stored in this nested name specifier.
@ NamespaceAlias
A namespace alias, stored as a NamespaceAliasDecl*.
@ TypeSpec
A type, stored as a Type*.
@ TypeSpecWithTemplate
A type that was preceded by the 'template' keyword, stored as a Type*.
@ Super
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Identifier
An identifier, stored as an IdentifierInfo*.
@ Global
The global specifier '::'. There is no stored value.
@ Namespace
A namespace, stored as a NamespaceDecl*.
NamespaceDecl * getAsNamespace() const
Retrieve the namespace stored in this nested name specifier.
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:55
This is a basic class for representing single OpenMP executable directive.
Definition: StmtOpenMP.h:266
bool hasAssociatedStmt() const
Returns true if directive has associated statement.
Definition: StmtOpenMP.h:531
OpenMPDirectiveKind getDirectiveKind() const
Definition: StmtOpenMP.h:569
const Stmt * getAssociatedStmt() const
Returns statement associated with the directive.
Definition: StmtOpenMP.h:534
SourceLocation getBeginLoc() const
Returns starting location of directive kind.
Definition: StmtOpenMP.h:502
const Stmt * getRawStmt() const
Definition: StmtOpenMP.h:606
ArrayRef< OMPClause * > clauses() const
Definition: StmtOpenMP.h:586
OpenMPDirectiveKind getMappedDirective() const
Definition: StmtOpenMP.h:615
SourceLocation getEndLoc() const
Returns ending location of directive.
Definition: StmtOpenMP.h:504
This represents clauses with a list of expressions that are mappable.
This represents '#pragma omp metadirective' directive.
Definition: StmtOpenMP.h:5943
ObjCIvarDecl - Represents an ObjC instance variable.
Definition: DeclObjC.h:1950
@ SuperInstance
The receiver is the instance of the superclass object.
Definition: ExprObjC.h:959
@ Instance
The receiver is an object instance.
Definition: ExprObjC.h:953
@ SuperClass
The receiver is a superclass.
Definition: ExprObjC.h:956
@ Class
The receiver is a class.
Definition: ExprObjC.h:950
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
bool isInstanceMethod() const
Definition: DeclObjC.h:426
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:730
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition: ExprObjC.h:617
Represents the declaration of an Objective-C type parameter.
Definition: DeclObjC.h:578
@ Array
An index into an array.
Definition: Expr.h:2364
@ Identifier
A field in a dependent type, known only by its name.
Definition: Expr.h:2368
@ Field
A field.
Definition: Expr.h:2366
@ Base
An implicit indirection through a C++ base class, when the field found is in a base class.
Definition: Expr.h:2371
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:1168
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
Definition: Expr.h:1218
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)
This is the base type for all OpenACC Clauses.
Definition: OpenACCClause.h:24
static OpenACCCopyClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCopyInClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsReadOnly, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCopyOutClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCCreateClause * Create(const ASTContext &C, OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, bool IsZero, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDefaultClause * Create(const ASTContext &C, OpenACCDefaultClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
static OpenACCDevicePtrClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCDeviceTypeClause * Create(const ASTContext &C, OpenACCClauseKind K, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< DeviceTypeArgument > Archs, SourceLocation EndLoc)
static OpenACCFirstPrivateClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef< Expr * > VarList, SourceLocation EndLoc)
static OpenACCIfClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *ConditionExpr, SourceLocation EndLoc)
static 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 OpenACCVectorLengthClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *IntExpr, SourceLocation EndLoc)
static OpenACCWaitClause * Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef< Expr * > QueueIdExprs, SourceLocation EndLoc)
A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.
Definition: ExprCXX.h:2978
bool hasExplicitTemplateArgs() const
Determines whether this expression had explicit template arguments.
Definition: ExprCXX.h:3129
SourceLocation getLAngleLoc() const
Retrieve the location of the left angle bracket starting the explicit template argument list followin...
Definition: ExprCXX.h:3111
SourceLocation getNameLoc() const
Gets the location of the name.
Definition: ExprCXX.h:3090
SourceLocation getTemplateKeywordLoc() const
Retrieve the location of the template keyword preceding this name, if any.
Definition: ExprCXX.h:3103
NestedNameSpecifierLoc getQualifierLoc() const
Fetches the nested-name qualifier with source-location information, if one was given.
Definition: ExprCXX.h:3099
TemplateArgumentLoc const * getTemplateArgs() const
Definition: ExprCXX.h:3131
llvm::iterator_range< decls_iterator > decls() const
Definition: ExprCXX.h:3076
unsigned getNumTemplateArgs() const
Definition: ExprCXX.h:3137
DeclarationName getName() const
Gets the name looked up.
Definition: ExprCXX.h:3087
SourceLocation getRAngleLoc() const
Retrieve the location of the right angle bracket ending the explicit template argument list following...
Definition: ExprCXX.h:3119
bool hasTemplateKeyword() const
Determines whether the name was preceded by the template keyword.
Definition: ExprCXX.h:3126
Represents a C++11 pack expansion that produces a sequence of expressions.
Definition: ExprCXX.h:4173
void setEllipsisLoc(SourceLocation Loc)
Definition: TypeLoc.h:2582
SourceLocation getEllipsisLoc() const
Definition: TypeLoc.h:2578
TypeLoc getPatternLoc() const
Definition: TypeLoc.h:2594
Represents a pack expansion of types.
Definition: Type.h:6569
std::optional< unsigned > getNumExpansions() const
Retrieve the number of expansions that this pack expansion will generate, if known.
Definition: Type.h:6594
ParenExpr - This represents a parethesized expression, e.g.
Definition: Expr.h:2130
SourceLocation getLParen() const
Get the location of the left parentheses '('.
Definition: Expr.h:2153
SourceLocation getRParen() const
Get the location of the right parentheses ')'.
Definition: Expr.h:2157
Represents a parameter to a function.
Definition: Decl.h:1761
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
Definition: Decl.h:1821
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
Definition: Decl.h:1794
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:2915
unsigned getFunctionScopeDepth() const
Definition: Decl.h:1811
void setSigilLoc(SourceLocation Loc)
Definition: TypeLoc.h:1278
TypeLoc getPointeeLoc() const
Definition: TypeLoc.h:1282
SourceLocation getSigilLoc() const
Definition: TypeLoc.h:1274
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3139
QualType getPointeeType() const
Definition: Type.h:3149
Stores the type being destroyed by a pseudo-destructor expression.
Definition: ExprCXX.h:2561
const IdentifierInfo * getIdentifier() const
Definition: ExprCXX.h:2581
SourceLocation getLocation() const
Definition: ExprCXX.h:2585
TypeSourceInfo * getTypeSourceInfo() const
Definition: ExprCXX.h:2577
A (possibly-)qualified type.
Definition: Type.h:940
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:7399
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:7453
Qualifiers getLocalQualifiers() const
Retrieve the set of qualifiers local to this particular QualType instance, not including any qualifie...
Definition: Type.h:7391
Represents a template name that was expressed as a qualified name.
Definition: TemplateName.h:431
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:318
void removeObjCLifetime()
Definition: Type.h:537
bool hasRestrict() const
Definition: Type.h:463
static Qualifiers fromCVRMask(unsigned CVR)
Definition: Type.h:421
bool hasObjCLifetime() const
Definition: Type.h:530
bool empty() const
Definition: Type.h:633
LangAS getAddressSpace() const
Definition: Type.h:557
Represents a struct/union/class.
Definition: Decl.h:4168
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5549
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3380
QualType getPointeeTypeAsWritten() const
Definition: Type.h:3396
Represents the body of a requires-expression.
Definition: DeclCXX.h:2029
static RequiresExprBodyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc)
Definition: DeclCXX.cpp:2174
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
Definition: ExprConcepts.h:510
static RequiresExpr * Create(ASTContext &C, SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, SourceLocation LParenLoc, ArrayRef< ParmVarDecl * > LocalParameters, SourceLocation RParenLoc, ArrayRef< concepts::Requirement * > Requirements, SourceLocation RBraceLoc)
static SEHFinallyStmt * Create(const ASTContext &C, SourceLocation FinallyLoc, Stmt *Block)
Definition: Stmt.cpp:1275
Represents a __leave statement.
Definition: Stmt.h:3718
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:56
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:32
StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)
FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.
Definition: SemaObjC.cpp:194
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:481
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:321
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:219
StmtResult ActOnObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body)
Definition: SemaObjC.cpp:214
StmtResult BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw)
Definition: SemaObjC.cpp:239
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:708
ExprResult ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand)
Definition: SemaObjC.cpp:283
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:203
StmtResult ActOnObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body)
Definition: SemaObjC.cpp:330
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:149
SourceLocation getEndLoc() const
Definition: SemaOpenACC.h:87
void setLParenLoc(SourceLocation EndLoc)
Definition: SemaOpenACC.h:226
void setConditionDetails(Expr *ConditionExpr)
Definition: SemaOpenACC.h:235
OpenACCClauseKind getClauseKind() const
Definition: SemaOpenACC.h:81
const Expr * getConditionExpr() const
Definition: SemaOpenACC.h:95
SourceLocation getLParenLoc() const
Definition: SemaOpenACC.h:85
SourceLocation getBeginLoc() const
Definition: SemaOpenACC.h:83
void setDefaultDetails(OpenACCDefaultClauseKind DefKind)
Definition: SemaOpenACC.h:229
SourceLocation getQueuesLoc() const
Definition: SemaOpenACC.h:129
void setVarListDetails(ArrayRef< Expr * > VarList, bool IsReadOnly, bool IsZero)
Definition: SemaOpenACC.h:266
void setWaitDetails(Expr *DevNum, SourceLocation QueuesLoc, llvm::SmallVector< Expr * > &&IntExprs)
Definition: SemaOpenACC.h:337
void setEndLoc(SourceLocation EndLoc)
Definition: SemaOpenACC.h:227
void setIntExprDetails(ArrayRef< Expr * > IntExprs)
Definition: SemaOpenACC.h:249
OpenACCDefaultClauseKind getDefaultClauseKind() const
Definition: SemaOpenACC.h:89
StmtResult ActOnEndStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult AssocStmt)
Called after the directive has been completely parsed, including the declaration group or associated ...
ExprResult ActOnArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLocFirst, Expr *Length, SourceLocation RBLoc)
Checks and creates an Array Section used in an OpenACC construct/clause.
OMPClause * ActOnOpenMPNocontextClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nocontext' clause.
OMPClause * ActOnOpenMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_dyn_cgroup_mem' clause.
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'safelen' clause.
OMPClause * ActOnOpenMPDefaultClause(llvm::omp::DefaultKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'default' clause.
OMPClause * ActOnOpenMPFilterClause(Expr *ThreadID, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'filter' clause.
OMPClause * ActOnOpenMPFullClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-form 'full' clauses.
OMPClause * ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'detach' clause.
OMPClause * ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'use' clause.
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'private' clause.
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed 'ordered' clause.
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr * > VarList, OpenMPReductionClauseModifier Modifier, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=std::nullopt)
Called on well-formed 'reduction' clause.
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'is_device_ptr' clause.
OMPClause * ActOnOpenMPHasDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'has_device_addr' clause.
OMPClause * ActOnOpenMPPartialClause(Expr *FactorExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'partial' clauses.
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr * > VarList, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'lastprivate' clause.
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'firstprivate' clause.
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'priority' clause.
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'dist_schedule' clause.
OMPClause * ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocate' clause.
OMPClause * ActOnOpenMPNontemporalClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'nontemporal' clause.
OMPClause * ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'bind' clause.
OMPClause * 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 * ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, Expr *DepModifier, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depend' clause.
OMPClause * ActOnOpenMPDoacrossClause(OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'doacross' clause.
OMPClause * ActOnOpenMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier, Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'grainsize' clause.
ExprResult ActOnOMPArraySectionExpr(Expr *Base, SourceLocation LBLoc, Expr *LowerBound, SourceLocation ColonLocFirst, SourceLocation ColonLocSecond, Expr *Length, Expr *Stride, SourceLocation RBLoc)
OMPClause * ActOnOpenMPFromClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers=std::nullopt)
Called on well-formed 'from' clause.
OMPClause * ActOnOpenMPToClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers=std::nullopt)
Called on well-formed 'to' clause.
ExprResult ActOnOMPIteratorExpr(Scope *S, SourceLocation IteratorKwLoc, SourceLocation LLoc, SourceLocation RLoc, ArrayRef< OMPIteratorData > Data)
OMPClause * ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< UsesAllocatorsData > Data)
Called on well-formed 'uses_allocators' clause.
OMPClause * ActOnOpenMPAllocatorClause(Expr *Allocator, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'allocator' clause.
OMPClause * ActOnOpenMPInclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'inclusive' clause.
OMPClause * ActOnOpenMPOrderClause(OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'order' clause.
OMPClause * ActOnOpenMPSizesClause(ArrayRef< Expr * > SizeExprs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-form 'sizes' clause.
OMPClause * ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'device' clause.
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_threads' clause.
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind PrevMappedDirective=llvm::omp::OMPD_unknown)
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'flush' pseudo clause.
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'num_teams' clause.
OMPClause * ActOnOpenMPMessageClause(Expr *MS, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'message' clause.
OMPClause * ActOnOpenMPMapClause(Expr *IteratorModifier, ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, bool NoDiagnose=false, ArrayRef< Expr * > UnresolvedMappers=std::nullopt)
Called on well-formed 'map' clause.
OMPClause * ActOnOpenMPTaskReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=std::nullopt)
Called on well-formed 'task_reduction' clause.
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed 'schedule' clause.
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'simdlen' clause.
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_ptr' clause.
OMPClause * ActOnOpenMPProcBindClause(llvm::omp::ProcBindKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'proc_bind' clause.
OMPClause * ActOnOpenMPXBareClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_bare' clause.
StmtResult ActOnOpenMPCanonicalLoop(Stmt *AStmt)
Called for syntactical loops (ForStmt or CXXForRangeStmt) associated to an OpenMP loop directive.
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'hint' clause.
ExprResult ActOnOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, SourceLocation RParenLoc, ArrayRef< Expr * > Dims, ArrayRef< SourceRange > Brackets)
OMPClause * ActOnOpenMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'at' clause.
OMPClause * ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Called on well-formed 'init' clause.
OMPClause * ActOnOpenMPUseDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Called on well-formed 'use_device_addr' clause.
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'final' clause.
OMPClause * ActOnOpenMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Called on well-formed 'num_tasks' clause.
OMPClause * ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'severity' clause.
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr * > VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation StepModifierLoc, SourceLocation EndLoc)
Called on well-formed 'linear' clause.
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed 'defaultmap' clause.
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'aligned' clause.
OMPClause * ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'depobj' pseudo clause.
OMPClause * ActOnOpenMPNovariantsClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'novariants' clause.
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'copyprivate' clause.
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'collapse' clause.
OMPClause * ActOnOpenMPAlignClause(Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'align' clause.
OMPClause * ActOnOpenMPXAttributeClause(ArrayRef< const Attr * > Attrs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on a well-formed 'ompx_attribute' clause.
OMPClause * ActOnOpenMPInReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions=std::nullopt)
Called on well-formed 'in_reduction' clause.
OMPClause * ActOnOpenMPExclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'exclusive' clause.
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed 'thread_limit' clause.
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed 'if' clause.
ExprResult BuildUniqueStableNameExpr(SourceLocation OpLoc, SourceLocation LParen, SourceLocation RParen, TypeSourceInfo *TSI)
Definition: SemaSYCL.cpp:137
RAII object used to change the argument pack substitution index within a Sema object.
Definition: Sema.h:10222
RAII object used to temporarily allow the C++ 'this' expression to be used, with the given qualifiers...
Definition: Sema.h:6476
A RAII object to enter scope of a compound statement.
Definition: Sema.h:855
A helper class for building up ExtParameterInfos.
Definition: Sema.h:9673
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:9692
void set(unsigned index, FunctionProtoType::ExtParameterInfo info)
Set the ExtParameterInfo for the parameter at the given index,.
Definition: Sema.h:9680
Records and restores the CurFPFeatures state on entry/exit of compound statements.
Definition: Sema.h:10473
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:451
QualType BuildParenType(QualType T)
Build a paren type including T.
Definition: SemaType.cpp:1648
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
Definition: SemaType.cpp:6350
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:4449
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition: Sema.h:7287
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
Definition: Sema.h:7295
@ LookupTagName
Tag name lookup, which finds the names of enums, classes, structs, and unions.
Definition: Sema.h:7290
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:6458
ExprResult ActOnConstantExpression(ExprResult Res)
Definition: SemaExpr.cpp:19469
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)
QualType BuildVectorType(QualType T, Expr *VecSize, SourceLocation AttrLoc)
Definition: SemaType.cpp:2354
StmtResult BuildAttributedStmt(SourceLocation AttrsLoc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)
Definition: SemaStmt.cpp:607
SemaOpenMP & OpenMP()
Definition: Sema.h:1013
@ IER_DoesNotExist
The symbol does not exist.
Definition: Sema.h:6794
@ IER_Dependent
The name is a dependent name, so the results will differ from one instantiation to the next.
Definition: Sema.h:6798
@ IER_Error
An error occurred.
Definition: Sema.h:6801
@ IER_Exists
The symbol exists.
Definition: Sema.h:6791
void ActOnStartStmtExpr()
Definition: SemaExpr.cpp:15732
void ActOnStmtExprError()
Definition: SemaExpr.cpp:15738
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:20218
ConditionKind
Definition: Sema.h:5828
@ 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:396
StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, LabelDecl *TheDecl)
Definition: SemaStmt.cpp:3154
ExprResult MaybeBindToTemporary(Expr *E)
MaybeBindToTemporary - If the passed in expression has a record type with a non-trivial destructor,...
StmtResult BuildCoreturnStmt(SourceLocation KwLoc, Expr *E, bool IsImplicit=false)
ExprResult ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, ParsedType &ObjectType, bool &MayBePseudoDestructor)
ExprResult ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val)
Definition: SemaStmt.cpp:464
QualType BuildExtVectorType(QualType T, Expr *ArraySize, SourceLocation AttrLoc)
Build an ext-vector type.
Definition: SemaType.cpp:2428
ExprResult ActOnDesignatedInitializer(Designation &Desig, SourceLocation EqualOrColonLoc, bool GNUSyntax, ExprResult Init)
Definition: SemaInit.cpp:3369
void MarkDeclarationsReferencedInExpr(Expr *E, bool SkipLocalVariables=false, ArrayRef< const Expr * > StopAt=std::nullopt)
Mark any declarations that appear within this expression or any potentially-evaluated subexpressions ...
Definition: SemaExpr.cpp:20003
ExprResult BuildStmtExpr(SourceLocation LPLoc, Stmt *SubStmt, SourceLocation RPLoc, unsigned TemplateDepth)
Definition: SemaExpr.cpp:15751
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:1018
ExprResult BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E, TypeSourceInfo *TInfo, SourceLocation RPLoc)
Definition: SemaExpr.cpp:16404
ExprResult ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, bool ArrayForm, Expr *Operand)
ActOnCXXDelete - Parsed a C++ 'delete' expression.
ASTContext & Context
Definition: Sema.h:848
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:2667
ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow)
Perform conversions on the LHS of a member access expression.
DiagnosticsEngine & getDiagnostics() const
Definition: Sema.h:514
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.
ExprResult checkPseudoObjectAssignment(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opcode, Expr *LHS, Expr *RHS)
SemaObjC & ObjC()
Definition: Sema.h:1003
ParsedType getDestructorName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec &SS, ParsedType ObjectType, bool EnteringContext)
ASTContext & getASTContext() const
Definition: Sema.h:517
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:15667
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:4373
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:645
ExprResult BuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK)
Definition: SemaExpr.cpp:3536
ExprResult BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, SourceLocation RParenLoc, Expr *LiteralExpr)
Definition: SemaExpr.cpp:7057
ExprResult ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc, LabelDecl *TheDecl)
ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
Definition: SemaExpr.cpp:15719
Expr * recreateSyntacticForm(PseudoObjectExpr *E)
Given a pseudo-object expression, recreate what it looks like syntactically without the attendant Opa...
ExprResult ActOnParenListExpr(SourceLocation L, SourceLocation R, MultiExprArg Val)
Definition: SemaExpr.cpp:7956
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:17036
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
Definition: SemaExpr.cpp:2208
QualType BuildBitIntType(bool IsUnsigned, Expr *BitWidth, SourceLocation Loc)
Build a bit-precise integer type.
Definition: SemaType.cpp:1963
ExprResult ActOnChooseExpr(SourceLocation BuiltinLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr, SourceLocation RPLoc)
Definition: SemaExpr.cpp:16007
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:1677
QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs, const DeclSpec *DS=nullptr)
Definition: SemaType.cpp:1553
StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body)
Definition: SemaStmt.cpp:1246
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
Definition: Sema.cpp:65
const LangOptions & getLangOpts() const
Definition: Sema.h:510
StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, ConditionResult Cond, SourceLocation RParenLoc, Stmt *Body)
Definition: SemaStmt.cpp:1720
SemaOpenACC & OpenACC()
Definition: Sema.h:1008
@ ReuseLambdaContextDecl
Definition: Sema.h:5194
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:16678
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:15821
sema::LambdaScopeInfo * getCurLambda(bool IgnoreNonLambdaCapturingScope=false)
Retrieve the current lambda scope info, if any.
Definition: Sema.cpp:2366
ExprResult TemporaryMaterializationConversion(Expr *E)
If E is a prvalue denoting an unmaterialized temporary, materialize it as an xvalue.
Definition: SemaInit.cpp:8564
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:692
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:17007
ExprResult BuildExpressionTrait(ExpressionTrait OET, SourceLocation KWLoc, Expr *Queried, SourceLocation RParen)
bool buildCoroutineParameterMoves(SourceLocation Loc)
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
Definition: SemaCast.cpp:3341
ExprResult BuildCXXUuidof(QualType TypeInfoType, SourceLocation TypeidLoc, TypeSourceInfo *Operand, SourceLocation RParenLoc)
Build a Microsoft __uuidof expression with a type operand.
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:882
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
Definition: SemaDecl.cpp:14970
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:1856
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:10216
ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool NeedsADL, bool AcceptInvalidDecl=false)
Definition: SemaExpr.cpp:3232
sema::BlockScopeInfo * getCurBlock()
Retrieve the current block, if any.
Definition: Sema.cpp:2322
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:986
VarDecl * BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id)
Perform semantic analysis for the variable declaration that occurs within a C++ catch clause,...
bool BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo, bool EnteringContext, CXXScopeSpec &SS, NamedDecl *ScopeLookupResult, bool ErrorRecoveryLookup, bool *IsCorrectedToColon=nullptr, bool OnlyNamespace=false)
Build a new nested-name-specifier for "identifier::", as described by ActOnCXXNestedNameSpecifier.
ExprResult BuildPackIndexingExpr(Expr *PackExpression, SourceLocation EllipsisLoc, Expr *IndexExpr, SourceLocation RSquareLoc, ArrayRef< Expr * > ExpandedExprs={}, bool EmptyPack=false)
void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base=nullptr)
Perform reference-marking and odr-use handling for a DeclRefExpr.
Definition: SemaExpr.cpp:19837
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:2919
StmtResult ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *First, ConditionResult Second, FullExprArg Third, SourceLocation RParenLoc, Stmt *Body)
Definition: SemaStmt.cpp:2165
StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, Expr *DestExp)
Definition: SemaStmt.cpp:3169
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Definition: SemaExpr.cpp:4151
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
Definition: SemaExpr.cpp:20806
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:3145
@ NTK_TypeAliasTemplate
Definition: Sema.h:3153
TryCaptureKind
Definition: Sema.h:5236
@ TryCapture_Implicit
Definition: Sema.h:5237
@ TryCapture_ExplicitByVal
Definition: Sema.h:5238
@ TryCapture_ExplicitByRef
Definition: Sema.h:5239
ExprResult BuildAsTypeExpr(Expr *E, QualType DestTy, SourceLocation BuiltinLoc, SourceLocation RParenLoc)
Create a new AsTypeExpr node (bitcast) from the arguments.
Definition: SemaExpr.cpp:6699
ExprResult checkPseudoObjectRValue(Expr *E)
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:8829
QualType BuildPackIndexingType(QualType Pattern, Expr *IndexExpr, SourceLocation Loc, SourceLocation EllipsisLoc, bool FullySubstituted=false, ArrayRef< QualType > Expansions={})
Definition: SemaType.cpp:9468
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:9751
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:13960
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:228
StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, bool AllowRecovery=false)
Definition: SemaStmt.cpp:3849
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:1791
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:2616
StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation CondLParen, Expr *Cond, SourceLocation CondRParen)
Definition: SemaStmt.cpp:1741
StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc)
Definition: SemaStmt.cpp:1122
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:9436
QualType BuildUnaryTransformType(QualType BaseType, UTTKind UKind, SourceLocation Loc)
Definition: SemaType.cpp:9695
StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
Definition: SemaStmt.cpp:4411
ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo, SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, SourceRange R)
Build a sizeof or alignof expression given a type operand.
Definition: SemaExpr.cpp:4654
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
Definition: SemaStmt.cpp:79
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)
MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups,...
SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts
A stack of expression evaluation contexts.
Definition: Sema.h:6362
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:2086
ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field)
Definition: SemaExpr.cpp:5600
QualType BuildReadPipeType(QualType T, SourceLocation Loc)
Build a Read-only Pipe type.
Definition: SemaType.cpp:1939
concepts::NestedRequirement * BuildNestedRequirement(Expr *E)
QualType BuildWritePipeType(QualType T, SourceLocation Loc)
Build a Write-only Pipe type.
Definition: SemaType.cpp:1951
@ BFRK_Rebuild
Instantiation or recovery rebuild of a for-range statement.
Definition: Sema.h:8488
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:548
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:16208
QualType BuildTypeofExprType(Expr *E, TypeOfKind Kind)
Definition: SemaType.cpp:9325
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:19860
ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)
Definition: SemaCast.cpp:298
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:17940
QualType BuildMatrixType(QualType T, Expr *NumRows, Expr *NumColumns, SourceLocation AttrLoc)
Definition: SemaType.cpp:2488
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:20999
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
Definition: SemaExpr.cpp:15232
ExprResult PerformObjectMemberConversion(Expr *From, NestedNameSpecifier *Qualifier, NamedDecl *FoundDecl, NamedDecl *Member)
Cast a base object to a member's actual type.
Definition: SemaExpr.cpp:3012
StmtResult ActOnIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)
Definition: SemaStmt.cpp:909
ExprResult BuildInitList(SourceLocation LBraceLoc, MultiExprArg InitArgList, SourceLocation RBraceLoc)
Definition: SemaExpr.cpp:7257
void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope)
ActOnBlockStart - This callback is invoked when a block literal is started.
Definition: SemaExpr.cpp:16046
ExprResult ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, MultiExprArg ArgExprs, SourceLocation RLoc)
Definition: SemaExpr.cpp:4878
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:14696
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:6431
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Definition: SemaType.cpp:2805
static ConditionResult ConditionError()
Definition: Sema.h:5815
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
Definition: SemaStmt.cpp:415
StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt)
Definition: SemaStmt.cpp:573
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:4260
QualType BuildCountAttributedArrayType(QualType WrappedTy, Expr *CountExpr)
Definition: SemaType.cpp:9348
StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope)
Definition: SemaStmt.cpp:553
ExprResult HandleExprEvaluationContextForTypeof(Expr *E)
Definition: SemaExpr.cpp:17765
StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHS, SourceLocation DotDotDotLoc, ExprResult RHS, SourceLocation ColonLoc)
Definition: SemaStmt.cpp:516
QualType BuildMemberPointerType(QualType T, QualType Class, SourceLocation Loc, DeclarationName Entity)
Build a member pointer type T Class::*.
Definition: SemaType.cpp:2725
QualType BuildBlockPointerType(QualType T, SourceLocation Loc, DeclarationName Entity)
Build a block pointer type.
Definition: SemaType.cpp:2788
StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body)
FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement.
Definition: SemaStmt.cpp:3136
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Definition: Sema.h:6650
ExprResult CreateBuiltinMatrixSubscriptExpr(Expr *Base, Expr *RowIdx, Expr *ColumnIdx, SourceLocation RBLoc)
Definition: SemaExpr.cpp:5053
StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, IdentifierInfo **Names, MultiExprArg Constraints, MultiExprArg Exprs, Expr *AsmString, MultiExprArg Clobbers, unsigned NumLabels, SourceLocation RParenLoc)
static SizeOfPackExpr * Create(ASTContext &Context, SourceLocation OperatorLoc, NamedDecl *Pack, SourceLocation PackLoc, SourceLocation RParenLoc, std::optional< unsigned > Length=std::nullopt, ArrayRef< TemplateArgument > PartialArgs=std::nullopt)
Definition: ExprCXX.cpp:1644
static bool MayBeDependent(SourceLocIdentKind Kind)
Definition: Expr.h:4787
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
StmtClass
Definition: Stmt.h:86
@ NoStmtClass
Definition: Stmt.h:87
StmtClass getStmtClass() const
Definition: Stmt.h:1358
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:326
A structure for storing an already-substituted template template parameter pack.
Definition: TemplateName.h:141
Wrapper for substituted template type parameters.
Definition: TypeLoc.h:864
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3584
A convenient class for passing around template argument information.
Definition: TemplateBase.h:632
void setLAngleLoc(SourceLocation Loc)
Definition: TemplateBase.h:650
void setRAngleLoc(SourceLocation Loc)
Definition: TemplateBase.h:651
void addArgument(const TemplateArgumentLoc &Loc)
Definition: TemplateBase.h:667
llvm::ArrayRef< TemplateArgumentLoc > arguments() const
Definition: TemplateBase.h:659
const TemplateArgumentLoc * operator->() const
Simple iterator that traverses the template arguments in a container that provides a getArgLoc() memb...
TemplateArgumentLocContainerIterator operator++(int)
friend bool operator!=(const TemplateArgumentLocContainerIterator &X, const TemplateArgumentLocContainerIterator &Y)
TemplateArgumentLocContainerIterator(ArgLocContainer &Container, unsigned Index)
friend bool operator==(const TemplateArgumentLocContainerIterator &X, const TemplateArgumentLocContainerIterator &Y)
TemplateArgumentLocContainerIterator & operator++()
const TemplateArgumentLoc * operator->() const
Iterator adaptor that invents template argument location information for each of the template argumen...
TemplateArgumentLocInventIterator & operator++()
std::iterator_traits< InputIterator >::difference_type difference_type
TemplateArgumentLocInventIterator operator++(int)
friend bool operator==(const TemplateArgumentLocInventIterator &X, const TemplateArgumentLocInventIterator &Y)
TemplateArgumentLocInventIterator(TreeTransform< Derived > &Self, InputIterator Iter)
friend bool operator!=(const TemplateArgumentLocInventIterator &X, const TemplateArgumentLocInventIterator &Y)
std::input_iterator_tag iterator_category
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:574
SourceLocation getTemplateNameLoc() const
Definition: TemplateBase.h:616
TypeSourceInfo * getTypeSourceInfo() const
Definition: TemplateBase.h:578
SourceRange getSourceRange() const LLVM_READONLY
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Definition: TemplateBase.h:609
Expr * getSourceExpression() const
Definition: TemplateBase.h:584
Represents a template argument.
Definition: TemplateBase.h:61
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:408
QualType getNonTypeTemplateArgumentType() const
If this is a non-type template argument, get its type.
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:319
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:363
TemplateName getAsTemplate() const
Retrieve the template name for a template name argument.
Definition: TemplateBase.h:343
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
Definition: TemplateBase.h:326
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
Definition: TemplateBase.h:74
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:93
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
Definition: TemplateBase.h:89
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:107
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:97
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
Definition: TemplateBase.h:78
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
Definition: TemplateBase.h:67
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:82
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:103
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:295
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
Definition: TemplateBase.h:396
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
Represents a C++ template name within the type system.
Definition: TemplateName.h:202
bool isNull() const
Determine whether this template name is NULL.
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI)
Definition: TypeLoc.h:1687
void setTemplateKeywordLoc(SourceLocation Loc)
Definition: TypeLoc.h:1663
void setTemplateNameLoc(SourceLocation Loc)
Definition: TypeLoc.h:1704
void setLAngleLoc(SourceLocation Loc)
Definition: TypeLoc.h:1671
SourceLocation getTemplateNameLoc() const
Definition: TypeLoc.h:1700
void setRAngleLoc(SourceLocation Loc)
Definition: TypeLoc.h:1679
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:6089
Wrapper for template type parameters.
Definition: TypeLoc.h:758
The top declaration context.
Definition: Decl.h:84
RAII object that temporarily sets the base location and entity used for reporting diagnostics in type...
TemporaryBase(TreeTransform &Self, SourceLocation Location, DeclarationName Entity)
A semantic tree transformation that allows one to transform one abstract syntax tree into another.
ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *object)
Rebuild the operand to an Objective-C @synchronized statement.
OMPClause * RebuildOMPNontemporalClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'nontemporal' clause.
ExprResult TransformInitializer(Expr *Init, bool NotCopyInit)
Transform the given initializer.
StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L, SourceLocation ColonLoc, Stmt *SubStmt)
Build a new label statement.
StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args)
StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc, Stmt *Body)
Build a new Objective-C @autoreleasepool statement.
OMPClause * RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Build a new OpenMP 'dist_schedule' clause.
ExprResult RebuildUnaryOperator(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *SubExpr)
Build a new unary operator expression.
OMPClause * RebuildOMPProcBindClause(ProcBindKind Kind, SourceLocation KindKwLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'proc_bind' clause.
ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field)
Build a new C++11 default-initialization expression.
OMPClause * RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'priority' clause.
ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc, TypeSourceInfo *EncodeTypeInfo, SourceLocation RParenLoc)
Build a new Objective-C @encode expression.
StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body)
Alternative implementation of TransformLambdaBody that skips transforming the body.
QualType TransformAttributedType(TypeLocBuilder &TLB, AttributedTypeLoc TL, Fn TransformModifiedType)
ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc, SourceLocation OpLoc, bool IsArrow)
Build a new Objective-C "isa" expression.
StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc, Stmt *Body)
Build a new Objective-C @finally statement.
SourceLocation getBaseLocation()
Returns the location of the entity being transformed, if that information was not available elsewhere...
ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc, Expr *ExecConfig=nullptr)
Build a new call expression.
ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar, SourceLocation IvarLoc, bool IsArrow, bool IsFreeIvar)
Build a new Objective-C ivar reference expression.
OMPClause * RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'at' clause.
StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result, bool IsImplicit)
Build a new co_return statement.
OMPClause * RebuildOMPInReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions)
Build a new OpenMP 'in_reduction' clause.
ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, SourceLocation RParenLoc, Expr *Init)
Build a new compound literal expression.
ExprResult TransformAddressOfOperand(Expr *E)
The operand of a unary address-of operator has special rules: it's allowed to refer to a non-static m...
ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc, QualType ThisType, bool isImplicit)
Build a new C++ "this" expression.
ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType, SourceLocation TypeidLoc, Expr *Operand, SourceLocation RParenLoc)
Build a new C++ typeid(expr) expression.
TreeTransform(Sema &SemaRef)
Initializes a new tree transformer.
QualType RebuildDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const IdentifierInfo *Name, SourceLocation NameLoc, TemplateArgumentListInfo &Args, bool AllowInjectedClassName)
Build a new typename type that refers to a template-id.
QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr, Expr *ColumnExpr, SourceLocation AttributeLoc)
Build a new matrix type given the type and dependently-defined dimensions.
QualType RebuildUnaryTransformType(QualType BaseType, UnaryTransformType::UTTKind UKind, SourceLocation Loc)
Build a new unary transform type.
ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg, ObjCPropertyDecl *Property, SourceLocation PropertyLoc)
Build a new Objective-C property reference expression.
void InventTemplateArgumentLoc(const TemplateArgument &Arg, TemplateArgumentLoc &ArgLoc)
Fakes up a TemplateArgumentLoc for a given TemplateArgument.
OMPClause * RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Build a new OpenMP 'use' clause.
QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL)
Transform the given type-with-location into a new type, collecting location information in the given ...
ExprResult RebuildCXXRewrittenBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opcode, const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS)
Build a new rewritten operator expression.
ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E, bool IsAddressOfOperand)
ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy, SourceLocation BuiltinLoc, SourceLocation RPLoc, DeclContext *ParentContext)
Build a new expression representing a call to a source location builtin.
QualType RebuildEnumType(EnumDecl *Enum)
Build a new Enum type.
TemplateName RebuildTemplateName(const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index, bool Final)
Build a new template name given a template template parameter pack and the.
ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, std::optional< unsigned > NumExpansions)
Build a new expression pack expansion.
QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL)
Transforms a reference type.
OMPClause * RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'message' clause.
ExprResult RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc, TypeSourceInfo *TInfo, SourceLocation RAngleLoc, SourceLocation LParenLoc, Expr *SubExpr, SourceLocation RParenLoc)
QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind)
Build a new typeof(type) type.
ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, Expr *SubExpr, TypeSourceInfo *TInfo, SourceLocation RParenLoc)
Build a new va_arg expression.
ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo, SourceLocation LParenLoc, SourceLocation RParenLoc)
Build a new C++ zero-initialization expression.
StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr)
StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block)
OMPClause * RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'simdlen' clause.
StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef< Stmt * > Handlers)
Build a new C++ try statement.
StmtDiscardKind
The reason why the value of a statement is not discarded, if any.
ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand, UnresolvedLookupExpr *OpCoawaitLookup, bool IsImplicit)
Build a new co_await expression.
bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs, unsigned NumInputs, TemplateArgumentListInfo &Outputs, bool Uneval=false)
Transform the given set of template arguments.
ExprResult RebuildDesignatedInitExpr(Designation &Desig, MultiExprArg ArrayExprs, SourceLocation EqualOrColonLoc, bool GNUSyntax, Expr *Init)
Build a new designated initializer expression.
OMPClause * RebuildOMPSizesClause(ArrayRef< Expr * > Sizes, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK)
Build a new predefined expression.
QualType RebuildElaboratedType(SourceLocation KeywordLoc, ElaboratedTypeKeyword Keyword, NestedNameSpecifierLoc QualifierLoc, QualType Named)
Build a new qualified name type.
ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc, TypeSourceInfo *TInfo, SourceLocation RAngleLoc, SourceLocation LParenLoc, Expr *SubExpr, SourceLocation RParenLoc)
Build a new C++ static_cast expression.
StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *Init, Sema::ConditionResult Cond, Sema::FullExprArg Inc, SourceLocation RParenLoc, Stmt *Body)
Build a new for statement.
StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, NestedNameSpecifierLoc QualifierLoc, DeclarationNameInfo NameInfo, Stmt *Nested)
Build a new C++0x range-based for statement.
ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt, SourceLocation RParenLoc, unsigned TemplateDepth)
Build a new GNU statement expression.
QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword, SourceLocation KeywordLoc, NestedNameSpecifierLoc QualifierLoc, const IdentifierInfo *Id, SourceLocation IdLoc, bool DeducedTSTContext)
Build a new typename type that refers to an identifier.
QualType RebuildTemplateSpecializationType(TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &Args)
Build a new template specialization type.
bool TryExpandParameterPacks(SourceLocation EllipsisLoc, SourceRange PatternRange, ArrayRef< UnexpandedParameterPack > Unexpanded, bool &ShouldExpand, bool &RetainExpansion, std::optional< unsigned > &NumExpansions)
Determine whether we should expand a pack expansion with the given set of parameter packs into separa...
Sema & getSema() const
Retrieves a reference to the semantic analysis object used for this tree transform.
ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs, SourceLocation RParenLoc)
Build a new shuffle vector expression.
QualType TransformType(QualType T)
Transforms the given type into another type.
OMPClause * RebuildOMPOrderClause(OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc)
Build a new OpenMP 'order' clause.
QualType RebuildReferenceType(QualType ReferentType, bool LValue, SourceLocation Sigil)
Build a new reference type given the type it references.
ExprResult TransformRequiresTypeParams(SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE, RequiresExprBodyDecl *Body, ArrayRef< ParmVarDecl * > Params, SmallVectorImpl< QualType > &PTypes, SmallVectorImpl< ParmVarDecl * > &TransParams, Sema::ExtParameterInfoBuilder &PInfos)
Transforms the parameters of a requires expresison into the given vectors.
ExprResult RebuildInitList(SourceLocation LBraceLoc, MultiExprArg Inits, SourceLocation RBraceLoc)
Build a new initializer list expression.
QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, SourceLocation ProtocolLAngleLoc, ArrayRef< ObjCProtocolDecl * > Protocols, ArrayRef< SourceLocation > ProtocolLocs, SourceLocation ProtocolRAngleLoc)
StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Operand)
Build a new Objective-C @throw statement.
OMPClause * RebuildOMPTaskReductionClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr * > UnresolvedReductions)
Build a new OpenMP 'task_reduction' clause.
OMPClause * RebuildOMPCopyinClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'copyin' clause.
QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc, bool isReadPipe)
Build a new pipe type given its value type.
StmtResult RebuildCaseStmt(SourceLocation CaseLoc, Expr *LHS, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation ColonLoc)
Build a new case statement.
ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS, SourceLocation TemplateKWLoc, LookupResult &R, bool RequiresADL, const TemplateArgumentListInfo *TemplateArgs)
Build a new template-id expression.
StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc, VarDecl *ExceptionDecl, Stmt *Handler)
Build a new C++ catch statement.
OMPClause * RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Build a new OpenMP 'destroy' clause.
ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, SourceRange R)
Build a new sizeof, alignof or vec step expression with an expression argument.
ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc, SourceLocation LabelLoc, LabelDecl *Label)
Build a new address-of-label expression.
ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc)
TemplateName TransformTemplateName(CXXScopeSpec &SS, TemplateName Name, SourceLocation NameLoc, QualType ObjectType=QualType(), NamedDecl *FirstQualifierInScope=nullptr, bool AllowInjectedClassName=false)
Transform the given template name.
OMPClause * RebuildOMPXBareClause(SourceLocation StartLoc, SourceLocation EndLoc)
Build a new OpenMP 'ompx_bare' clause.
const Attr * TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS, const Attr *A)
ExprResult RebuildConditionalOperator(Expr *Cond, SourceLocation QuestionLoc, Expr *LHS, SourceLocation ColonLoc, Expr *RHS)
Build a new conditional operator expression.
StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body)
Attach body to a C++0x range-based for statement.
StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc, Expr *Object, Stmt *Body)
Build a new Objective-C @synchronized statement.
TemplateName RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW, TemplateDecl *Template)
Build a new template name given a nested name specifier, a flag indicating whether the "template" key...
OMPClause * RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier, Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ModifierLoc, SourceLocation EndLoc)
Build a new OpenMP 'device' clause.
QualType TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL, TemplateName Template, CXXScopeSpec &SS)
OMPClause * RebuildOMPHasDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Build a new OpenMP 'has_device_addr' clause.
QualType RebuildDependentSizedExtVectorType(QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc)
Build a new potentially dependently-sized extended vector type given the element type and number of e...
void RememberPartiallySubstitutedPack(TemplateArgument Arg)
"Remember" the partially-substituted pack template argument after performing an instantiation that mu...
Decl * TransformDefinition(SourceLocation Loc, Decl *D)
Transform the definition of the given declaration.
OMPClause * RebuildOMPFromClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers)
Build a new OpenMP 'from' clause.
StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind, DeclarationNameInfo DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause * > Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind PrevMappedDirective=OMPD_unknown)
Build a new OpenMP executable directive.
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.
StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K, SourceLocation BeginLoc, SourceLocation EndLoc, ArrayRef< OpenACCClause * > Clauses, StmtResult StrBlock)
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.
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.
ExprResult RebuildImplicitValueInitExpr(QualType T)
Build a new value-initialized expression.
bool TransformFunctionTypeParams(SourceLocation Loc, ArrayRef< ParmVarDecl * > Params, const QualType *ParamTypes, const FunctionProtoType::ExtParameterInfo *ParamInfos, SmallVectorImpl< QualType > &PTypes, SmallVectorImpl< ParmVarDecl * > *PVars, Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed)
Transforms the parameters of a function type into the given vectors.
StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, IdentifierInfo **Names, MultiExprArg Constraints, MultiExprArg Exprs, Expr *AsmString, MultiExprArg Clobbers, unsigned NumLabels, SourceLocation RParenLoc)
Build a new inline asm statement.
StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S)
ExprResult RebuildObjCMessageExpr(Expr *Receiver, Selector Sel, ArrayRef< SourceLocation > SelectorLocs, ObjCMethodDecl *Method, SourceLocation LBracLoc, MultiExprArg Args, SourceLocation RBracLoc)
Build a new Objective-C instance message.
QualType TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool SuppressObjCLifetime)
ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool RequiresADL)
Build a new expression that references a declaration.
bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall, SmallVectorImpl< Expr * > &Outputs, bool *ArgChanged=nullptr)
Transform the given list of expressions.
StmtResult TransformSEHHandler(Stmt *Handler)
NestedNameSpecifierLoc TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, QualType ObjectType=QualType(), NamedDecl *FirstQualifierInScope=nullptr)
Transform the given nested-name-specifier with source-location information.
TemplateName RebuildTemplateName(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, OverloadedOperatorKind Operator, SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName)
Build a new template name given a nested name specifier and the overloaded operator name that is refe...
QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc)
Build a new C++11 decltype type.
OMPClause * RebuildOMPUseDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Build a new OpenMP 'use_device_ptr' clause.
QualType TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL, NestedNameSpecifierLoc QualifierLoc)
void ExpandingFunctionParameterPack(ParmVarDecl *Pack)
Note to the derived class when a function parameter pack is being expanded.
void setBase(SourceLocation Loc, DeclarationName Entity)
Sets the "base" location and entity when that information is known based on another transformation.
concepts::TypeRequirement * TransformTypeRequirement(concepts::TypeRequirement *Req)
const Derived & getDerived() const
Retrieves a reference to the derived class.
OMPClause * RebuildOMPAllocateClause(Expr *Allocate, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Build a new OpenMP 'allocate' clause.
ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen, SourceLocation RParen)
Build a new expression in parentheses.
OMPClause * RebuildOMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'num_threads' clause.
QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil)
Build a new block pointer type given its pointee type.
ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc, bool isArrow, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &MemberNameInfo, ValueDecl *Member, NamedDecl *FoundDecl, const TemplateArgumentListInfo *ExplicitTemplateArgs, NamedDecl *FirstQualifierInScope)
Build a new member access expression.
OMPClause * RebuildOMPSharedClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'shared' clause.
ExprResult RebuildCXXConstructExpr(QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor, bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates, bool ListInitialization, bool StdInitListInitialization, bool RequiresZeroInit, CXXConstructionKind ConstructKind, SourceRange ParenRange)
Build a new object-construction expression.
bool TransformFunctionTypeParams(SourceLocation Loc, ArrayRef< ParmVarDecl * > Params, const QualType *ParamTypes, const FunctionProtoType::ExtParameterInfo *ParamInfos, SmallVectorImpl< QualType > &PTypes, SmallVectorImpl< ParmVarDecl * > *PVars, Sema::ExtParameterInfoBuilder &PInfos)
OMPClause * RebuildOMPLinearClause(ArrayRef< Expr * > VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation StepModifierLoc, SourceLocation EndLoc)
Build a new OpenMP 'linear' clause.
VarDecl * RebuildExceptionDecl(VarDecl *ExceptionDecl, TypeSourceInfo *Declarator, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id)
Build a new C++ exception declaration.
ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg)
Build a new noexcept expression.
QualType RebuildFunctionProtoType(QualType T, MutableArrayRef< QualType > ParamTypes, const FunctionProtoType::ExtProtoInfo &EPI)
Build a new function type.
ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB, Expr *Base, Expr *Key, ObjCMethodDecl *getterMethod, ObjCMethodDecl *setterMethod)
ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc, ArrayRef< Expr * > SubExprs, QualType Type)
QualType RebuildIncompleteArrayType(QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals, SourceRange BracketsRange)
Build a new incomplete array type given the element type, size modifier, and index type qualifiers.
TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern, SourceLocation EllipsisLoc, std::optional< unsigned > NumExpansions)
Build a new template argument pack expansion.
CXXRecordDecl::LambdaDependencyKind ComputeLambdaDependency(LambdaScopeInfo *LSI)
ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, SourceLocation LParenLoc, Expr *Sub, SourceLocation RParenLoc, bool ListInitialization)
Build a new C++ functional-style cast expression.
TypeSourceInfo * TransformType(TypeSourceInfo *DI)
Transforms the given type-with-location into a new type-with-location.
ExprResult RebuildObjCDictionaryLiteral(SourceRange Range, MutableArrayRef< ObjCDictionaryElement > Elements)
Build a new Objective-C dictionary literal.
StmtResult TransformStmt(Stmt *S, StmtDiscardKind SDK=SDK_Discarded)
Transform the given statement.
StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, Expr *Target)
Build a new indirect goto statement.
ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc, bool IsArrow, SourceLocation AccessorLoc, IdentifierInfo &Accessor)
Build a new extended vector element access expression.
ExprResult RebuildParenListExpr(SourceLocation LParenLoc, MultiExprArg SubExprs, SourceLocation RParenLoc)
Build a new expression list in parentheses.
OMPClause * RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'allocator' clause.
QualType RebuildDependentSizedArrayType(QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange)
Build a new dependent-sized array type given the element type, size modifier, size expression,...
NamedDecl * TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc)
Transform the given declaration, which was the first part of a nested-name-specifier in a member acce...
OMPClause * RebuildOMPInclusiveClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'inclusive' clause.
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.
ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E)
OMPClause * RebuildOMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'num_teams' clause.
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.
OMPClause * RebuildOMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'thread_limit' clause.
StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc, Stmt *Element, Expr *Collection, SourceLocation RParenLoc, Stmt *Body)
Build a new Objective-C fast enumeration statement.
ExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI)
Build a new (previously unresolved) declaration reference expression.
StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc, Stmt *TryBody, MultiStmtArg CatchStmts, Stmt *Finally)
Build a new Objective-C @try statement.
DeclarationName getBaseEntity()
Returns the name of the entity being transformed, if that information was not available elsewhere in ...
ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc, bool ListInitialization)
Build a new object-construction expression.
ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack, SourceLocation PackLoc, SourceLocation RParenLoc, std::optional< unsigned > Length, ArrayRef< TemplateArgument > PartialArgs)
Build a new expression to compute the length of a parameter pack.
ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc, bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First, Expr *Second)
Build a new overloaded operator call expression.
OMPClause * RebuildOMPUseDeviceAddrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Build a new OpenMP 'use_device_addr' clause.
QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc)
Build a dependent bit-precise int given its value type.
OMPClause * RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'hint' clause.
Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind)
Transform the specified condition.
TemplateName RebuildTemplateName(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name, SourceLocation NameLoc, QualType ObjectType, NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName)
Build a new template name given a nested name specifier and the name that is referred to as a templat...
OMPClause * RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind, SourceLocation KwLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'severity' clause.
OMPClause * RebuildOMPFirstprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'firstprivate' clause.
StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, ArrayRef< Token > AsmToks, StringRef AsmString, unsigned NumOutputs, unsigned NumInputs, ArrayRef< StringRef > Constraints, ArrayRef< StringRef > Clobbers, ArrayRef< Expr * > Exprs, SourceLocation EndLoc)
Build a new MS style inline asm statement.
QualType TransformTemplateSpecializationType(TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL, TemplateName Template)
VarDecl * RebuildObjCExceptionDecl(VarDecl *ExceptionDecl, TypeSourceInfo *TInfo, QualType T)
Rebuild an Objective-C exception declaration.
concepts::NestedRequirement * TransformNestedRequirement(concepts::NestedRequirement *Req)
QualType RebuildConstantArrayType(QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size, Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange)
Build a new constant array type given the element type, size modifier, (known) size of the array,...
ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc, SourceLocation RParenLoc, ArrayRef< Expr * > Dims, ArrayRef< SourceRange > BracketsRanges)
Build a new array shaping expression.
ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc, bool IsGlobalDelete, bool IsArrayForm, Expr *Operand)
Build a new C++ "delete" expression.
bool TransformExceptionSpec(SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI, SmallVectorImpl< QualType > &Exceptions, bool &Changed)
QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D)
Rebuild an unresolved typename type, given the decl that the UnresolvedUsingTypenameDecl was transfor...
ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait, SourceLocation StartLoc, TypeSourceInfo *TSInfo, Expr *DimExpr, SourceLocation RParenLoc)
Build a new array type trait expression.
OMPClause * RebuildOMPIsDevicePtrClause(ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs)
Build a new OpenMP 'is_device_ptr' clause.
QualType RebuildMacroQualifiedType(QualType T, const IdentifierInfo *MacroII)
Build a new MacroDefined type.
concepts::NestedRequirement * RebuildNestedRequirement(Expr *Constraint)
ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx, Expr *ColumnIdx, SourceLocation RBracketLoc)
Build a new matrix subscript expression.
ExprResult TransformParenDependentScopeDeclRefExpr(ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand, TypeSourceInfo **RecoveryTSI)
TemplateParameterList * TransformTemplateParameterList(TemplateParameterList *TPL)
QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType, SourceLocation Sigil)
Build a new member pointer type given the pointee type and the class type it refers into.
void transformAttrs(Decl *Old, Decl *New)
Transform the attributes associated with the given declaration and place them on the new declaration.
Decl * TransformDecl(SourceLocation Loc, Decl *D)
Transform the given declaration, which is referenced from a type or expression.
bool AlwaysRebuild()
Whether the transformation should always rebuild AST nodes, even if none of the children have changed...
ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc, Selector Sel, ArrayRef< SourceLocation > SelectorLocs, QualType SuperType, ObjCMethodDecl *Method, SourceLocation LBracLoc, MultiExprArg Args, SourceLocation RBracLoc)
Build a new Objective-C instance/class message to 'super'.
OMPClause * RebuildOMPLastprivateClause(ArrayRef< Expr * > VarList, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'lastprivate' clause.
QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc, VectorKind)
Build a new potentially dependently-sized extended vector type given the element type and number of e...
bool AllowSkippingCXXConstructExpr()
Wether CXXConstructExpr can be skipped when they are implicit.
OMPClause * RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'safelen' clause.
StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc, SourceLocation LParenLoc, Stmt *Init, Sema::ConditionResult Cond, SourceLocation RParenLoc)
Start building a new switch statement.
StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt)
Build a new default statement.
StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc, SourceLocation RParenLoc, VarDecl *Var, Stmt *Body)
Build a new Objective-C @catch statement.
OMPClause * RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'filter' clause.
ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base, SourceLocation OperatorLoc, bool isArrow, CXXScopeSpec &SS, TypeSourceInfo *ScopeType, SourceLocation CCLoc, SourceLocation TildeLoc, PseudoDestructorTypeStorage Destroyed)
Build a new pseudo-destructor expression.
QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange, SourceLocation EllipsisLoc, std::optional< unsigned > NumExpansions)
Build a new pack expansion type.
QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits, SourceLocation Loc)
Build a bit-precise int given its value type.
ExprResult RebuildObjCArrayLiteral(SourceRange Range, Expr **Elements, unsigned NumElements)
Build a new Objective-C array literal.
ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc, TypeSourceInfo *Operand, SourceLocation RParenLoc)
Build a new C++ __uuidof(type) expression.
ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType, SourceLocation OperatorLoc, bool IsArrow, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, LookupResult &R, const TemplateArgumentListInfo *TemplateArgs)
Build a new member reference expression.
OMPClause * RebuildOMPBindClause(OpenMPBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'bind' clause.
concepts::NestedRequirement * RebuildNestedRequirement(StringRef InvalidConstraintEntity, const ASTConstraintSatisfaction &Satisfaction)
OMPClause * RebuildOMPCopyprivateClause(ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'copyprivate' clause.
QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword, ConceptDecl *TypeConstraintConcept, ArrayRef< TemplateArgument > TypeConstraintArgs)
Build a new C++11 auto type.
ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc, SourceLocation RSquareLoc, Expr *PackIdExpression, Expr *IndexExpr, ArrayRef< Expr * > ExpandedExprs, bool EmptyPack=false)
QualType RebuildVariableArrayType(QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange)
Build a new variable-length array type given the element type, size modifier, size expression,...
ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc, TypeSourceInfo *TInfo, SourceLocation RAngleLoc, SourceLocation LParenLoc, Expr *SubExpr, SourceLocation RParenLoc)
Build a new C++ dynamic_cast expression.
ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc, SourceLocation DefaultLoc, SourceLocation RParenLoc, TypeSourceInfo *ControllingType, ArrayRef< TypeSourceInfo * > Types, ArrayRef< Expr * > Exprs)
Build a new generic selection expression with a type predicate.
QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil)
Build a new pointer type given its pointee type.
concepts::TypeRequirement * RebuildTypeRequirement(concepts::Requirement::SubstitutionDiagnostic *SubstDiag)
OMPClause * RebuildOMPUsesAllocatorsClause(ArrayRef< SemaOpenMP::UsesAllocatorsData > Data, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'uses_allocators' clause.
ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor, bool ConstructsVBase, bool InheritedFromVBase)
Build a new implicit construction via inherited constructor expression.
ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc, TypeSourceInfo *TInfo, SourceLocation RAngleLoc, SourceLocation LParenLoc, Expr *SubExpr, SourceLocation RParenLoc)
Build a new C++ const_cast expression.
ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs, AtomicExpr::AtomicOp Op, SourceLocation RParenLoc)
Build a new atomic operation expression.
DeclarationNameInfo TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo)
Transform the given declaration name.
OMPClause * RebuildOMPXAttributeClause(ArrayRef< const Attr * > Attrs, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'ompx_attribute' clause.
ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE, SourceLocation LParenLoc, Expr *LHS, BinaryOperatorKind Operator, SourceLocation EllipsisLoc, Expr *RHS, SourceLocation RParenLoc, std::optional< unsigned > NumExpansions)
Build a new C++1z fold-expression.
OMPClause * RebuildOMPToClause(ArrayRef< OpenMPMotionModifierKind > MotionModifiers, ArrayRef< SourceLocation > MotionModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers)
Build a new OpenMP 'to' clause.
StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation LParenLoc, Expr *Cond, SourceLocation RParenLoc)
Build a new do-while statement.
OMPClause * RebuildOMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Build a new OpenMP 'if' clause.
StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body)
Attach the body to a new case statement.
ExprResult RebuildTypeTrait(TypeTrait Trait, SourceLocation StartLoc, ArrayRef< TypeSourceInfo * > Args, SourceLocation RParenLoc)
Build a new type trait expression.
ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, BinaryOperatorKind Operator)
Build an empty C++1z fold-expression with the given operator.
QualType TransformTypeWithDeducedTST(QualType T)
Transform a type that is permitted to produce a DeducedTemplateSpecializationType.
OMPClause * RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc)
Build a new OpenMP 'init' clause.
OMPClause * RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'detach' clause.
StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc, MultiStmtArg Statements, SourceLocation RBraceLoc, bool IsStmtExpr)
Build a new compound statement.
ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc, ValueDecl *VD, const DeclarationNameInfo &NameInfo, NamedDecl *Found, TemplateArgumentListInfo *TemplateArgs)
Build a new expression that references a declaration.
QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size, Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange)
Build a new array type given the element type, size modifier, size of the array (if known),...
StmtResult RebuildDeclStmt(MutableArrayRef< Decl * > Decls, SourceLocation StartLoc, SourceLocation EndLoc)
Build a new declaration statement.
QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying)
Build a new type found via an alias.
ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc, Expr *SrcExpr, TypeSourceInfo *DstTInfo, SourceLocation RParenLoc)
Build a new convert vector expression.
QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL)
Build a new qualified type given its unqualified type and type location.
OMPClause * RebuildOMPDependClause(OMPDependClause::DependDataTy Data, Expr *DepModifier, ArrayRef< Expr * > VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build a new OpenMP 'depend' pseudo clause.
OMPClause * RebuildOMPAlignedClause(ArrayRef< Expr * > VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Build a new OpenMP 'aligned' clause.
unsigned TransformTemplateDepth(unsigned Depth)
Transform a template parameter depth level.
QualType RebuildFunctionNoProtoType(QualType ResultType)
Build a new unprototyped function type.
QualType TransformFunctionProtoType(TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, Qualifiers ThisTypeQuals, Fn TransformExceptionSpec)
const Attr * TransformAttr(const Attr *S)
Transform the given attribute.
QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows, unsigned NumColumns)
Build a new matrix type given the element type and dimensions.
OMPClause * RebuildOMPMapClause(Expr *IteratorModifier, ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr * > VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr * > UnresolvedMappers)
Build a new OpenMP 'map' clause.
ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc, TypeSourceInfo *TSI, Expr *Sub, SourceLocation RParenLoc)
Build a new C++ __builtin_bit_cast expression.
QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr, SourceLocation Loc, SourceLocation EllipsisLoc, bool FullySubstituted, ArrayRef< QualType > Expansions={})
StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt)
Build a new OpenMP Canonical loop.
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.
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:747
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition: TypeLoc.h:2684
SourceLocation getBeginLoc() const
Get the begin source location.
Definition: TypeLoc.cpp:192
A container of type source information.
Definition: Type.h:7330
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:7341
static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword)
Converts an elaborated type keyword into a TagTypeKind.
Definition: Type.cpp:3177
ElaboratedTypeKeyword getKeyword() const
Definition: Type.h:6329
The base class of the type hierarchy.
Definition: Type.h:1813
bool isPointerType() const
Definition: Type.h:7612
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8193
bool isReferenceType() const
Definition: Type.h:7624
bool isEnumeralType() const
Definition: Type.h:7710
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:695
bool canHaveNullability(bool ResultIfUnknown=true) const
Determine whether the given type can have a nullability specifier applied to it, i....
Definition: Type.cpp:4646
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
Definition: Type.h:2758
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2653
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:2320
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
Definition: Type.h:8046
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
Definition: Type.cpp:4906
bool isFunctionType() const
Definition: Type.h:7608
bool isObjCObjectPointerType() const
Definition: Type.h:7744
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8126
bool isRecordType() const
Definition: Type.h:7706
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3432
Wrapper for source info for typedefs.
Definition: TypeLoc.h:693
TypedefNameDecl * getTypedefNameDecl() const
Definition: TypeLoc.h:695
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition: Expr.h:2183
SourceLocation getOperatorLoc() const
getOperatorLoc - Return the location of the operator.
Definition: Expr.h:2232
Expr * getSubExpr() const
Definition: Expr.h:2228
Opcode getOpcode() const
Definition: Expr.h:2223
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO, bool Postfix)
Retrieve the unary opcode that corresponds to the given overloaded operator.
Definition: Expr.cpp:1414
Represents a C++ unqualified-id that has been parsed.
Definition: DeclSpec.h:1025
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition: ExprCXX.h:3197
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent)
Definition: ExprCXX.cpp:372
CXXRecordDecl * getNamingClass()
Gets the 'naming class' (in the sense of C++0x [class.access.base]p5) of the lookup.
Definition: ExprCXX.h:3270
bool requiresADL() const
True if this declaration should be extended by argument-dependent lookup.
Definition: ExprCXX.h:3265
A set of unresolved declarations.
Definition: UnresolvedSet.h:61
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:5144
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition: DeclCXX.h:3320
NamedDecl * getTargetDecl() const
Gets the underlying declaration which has been brought into the local scope.
Definition: DeclCXX.h:3384
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:706
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
@ CInit
C-style initialization with assignment.
Definition: Decl.h:923
@ CallInit
Call-style initialization (C++98)
Definition: Decl.h:926
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition: Decl.h:1155
bool isParameterPack() const
Determine whether this variable is actually a function parameter pack or init-capture pack.
Definition: Decl.cpp:2663
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
CXXRecordDecl * Lambda
The class that describes the lambda.
Definition: ScopeInfo.h:865
@ 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:589
bool Comp(InterpState &S, CodePtr OpPC)
1) Pops the value from the stack.
Definition: Interp.h:708
llvm::PointerUnion< const Decl *, const Expr * > DeclTy
Definition: Descriptor.h:27
CharSourceRange getSourceRange(const SourceRange &Range)
Returns the token CharSourceRange corresponding to Range.
Definition: FixIt.h:32
The JSON file list parser is used to communicate input to InstallAPI.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
@ OO_None
Not an overloaded operator.
Definition: OperatorKinds.h:22
@ NUM_OVERLOADED_OPERATORS
Definition: OperatorKinds.h:26
ArrayTypeTrait
Names for the array type traits.
Definition: TypeTraits.h:42
@ CPlusPlus23
Definition: LangStandard.h:60
AutoTypeKeyword
Which keyword(s) were used to create an AutoType.
Definition: Type.h:1772
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
Definition: OpenMPKinds.h:24
OpenMPDefaultmapClauseModifier
OpenMP modifiers for 'defaultmap' clause.
Definition: OpenMPKinds.h:118
OpenMPOrderClauseModifier
OpenMP modifiers for 'order' clause.
Definition: OpenMPKinds.h:171
IfStatementKind
In an if statement, this denotes whether the statement is a constexpr or consteval if statement.
Definition: Specifiers.h:39
CXXConstructionKind
Definition: ExprCXX.h:1534
@ 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:158
OpenMPAtClauseKind
OpenMP attributes for 'at' clause.
Definition: OpenMPKinds.h:135
@ LCK_ByCopy
Capturing by copy (a.k.a., by value)
Definition: Lambda.h:36
@ LCK_ByRef
Capturing by reference.
Definition: Lambda.h:37
@ LCK_StarThis
Capturing the *this object by copy.
Definition: Lambda.h:35
OpenMPReductionClauseModifier
OpenMP modifiers for 'reduction' clause.
Definition: OpenMPKinds.h:186
BinaryOperatorKind
TypeOfKind
The kind of 'typeof' expression we're after.
Definition: Type.h:921
OpenMPScheduleClauseModifier
OpenMP modifiers for 'schedule' clause.
Definition: OpenMPKinds.h:38
OpenMPDistScheduleClauseKind
OpenMP attributes for 'dist_schedule' clause.
Definition: OpenMPKinds.h:103
OpenMPDoacrossClauseModifier
OpenMP dependence types for 'doacross' clause.
Definition: OpenMPKinds.h:219
UnaryExprOrTypeTrait
Names for the "expression or type" traits.
Definition: TypeTraits.h:51
ExprResult ExprEmpty()
Definition: Ownership.h:271
StmtResult StmtError()
Definition: Ownership.h:265
@ Property
The type of a property.
@ Result
The result type of a method or function.
OpenMPBindClauseKind
OpenMP bindings for the 'bind' clause.
Definition: OpenMPKinds.h:200
ArraySizeModifier
Capture whether this is a normal array (e.g.
Definition: Type.h:3515
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
OpenMPLastprivateModifier
OpenMP 'lastprivate' clause modifier.
Definition: OpenMPKinds.h:157
OpenMPGrainsizeClauseModifier
Definition: OpenMPKinds.h:206
OpenMPNumTasksClauseModifier
Definition: OpenMPKinds.h:212
UnaryOperatorKind
ActionResult< Expr * > ExprResult
Definition: Ownership.h:248
TagTypeKind
The kind of a tag type.
Definition: Type.h:6299
bool transformOMPMappableExprListClause(TreeTransform< Derived > &TT, OMPMappableExprListClause< T > *C, llvm::SmallVectorImpl< Expr * > &Vars, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperIdInfo, llvm::SmallVectorImpl< Expr * > &UnresolvedMappers)
OpenACCDirectiveKind
Definition: OpenACCKinds.h:25
ExprResult ExprError()
Definition: Ownership.h:264
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
std::pair< NullabilityKind, bool > DiagNullabilityKind
A nullability kind paired with a bit indicating whether it used a context-sensitive keyword.
Definition: Diagnostic.h:1542
OpenMPSeverityClauseKind
OpenMP attributes for 'severity' clause.
Definition: OpenMPKinds.h:142
ActionResult< Stmt * > StmtResult
Definition: Ownership.h:249
OpenMPDefaultmapClauseKind
OpenMP attributes for 'defaultmap' clause.
Definition: OpenMPKinds.h:110
OpenMPLinearClauseKind
OpenMP attributes for 'linear' clause.
Definition: OpenMPKinds.h:62
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:132
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:136
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Definition: Ownership.h:229
const FunctionProtoType * T
std::pair< llvm::PointerUnion< const TemplateTypeParmType *, NamedDecl * >, SourceLocation > UnexpandedParameterPack
Definition: Sema.h:238
VectorKind
Definition: Type.h:3932
OpenMPDeviceClauseModifier
OpenMP modifiers for 'device' clause.
Definition: OpenMPKinds.h:47
SourceLocIdentKind
Definition: Expr.h:4714
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
Definition: Type.h:6274
@ None
No keyword precedes the qualified type name.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
OpenMPOrderClauseKind
OpenMP attributes for 'order' clause.
Definition: OpenMPKinds.h:164
TypeTrait
Names for traits that operate specifically on types.
Definition: TypeTraits.h:21
@ Parens
New-expression has a C++98 paren-delimited initializer.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_DynamicNone
throw()
@ EST_Uninstantiated
not instantiated yet
@ EST_Unevaluated
not evaluated yet, for special member function
@ EST_Dynamic
throw(T1, T2)
PredefinedIdentKind
Definition: Expr.h:1970
OpenMPScheduleClauseKind
OpenMP attributes for 'schedule' clause.
Definition: OpenMPKinds.h:30
static QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T)
MutableArrayRef< Expr * > MultiExprArg
Definition: Ownership.h:258
OpenMPMapClauseKind
OpenMP mapping kind for 'map' clause.
Definition: OpenMPKinds.h:70
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Definition: ASTConcept.h:93
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.
Holds information about the various types of exception specification.
Definition: Type.h:4707
FunctionDecl * SourceTemplate
The function template whose exception specification this is instantiated from, for EST_Uninstantiated...
Definition: Type.h:4723
ExceptionSpecificationType Type
The kind of exception specification this is.
Definition: Type.h:4709
ArrayRef< QualType > Exceptions
Explicitly-specified list of exception types.
Definition: Type.h:4712
Expr * NoexceptExpr
Noexcept expression, if this is a computed noexcept specification.
Definition: Type.h:4715
Extra information about a function prototype.
Definition: Type.h:4735
ExceptionSpecInfo ExceptionSpec
Definition: Type.h:4742
const ExtParameterInfo * ExtParameterInfos
Definition: Type.h:4743
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:9750
Keeps information about an identifier in a nested-name-spec.
Definition: Sema.h:2368
Location information for a TemplateArgument.
Definition: TemplateBase.h:472