17854 lines · c
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-exception6//===----------------------------------------------------------------------===//7//8// This file implements a semantic tree transformation that takes a given9// AST and rebuilds it, possibly transforming some nodes in the process.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H14#define LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H15 16#include "CoroutineStmtBuilder.h"17#include "TypeLocBuilder.h"18#include "clang/AST/Decl.h"19#include "clang/AST/DeclObjC.h"20#include "clang/AST/DeclTemplate.h"21#include "clang/AST/Expr.h"22#include "clang/AST/ExprCXX.h"23#include "clang/AST/ExprConcepts.h"24#include "clang/AST/ExprObjC.h"25#include "clang/AST/ExprOpenMP.h"26#include "clang/AST/OpenMPClause.h"27#include "clang/AST/Stmt.h"28#include "clang/AST/StmtCXX.h"29#include "clang/AST/StmtObjC.h"30#include "clang/AST/StmtOpenACC.h"31#include "clang/AST/StmtOpenMP.h"32#include "clang/AST/StmtSYCL.h"33#include "clang/Basic/DiagnosticParse.h"34#include "clang/Basic/OpenMPKinds.h"35#include "clang/Sema/Designator.h"36#include "clang/Sema/EnterExpressionEvaluationContext.h"37#include "clang/Sema/Lookup.h"38#include "clang/Sema/Ownership.h"39#include "clang/Sema/ParsedTemplate.h"40#include "clang/Sema/ScopeInfo.h"41#include "clang/Sema/SemaDiagnostic.h"42#include "clang/Sema/SemaInternal.h"43#include "clang/Sema/SemaObjC.h"44#include "clang/Sema/SemaOpenACC.h"45#include "clang/Sema/SemaOpenMP.h"46#include "clang/Sema/SemaPseudoObject.h"47#include "clang/Sema/SemaSYCL.h"48#include "clang/Sema/Template.h"49#include "llvm/ADT/ArrayRef.h"50#include "llvm/Support/ErrorHandling.h"51#include <algorithm>52#include <optional>53 54using namespace llvm::omp;55 56namespace clang {57using namespace sema;58 59// This helper class is used to facilitate pack expansion during tree transform.60struct UnexpandedInfo {61 SourceLocation Ellipsis;62 UnsignedOrNone OrigNumExpansions = std::nullopt;63 64 bool Expand = false;65 bool RetainExpansion = false;66 UnsignedOrNone NumExpansions = std::nullopt;67 bool ExpandUnderForgetSubstitions = false;68};69 70/// A semantic tree transformation that allows one to transform one71/// abstract syntax tree into another.72///73/// A new tree transformation is defined by creating a new subclass \c X of74/// \c TreeTransform<X> and then overriding certain operations to provide75/// behavior specific to that transformation. For example, template76/// instantiation is implemented as a tree transformation where the77/// transformation of TemplateTypeParmType nodes involves substituting the78/// template arguments for their corresponding template parameters; a similar79/// transformation is performed for non-type template parameters and80/// template template parameters.81///82/// This tree-transformation template uses static polymorphism to allow83/// subclasses to customize any of its operations. Thus, a subclass can84/// override any of the transformation or rebuild operators by providing an85/// operation with the same signature as the default implementation. The86/// overriding function should not be virtual.87///88/// Semantic tree transformations are split into two stages, either of which89/// can be replaced by a subclass. The "transform" step transforms an AST node90/// or the parts of an AST node using the various transformation functions,91/// then passes the pieces on to the "rebuild" step, which constructs a new AST92/// node of the appropriate kind from the pieces. The default transformation93/// routines recursively transform the operands to composite AST nodes (e.g.,94/// the pointee type of a PointerType node) and, if any of those operand nodes95/// were changed by the transformation, invokes the rebuild operation to create96/// a new AST node.97///98/// Subclasses can customize the transformation at various levels. The99/// most coarse-grained transformations involve replacing TransformType(),100/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),101/// TransformTemplateName(), or TransformTemplateArgument() with entirely102/// new implementations.103///104/// For more fine-grained transformations, subclasses can replace any of the105/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,106/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,107/// replacing TransformTemplateTypeParmType() allows template instantiation108/// to substitute template arguments for their corresponding template109/// parameters. Additionally, subclasses can override the \c RebuildXXX110/// functions to control how AST nodes are rebuilt when their operands change.111/// By default, \c TreeTransform will invoke semantic analysis to rebuild112/// AST nodes. However, certain other tree transformations (e.g, cloning) may113/// be able to use more efficient rebuild steps.114///115/// There are a handful of other functions that can be overridden, allowing one116/// to avoid traversing nodes that don't need any transformation117/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their118/// operands have not changed (\c AlwaysRebuild()), and customize the119/// default locations and entity names used for type-checking120/// (\c getBaseLocation(), \c getBaseEntity()).121template<typename Derived>122class TreeTransform {123 /// Private RAII object that helps us forget and then re-remember124 /// the template argument corresponding to a partially-substituted parameter125 /// pack.126 class ForgetPartiallySubstitutedPackRAII {127 Derived &Self;128 TemplateArgument Old;129 // Set the pack expansion index to -1 to avoid pack substitution and130 // indicate that parameter packs should be instantiated as themselves.131 Sema::ArgPackSubstIndexRAII ResetPackSubstIndex;132 133 public:134 ForgetPartiallySubstitutedPackRAII(Derived &Self)135 : Self(Self), ResetPackSubstIndex(Self.getSema(), std::nullopt) {136 Old = Self.ForgetPartiallySubstitutedPack();137 }138 139 ~ForgetPartiallySubstitutedPackRAII() {140 Self.RememberPartiallySubstitutedPack(Old);141 }142 };143 144protected:145 Sema &SemaRef;146 147 /// The set of local declarations that have been transformed, for148 /// cases where we are forced to build new declarations within the transformer149 /// rather than in the subclass (e.g., lambda closure types).150 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;151 152public:153 /// Initializes a new tree transformer.154 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }155 156 /// Retrieves a reference to the derived class.157 Derived &getDerived() { return static_cast<Derived&>(*this); }158 159 /// Retrieves a reference to the derived class.160 const Derived &getDerived() const {161 return static_cast<const Derived&>(*this);162 }163 164 static inline ExprResult Owned(Expr *E) { return E; }165 static inline StmtResult Owned(Stmt *S) { return S; }166 167 /// Retrieves a reference to the semantic analysis object used for168 /// this tree transform.169 Sema &getSema() const { return SemaRef; }170 171 /// Whether the transformation should always rebuild AST nodes, even172 /// if none of the children have changed.173 ///174 /// Subclasses may override this function to specify when the transformation175 /// should rebuild all AST nodes.176 ///177 /// We must always rebuild all AST nodes when performing variadic template178 /// pack expansion, in order to avoid violating the AST invariant that each179 /// statement node appears at most once in its containing declaration.180 bool AlwaysRebuild() { return static_cast<bool>(SemaRef.ArgPackSubstIndex); }181 182 /// Whether the transformation is forming an expression or statement that183 /// replaces the original. In this case, we'll reuse mangling numbers from184 /// existing lambdas.185 bool ReplacingOriginal() { return false; }186 187 /// Wether CXXConstructExpr can be skipped when they are implicit.188 /// They will be reconstructed when used if needed.189 /// This is useful when the user that cause rebuilding of the190 /// CXXConstructExpr is outside of the expression at which the TreeTransform191 /// started.192 bool AllowSkippingCXXConstructExpr() { return true; }193 194 /// Returns the location of the entity being transformed, if that195 /// information was not available elsewhere in the AST.196 ///197 /// By default, returns no source-location information. Subclasses can198 /// provide an alternative implementation that provides better location199 /// information.200 SourceLocation getBaseLocation() { return SourceLocation(); }201 202 /// Returns the name of the entity being transformed, if that203 /// information was not available elsewhere in the AST.204 ///205 /// By default, returns an empty name. Subclasses can provide an alternative206 /// implementation with a more precise name.207 DeclarationName getBaseEntity() { return DeclarationName(); }208 209 /// Sets the "base" location and entity when that210 /// information is known based on another transformation.211 ///212 /// By default, the source location and entity are ignored. Subclasses can213 /// override this function to provide a customized implementation.214 void setBase(SourceLocation Loc, DeclarationName Entity) { }215 216 /// RAII object that temporarily sets the base location and entity217 /// used for reporting diagnostics in types.218 class TemporaryBase {219 TreeTransform &Self;220 SourceLocation OldLocation;221 DeclarationName OldEntity;222 223 public:224 TemporaryBase(TreeTransform &Self, SourceLocation Location,225 DeclarationName Entity) : Self(Self) {226 OldLocation = Self.getDerived().getBaseLocation();227 OldEntity = Self.getDerived().getBaseEntity();228 229 if (Location.isValid())230 Self.getDerived().setBase(Location, Entity);231 }232 233 ~TemporaryBase() {234 Self.getDerived().setBase(OldLocation, OldEntity);235 }236 };237 238 /// Determine whether the given type \p T has already been239 /// transformed.240 ///241 /// Subclasses can provide an alternative implementation of this routine242 /// to short-circuit evaluation when it is known that a given type will243 /// not change. For example, template instantiation need not traverse244 /// non-dependent types.245 bool AlreadyTransformed(QualType T) {246 return T.isNull();247 }248 249 /// Transform a template parameter depth level.250 ///251 /// During a transformation that transforms template parameters, this maps252 /// an old template parameter depth to a new depth.253 unsigned TransformTemplateDepth(unsigned Depth) {254 return Depth;255 }256 257 /// Determine whether the given call argument should be dropped, e.g.,258 /// because it is a default argument.259 ///260 /// Subclasses can provide an alternative implementation of this routine to261 /// determine which kinds of call arguments get dropped. By default,262 /// CXXDefaultArgument nodes are dropped (prior to transformation).263 bool DropCallArgument(Expr *E) {264 return E->isDefaultArgument();265 }266 267 /// Determine whether we should expand a pack expansion with the268 /// given set of parameter packs into separate arguments by repeatedly269 /// transforming the pattern.270 ///271 /// By default, the transformer never tries to expand pack expansions.272 /// Subclasses can override this routine to provide different behavior.273 ///274 /// \param EllipsisLoc The location of the ellipsis that identifies the275 /// pack expansion.276 ///277 /// \param PatternRange The source range that covers the entire pattern of278 /// the pack expansion.279 ///280 /// \param Unexpanded The set of unexpanded parameter packs within the281 /// pattern.282 ///283 /// \param ShouldExpand Will be set to \c true if the transformer should284 /// expand the corresponding pack expansions into separate arguments. When285 /// set, \c NumExpansions must also be set.286 ///287 /// \param RetainExpansion Whether the caller should add an unexpanded288 /// pack expansion after all of the expanded arguments. This is used289 /// when extending explicitly-specified template argument packs per290 /// C++0x [temp.arg.explicit]p9.291 ///292 /// \param NumExpansions The number of separate arguments that will be in293 /// the expanded form of the corresponding pack expansion. This is both an294 /// input and an output parameter, which can be set by the caller if the295 /// number of expansions is known a priori (e.g., due to a prior substitution)296 /// and will be set by the callee when the number of expansions is known.297 /// The callee must set this value when \c ShouldExpand is \c true; it may298 /// set this value in other cases.299 ///300 /// \returns true if an error occurred (e.g., because the parameter packs301 /// are to be instantiated with arguments of different lengths), false302 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)303 /// must be set.304 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,305 SourceRange PatternRange,306 ArrayRef<UnexpandedParameterPack> Unexpanded,307 bool FailOnPackProducingTemplates,308 bool &ShouldExpand, bool &RetainExpansion,309 UnsignedOrNone &NumExpansions) {310 ShouldExpand = false;311 return false;312 }313 314 /// "Forget" about the partially-substituted pack template argument,315 /// when performing an instantiation that must preserve the parameter pack316 /// use.317 ///318 /// This routine is meant to be overridden by the template instantiator.319 TemplateArgument ForgetPartiallySubstitutedPack() {320 return TemplateArgument();321 }322 323 /// "Remember" the partially-substituted pack template argument324 /// after performing an instantiation that must preserve the parameter pack325 /// use.326 ///327 /// This routine is meant to be overridden by the template instantiator.328 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }329 330 /// "Forget" the template substitution to allow transforming the AST without331 /// any template instantiations. This is used to expand template packs when332 /// their size is not known in advance (e.g. for builtins that produce type333 /// packs).334 MultiLevelTemplateArgumentList ForgetSubstitution() { return {}; }335 void RememberSubstitution(MultiLevelTemplateArgumentList) {}336 337private:338 struct ForgetSubstitutionRAII {339 Derived &Self;340 MultiLevelTemplateArgumentList Old;341 342 public:343 ForgetSubstitutionRAII(Derived &Self) : Self(Self) {344 Old = Self.ForgetSubstitution();345 }346 347 ~ForgetSubstitutionRAII() { Self.RememberSubstitution(std::move(Old)); }348 };349 350public:351 /// Note to the derived class when a function parameter pack is352 /// being expanded.353 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }354 355 /// Transforms the given type into another type.356 ///357 /// By default, this routine transforms a type by creating a358 /// TypeSourceInfo for it and delegating to the appropriate359 /// function. This is expensive, but we don't mind, because360 /// this method is deprecated anyway; all users should be361 /// switched to storing TypeSourceInfos.362 ///363 /// \returns the transformed type.364 QualType TransformType(QualType T);365 366 /// Transforms the given type-with-location into a new367 /// type-with-location.368 ///369 /// By default, this routine transforms a type by delegating to the370 /// appropriate TransformXXXType to build a new type. Subclasses371 /// may override this function (to take over all type372 /// transformations) or some set of the TransformXXXType functions373 /// to alter the transformation.374 TypeSourceInfo *TransformType(TypeSourceInfo *TSI);375 376 /// Transform the given type-with-location into a new377 /// type, collecting location information in the given builder378 /// as necessary.379 ///380 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);381 382 /// Transform a type that is permitted to produce a383 /// DeducedTemplateSpecializationType.384 ///385 /// This is used in the (relatively rare) contexts where it is acceptable386 /// for transformation to produce a class template type with deduced387 /// template arguments.388 /// @{389 QualType TransformTypeWithDeducedTST(QualType T);390 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *TSI);391 /// @}392 393 /// The reason why the value of a statement is not discarded, if any.394 enum class StmtDiscardKind {395 Discarded,396 NotDiscarded,397 StmtExprResult,398 };399 400 /// Transform the given statement.401 ///402 /// By default, this routine transforms a statement by delegating to the403 /// appropriate TransformXXXStmt function to transform a specific kind of404 /// statement or the TransformExpr() function to transform an expression.405 /// Subclasses may override this function to transform statements using some406 /// other mechanism.407 ///408 /// \returns the transformed statement.409 StmtResult TransformStmt(Stmt *S,410 StmtDiscardKind SDK = StmtDiscardKind::Discarded);411 412 /// Transform the given statement.413 ///414 /// By default, this routine transforms a statement by delegating to the415 /// appropriate TransformOMPXXXClause function to transform a specific kind416 /// of clause. Subclasses may override this function to transform statements417 /// using some other mechanism.418 ///419 /// \returns the transformed OpenMP clause.420 OMPClause *TransformOMPClause(OMPClause *S);421 422 /// Transform the given attribute.423 ///424 /// By default, this routine transforms a statement by delegating to the425 /// appropriate TransformXXXAttr function to transform a specific kind426 /// of attribute. Subclasses may override this function to transform427 /// attributed statements/types using some other mechanism.428 ///429 /// \returns the transformed attribute430 const Attr *TransformAttr(const Attr *S);431 432 // Transform the given statement attribute.433 //434 // Delegates to the appropriate TransformXXXAttr function to transform a435 // specific kind of statement attribute. Unlike the non-statement taking436 // version of this, this implements all attributes, not just pragmas.437 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,438 const Attr *A);439 440 // Transform the specified attribute.441 //442 // Subclasses should override the transformation of attributes with a pragma443 // spelling to transform expressions stored within the attribute.444 //445 // \returns the transformed attribute.446#define ATTR(X) \447 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }448#include "clang/Basic/AttrList.inc"449 450 // Transform the specified attribute.451 //452 // Subclasses should override the transformation of attributes to do453 // transformation and checking of statement attributes. By default, this454 // delegates to the non-statement taking version.455 //456 // \returns the transformed attribute.457#define ATTR(X) \458 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \459 const X##Attr *A) { \460 return getDerived().Transform##X##Attr(A); \461 }462#include "clang/Basic/AttrList.inc"463 464 /// Transform the given expression.465 ///466 /// By default, this routine transforms an expression by delegating to the467 /// appropriate TransformXXXExpr function to build a new expression.468 /// Subclasses may override this function to transform expressions using some469 /// other mechanism.470 ///471 /// \returns the transformed expression.472 ExprResult TransformExpr(Expr *E);473 474 /// Transform the given initializer.475 ///476 /// By default, this routine transforms an initializer by stripping off the477 /// semantic nodes added by initialization, then passing the result to478 /// TransformExpr or TransformExprs.479 ///480 /// \returns the transformed initializer.481 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);482 483 /// Transform the given list of expressions.484 ///485 /// This routine transforms a list of expressions by invoking486 /// \c TransformExpr() for each subexpression. However, it also provides487 /// support for variadic templates by expanding any pack expansions (if the488 /// derived class permits such expansion) along the way. When pack expansions489 /// are present, the number of outputs may not equal the number of inputs.490 ///491 /// \param Inputs The set of expressions to be transformed.492 ///493 /// \param NumInputs The number of expressions in \c Inputs.494 ///495 /// \param IsCall If \c true, then this transform is being performed on496 /// function-call arguments, and any arguments that should be dropped, will497 /// be.498 ///499 /// \param Outputs The transformed input expressions will be added to this500 /// vector.501 ///502 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed503 /// due to transformation.504 ///505 /// \returns true if an error occurred, false otherwise.506 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,507 SmallVectorImpl<Expr *> &Outputs,508 bool *ArgChanged = nullptr);509 510 /// Transform the given declaration, which is referenced from a type511 /// or expression.512 ///513 /// By default, acts as the identity function on declarations, unless the514 /// transformer has had to transform the declaration itself. Subclasses515 /// may override this function to provide alternate behavior.516 Decl *TransformDecl(SourceLocation Loc, Decl *D) {517 llvm::DenseMap<Decl *, Decl *>::iterator Known518 = TransformedLocalDecls.find(D);519 if (Known != TransformedLocalDecls.end())520 return Known->second;521 522 return D;523 }524 525 /// Transform the specified condition.526 ///527 /// By default, this transforms the variable and expression and rebuilds528 /// the condition.529 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,530 Expr *Expr,531 Sema::ConditionKind Kind);532 533 /// Transform the attributes associated with the given declaration and534 /// place them on the new declaration.535 ///536 /// By default, this operation does nothing. Subclasses may override this537 /// behavior to transform attributes.538 void transformAttrs(Decl *Old, Decl *New) { }539 540 /// Note that a local declaration has been transformed by this541 /// transformer.542 ///543 /// Local declarations are typically transformed via a call to544 /// TransformDefinition. However, in some cases (e.g., lambda expressions),545 /// the transformer itself has to transform the declarations. This routine546 /// can be overridden by a subclass that keeps track of such mappings.547 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {548 assert(New.size() == 1 &&549 "must override transformedLocalDecl if performing pack expansion");550 TransformedLocalDecls[Old] = New.front();551 }552 553 /// Transform the definition of the given declaration.554 ///555 /// By default, invokes TransformDecl() to transform the declaration.556 /// Subclasses may override this function to provide alternate behavior.557 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {558 return getDerived().TransformDecl(Loc, D);559 }560 561 /// Transform the given declaration, which was the first part of a562 /// nested-name-specifier in a member access expression.563 ///564 /// This specific declaration transformation only applies to the first565 /// identifier in a nested-name-specifier of a member access expression, e.g.,566 /// the \c T in \c x->T::member567 ///568 /// By default, invokes TransformDecl() to transform the declaration.569 /// Subclasses may override this function to provide alternate behavior.570 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {571 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));572 }573 574 /// Transform the set of declarations in an OverloadExpr.575 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,576 LookupResult &R);577 578 /// Transform the given nested-name-specifier with source-location579 /// information.580 ///581 /// By default, transforms all of the types and declarations within the582 /// nested-name-specifier. Subclasses may override this function to provide583 /// alternate behavior.584 NestedNameSpecifierLoc585 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,586 QualType ObjectType = QualType(),587 NamedDecl *FirstQualifierInScope = nullptr);588 589 /// Transform the given declaration name.590 ///591 /// By default, transforms the types of conversion function, constructor,592 /// and destructor names and then (if needed) rebuilds the declaration name.593 /// Identifiers and selectors are returned unmodified. Subclasses may594 /// override this function to provide alternate behavior.595 DeclarationNameInfo596 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);597 598 bool TransformRequiresExprRequirements(599 ArrayRef<concepts::Requirement *> Reqs,600 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);601 concepts::TypeRequirement *602 TransformTypeRequirement(concepts::TypeRequirement *Req);603 concepts::ExprRequirement *604 TransformExprRequirement(concepts::ExprRequirement *Req);605 concepts::NestedRequirement *606 TransformNestedRequirement(concepts::NestedRequirement *Req);607 608 /// Transform the given template name.609 ///610 /// \param SS The nested-name-specifier that qualifies the template611 /// name. This nested-name-specifier must already have been transformed.612 ///613 /// \param Name The template name to transform.614 ///615 /// \param NameLoc The source location of the template name.616 ///617 /// \param ObjectType If we're translating a template name within a member618 /// access expression, this is the type of the object whose member template619 /// is being referenced.620 ///621 /// \param FirstQualifierInScope If the first part of a nested-name-specifier622 /// also refers to a name within the current (lexical) scope, this is the623 /// declaration it refers to.624 ///625 /// By default, transforms the template name by transforming the declarations626 /// and nested-name-specifiers that occur within the template name.627 /// Subclasses may override this function to provide alternate behavior.628 TemplateName TransformTemplateName(NestedNameSpecifierLoc &QualifierLoc,629 SourceLocation TemplateKWLoc,630 TemplateName Name, SourceLocation NameLoc,631 QualType ObjectType = QualType(),632 NamedDecl *FirstQualifierInScope = nullptr,633 bool AllowInjectedClassName = false);634 635 /// Transform the given template argument.636 ///637 /// By default, this operation transforms the type, expression, or638 /// declaration stored within the template argument and constructs a639 /// new template argument from the transformed result. Subclasses may640 /// override this function to provide alternate behavior.641 ///642 /// Returns true if there was an error.643 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,644 TemplateArgumentLoc &Output,645 bool Uneval = false);646 647 TemplateArgument TransformNamedTemplateTemplateArgument(648 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,649 TemplateName Name, SourceLocation NameLoc);650 651 /// Transform the given set of template arguments.652 ///653 /// By default, this operation transforms all of the template arguments654 /// in the input set using \c TransformTemplateArgument(), and appends655 /// the transformed arguments to the output list.656 ///657 /// Note that this overload of \c TransformTemplateArguments() is merely658 /// a convenience function. Subclasses that wish to override this behavior659 /// should override the iterator-based member template version.660 ///661 /// \param Inputs The set of template arguments to be transformed.662 ///663 /// \param NumInputs The number of template arguments in \p Inputs.664 ///665 /// \param Outputs The set of transformed template arguments output by this666 /// routine.667 ///668 /// Returns true if an error occurred.669 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,670 unsigned NumInputs,671 TemplateArgumentListInfo &Outputs,672 bool Uneval = false) {673 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,674 Uneval);675 }676 677 /// Transform the given set of template arguments.678 ///679 /// By default, this operation transforms all of the template arguments680 /// in the input set using \c TransformTemplateArgument(), and appends681 /// the transformed arguments to the output list.682 ///683 /// \param First An iterator to the first template argument.684 ///685 /// \param Last An iterator one step past the last template argument.686 ///687 /// \param Outputs The set of transformed template arguments output by this688 /// routine.689 ///690 /// Returns true if an error occurred.691 template<typename InputIterator>692 bool TransformTemplateArguments(InputIterator First,693 InputIterator Last,694 TemplateArgumentListInfo &Outputs,695 bool Uneval = false);696 697 template <typename InputIterator>698 bool TransformConceptTemplateArguments(InputIterator First,699 InputIterator Last,700 TemplateArgumentListInfo &Outputs,701 bool Uneval = false);702 703 /// Checks if the argument pack from \p In will need to be expanded and does704 /// the necessary prework.705 /// Whether the expansion is needed is captured in Info.Expand.706 ///707 /// - When the expansion is required, \p Out will be a template pattern that708 /// would need to be expanded.709 /// - When the expansion must not happen, \p Out will be a pack that must be710 /// returned to the outputs directly.711 ///712 /// \return true iff the error occurred713 bool PreparePackForExpansion(TemplateArgumentLoc In, bool Uneval,714 TemplateArgumentLoc &Out, UnexpandedInfo &Info);715 716 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.717 void InventTemplateArgumentLoc(const TemplateArgument &Arg,718 TemplateArgumentLoc &ArgLoc);719 720 /// Fakes up a TypeSourceInfo for a type.721 TypeSourceInfo *InventTypeSourceInfo(QualType T) {722 return SemaRef.Context.getTrivialTypeSourceInfo(T,723 getDerived().getBaseLocation());724 }725 726#define ABSTRACT_TYPELOC(CLASS, PARENT)727#define TYPELOC(CLASS, PARENT) \728 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);729#include "clang/AST/TypeLocNodes.def"730 731 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,732 TemplateTypeParmTypeLoc TL,733 bool SuppressObjCLifetime);734 QualType735 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,736 SubstTemplateTypeParmPackTypeLoc TL,737 bool SuppressObjCLifetime);738 739 template<typename Fn>740 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,741 FunctionProtoTypeLoc TL,742 CXXRecordDecl *ThisContext,743 Qualifiers ThisTypeQuals,744 Fn TransformExceptionSpec);745 746 bool TransformExceptionSpec(SourceLocation Loc,747 FunctionProtoType::ExceptionSpecInfo &ESI,748 SmallVectorImpl<QualType> &Exceptions,749 bool &Changed);750 751 StmtResult TransformSEHHandler(Stmt *Handler);752 753 QualType TransformTemplateSpecializationType(TypeLocBuilder &TLB,754 TemplateSpecializationTypeLoc TL,755 QualType ObjectType,756 NamedDecl *FirstQualifierInScope,757 bool AllowInjectedClassName);758 759 QualType TransformTagType(TypeLocBuilder &TLB, TagTypeLoc TL);760 761 /// Transforms the parameters of a function type into the762 /// given vectors.763 ///764 /// The result vectors should be kept in sync; null entries in the765 /// variables vector are acceptable.766 ///767 /// LastParamTransformed, if non-null, will be set to the index of the last768 /// parameter on which transformation was started. In the event of an error,769 /// this will contain the parameter which failed to instantiate.770 ///771 /// Return true on error.772 bool TransformFunctionTypeParams(773 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,774 const QualType *ParamTypes,775 const FunctionProtoType::ExtParameterInfo *ParamInfos,776 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,777 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);778 779 bool TransformFunctionTypeParams(780 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,781 const QualType *ParamTypes,782 const FunctionProtoType::ExtParameterInfo *ParamInfos,783 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,784 Sema::ExtParameterInfoBuilder &PInfos) {785 return getDerived().TransformFunctionTypeParams(786 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);787 }788 789 /// Transforms the parameters of a requires expresison into the given vectors.790 ///791 /// The result vectors should be kept in sync; null entries in the792 /// variables vector are acceptable.793 ///794 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not795 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of796 /// which are cases where transformation shouldn't continue.797 ExprResult TransformRequiresTypeParams(798 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,799 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,800 SmallVectorImpl<QualType> &PTypes,801 SmallVectorImpl<ParmVarDecl *> &TransParams,802 Sema::ExtParameterInfoBuilder &PInfos) {803 if (getDerived().TransformFunctionTypeParams(804 KWLoc, Params, /*ParamTypes=*/nullptr,805 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))806 return ExprError();807 808 return ExprResult{};809 }810 811 /// Transforms a single function-type parameter. Return null812 /// on error.813 ///814 /// \param indexAdjustment - A number to add to the parameter's815 /// scope index; can be negative816 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,817 int indexAdjustment,818 UnsignedOrNone NumExpansions,819 bool ExpectParameterPack);820 821 /// Transform the body of a lambda-expression.822 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);823 /// Alternative implementation of TransformLambdaBody that skips transforming824 /// the body.825 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);826 827 CXXRecordDecl::LambdaDependencyKind828 ComputeLambdaDependency(LambdaScopeInfo *LSI) {829 return static_cast<CXXRecordDecl::LambdaDependencyKind>(830 LSI->Lambda->getLambdaDependencyKind());831 }832 833 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);834 835 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);836 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);837 838 TemplateParameterList *TransformTemplateParameterList(839 TemplateParameterList *TPL) {840 return TPL;841 }842 843 ExprResult TransformAddressOfOperand(Expr *E);844 845 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,846 bool IsAddressOfOperand,847 TypeSourceInfo **RecoveryTSI);848 849 ExprResult TransformParenDependentScopeDeclRefExpr(850 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,851 TypeSourceInfo **RecoveryTSI);852 853 ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,854 bool IsAddressOfOperand);855 856 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);857 858 StmtResult TransformOMPInformationalDirective(OMPExecutableDirective *S);859 860// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous861// amount of stack usage with clang.862#define STMT(Node, Parent) \863 LLVM_ATTRIBUTE_NOINLINE \864 StmtResult Transform##Node(Node *S);865#define VALUESTMT(Node, Parent) \866 LLVM_ATTRIBUTE_NOINLINE \867 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);868#define EXPR(Node, Parent) \869 LLVM_ATTRIBUTE_NOINLINE \870 ExprResult Transform##Node(Node *E);871#define ABSTRACT_STMT(Stmt)872#include "clang/AST/StmtNodes.inc"873 874#define GEN_CLANG_CLAUSE_CLASS875#define CLAUSE_CLASS(Enum, Str, Class) \876 LLVM_ATTRIBUTE_NOINLINE \877 OMPClause *Transform##Class(Class *S);878#include "llvm/Frontend/OpenMP/OMP.inc"879 880 /// Build a new qualified type given its unqualified type and type location.881 ///882 /// By default, this routine adds type qualifiers only to types that can883 /// have qualifiers, and silently suppresses those qualifiers that are not884 /// permitted. Subclasses may override this routine to provide different885 /// behavior.886 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);887 888 /// Build a new pointer type given its pointee type.889 ///890 /// By default, performs semantic analysis when building the pointer type.891 /// Subclasses may override this routine to provide different behavior.892 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);893 894 /// Build a new block pointer type given its pointee type.895 ///896 /// By default, performs semantic analysis when building the block pointer897 /// type. Subclasses may override this routine to provide different behavior.898 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);899 900 /// Build a new reference type given the type it references.901 ///902 /// By default, performs semantic analysis when building the903 /// reference type. Subclasses may override this routine to provide904 /// different behavior.905 ///906 /// \param LValue whether the type was written with an lvalue sigil907 /// or an rvalue sigil.908 QualType RebuildReferenceType(QualType ReferentType,909 bool LValue,910 SourceLocation Sigil);911 912 /// Build a new member pointer type given the pointee type and the913 /// qualifier it refers into.914 ///915 /// By default, performs semantic analysis when building the member pointer916 /// type. Subclasses may override this routine to provide different behavior.917 QualType RebuildMemberPointerType(QualType PointeeType,918 const CXXScopeSpec &SS, CXXRecordDecl *Cls,919 SourceLocation Sigil);920 921 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,922 SourceLocation ProtocolLAngleLoc,923 ArrayRef<ObjCProtocolDecl *> Protocols,924 ArrayRef<SourceLocation> ProtocolLocs,925 SourceLocation ProtocolRAngleLoc);926 927 /// Build an Objective-C object type.928 ///929 /// By default, performs semantic analysis when building the object type.930 /// Subclasses may override this routine to provide different behavior.931 QualType RebuildObjCObjectType(QualType BaseType,932 SourceLocation Loc,933 SourceLocation TypeArgsLAngleLoc,934 ArrayRef<TypeSourceInfo *> TypeArgs,935 SourceLocation TypeArgsRAngleLoc,936 SourceLocation ProtocolLAngleLoc,937 ArrayRef<ObjCProtocolDecl *> Protocols,938 ArrayRef<SourceLocation> ProtocolLocs,939 SourceLocation ProtocolRAngleLoc);940 941 /// Build a new Objective-C object pointer type given the pointee type.942 ///943 /// By default, directly builds the pointer type, with no additional semantic944 /// analysis.945 QualType RebuildObjCObjectPointerType(QualType PointeeType,946 SourceLocation Star);947 948 /// Build a new array type given the element type, size949 /// modifier, size of the array (if known), size expression, and index type950 /// qualifiers.951 ///952 /// By default, performs semantic analysis when building the array type.953 /// Subclasses may override this routine to provide different behavior.954 /// Also by default, all of the other Rebuild*Array955 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,956 const llvm::APInt *Size, Expr *SizeExpr,957 unsigned IndexTypeQuals, SourceRange BracketsRange);958 959 /// Build a new constant array type given the element type, size960 /// modifier, (known) size of the array, and index type qualifiers.961 ///962 /// By default, performs semantic analysis when building the array type.963 /// Subclasses may override this routine to provide different behavior.964 QualType RebuildConstantArrayType(QualType ElementType,965 ArraySizeModifier SizeMod,966 const llvm::APInt &Size, Expr *SizeExpr,967 unsigned IndexTypeQuals,968 SourceRange BracketsRange);969 970 /// Build a new incomplete array type given the element type, size971 /// modifier, and index type qualifiers.972 ///973 /// By default, performs semantic analysis when building the array type.974 /// Subclasses may override this routine to provide different behavior.975 QualType RebuildIncompleteArrayType(QualType ElementType,976 ArraySizeModifier SizeMod,977 unsigned IndexTypeQuals,978 SourceRange BracketsRange);979 980 /// Build a new variable-length array type given the element type,981 /// size modifier, size expression, and index type qualifiers.982 ///983 /// By default, performs semantic analysis when building the array type.984 /// Subclasses may override this routine to provide different behavior.985 QualType RebuildVariableArrayType(QualType ElementType,986 ArraySizeModifier SizeMod, Expr *SizeExpr,987 unsigned IndexTypeQuals,988 SourceRange BracketsRange);989 990 /// Build a new dependent-sized array type given the element type,991 /// size modifier, size expression, and index type qualifiers.992 ///993 /// By default, performs semantic analysis when building the array type.994 /// Subclasses may override this routine to provide different behavior.995 QualType RebuildDependentSizedArrayType(QualType ElementType,996 ArraySizeModifier SizeMod,997 Expr *SizeExpr,998 unsigned IndexTypeQuals,999 SourceRange BracketsRange);1000 1001 /// Build a new vector type given the element type and1002 /// number of elements.1003 ///1004 /// By default, performs semantic analysis when building the vector type.1005 /// Subclasses may override this routine to provide different behavior.1006 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,1007 VectorKind VecKind);1008 1009 /// Build a new potentially dependently-sized extended vector type1010 /// given the element type and number of elements.1011 ///1012 /// By default, performs semantic analysis when building the vector type.1013 /// Subclasses may override this routine to provide different behavior.1014 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,1015 SourceLocation AttributeLoc, VectorKind);1016 1017 /// Build a new extended vector type given the element type and1018 /// number of elements.1019 ///1020 /// By default, performs semantic analysis when building the vector type.1021 /// Subclasses may override this routine to provide different behavior.1022 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,1023 SourceLocation AttributeLoc);1024 1025 /// Build a new potentially dependently-sized extended vector type1026 /// given the element type and number of elements.1027 ///1028 /// By default, performs semantic analysis when building the vector type.1029 /// Subclasses may override this routine to provide different behavior.1030 QualType RebuildDependentSizedExtVectorType(QualType ElementType,1031 Expr *SizeExpr,1032 SourceLocation AttributeLoc);1033 1034 /// Build a new matrix type given the element type and dimensions.1035 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,1036 unsigned NumColumns);1037 1038 /// Build a new matrix type given the type and dependently-defined1039 /// dimensions.1040 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,1041 Expr *ColumnExpr,1042 SourceLocation AttributeLoc);1043 1044 /// Build a new DependentAddressSpaceType or return the pointee1045 /// type variable with the correct address space (retrieved from1046 /// AddrSpaceExpr) applied to it. The former will be returned in cases1047 /// where the address space remains dependent.1048 ///1049 /// By default, performs semantic analysis when building the type with address1050 /// space applied. Subclasses may override this routine to provide different1051 /// behavior.1052 QualType RebuildDependentAddressSpaceType(QualType PointeeType,1053 Expr *AddrSpaceExpr,1054 SourceLocation AttributeLoc);1055 1056 /// Build a new function type.1057 ///1058 /// By default, performs semantic analysis when building the function type.1059 /// Subclasses may override this routine to provide different behavior.1060 QualType RebuildFunctionProtoType(QualType T,1061 MutableArrayRef<QualType> ParamTypes,1062 const FunctionProtoType::ExtProtoInfo &EPI);1063 1064 /// Build a new unprototyped function type.1065 QualType RebuildFunctionNoProtoType(QualType ResultType);1066 1067 /// Rebuild an unresolved typename type, given the decl that1068 /// the UnresolvedUsingTypenameDecl was transformed to.1069 QualType RebuildUnresolvedUsingType(ElaboratedTypeKeyword Keyword,1070 NestedNameSpecifier Qualifier,1071 SourceLocation NameLoc, Decl *D);1072 1073 /// Build a new type found via an alias.1074 QualType RebuildUsingType(ElaboratedTypeKeyword Keyword,1075 NestedNameSpecifier Qualifier, UsingShadowDecl *D,1076 QualType UnderlyingType) {1077 return SemaRef.Context.getUsingType(Keyword, Qualifier, D, UnderlyingType);1078 }1079 1080 /// Build a new typedef type.1081 QualType RebuildTypedefType(ElaboratedTypeKeyword Keyword,1082 NestedNameSpecifier Qualifier,1083 TypedefNameDecl *Typedef) {1084 return SemaRef.Context.getTypedefType(Keyword, Qualifier, Typedef);1085 }1086 1087 /// Build a new MacroDefined type.1088 QualType RebuildMacroQualifiedType(QualType T,1089 const IdentifierInfo *MacroII) {1090 return SemaRef.Context.getMacroQualifiedType(T, MacroII);1091 }1092 1093 /// Build a new class/struct/union/enum type.1094 QualType RebuildTagType(ElaboratedTypeKeyword Keyword,1095 NestedNameSpecifier Qualifier, TagDecl *Tag) {1096 return SemaRef.Context.getTagType(Keyword, Qualifier, Tag,1097 /*OwnsTag=*/false);1098 }1099 QualType RebuildCanonicalTagType(TagDecl *Tag) {1100 return SemaRef.Context.getCanonicalTagType(Tag);1101 }1102 1103 /// Build a new typeof(expr) type.1104 ///1105 /// By default, performs semantic analysis when building the typeof type.1106 /// Subclasses may override this routine to provide different behavior.1107 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,1108 TypeOfKind Kind);1109 1110 /// Build a new typeof(type) type.1111 ///1112 /// By default, builds a new TypeOfType with the given underlying type.1113 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);1114 1115 /// Build a new unary transform type.1116 QualType RebuildUnaryTransformType(QualType BaseType,1117 UnaryTransformType::UTTKind UKind,1118 SourceLocation Loc);1119 1120 /// Build a new C++11 decltype type.1121 ///1122 /// By default, performs semantic analysis when building the decltype type.1123 /// Subclasses may override this routine to provide different behavior.1124 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);1125 1126 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,1127 SourceLocation Loc,1128 SourceLocation EllipsisLoc,1129 bool FullySubstituted,1130 ArrayRef<QualType> Expansions = {});1131 1132 /// Build a new C++11 auto type.1133 ///1134 /// By default, builds a new AutoType with the given deduced type.1135 QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword,1136 ConceptDecl *TypeConstraintConcept,1137 ArrayRef<TemplateArgument> TypeConstraintArgs) {1138 // Note, IsDependent is always false here: we implicitly convert an 'auto'1139 // which has been deduced to a dependent type into an undeduced 'auto', so1140 // that we'll retry deduction after the transformation.1141 return SemaRef.Context.getAutoType(Deduced, Keyword,1142 /*IsDependent*/ false, /*IsPack=*/false,1143 TypeConstraintConcept,1144 TypeConstraintArgs);1145 }1146 1147 /// By default, builds a new DeducedTemplateSpecializationType with the given1148 /// deduced type.1149 QualType RebuildDeducedTemplateSpecializationType(1150 ElaboratedTypeKeyword Keyword, TemplateName Template, QualType Deduced) {1151 return SemaRef.Context.getDeducedTemplateSpecializationType(1152 Keyword, Template, Deduced, /*IsDependent*/ false);1153 }1154 1155 /// Build a new template specialization type.1156 ///1157 /// By default, performs semantic analysis when building the template1158 /// specialization type. Subclasses may override this routine to provide1159 /// different behavior.1160 QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword,1161 TemplateName Template,1162 SourceLocation TemplateLoc,1163 TemplateArgumentListInfo &Args);1164 1165 /// Build a new parenthesized type.1166 ///1167 /// By default, builds a new ParenType type from the inner type.1168 /// Subclasses may override this routine to provide different behavior.1169 QualType RebuildParenType(QualType InnerType) {1170 return SemaRef.BuildParenType(InnerType);1171 }1172 1173 /// Build a new typename type that refers to an identifier.1174 ///1175 /// By default, performs semantic analysis when building the typename type1176 /// (or elaborated type). Subclasses may override this routine to provide1177 /// different behavior.1178 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,1179 SourceLocation KeywordLoc,1180 NestedNameSpecifierLoc QualifierLoc,1181 const IdentifierInfo *Id,1182 SourceLocation IdLoc,1183 bool DeducedTSTContext) {1184 CXXScopeSpec SS;1185 SS.Adopt(QualifierLoc);1186 1187 if (QualifierLoc.getNestedNameSpecifier().isDependent()) {1188 // If the name is still dependent, just build a new dependent name type.1189 if (!SemaRef.computeDeclContext(SS))1190 return SemaRef.Context.getDependentNameType(Keyword,1191 QualifierLoc.getNestedNameSpecifier(),1192 Id);1193 }1194 1195 if (Keyword == ElaboratedTypeKeyword::None ||1196 Keyword == ElaboratedTypeKeyword::Typename) {1197 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,1198 *Id, IdLoc, DeducedTSTContext);1199 }1200 1201 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);1202 1203 // We had a dependent elaborated-type-specifier that has been transformed1204 // into a non-dependent elaborated-type-specifier. Find the tag we're1205 // referring to.1206 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);1207 DeclContext *DC = SemaRef.computeDeclContext(SS, false);1208 if (!DC)1209 return QualType();1210 1211 if (SemaRef.RequireCompleteDeclContext(SS, DC))1212 return QualType();1213 1214 TagDecl *Tag = nullptr;1215 SemaRef.LookupQualifiedName(Result, DC);1216 switch (Result.getResultKind()) {1217 case LookupResultKind::NotFound:1218 case LookupResultKind::NotFoundInCurrentInstantiation:1219 break;1220 1221 case LookupResultKind::Found:1222 Tag = Result.getAsSingle<TagDecl>();1223 break;1224 1225 case LookupResultKind::FoundOverloaded:1226 case LookupResultKind::FoundUnresolvedValue:1227 llvm_unreachable("Tag lookup cannot find non-tags");1228 1229 case LookupResultKind::Ambiguous:1230 // Let the LookupResult structure handle ambiguities.1231 return QualType();1232 }1233 1234 if (!Tag) {1235 // Check where the name exists but isn't a tag type and use that to emit1236 // better diagnostics.1237 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);1238 SemaRef.LookupQualifiedName(Result, DC);1239 switch (Result.getResultKind()) {1240 case LookupResultKind::Found:1241 case LookupResultKind::FoundOverloaded:1242 case LookupResultKind::FoundUnresolvedValue: {1243 NamedDecl *SomeDecl = Result.getRepresentativeDecl();1244 NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind);1245 SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag)1246 << SomeDecl << NTK << Kind;1247 SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);1248 break;1249 }1250 default:1251 SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)1252 << Kind << Id << DC << QualifierLoc.getSourceRange();1253 break;1254 }1255 return QualType();1256 }1257 if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false,1258 IdLoc, Id)) {1259 SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;1260 SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);1261 return QualType();1262 }1263 return getDerived().RebuildTagType(1264 Keyword, QualifierLoc.getNestedNameSpecifier(), Tag);1265 }1266 1267 /// Build a new pack expansion type.1268 ///1269 /// By default, builds a new PackExpansionType type from the given pattern.1270 /// Subclasses may override this routine to provide different behavior.1271 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,1272 SourceLocation EllipsisLoc,1273 UnsignedOrNone NumExpansions) {1274 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,1275 NumExpansions);1276 }1277 1278 /// Build a new atomic type given its value type.1279 ///1280 /// By default, performs semantic analysis when building the atomic type.1281 /// Subclasses may override this routine to provide different behavior.1282 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);1283 1284 /// Build a new pipe type given its value type.1285 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,1286 bool isReadPipe);1287 1288 /// Build a bit-precise int given its value type.1289 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,1290 SourceLocation Loc);1291 1292 /// Build a dependent bit-precise int given its value type.1293 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,1294 SourceLocation Loc);1295 1296 /// Build a new template name given a nested name specifier, a flag1297 /// indicating whether the "template" keyword was provided, and the template1298 /// that the template name refers to.1299 ///1300 /// By default, builds the new template name directly. Subclasses may override1301 /// this routine to provide different behavior.1302 TemplateName RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW,1303 TemplateName Name);1304 1305 /// Build a new template name given a nested name specifier and the1306 /// name that is referred to as a template.1307 ///1308 /// By default, performs semantic analysis to determine whether the name can1309 /// be resolved to a specific template, then builds the appropriate kind of1310 /// template name. Subclasses may override this routine to provide different1311 /// behavior.1312 TemplateName RebuildTemplateName(CXXScopeSpec &SS,1313 SourceLocation TemplateKWLoc,1314 const IdentifierInfo &Name,1315 SourceLocation NameLoc, QualType ObjectType,1316 bool AllowInjectedClassName);1317 1318 /// Build a new template name given a nested name specifier and the1319 /// overloaded operator name that is referred to as a template.1320 ///1321 /// By default, performs semantic analysis to determine whether the name can1322 /// be resolved to a specific template, then builds the appropriate kind of1323 /// template name. Subclasses may override this routine to provide different1324 /// behavior.1325 TemplateName RebuildTemplateName(CXXScopeSpec &SS,1326 SourceLocation TemplateKWLoc,1327 OverloadedOperatorKind Operator,1328 SourceLocation NameLoc, QualType ObjectType,1329 bool AllowInjectedClassName);1330 1331 TemplateName RebuildTemplateName(CXXScopeSpec &SS,1332 SourceLocation TemplateKWLoc,1333 IdentifierOrOverloadedOperator IO,1334 SourceLocation NameLoc, QualType ObjectType,1335 bool AllowInjectedClassName);1336 1337 /// Build a new template name given a template template parameter pack1338 /// and the1339 ///1340 /// By default, performs semantic analysis to determine whether the name can1341 /// be resolved to a specific template, then builds the appropriate kind of1342 /// template name. Subclasses may override this routine to provide different1343 /// behavior.1344 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,1345 Decl *AssociatedDecl, unsigned Index,1346 bool Final) {1347 return getSema().Context.getSubstTemplateTemplateParmPack(1348 ArgPack, AssociatedDecl, Index, Final);1349 }1350 1351 /// Build a new compound statement.1352 ///1353 /// By default, performs semantic analysis to build the new statement.1354 /// Subclasses may override this routine to provide different behavior.1355 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,1356 MultiStmtArg Statements,1357 SourceLocation RBraceLoc,1358 bool IsStmtExpr) {1359 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,1360 IsStmtExpr);1361 }1362 1363 /// Build a new case statement.1364 ///1365 /// By default, performs semantic analysis to build the new statement.1366 /// Subclasses may override this routine to provide different behavior.1367 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,1368 Expr *LHS,1369 SourceLocation EllipsisLoc,1370 Expr *RHS,1371 SourceLocation ColonLoc) {1372 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,1373 ColonLoc);1374 }1375 1376 /// Attach the body to a new case statement.1377 ///1378 /// By default, performs semantic analysis to build the new statement.1379 /// Subclasses may override this routine to provide different behavior.1380 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {1381 getSema().ActOnCaseStmtBody(S, Body);1382 return S;1383 }1384 1385 /// Build a new default statement.1386 ///1387 /// By default, performs semantic analysis to build the new statement.1388 /// Subclasses may override this routine to provide different behavior.1389 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,1390 SourceLocation ColonLoc,1391 Stmt *SubStmt) {1392 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,1393 /*CurScope=*/nullptr);1394 }1395 1396 /// Build a new label statement.1397 ///1398 /// By default, performs semantic analysis to build the new statement.1399 /// Subclasses may override this routine to provide different behavior.1400 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,1401 SourceLocation ColonLoc, Stmt *SubStmt) {1402 return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt);1403 }1404 1405 /// Build a new attributed statement.1406 ///1407 /// By default, performs semantic analysis to build the new statement.1408 /// Subclasses may override this routine to provide different behavior.1409 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,1410 ArrayRef<const Attr *> Attrs,1411 Stmt *SubStmt) {1412 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))1413 return StmtError();1414 return SemaRef.BuildAttributedStmt(AttrLoc, Attrs, SubStmt);1415 }1416 1417 /// Build a new "if" statement.1418 ///1419 /// By default, performs semantic analysis to build the new statement.1420 /// Subclasses may override this routine to provide different behavior.1421 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,1422 SourceLocation LParenLoc, Sema::ConditionResult Cond,1423 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,1424 SourceLocation ElseLoc, Stmt *Else) {1425 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,1426 Then, ElseLoc, Else);1427 }1428 1429 /// Start building a new switch statement.1430 ///1431 /// By default, performs semantic analysis to build the new statement.1432 /// Subclasses may override this routine to provide different behavior.1433 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,1434 SourceLocation LParenLoc, Stmt *Init,1435 Sema::ConditionResult Cond,1436 SourceLocation RParenLoc) {1437 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,1438 RParenLoc);1439 }1440 1441 /// Attach the body to the switch statement.1442 ///1443 /// By default, performs semantic analysis to build the new statement.1444 /// Subclasses may override this routine to provide different behavior.1445 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,1446 Stmt *Switch, Stmt *Body) {1447 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);1448 }1449 1450 /// Build a new while statement.1451 ///1452 /// By default, performs semantic analysis to build the new statement.1453 /// Subclasses may override this routine to provide different behavior.1454 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,1455 Sema::ConditionResult Cond,1456 SourceLocation RParenLoc, Stmt *Body) {1457 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);1458 }1459 1460 /// Build a new do-while statement.1461 ///1462 /// By default, performs semantic analysis to build the new statement.1463 /// Subclasses may override this routine to provide different behavior.1464 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,1465 SourceLocation WhileLoc, SourceLocation LParenLoc,1466 Expr *Cond, SourceLocation RParenLoc) {1467 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,1468 Cond, RParenLoc);1469 }1470 1471 /// Build a new for statement.1472 ///1473 /// By default, performs semantic analysis to build the new statement.1474 /// Subclasses may override this routine to provide different behavior.1475 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,1476 Stmt *Init, Sema::ConditionResult Cond,1477 Sema::FullExprArg Inc, SourceLocation RParenLoc,1478 Stmt *Body) {1479 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,1480 Inc, RParenLoc, Body);1481 }1482 1483 /// Build a new goto statement.1484 ///1485 /// By default, performs semantic analysis to build the new statement.1486 /// Subclasses may override this routine to provide different behavior.1487 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,1488 LabelDecl *Label) {1489 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);1490 }1491 1492 /// Build a new indirect goto statement.1493 ///1494 /// By default, performs semantic analysis to build the new statement.1495 /// Subclasses may override this routine to provide different behavior.1496 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,1497 SourceLocation StarLoc,1498 Expr *Target) {1499 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);1500 }1501 1502 /// Build a new return statement.1503 ///1504 /// By default, performs semantic analysis to build the new statement.1505 /// Subclasses may override this routine to provide different behavior.1506 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {1507 return getSema().BuildReturnStmt(ReturnLoc, Result);1508 }1509 1510 /// Build a new declaration statement.1511 ///1512 /// By default, performs semantic analysis to build the new statement.1513 /// Subclasses may override this routine to provide different behavior.1514 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,1515 SourceLocation StartLoc, SourceLocation EndLoc) {1516 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);1517 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);1518 }1519 1520 /// Build a new inline asm statement.1521 ///1522 /// By default, performs semantic analysis to build the new statement.1523 /// Subclasses may override this routine to provide different behavior.1524 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,1525 bool IsVolatile, unsigned NumOutputs,1526 unsigned NumInputs, IdentifierInfo **Names,1527 MultiExprArg Constraints, MultiExprArg Exprs,1528 Expr *AsmString, MultiExprArg Clobbers,1529 unsigned NumLabels,1530 SourceLocation RParenLoc) {1531 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,1532 NumInputs, Names, Constraints, Exprs,1533 AsmString, Clobbers, NumLabels, RParenLoc);1534 }1535 1536 /// Build a new MS style inline asm statement.1537 ///1538 /// By default, performs semantic analysis to build the new statement.1539 /// Subclasses may override this routine to provide different behavior.1540 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,1541 ArrayRef<Token> AsmToks,1542 StringRef AsmString,1543 unsigned NumOutputs, unsigned NumInputs,1544 ArrayRef<StringRef> Constraints,1545 ArrayRef<StringRef> Clobbers,1546 ArrayRef<Expr*> Exprs,1547 SourceLocation EndLoc) {1548 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,1549 NumOutputs, NumInputs,1550 Constraints, Clobbers, Exprs, EndLoc);1551 }1552 1553 /// Build a new co_return statement.1554 ///1555 /// By default, performs semantic analysis to build the new statement.1556 /// Subclasses may override this routine to provide different behavior.1557 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,1558 bool IsImplicit) {1559 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);1560 }1561 1562 /// Build a new co_await expression.1563 ///1564 /// By default, performs semantic analysis to build the new expression.1565 /// Subclasses may override this routine to provide different behavior.1566 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,1567 UnresolvedLookupExpr *OpCoawaitLookup,1568 bool IsImplicit) {1569 // This function rebuilds a coawait-expr given its operator.1570 // For an explicit coawait-expr, the rebuild involves the full set1571 // of transformations performed by BuildUnresolvedCoawaitExpr(),1572 // including calling await_transform().1573 // For an implicit coawait-expr, we need to rebuild the "operator1574 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().1575 // This mirrors how the implicit CoawaitExpr is originally created1576 // in Sema::ActOnCoroutineBodyStart().1577 if (IsImplicit) {1578 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(1579 CoawaitLoc, Operand, OpCoawaitLookup);1580 if (Suspend.isInvalid())1581 return ExprError();1582 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,1583 Suspend.get(), true);1584 }1585 1586 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,1587 OpCoawaitLookup);1588 }1589 1590 /// Build a new co_await expression.1591 ///1592 /// By default, performs semantic analysis to build the new expression.1593 /// Subclasses may override this routine to provide different behavior.1594 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,1595 Expr *Result,1596 UnresolvedLookupExpr *Lookup) {1597 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);1598 }1599 1600 /// Build a new co_yield expression.1601 ///1602 /// By default, performs semantic analysis to build the new expression.1603 /// Subclasses may override this routine to provide different behavior.1604 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {1605 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);1606 }1607 1608 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {1609 return getSema().BuildCoroutineBodyStmt(Args);1610 }1611 1612 /// Build a new Objective-C \@try statement.1613 ///1614 /// By default, performs semantic analysis to build the new statement.1615 /// Subclasses may override this routine to provide different behavior.1616 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,1617 Stmt *TryBody,1618 MultiStmtArg CatchStmts,1619 Stmt *Finally) {1620 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,1621 Finally);1622 }1623 1624 /// Rebuild an Objective-C exception declaration.1625 ///1626 /// By default, performs semantic analysis to build the new declaration.1627 /// Subclasses may override this routine to provide different behavior.1628 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,1629 TypeSourceInfo *TInfo, QualType T) {1630 return getSema().ObjC().BuildObjCExceptionDecl(1631 TInfo, T, ExceptionDecl->getInnerLocStart(),1632 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());1633 }1634 1635 /// Build a new Objective-C \@catch statement.1636 ///1637 /// By default, performs semantic analysis to build the new statement.1638 /// Subclasses may override this routine to provide different behavior.1639 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,1640 SourceLocation RParenLoc,1641 VarDecl *Var,1642 Stmt *Body) {1643 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);1644 }1645 1646 /// Build a new Objective-C \@finally statement.1647 ///1648 /// By default, performs semantic analysis to build the new statement.1649 /// Subclasses may override this routine to provide different behavior.1650 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,1651 Stmt *Body) {1652 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);1653 }1654 1655 /// Build a new Objective-C \@throw statement.1656 ///1657 /// By default, performs semantic analysis to build the new statement.1658 /// Subclasses may override this routine to provide different behavior.1659 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,1660 Expr *Operand) {1661 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);1662 }1663 1664 /// Build a new OpenMP Canonical loop.1665 ///1666 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a1667 /// OMPCanonicalLoop.1668 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {1669 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);1670 }1671 1672 /// Build a new OpenMP executable directive.1673 ///1674 /// By default, performs semantic analysis to build the new statement.1675 /// Subclasses may override this routine to provide different behavior.1676 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,1677 DeclarationNameInfo DirName,1678 OpenMPDirectiveKind CancelRegion,1679 ArrayRef<OMPClause *> Clauses,1680 Stmt *AStmt, SourceLocation StartLoc,1681 SourceLocation EndLoc) {1682 1683 return getSema().OpenMP().ActOnOpenMPExecutableDirective(1684 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);1685 }1686 1687 /// Build a new OpenMP informational directive.1688 StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,1689 DeclarationNameInfo DirName,1690 ArrayRef<OMPClause *> Clauses,1691 Stmt *AStmt,1692 SourceLocation StartLoc,1693 SourceLocation EndLoc) {1694 1695 return getSema().OpenMP().ActOnOpenMPInformationalDirective(1696 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);1697 }1698 1699 /// Build a new OpenMP 'if' clause.1700 ///1701 /// By default, performs semantic analysis to build the new OpenMP clause.1702 /// Subclasses may override this routine to provide different behavior.1703 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,1704 Expr *Condition, SourceLocation StartLoc,1705 SourceLocation LParenLoc,1706 SourceLocation NameModifierLoc,1707 SourceLocation ColonLoc,1708 SourceLocation EndLoc) {1709 return getSema().OpenMP().ActOnOpenMPIfClause(1710 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,1711 EndLoc);1712 }1713 1714 /// Build a new OpenMP 'final' clause.1715 ///1716 /// By default, performs semantic analysis to build the new OpenMP clause.1717 /// Subclasses may override this routine to provide different behavior.1718 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,1719 SourceLocation LParenLoc,1720 SourceLocation EndLoc) {1721 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,1722 LParenLoc, EndLoc);1723 }1724 1725 /// Build a new OpenMP 'num_threads' clause.1726 ///1727 /// By default, performs semantic analysis to build the new OpenMP clause.1728 /// Subclasses may override this routine to provide different behavior.1729 OMPClause *RebuildOMPNumThreadsClause(OpenMPNumThreadsClauseModifier Modifier,1730 Expr *NumThreads,1731 SourceLocation StartLoc,1732 SourceLocation LParenLoc,1733 SourceLocation ModifierLoc,1734 SourceLocation EndLoc) {1735 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(1736 Modifier, NumThreads, StartLoc, LParenLoc, ModifierLoc, EndLoc);1737 }1738 1739 /// Build a new OpenMP 'safelen' clause.1740 ///1741 /// By default, performs semantic analysis to build the new OpenMP clause.1742 /// Subclasses may override this routine to provide different behavior.1743 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,1744 SourceLocation LParenLoc,1745 SourceLocation EndLoc) {1746 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,1747 EndLoc);1748 }1749 1750 /// Build a new OpenMP 'simdlen' clause.1751 ///1752 /// By default, performs semantic analysis to build the new OpenMP clause.1753 /// Subclasses may override this routine to provide different behavior.1754 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,1755 SourceLocation LParenLoc,1756 SourceLocation EndLoc) {1757 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,1758 EndLoc);1759 }1760 1761 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,1762 SourceLocation StartLoc,1763 SourceLocation LParenLoc,1764 SourceLocation EndLoc) {1765 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,1766 EndLoc);1767 }1768 1769 /// Build a new OpenMP 'permutation' clause.1770 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,1771 SourceLocation StartLoc,1772 SourceLocation LParenLoc,1773 SourceLocation EndLoc) {1774 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,1775 LParenLoc, EndLoc);1776 }1777 1778 /// Build a new OpenMP 'full' clause.1779 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,1780 SourceLocation EndLoc) {1781 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);1782 }1783 1784 /// Build a new OpenMP 'partial' clause.1785 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,1786 SourceLocation LParenLoc,1787 SourceLocation EndLoc) {1788 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,1789 LParenLoc, EndLoc);1790 }1791 1792 OMPClause *1793 RebuildOMPLoopRangeClause(Expr *First, Expr *Count, SourceLocation StartLoc,1794 SourceLocation LParenLoc, SourceLocation FirstLoc,1795 SourceLocation CountLoc, SourceLocation EndLoc) {1796 return getSema().OpenMP().ActOnOpenMPLoopRangeClause(1797 First, Count, StartLoc, LParenLoc, FirstLoc, CountLoc, EndLoc);1798 }1799 1800 /// Build a new OpenMP 'allocator' clause.1801 ///1802 /// By default, performs semantic analysis to build the new OpenMP clause.1803 /// Subclasses may override this routine to provide different behavior.1804 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,1805 SourceLocation LParenLoc,1806 SourceLocation EndLoc) {1807 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,1808 EndLoc);1809 }1810 1811 /// Build a new OpenMP 'collapse' clause.1812 ///1813 /// By default, performs semantic analysis to build the new OpenMP clause.1814 /// Subclasses may override this routine to provide different behavior.1815 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,1816 SourceLocation LParenLoc,1817 SourceLocation EndLoc) {1818 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,1819 LParenLoc, EndLoc);1820 }1821 1822 /// Build a new OpenMP 'default' clause.1823 ///1824 /// By default, performs semantic analysis to build the new OpenMP clause.1825 /// Subclasses may override this routine to provide different behavior.1826 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,1827 OpenMPDefaultClauseVariableCategory VCKind,1828 SourceLocation VCLoc,1829 SourceLocation StartLoc,1830 SourceLocation LParenLoc,1831 SourceLocation EndLoc) {1832 return getSema().OpenMP().ActOnOpenMPDefaultClause(1833 Kind, KindKwLoc, VCKind, VCLoc, StartLoc, LParenLoc, EndLoc);1834 }1835 1836 /// Build a new OpenMP 'proc_bind' clause.1837 ///1838 /// By default, performs semantic analysis to build the new OpenMP clause.1839 /// Subclasses may override this routine to provide different behavior.1840 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,1841 SourceLocation KindKwLoc,1842 SourceLocation StartLoc,1843 SourceLocation LParenLoc,1844 SourceLocation EndLoc) {1845 return getSema().OpenMP().ActOnOpenMPProcBindClause(1846 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);1847 }1848 1849 /// Build a new OpenMP 'schedule' clause.1850 ///1851 /// By default, performs semantic analysis to build the new OpenMP clause.1852 /// Subclasses may override this routine to provide different behavior.1853 OMPClause *RebuildOMPScheduleClause(1854 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,1855 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,1856 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,1857 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {1858 return getSema().OpenMP().ActOnOpenMPScheduleClause(1859 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,1860 CommaLoc, EndLoc);1861 }1862 1863 /// Build a new OpenMP 'ordered' clause.1864 ///1865 /// By default, performs semantic analysis to build the new OpenMP clause.1866 /// Subclasses may override this routine to provide different behavior.1867 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,1868 SourceLocation EndLoc,1869 SourceLocation LParenLoc, Expr *Num) {1870 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,1871 LParenLoc, Num);1872 }1873 1874 /// Build a new OpenMP 'nowait' clause.1875 ///1876 /// By default, performs semantic analysis to build the new OpenMP clause.1877 /// Subclasses may override this routine to provide different behavior.1878 OMPClause *RebuildOMPNowaitClause(Expr *Condition, SourceLocation StartLoc,1879 SourceLocation LParenLoc,1880 SourceLocation EndLoc) {1881 return getSema().OpenMP().ActOnOpenMPNowaitClause(StartLoc, EndLoc,1882 LParenLoc, Condition);1883 }1884 1885 /// Build a new OpenMP 'private' clause.1886 ///1887 /// By default, performs semantic analysis to build the new OpenMP clause.1888 /// Subclasses may override this routine to provide different behavior.1889 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,1890 SourceLocation StartLoc,1891 SourceLocation LParenLoc,1892 SourceLocation EndLoc) {1893 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,1894 LParenLoc, EndLoc);1895 }1896 1897 /// Build a new OpenMP 'firstprivate' clause.1898 ///1899 /// By default, performs semantic analysis to build the new OpenMP clause.1900 /// Subclasses may override this routine to provide different behavior.1901 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,1902 SourceLocation StartLoc,1903 SourceLocation LParenLoc,1904 SourceLocation EndLoc) {1905 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,1906 LParenLoc, EndLoc);1907 }1908 1909 /// Build a new OpenMP 'lastprivate' clause.1910 ///1911 /// By default, performs semantic analysis to build the new OpenMP clause.1912 /// Subclasses may override this routine to provide different behavior.1913 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,1914 OpenMPLastprivateModifier LPKind,1915 SourceLocation LPKindLoc,1916 SourceLocation ColonLoc,1917 SourceLocation StartLoc,1918 SourceLocation LParenLoc,1919 SourceLocation EndLoc) {1920 return getSema().OpenMP().ActOnOpenMPLastprivateClause(1921 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);1922 }1923 1924 /// Build a new OpenMP 'shared' clause.1925 ///1926 /// By default, performs semantic analysis to build the new OpenMP clause.1927 /// Subclasses may override this routine to provide different behavior.1928 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,1929 SourceLocation StartLoc,1930 SourceLocation LParenLoc,1931 SourceLocation EndLoc) {1932 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,1933 LParenLoc, EndLoc);1934 }1935 1936 /// Build a new OpenMP 'reduction' clause.1937 ///1938 /// By default, performs semantic analysis to build the new statement.1939 /// Subclasses may override this routine to provide different behavior.1940 OMPClause *RebuildOMPReductionClause(1941 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,1942 OpenMPOriginalSharingModifier OriginalSharingModifier,1943 SourceLocation StartLoc, SourceLocation LParenLoc,1944 SourceLocation ModifierLoc, SourceLocation ColonLoc,1945 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,1946 const DeclarationNameInfo &ReductionId,1947 ArrayRef<Expr *> UnresolvedReductions) {1948 return getSema().OpenMP().ActOnOpenMPReductionClause(1949 VarList, {Modifier, OriginalSharingModifier}, StartLoc, LParenLoc,1950 ModifierLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, ReductionId,1951 UnresolvedReductions);1952 }1953 1954 /// Build a new OpenMP 'task_reduction' clause.1955 ///1956 /// By default, performs semantic analysis to build the new statement.1957 /// Subclasses may override this routine to provide different behavior.1958 OMPClause *RebuildOMPTaskReductionClause(1959 ArrayRef<Expr *> VarList, SourceLocation StartLoc,1960 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,1961 CXXScopeSpec &ReductionIdScopeSpec,1962 const DeclarationNameInfo &ReductionId,1963 ArrayRef<Expr *> UnresolvedReductions) {1964 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(1965 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,1966 ReductionId, UnresolvedReductions);1967 }1968 1969 /// Build a new OpenMP 'in_reduction' clause.1970 ///1971 /// By default, performs semantic analysis to build the new statement.1972 /// Subclasses may override this routine to provide different behavior.1973 OMPClause *1974 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,1975 SourceLocation LParenLoc, SourceLocation ColonLoc,1976 SourceLocation EndLoc,1977 CXXScopeSpec &ReductionIdScopeSpec,1978 const DeclarationNameInfo &ReductionId,1979 ArrayRef<Expr *> UnresolvedReductions) {1980 return getSema().OpenMP().ActOnOpenMPInReductionClause(1981 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,1982 ReductionId, UnresolvedReductions);1983 }1984 1985 /// Build a new OpenMP 'linear' clause.1986 ///1987 /// By default, performs semantic analysis to build the new OpenMP clause.1988 /// Subclasses may override this routine to provide different behavior.1989 OMPClause *RebuildOMPLinearClause(1990 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,1991 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,1992 SourceLocation ModifierLoc, SourceLocation ColonLoc,1993 SourceLocation StepModifierLoc, SourceLocation EndLoc) {1994 return getSema().OpenMP().ActOnOpenMPLinearClause(1995 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,1996 StepModifierLoc, EndLoc);1997 }1998 1999 /// Build a new OpenMP 'aligned' clause.2000 ///2001 /// By default, performs semantic analysis to build the new OpenMP clause.2002 /// Subclasses may override this routine to provide different behavior.2003 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,2004 SourceLocation StartLoc,2005 SourceLocation LParenLoc,2006 SourceLocation ColonLoc,2007 SourceLocation EndLoc) {2008 return getSema().OpenMP().ActOnOpenMPAlignedClause(2009 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);2010 }2011 2012 /// Build a new OpenMP 'copyin' clause.2013 ///2014 /// By default, performs semantic analysis to build the new OpenMP clause.2015 /// Subclasses may override this routine to provide different behavior.2016 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,2017 SourceLocation StartLoc,2018 SourceLocation LParenLoc,2019 SourceLocation EndLoc) {2020 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,2021 LParenLoc, EndLoc);2022 }2023 2024 /// Build a new OpenMP 'copyprivate' clause.2025 ///2026 /// By default, performs semantic analysis to build the new OpenMP clause.2027 /// Subclasses may override this routine to provide different behavior.2028 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,2029 SourceLocation StartLoc,2030 SourceLocation LParenLoc,2031 SourceLocation EndLoc) {2032 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,2033 LParenLoc, EndLoc);2034 }2035 2036 /// Build a new OpenMP 'flush' pseudo clause.2037 ///2038 /// By default, performs semantic analysis to build the new OpenMP clause.2039 /// Subclasses may override this routine to provide different behavior.2040 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,2041 SourceLocation StartLoc,2042 SourceLocation LParenLoc,2043 SourceLocation EndLoc) {2044 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,2045 LParenLoc, EndLoc);2046 }2047 2048 /// Build a new OpenMP 'depobj' pseudo clause.2049 ///2050 /// By default, performs semantic analysis to build the new OpenMP clause.2051 /// Subclasses may override this routine to provide different behavior.2052 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,2053 SourceLocation LParenLoc,2054 SourceLocation EndLoc) {2055 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,2056 LParenLoc, EndLoc);2057 }2058 2059 /// Build a new OpenMP 'depend' pseudo clause.2060 ///2061 /// By default, performs semantic analysis to build the new OpenMP clause.2062 /// Subclasses may override this routine to provide different behavior.2063 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,2064 Expr *DepModifier, ArrayRef<Expr *> VarList,2065 SourceLocation StartLoc,2066 SourceLocation LParenLoc,2067 SourceLocation EndLoc) {2068 return getSema().OpenMP().ActOnOpenMPDependClause(2069 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);2070 }2071 2072 /// Build a new OpenMP 'device' clause.2073 ///2074 /// By default, performs semantic analysis to build the new statement.2075 /// Subclasses may override this routine to provide different behavior.2076 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,2077 Expr *Device, SourceLocation StartLoc,2078 SourceLocation LParenLoc,2079 SourceLocation ModifierLoc,2080 SourceLocation EndLoc) {2081 return getSema().OpenMP().ActOnOpenMPDeviceClause(2082 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);2083 }2084 2085 /// Build a new OpenMP 'map' clause.2086 ///2087 /// By default, performs semantic analysis to build the new OpenMP clause.2088 /// Subclasses may override this routine to provide different behavior.2089 OMPClause *RebuildOMPMapClause(2090 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,2091 ArrayRef<SourceLocation> MapTypeModifiersLoc,2092 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,2093 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,2094 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,2095 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {2096 return getSema().OpenMP().ActOnOpenMPMapClause(2097 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,2098 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,2099 ColonLoc, VarList, Locs,2100 /*NoDiagnose=*/false, UnresolvedMappers);2101 }2102 2103 /// Build a new OpenMP 'allocate' clause.2104 ///2105 /// By default, performs semantic analysis to build the new OpenMP clause.2106 /// Subclasses may override this routine to provide different behavior.2107 OMPClause *2108 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,2109 OpenMPAllocateClauseModifier FirstModifier,2110 SourceLocation FirstModifierLoc,2111 OpenMPAllocateClauseModifier SecondModifier,2112 SourceLocation SecondModifierLoc,2113 ArrayRef<Expr *> VarList, SourceLocation StartLoc,2114 SourceLocation LParenLoc, SourceLocation ColonLoc,2115 SourceLocation EndLoc) {2116 return getSema().OpenMP().ActOnOpenMPAllocateClause(2117 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,2118 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);2119 }2120 2121 /// Build a new OpenMP 'num_teams' clause.2122 ///2123 /// By default, performs semantic analysis to build the new statement.2124 /// Subclasses may override this routine to provide different behavior.2125 OMPClause *RebuildOMPNumTeamsClause(ArrayRef<Expr *> VarList,2126 SourceLocation StartLoc,2127 SourceLocation LParenLoc,2128 SourceLocation EndLoc) {2129 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(VarList, StartLoc,2130 LParenLoc, EndLoc);2131 }2132 2133 /// Build a new OpenMP 'thread_limit' clause.2134 ///2135 /// By default, performs semantic analysis to build the new statement.2136 /// Subclasses may override this routine to provide different behavior.2137 OMPClause *RebuildOMPThreadLimitClause(ArrayRef<Expr *> VarList,2138 SourceLocation StartLoc,2139 SourceLocation LParenLoc,2140 SourceLocation EndLoc) {2141 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(VarList, StartLoc,2142 LParenLoc, EndLoc);2143 }2144 2145 /// Build a new OpenMP 'priority' clause.2146 ///2147 /// By default, performs semantic analysis to build the new statement.2148 /// Subclasses may override this routine to provide different behavior.2149 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,2150 SourceLocation LParenLoc,2151 SourceLocation EndLoc) {2152 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,2153 LParenLoc, EndLoc);2154 }2155 2156 /// Build a new OpenMP 'grainsize' clause.2157 ///2158 /// By default, performs semantic analysis to build the new statement.2159 /// Subclasses may override this routine to provide different behavior.2160 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,2161 Expr *Device, SourceLocation StartLoc,2162 SourceLocation LParenLoc,2163 SourceLocation ModifierLoc,2164 SourceLocation EndLoc) {2165 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(2166 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);2167 }2168 2169 /// Build a new OpenMP 'num_tasks' clause.2170 ///2171 /// By default, performs semantic analysis to build the new statement.2172 /// Subclasses may override this routine to provide different behavior.2173 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,2174 Expr *NumTasks, SourceLocation StartLoc,2175 SourceLocation LParenLoc,2176 SourceLocation ModifierLoc,2177 SourceLocation EndLoc) {2178 return getSema().OpenMP().ActOnOpenMPNumTasksClause(2179 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);2180 }2181 2182 /// Build a new OpenMP 'hint' clause.2183 ///2184 /// By default, performs semantic analysis to build the new statement.2185 /// Subclasses may override this routine to provide different behavior.2186 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,2187 SourceLocation LParenLoc,2188 SourceLocation EndLoc) {2189 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,2190 EndLoc);2191 }2192 2193 /// Build a new OpenMP 'detach' clause.2194 ///2195 /// By default, performs semantic analysis to build the new statement.2196 /// Subclasses may override this routine to provide different behavior.2197 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,2198 SourceLocation LParenLoc,2199 SourceLocation EndLoc) {2200 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,2201 EndLoc);2202 }2203 2204 /// Build a new OpenMP 'dist_schedule' clause.2205 ///2206 /// By default, performs semantic analysis to build the new OpenMP clause.2207 /// Subclasses may override this routine to provide different behavior.2208 OMPClause *2209 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,2210 Expr *ChunkSize, SourceLocation StartLoc,2211 SourceLocation LParenLoc, SourceLocation KindLoc,2212 SourceLocation CommaLoc, SourceLocation EndLoc) {2213 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(2214 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);2215 }2216 2217 /// Build a new OpenMP 'to' clause.2218 ///2219 /// By default, performs semantic analysis to build the new statement.2220 /// Subclasses may override this routine to provide different behavior.2221 OMPClause *2222 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,2223 ArrayRef<SourceLocation> MotionModifiersLoc,2224 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,2225 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,2226 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,2227 ArrayRef<Expr *> UnresolvedMappers) {2228 return getSema().OpenMP().ActOnOpenMPToClause(2229 MotionModifiers, MotionModifiersLoc, IteratorModifier,2230 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,2231 UnresolvedMappers);2232 }2233 2234 /// Build a new OpenMP 'from' clause.2235 ///2236 /// By default, performs semantic analysis to build the new statement.2237 /// Subclasses may override this routine to provide different behavior.2238 OMPClause *2239 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,2240 ArrayRef<SourceLocation> MotionModifiersLoc,2241 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,2242 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,2243 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,2244 ArrayRef<Expr *> UnresolvedMappers) {2245 return getSema().OpenMP().ActOnOpenMPFromClause(2246 MotionModifiers, MotionModifiersLoc, IteratorModifier,2247 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,2248 UnresolvedMappers);2249 }2250 2251 /// Build a new OpenMP 'use_device_ptr' clause.2252 ///2253 /// By default, performs semantic analysis to build the new OpenMP clause.2254 /// Subclasses may override this routine to provide different behavior.2255 OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,2256 const OMPVarListLocTy &Locs) {2257 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(VarList, Locs);2258 }2259 2260 /// Build a new OpenMP 'use_device_addr' clause.2261 ///2262 /// By default, performs semantic analysis to build the new OpenMP clause.2263 /// Subclasses may override this routine to provide different behavior.2264 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,2265 const OMPVarListLocTy &Locs) {2266 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);2267 }2268 2269 /// Build a new OpenMP 'is_device_ptr' clause.2270 ///2271 /// By default, performs semantic analysis to build the new OpenMP clause.2272 /// Subclasses may override this routine to provide different behavior.2273 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,2274 const OMPVarListLocTy &Locs) {2275 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);2276 }2277 2278 /// Build a new OpenMP 'has_device_addr' clause.2279 ///2280 /// By default, performs semantic analysis to build the new OpenMP clause.2281 /// Subclasses may override this routine to provide different behavior.2282 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,2283 const OMPVarListLocTy &Locs) {2284 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);2285 }2286 2287 /// Build a new OpenMP 'defaultmap' clause.2288 ///2289 /// By default, performs semantic analysis to build the new OpenMP clause.2290 /// Subclasses may override this routine to provide different behavior.2291 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,2292 OpenMPDefaultmapClauseKind Kind,2293 SourceLocation StartLoc,2294 SourceLocation LParenLoc,2295 SourceLocation MLoc,2296 SourceLocation KindLoc,2297 SourceLocation EndLoc) {2298 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(2299 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);2300 }2301 2302 /// Build a new OpenMP 'nontemporal' clause.2303 ///2304 /// By default, performs semantic analysis to build the new OpenMP clause.2305 /// Subclasses may override this routine to provide different behavior.2306 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,2307 SourceLocation StartLoc,2308 SourceLocation LParenLoc,2309 SourceLocation EndLoc) {2310 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,2311 LParenLoc, EndLoc);2312 }2313 2314 /// Build a new OpenMP 'inclusive' clause.2315 ///2316 /// By default, performs semantic analysis to build the new OpenMP clause.2317 /// Subclasses may override this routine to provide different behavior.2318 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,2319 SourceLocation StartLoc,2320 SourceLocation LParenLoc,2321 SourceLocation EndLoc) {2322 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,2323 LParenLoc, EndLoc);2324 }2325 2326 /// Build a new OpenMP 'exclusive' clause.2327 ///2328 /// By default, performs semantic analysis to build the new OpenMP clause.2329 /// Subclasses may override this routine to provide different behavior.2330 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,2331 SourceLocation StartLoc,2332 SourceLocation LParenLoc,2333 SourceLocation EndLoc) {2334 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,2335 LParenLoc, EndLoc);2336 }2337 2338 /// Build a new OpenMP 'uses_allocators' clause.2339 ///2340 /// By default, performs semantic analysis to build the new OpenMP clause.2341 /// Subclasses may override this routine to provide different behavior.2342 OMPClause *RebuildOMPUsesAllocatorsClause(2343 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,2344 SourceLocation LParenLoc, SourceLocation EndLoc) {2345 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(2346 StartLoc, LParenLoc, EndLoc, Data);2347 }2348 2349 /// Build a new OpenMP 'affinity' clause.2350 ///2351 /// By default, performs semantic analysis to build the new OpenMP clause.2352 /// Subclasses may override this routine to provide different behavior.2353 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,2354 SourceLocation LParenLoc,2355 SourceLocation ColonLoc,2356 SourceLocation EndLoc, Expr *Modifier,2357 ArrayRef<Expr *> Locators) {2358 return getSema().OpenMP().ActOnOpenMPAffinityClause(2359 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);2360 }2361 2362 /// Build a new OpenMP 'order' clause.2363 ///2364 /// By default, performs semantic analysis to build the new OpenMP clause.2365 /// Subclasses may override this routine to provide different behavior.2366 OMPClause *RebuildOMPOrderClause(2367 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,2368 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,2369 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {2370 return getSema().OpenMP().ActOnOpenMPOrderClause(2371 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);2372 }2373 2374 /// Build a new OpenMP 'init' clause.2375 ///2376 /// By default, performs semantic analysis to build the new OpenMP clause.2377 /// Subclasses may override this routine to provide different behavior.2378 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,2379 SourceLocation StartLoc,2380 SourceLocation LParenLoc,2381 SourceLocation VarLoc,2382 SourceLocation EndLoc) {2383 return getSema().OpenMP().ActOnOpenMPInitClause(2384 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);2385 }2386 2387 /// Build a new OpenMP 'use' clause.2388 ///2389 /// By default, performs semantic analysis to build the new OpenMP clause.2390 /// Subclasses may override this routine to provide different behavior.2391 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,2392 SourceLocation LParenLoc,2393 SourceLocation VarLoc, SourceLocation EndLoc) {2394 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,2395 LParenLoc, VarLoc, EndLoc);2396 }2397 2398 /// Build a new OpenMP 'destroy' clause.2399 ///2400 /// By default, performs semantic analysis to build the new OpenMP clause.2401 /// Subclasses may override this routine to provide different behavior.2402 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,2403 SourceLocation LParenLoc,2404 SourceLocation VarLoc,2405 SourceLocation EndLoc) {2406 return getSema().OpenMP().ActOnOpenMPDestroyClause(2407 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);2408 }2409 2410 /// Build a new OpenMP 'novariants' clause.2411 ///2412 /// By default, performs semantic analysis to build the new OpenMP clause.2413 /// Subclasses may override this routine to provide different behavior.2414 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,2415 SourceLocation StartLoc,2416 SourceLocation LParenLoc,2417 SourceLocation EndLoc) {2418 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,2419 LParenLoc, EndLoc);2420 }2421 2422 /// Build a new OpenMP 'nocontext' clause.2423 ///2424 /// By default, performs semantic analysis to build the new OpenMP clause.2425 /// Subclasses may override this routine to provide different behavior.2426 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,2427 SourceLocation LParenLoc,2428 SourceLocation EndLoc) {2429 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,2430 LParenLoc, EndLoc);2431 }2432 2433 /// Build a new OpenMP 'filter' clause.2434 ///2435 /// By default, performs semantic analysis to build the new OpenMP clause.2436 /// Subclasses may override this routine to provide different behavior.2437 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,2438 SourceLocation LParenLoc,2439 SourceLocation EndLoc) {2440 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,2441 LParenLoc, EndLoc);2442 }2443 2444 /// Build a new OpenMP 'bind' clause.2445 ///2446 /// By default, performs semantic analysis to build the new OpenMP clause.2447 /// Subclasses may override this routine to provide different behavior.2448 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,2449 SourceLocation KindLoc,2450 SourceLocation StartLoc,2451 SourceLocation LParenLoc,2452 SourceLocation EndLoc) {2453 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,2454 LParenLoc, EndLoc);2455 }2456 2457 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.2458 ///2459 /// By default, performs semantic analysis to build the new OpenMP clause.2460 /// Subclasses may override this routine to provide different behavior.2461 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,2462 SourceLocation LParenLoc,2463 SourceLocation EndLoc) {2464 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,2465 LParenLoc, EndLoc);2466 }2467 2468 /// Build a new OpenMP 'dyn_groupprivate' clause.2469 ///2470 /// By default, performs semantic analysis to build the new OpenMP clause.2471 /// Subclasses may override this routine to provide different behavior.2472 OMPClause *RebuildOMPDynGroupprivateClause(2473 OpenMPDynGroupprivateClauseModifier M1,2474 OpenMPDynGroupprivateClauseFallbackModifier M2, Expr *Size,2475 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc,2476 SourceLocation M2Loc, SourceLocation EndLoc) {2477 return getSema().OpenMP().ActOnOpenMPDynGroupprivateClause(2478 M1, M2, Size, StartLoc, LParenLoc, M1Loc, M2Loc, EndLoc);2479 }2480 2481 /// Build a new OpenMP 'ompx_attribute' clause.2482 ///2483 /// By default, performs semantic analysis to build the new OpenMP clause.2484 /// Subclasses may override this routine to provide different behavior.2485 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,2486 SourceLocation StartLoc,2487 SourceLocation LParenLoc,2488 SourceLocation EndLoc) {2489 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,2490 LParenLoc, EndLoc);2491 }2492 2493 /// Build a new OpenMP 'ompx_bare' clause.2494 ///2495 /// By default, performs semantic analysis to build the new OpenMP clause.2496 /// Subclasses may override this routine to provide different behavior.2497 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,2498 SourceLocation EndLoc) {2499 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);2500 }2501 2502 /// Build a new OpenMP 'align' clause.2503 ///2504 /// By default, performs semantic analysis to build the new OpenMP clause.2505 /// Subclasses may override this routine to provide different behavior.2506 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,2507 SourceLocation LParenLoc,2508 SourceLocation EndLoc) {2509 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,2510 EndLoc);2511 }2512 2513 /// Build a new OpenMP 'at' clause.2514 ///2515 /// By default, performs semantic analysis to build the new OpenMP clause.2516 /// Subclasses may override this routine to provide different behavior.2517 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,2518 SourceLocation StartLoc,2519 SourceLocation LParenLoc,2520 SourceLocation EndLoc) {2521 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,2522 LParenLoc, EndLoc);2523 }2524 2525 /// Build a new OpenMP 'severity' clause.2526 ///2527 /// By default, performs semantic analysis to build the new OpenMP clause.2528 /// Subclasses may override this routine to provide different behavior.2529 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,2530 SourceLocation KwLoc,2531 SourceLocation StartLoc,2532 SourceLocation LParenLoc,2533 SourceLocation EndLoc) {2534 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,2535 LParenLoc, EndLoc);2536 }2537 2538 /// Build a new OpenMP 'message' clause.2539 ///2540 /// By default, performs semantic analysis to build the new OpenMP clause.2541 /// Subclasses may override this routine to provide different behavior.2542 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,2543 SourceLocation LParenLoc,2544 SourceLocation EndLoc) {2545 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,2546 EndLoc);2547 }2548 2549 /// Build a new OpenMP 'doacross' clause.2550 ///2551 /// By default, performs semantic analysis to build the new OpenMP clause.2552 /// Subclasses may override this routine to provide different behavior.2553 OMPClause *2554 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,2555 SourceLocation DepLoc, SourceLocation ColonLoc,2556 ArrayRef<Expr *> VarList, SourceLocation StartLoc,2557 SourceLocation LParenLoc, SourceLocation EndLoc) {2558 return getSema().OpenMP().ActOnOpenMPDoacrossClause(2559 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);2560 }2561 2562 /// Build a new OpenMP 'holds' clause.2563 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,2564 SourceLocation LParenLoc,2565 SourceLocation EndLoc) {2566 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,2567 EndLoc);2568 }2569 2570 /// Rebuild the operand to an Objective-C \@synchronized statement.2571 ///2572 /// By default, performs semantic analysis to build the new statement.2573 /// Subclasses may override this routine to provide different behavior.2574 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,2575 Expr *object) {2576 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);2577 }2578 2579 /// Build a new Objective-C \@synchronized statement.2580 ///2581 /// By default, performs semantic analysis to build the new statement.2582 /// Subclasses may override this routine to provide different behavior.2583 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,2584 Expr *Object, Stmt *Body) {2585 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);2586 }2587 2588 /// Build a new Objective-C \@autoreleasepool statement.2589 ///2590 /// By default, performs semantic analysis to build the new statement.2591 /// Subclasses may override this routine to provide different behavior.2592 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,2593 Stmt *Body) {2594 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);2595 }2596 2597 /// Build a new Objective-C fast enumeration statement.2598 ///2599 /// By default, performs semantic analysis to build the new statement.2600 /// Subclasses may override this routine to provide different behavior.2601 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,2602 Stmt *Element,2603 Expr *Collection,2604 SourceLocation RParenLoc,2605 Stmt *Body) {2606 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(2607 ForLoc, Element, Collection, RParenLoc);2608 if (ForEachStmt.isInvalid())2609 return StmtError();2610 2611 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),2612 Body);2613 }2614 2615 /// Build a new C++ exception declaration.2616 ///2617 /// By default, performs semantic analysis to build the new decaration.2618 /// Subclasses may override this routine to provide different behavior.2619 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,2620 TypeSourceInfo *Declarator,2621 SourceLocation StartLoc,2622 SourceLocation IdLoc,2623 IdentifierInfo *Id) {2624 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,2625 StartLoc, IdLoc, Id);2626 if (Var)2627 getSema().CurContext->addDecl(Var);2628 return Var;2629 }2630 2631 /// Build a new C++ catch statement.2632 ///2633 /// By default, performs semantic analysis to build the new statement.2634 /// Subclasses may override this routine to provide different behavior.2635 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,2636 VarDecl *ExceptionDecl,2637 Stmt *Handler) {2638 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,2639 Handler));2640 }2641 2642 /// Build a new C++ try statement.2643 ///2644 /// By default, performs semantic analysis to build the new statement.2645 /// Subclasses may override this routine to provide different behavior.2646 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,2647 ArrayRef<Stmt *> Handlers) {2648 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);2649 }2650 2651 /// Build a new C++0x range-based for statement.2652 ///2653 /// By default, performs semantic analysis to build the new statement.2654 /// Subclasses may override this routine to provide different behavior.2655 StmtResult RebuildCXXForRangeStmt(2656 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,2657 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,2658 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,2659 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {2660 // If we've just learned that the range is actually an Objective-C2661 // collection, treat this as an Objective-C fast enumeration loop.2662 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {2663 if (RangeStmt->isSingleDecl()) {2664 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {2665 if (RangeVar->isInvalidDecl())2666 return StmtError();2667 2668 Expr *RangeExpr = RangeVar->getInit();2669 if (!RangeExpr->isTypeDependent() &&2670 RangeExpr->getType()->isObjCObjectPointerType()) {2671 // FIXME: Support init-statements in Objective-C++20 ranged for2672 // statement.2673 if (Init) {2674 return SemaRef.Diag(Init->getBeginLoc(),2675 diag::err_objc_for_range_init_stmt)2676 << Init->getSourceRange();2677 }2678 return getSema().ObjC().ActOnObjCForCollectionStmt(2679 ForLoc, LoopVar, RangeExpr, RParenLoc);2680 }2681 }2682 }2683 }2684 2685 return getSema().BuildCXXForRangeStmt(2686 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,2687 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);2688 }2689 2690 /// Build a new C++0x range-based for statement.2691 ///2692 /// By default, performs semantic analysis to build the new statement.2693 /// Subclasses may override this routine to provide different behavior.2694 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,2695 bool IsIfExists,2696 NestedNameSpecifierLoc QualifierLoc,2697 DeclarationNameInfo NameInfo,2698 Stmt *Nested) {2699 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,2700 QualifierLoc, NameInfo, Nested);2701 }2702 2703 /// Attach body to a C++0x range-based for statement.2704 ///2705 /// By default, performs semantic analysis to finish the new statement.2706 /// Subclasses may override this routine to provide different behavior.2707 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {2708 return getSema().FinishCXXForRangeStmt(ForRange, Body);2709 }2710 2711 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,2712 Stmt *TryBlock, Stmt *Handler) {2713 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);2714 }2715 2716 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,2717 Stmt *Block) {2718 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);2719 }2720 2721 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {2722 return SEHFinallyStmt::Create(getSema().getASTContext(), Loc, Block);2723 }2724 2725 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,2726 SourceLocation LParen,2727 SourceLocation RParen,2728 TypeSourceInfo *TSI) {2729 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,2730 TSI);2731 }2732 2733 /// Build a new predefined expression.2734 ///2735 /// By default, performs semantic analysis to build the new expression.2736 /// Subclasses may override this routine to provide different behavior.2737 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {2738 return getSema().BuildPredefinedExpr(Loc, IK);2739 }2740 2741 /// Build a new expression that references a declaration.2742 ///2743 /// By default, performs semantic analysis to build the new expression.2744 /// Subclasses may override this routine to provide different behavior.2745 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,2746 LookupResult &R,2747 bool RequiresADL) {2748 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);2749 }2750 2751 2752 /// Build a new expression that references a declaration.2753 ///2754 /// By default, performs semantic analysis to build the new expression.2755 /// Subclasses may override this routine to provide different behavior.2756 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,2757 ValueDecl *VD,2758 const DeclarationNameInfo &NameInfo,2759 NamedDecl *Found,2760 TemplateArgumentListInfo *TemplateArgs) {2761 CXXScopeSpec SS;2762 SS.Adopt(QualifierLoc);2763 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,2764 TemplateArgs);2765 }2766 2767 /// Build a new expression in parentheses.2768 ///2769 /// By default, performs semantic analysis to build the new expression.2770 /// Subclasses may override this routine to provide different behavior.2771 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,2772 SourceLocation RParen) {2773 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);2774 }2775 2776 /// Build a new pseudo-destructor expression.2777 ///2778 /// By default, performs semantic analysis to build the new expression.2779 /// Subclasses may override this routine to provide different behavior.2780 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,2781 SourceLocation OperatorLoc,2782 bool isArrow,2783 CXXScopeSpec &SS,2784 TypeSourceInfo *ScopeType,2785 SourceLocation CCLoc,2786 SourceLocation TildeLoc,2787 PseudoDestructorTypeStorage Destroyed);2788 2789 /// Build a new unary operator expression.2790 ///2791 /// By default, performs semantic analysis to build the new expression.2792 /// Subclasses may override this routine to provide different behavior.2793 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,2794 UnaryOperatorKind Opc,2795 Expr *SubExpr) {2796 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);2797 }2798 2799 /// Build a new builtin offsetof expression.2800 ///2801 /// By default, performs semantic analysis to build the new expression.2802 /// Subclasses may override this routine to provide different behavior.2803 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,2804 TypeSourceInfo *Type,2805 ArrayRef<Sema::OffsetOfComponent> Components,2806 SourceLocation RParenLoc) {2807 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,2808 RParenLoc);2809 }2810 2811 /// Build a new sizeof, alignof or vec_step expression with a2812 /// type argument.2813 ///2814 /// By default, performs semantic analysis to build the new expression.2815 /// Subclasses may override this routine to provide different behavior.2816 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,2817 SourceLocation OpLoc,2818 UnaryExprOrTypeTrait ExprKind,2819 SourceRange R) {2820 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);2821 }2822 2823 /// Build a new sizeof, alignof or vec step expression with an2824 /// expression argument.2825 ///2826 /// By default, performs semantic analysis to build the new expression.2827 /// Subclasses may override this routine to provide different behavior.2828 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,2829 UnaryExprOrTypeTrait ExprKind,2830 SourceRange R) {2831 ExprResult Result2832 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);2833 if (Result.isInvalid())2834 return ExprError();2835 2836 return Result;2837 }2838 2839 /// Build a new array subscript expression.2840 ///2841 /// By default, performs semantic analysis to build the new expression.2842 /// Subclasses may override this routine to provide different behavior.2843 ExprResult RebuildArraySubscriptExpr(Expr *LHS,2844 SourceLocation LBracketLoc,2845 Expr *RHS,2846 SourceLocation RBracketLoc) {2847 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,2848 LBracketLoc, RHS,2849 RBracketLoc);2850 }2851 2852 /// Build a new matrix subscript expression.2853 ///2854 /// By default, performs semantic analysis to build the new expression.2855 /// Subclasses may override this routine to provide different behavior.2856 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,2857 Expr *ColumnIdx,2858 SourceLocation RBracketLoc) {2859 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,2860 RBracketLoc);2861 }2862 2863 /// Build a new array section expression.2864 ///2865 /// By default, performs semantic analysis to build the new expression.2866 /// Subclasses may override this routine to provide different behavior.2867 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,2868 SourceLocation LBracketLoc,2869 Expr *LowerBound,2870 SourceLocation ColonLocFirst,2871 SourceLocation ColonLocSecond,2872 Expr *Length, Expr *Stride,2873 SourceLocation RBracketLoc) {2874 if (IsOMPArraySection)2875 return getSema().OpenMP().ActOnOMPArraySectionExpr(2876 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,2877 Stride, RBracketLoc);2878 2879 assert(Stride == nullptr && !ColonLocSecond.isValid() &&2880 "Stride/second colon not allowed for OpenACC");2881 2882 return getSema().OpenACC().ActOnArraySectionExpr(2883 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);2884 }2885 2886 /// Build a new array shaping expression.2887 ///2888 /// By default, performs semantic analysis to build the new expression.2889 /// Subclasses may override this routine to provide different behavior.2890 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,2891 SourceLocation RParenLoc,2892 ArrayRef<Expr *> Dims,2893 ArrayRef<SourceRange> BracketsRanges) {2894 return getSema().OpenMP().ActOnOMPArrayShapingExpr(2895 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);2896 }2897 2898 /// Build a new iterator expression.2899 ///2900 /// By default, performs semantic analysis to build the new expression.2901 /// Subclasses may override this routine to provide different behavior.2902 ExprResult2903 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,2904 SourceLocation RLoc,2905 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {2906 return getSema().OpenMP().ActOnOMPIteratorExpr(2907 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);2908 }2909 2910 /// Build a new call expression.2911 ///2912 /// By default, performs semantic analysis to build the new expression.2913 /// Subclasses may override this routine to provide different behavior.2914 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,2915 MultiExprArg Args,2916 SourceLocation RParenLoc,2917 Expr *ExecConfig = nullptr) {2918 return getSema().ActOnCallExpr(2919 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);2920 }2921 2922 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,2923 MultiExprArg Args,2924 SourceLocation RParenLoc) {2925 return getSema().ActOnArraySubscriptExpr(2926 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);2927 }2928 2929 /// Build a new member access expression.2930 ///2931 /// By default, performs semantic analysis to build the new expression.2932 /// Subclasses may override this routine to provide different behavior.2933 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,2934 bool isArrow,2935 NestedNameSpecifierLoc QualifierLoc,2936 SourceLocation TemplateKWLoc,2937 const DeclarationNameInfo &MemberNameInfo,2938 ValueDecl *Member,2939 NamedDecl *FoundDecl,2940 const TemplateArgumentListInfo *ExplicitTemplateArgs,2941 NamedDecl *FirstQualifierInScope) {2942 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,2943 isArrow);2944 if (!Member->getDeclName()) {2945 // We have a reference to an unnamed field. This is always the2946 // base of an anonymous struct/union member access, i.e. the2947 // field is always of record type.2948 assert(Member->getType()->isRecordType() &&2949 "unnamed member not of record type?");2950 2951 BaseResult =2952 getSema().PerformObjectMemberConversion(BaseResult.get(),2953 QualifierLoc.getNestedNameSpecifier(),2954 FoundDecl, Member);2955 if (BaseResult.isInvalid())2956 return ExprError();2957 Base = BaseResult.get();2958 2959 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries2960 // from the AST, so we need to re-insert them if needed (since2961 // `BuildFieldRefereneExpr()` doesn't do this).2962 if (!isArrow && Base->isPRValue()) {2963 BaseResult = getSema().TemporaryMaterializationConversion(Base);2964 if (BaseResult.isInvalid())2965 return ExprError();2966 Base = BaseResult.get();2967 }2968 2969 CXXScopeSpec EmptySS;2970 return getSema().BuildFieldReferenceExpr(2971 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),2972 DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()),2973 MemberNameInfo);2974 }2975 2976 CXXScopeSpec SS;2977 SS.Adopt(QualifierLoc);2978 2979 Base = BaseResult.get();2980 if (Base->containsErrors())2981 return ExprError();2982 2983 QualType BaseType = Base->getType();2984 2985 if (isArrow && !BaseType->isPointerType())2986 return ExprError();2987 2988 // FIXME: this involves duplicating earlier analysis in a lot of2989 // cases; we should avoid this when possible.2990 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);2991 R.addDecl(FoundDecl);2992 R.resolveKind();2993 2994 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&2995 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {2996 if (auto *ThisClass = cast<CXXThisExpr>(Base)2997 ->getType()2998 ->getPointeeType()2999 ->getAsCXXRecordDecl()) {3000 auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());3001 // In unevaluated contexts, an expression supposed to be a member access3002 // might reference a member in an unrelated class.3003 if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))3004 return getSema().BuildDeclRefExpr(Member, Member->getType(),3005 VK_LValue, Member->getLocation());3006 }3007 }3008 3009 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,3010 SS, TemplateKWLoc,3011 FirstQualifierInScope,3012 R, ExplicitTemplateArgs,3013 /*S*/nullptr);3014 }3015 3016 /// Build a new binary operator expression.3017 ///3018 /// By default, performs semantic analysis to build the new expression.3019 /// Subclasses may override this routine to provide different behavior.3020 ExprResult RebuildBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opc,3021 Expr *LHS, Expr *RHS,3022 bool ForFoldExpression = false) {3023 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS,3024 ForFoldExpression);3025 }3026 3027 /// Build a new rewritten operator expression.3028 ///3029 /// By default, performs semantic analysis to build the new expression.3030 /// Subclasses may override this routine to provide different behavior.3031 ExprResult RebuildCXXRewrittenBinaryOperator(3032 SourceLocation OpLoc, BinaryOperatorKind Opcode,3033 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {3034 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,3035 RHS, /*RequiresADL*/false);3036 }3037 3038 /// Build a new conditional operator expression.3039 ///3040 /// By default, performs semantic analysis to build the new expression.3041 /// Subclasses may override this routine to provide different behavior.3042 ExprResult RebuildConditionalOperator(Expr *Cond,3043 SourceLocation QuestionLoc,3044 Expr *LHS,3045 SourceLocation ColonLoc,3046 Expr *RHS) {3047 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,3048 LHS, RHS);3049 }3050 3051 /// Build a new C-style cast expression.3052 ///3053 /// By default, performs semantic analysis to build the new expression.3054 /// Subclasses may override this routine to provide different behavior.3055 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,3056 TypeSourceInfo *TInfo,3057 SourceLocation RParenLoc,3058 Expr *SubExpr) {3059 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,3060 SubExpr);3061 }3062 3063 /// Build a new compound literal expression.3064 ///3065 /// By default, performs semantic analysis to build the new expression.3066 /// Subclasses may override this routine to provide different behavior.3067 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,3068 TypeSourceInfo *TInfo,3069 SourceLocation RParenLoc,3070 Expr *Init) {3071 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,3072 Init);3073 }3074 3075 /// Build a new extended vector element access expression.3076 ///3077 /// By default, performs semantic analysis to build the new expression.3078 /// Subclasses may override this routine to provide different behavior.3079 ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,3080 bool IsArrow,3081 SourceLocation AccessorLoc,3082 IdentifierInfo &Accessor) {3083 3084 CXXScopeSpec SS;3085 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);3086 return getSema().BuildMemberReferenceExpr(3087 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),3088 /*FirstQualifierInScope*/ nullptr, NameInfo,3089 /* TemplateArgs */ nullptr,3090 /*S*/ nullptr);3091 }3092 3093 /// Build a new initializer list expression.3094 ///3095 /// By default, performs semantic analysis to build the new expression.3096 /// Subclasses may override this routine to provide different behavior.3097 ExprResult RebuildInitList(SourceLocation LBraceLoc,3098 MultiExprArg Inits,3099 SourceLocation RBraceLoc) {3100 return SemaRef.BuildInitList(LBraceLoc, Inits, RBraceLoc);3101 }3102 3103 /// Build a new designated initializer expression.3104 ///3105 /// By default, performs semantic analysis to build the new expression.3106 /// Subclasses may override this routine to provide different behavior.3107 ExprResult RebuildDesignatedInitExpr(Designation &Desig,3108 MultiExprArg ArrayExprs,3109 SourceLocation EqualOrColonLoc,3110 bool GNUSyntax,3111 Expr *Init) {3112 ExprResult Result3113 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,3114 Init);3115 if (Result.isInvalid())3116 return ExprError();3117 3118 return Result;3119 }3120 3121 /// Build a new value-initialized expression.3122 ///3123 /// By default, builds the implicit value initialization without performing3124 /// any semantic analysis. Subclasses may override this routine to provide3125 /// different behavior.3126 ExprResult RebuildImplicitValueInitExpr(QualType T) {3127 return new (SemaRef.Context) ImplicitValueInitExpr(T);3128 }3129 3130 /// Build a new \c va_arg expression.3131 ///3132 /// By default, performs semantic analysis to build the new expression.3133 /// Subclasses may override this routine to provide different behavior.3134 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,3135 Expr *SubExpr, TypeSourceInfo *TInfo,3136 SourceLocation RParenLoc) {3137 return getSema().BuildVAArgExpr(BuiltinLoc,3138 SubExpr, TInfo,3139 RParenLoc);3140 }3141 3142 /// Build a new expression list in parentheses.3143 ///3144 /// By default, performs semantic analysis to build the new expression.3145 /// Subclasses may override this routine to provide different behavior.3146 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,3147 MultiExprArg SubExprs,3148 SourceLocation RParenLoc) {3149 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);3150 }3151 3152 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,3153 unsigned NumUserSpecifiedExprs,3154 SourceLocation InitLoc,3155 SourceLocation LParenLoc,3156 SourceLocation RParenLoc) {3157 return getSema().ActOnCXXParenListInitExpr(Args, T, NumUserSpecifiedExprs,3158 InitLoc, LParenLoc, RParenLoc);3159 }3160 3161 /// Build a new address-of-label expression.3162 ///3163 /// By default, performs semantic analysis, using the name of the label3164 /// rather than attempting to map the label statement itself.3165 /// Subclasses may override this routine to provide different behavior.3166 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,3167 SourceLocation LabelLoc, LabelDecl *Label) {3168 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);3169 }3170 3171 /// Build a new GNU statement expression.3172 ///3173 /// By default, performs semantic analysis to build the new expression.3174 /// Subclasses may override this routine to provide different behavior.3175 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,3176 SourceLocation RParenLoc, unsigned TemplateDepth) {3177 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,3178 TemplateDepth);3179 }3180 3181 /// Build a new __builtin_choose_expr expression.3182 ///3183 /// By default, performs semantic analysis to build the new expression.3184 /// Subclasses may override this routine to provide different behavior.3185 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,3186 Expr *Cond, Expr *LHS, Expr *RHS,3187 SourceLocation RParenLoc) {3188 return SemaRef.ActOnChooseExpr(BuiltinLoc,3189 Cond, LHS, RHS,3190 RParenLoc);3191 }3192 3193 /// Build a new generic selection expression with an expression predicate.3194 ///3195 /// By default, performs semantic analysis to build the new expression.3196 /// Subclasses may override this routine to provide different behavior.3197 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,3198 SourceLocation DefaultLoc,3199 SourceLocation RParenLoc,3200 Expr *ControllingExpr,3201 ArrayRef<TypeSourceInfo *> Types,3202 ArrayRef<Expr *> Exprs) {3203 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,3204 /*PredicateIsExpr=*/true,3205 ControllingExpr, Types, Exprs);3206 }3207 3208 /// Build a new generic selection expression with a type predicate.3209 ///3210 /// By default, performs semantic analysis to build the new expression.3211 /// Subclasses may override this routine to provide different behavior.3212 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,3213 SourceLocation DefaultLoc,3214 SourceLocation RParenLoc,3215 TypeSourceInfo *ControllingType,3216 ArrayRef<TypeSourceInfo *> Types,3217 ArrayRef<Expr *> Exprs) {3218 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,3219 /*PredicateIsExpr=*/false,3220 ControllingType, Types, Exprs);3221 }3222 3223 /// Build a new overloaded operator call expression.3224 ///3225 /// By default, performs semantic analysis to build the new expression.3226 /// The semantic analysis provides the behavior of template instantiation,3227 /// copying with transformations that turn what looks like an overloaded3228 /// operator call into a use of a builtin operator, performing3229 /// argument-dependent lookup, etc. Subclasses may override this routine to3230 /// provide different behavior.3231 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,3232 SourceLocation OpLoc,3233 SourceLocation CalleeLoc,3234 bool RequiresADL,3235 const UnresolvedSetImpl &Functions,3236 Expr *First, Expr *Second);3237 3238 /// Build a new C++ "named" cast expression, such as static_cast or3239 /// reinterpret_cast.3240 ///3241 /// By default, this routine dispatches to one of the more-specific routines3242 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().3243 /// Subclasses may override this routine to provide different behavior.3244 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,3245 Stmt::StmtClass Class,3246 SourceLocation LAngleLoc,3247 TypeSourceInfo *TInfo,3248 SourceLocation RAngleLoc,3249 SourceLocation LParenLoc,3250 Expr *SubExpr,3251 SourceLocation RParenLoc) {3252 switch (Class) {3253 case Stmt::CXXStaticCastExprClass:3254 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,3255 RAngleLoc, LParenLoc,3256 SubExpr, RParenLoc);3257 3258 case Stmt::CXXDynamicCastExprClass:3259 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,3260 RAngleLoc, LParenLoc,3261 SubExpr, RParenLoc);3262 3263 case Stmt::CXXReinterpretCastExprClass:3264 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,3265 RAngleLoc, LParenLoc,3266 SubExpr,3267 RParenLoc);3268 3269 case Stmt::CXXConstCastExprClass:3270 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,3271 RAngleLoc, LParenLoc,3272 SubExpr, RParenLoc);3273 3274 case Stmt::CXXAddrspaceCastExprClass:3275 return getDerived().RebuildCXXAddrspaceCastExpr(3276 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);3277 3278 default:3279 llvm_unreachable("Invalid C++ named cast");3280 }3281 }3282 3283 /// Build a new C++ static_cast expression.3284 ///3285 /// By default, performs semantic analysis to build the new expression.3286 /// Subclasses may override this routine to provide different behavior.3287 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,3288 SourceLocation LAngleLoc,3289 TypeSourceInfo *TInfo,3290 SourceLocation RAngleLoc,3291 SourceLocation LParenLoc,3292 Expr *SubExpr,3293 SourceLocation RParenLoc) {3294 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,3295 TInfo, SubExpr,3296 SourceRange(LAngleLoc, RAngleLoc),3297 SourceRange(LParenLoc, RParenLoc));3298 }3299 3300 /// Build a new C++ dynamic_cast expression.3301 ///3302 /// By default, performs semantic analysis to build the new expression.3303 /// Subclasses may override this routine to provide different behavior.3304 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,3305 SourceLocation LAngleLoc,3306 TypeSourceInfo *TInfo,3307 SourceLocation RAngleLoc,3308 SourceLocation LParenLoc,3309 Expr *SubExpr,3310 SourceLocation RParenLoc) {3311 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,3312 TInfo, SubExpr,3313 SourceRange(LAngleLoc, RAngleLoc),3314 SourceRange(LParenLoc, RParenLoc));3315 }3316 3317 /// Build a new C++ reinterpret_cast expression.3318 ///3319 /// By default, performs semantic analysis to build the new expression.3320 /// Subclasses may override this routine to provide different behavior.3321 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,3322 SourceLocation LAngleLoc,3323 TypeSourceInfo *TInfo,3324 SourceLocation RAngleLoc,3325 SourceLocation LParenLoc,3326 Expr *SubExpr,3327 SourceLocation RParenLoc) {3328 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,3329 TInfo, SubExpr,3330 SourceRange(LAngleLoc, RAngleLoc),3331 SourceRange(LParenLoc, RParenLoc));3332 }3333 3334 /// Build a new C++ const_cast expression.3335 ///3336 /// By default, performs semantic analysis to build the new expression.3337 /// Subclasses may override this routine to provide different behavior.3338 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,3339 SourceLocation LAngleLoc,3340 TypeSourceInfo *TInfo,3341 SourceLocation RAngleLoc,3342 SourceLocation LParenLoc,3343 Expr *SubExpr,3344 SourceLocation RParenLoc) {3345 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,3346 TInfo, SubExpr,3347 SourceRange(LAngleLoc, RAngleLoc),3348 SourceRange(LParenLoc, RParenLoc));3349 }3350 3351 ExprResult3352 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,3353 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,3354 SourceLocation LParenLoc, Expr *SubExpr,3355 SourceLocation RParenLoc) {3356 return getSema().BuildCXXNamedCast(3357 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,3358 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));3359 }3360 3361 /// Build a new C++ functional-style cast expression.3362 ///3363 /// By default, performs semantic analysis to build the new expression.3364 /// Subclasses may override this routine to provide different behavior.3365 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,3366 SourceLocation LParenLoc,3367 Expr *Sub,3368 SourceLocation RParenLoc,3369 bool ListInitialization) {3370 // If Sub is a ParenListExpr, then Sub is the syntatic form of a3371 // CXXParenListInitExpr. Pass its expanded arguments so that the3372 // CXXParenListInitExpr can be rebuilt.3373 if (auto *PLE = dyn_cast<ParenListExpr>(Sub))3374 return getSema().BuildCXXTypeConstructExpr(3375 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),3376 RParenLoc, ListInitialization);3377 3378 if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Sub))3379 return getSema().BuildCXXTypeConstructExpr(3380 TInfo, LParenLoc, PLE->getInitExprs(), RParenLoc, ListInitialization);3381 3382 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,3383 MultiExprArg(&Sub, 1), RParenLoc,3384 ListInitialization);3385 }3386 3387 /// Build a new C++ __builtin_bit_cast expression.3388 ///3389 /// By default, performs semantic analysis to build the new expression.3390 /// Subclasses may override this routine to provide different behavior.3391 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,3392 TypeSourceInfo *TSI, Expr *Sub,3393 SourceLocation RParenLoc) {3394 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);3395 }3396 3397 /// Build a new C++ typeid(type) expression.3398 ///3399 /// By default, performs semantic analysis to build the new expression.3400 /// Subclasses may override this routine to provide different behavior.3401 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,3402 SourceLocation TypeidLoc,3403 TypeSourceInfo *Operand,3404 SourceLocation RParenLoc) {3405 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,3406 RParenLoc);3407 }3408 3409 3410 /// Build a new C++ typeid(expr) expression.3411 ///3412 /// By default, performs semantic analysis to build the new expression.3413 /// Subclasses may override this routine to provide different behavior.3414 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,3415 SourceLocation TypeidLoc,3416 Expr *Operand,3417 SourceLocation RParenLoc) {3418 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,3419 RParenLoc);3420 }3421 3422 /// Build a new C++ __uuidof(type) expression.3423 ///3424 /// By default, performs semantic analysis to build the new expression.3425 /// Subclasses may override this routine to provide different behavior.3426 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,3427 TypeSourceInfo *Operand,3428 SourceLocation RParenLoc) {3429 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);3430 }3431 3432 /// Build a new C++ __uuidof(expr) expression.3433 ///3434 /// By default, performs semantic analysis to build the new expression.3435 /// Subclasses may override this routine to provide different behavior.3436 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,3437 Expr *Operand, SourceLocation RParenLoc) {3438 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);3439 }3440 3441 /// Build a new C++ "this" expression.3442 ///3443 /// By default, performs semantic analysis to build a new "this" expression.3444 /// Subclasses may override this routine to provide different behavior.3445 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,3446 QualType ThisType,3447 bool isImplicit) {3448 if (getSema().CheckCXXThisType(ThisLoc, ThisType))3449 return ExprError();3450 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);3451 }3452 3453 /// Build a new C++ throw expression.3454 ///3455 /// By default, performs semantic analysis to build the new expression.3456 /// Subclasses may override this routine to provide different behavior.3457 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,3458 bool IsThrownVariableInScope) {3459 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);3460 }3461 3462 /// Build a new C++ default-argument expression.3463 ///3464 /// By default, builds a new default-argument expression, which does not3465 /// require any semantic analysis. Subclasses may override this routine to3466 /// provide different behavior.3467 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,3468 Expr *RewrittenExpr) {3469 return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param,3470 RewrittenExpr, getSema().CurContext);3471 }3472 3473 /// Build a new C++11 default-initialization expression.3474 ///3475 /// By default, builds a new default field initialization expression, which3476 /// does not require any semantic analysis. Subclasses may override this3477 /// routine to provide different behavior.3478 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,3479 FieldDecl *Field) {3480 return getSema().BuildCXXDefaultInitExpr(Loc, Field);3481 }3482 3483 /// Build a new C++ zero-initialization expression.3484 ///3485 /// By default, performs semantic analysis to build the new expression.3486 /// Subclasses may override this routine to provide different behavior.3487 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,3488 SourceLocation LParenLoc,3489 SourceLocation RParenLoc) {3490 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,3491 /*ListInitialization=*/false);3492 }3493 3494 /// Build a new C++ "new" expression.3495 ///3496 /// By default, performs semantic analysis to build the new expression.3497 /// Subclasses may override this routine to provide different behavior.3498 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,3499 SourceLocation PlacementLParen,3500 MultiExprArg PlacementArgs,3501 SourceLocation PlacementRParen,3502 SourceRange TypeIdParens, QualType AllocatedType,3503 TypeSourceInfo *AllocatedTypeInfo,3504 std::optional<Expr *> ArraySize,3505 SourceRange DirectInitRange, Expr *Initializer) {3506 return getSema().BuildCXXNew(StartLoc, UseGlobal,3507 PlacementLParen,3508 PlacementArgs,3509 PlacementRParen,3510 TypeIdParens,3511 AllocatedType,3512 AllocatedTypeInfo,3513 ArraySize,3514 DirectInitRange,3515 Initializer);3516 }3517 3518 /// Build a new C++ "delete" expression.3519 ///3520 /// By default, performs semantic analysis to build the new expression.3521 /// Subclasses may override this routine to provide different behavior.3522 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,3523 bool IsGlobalDelete,3524 bool IsArrayForm,3525 Expr *Operand) {3526 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,3527 Operand);3528 }3529 3530 /// Build a new type trait expression.3531 ///3532 /// By default, performs semantic analysis to build the new expression.3533 /// Subclasses may override this routine to provide different behavior.3534 ExprResult RebuildTypeTrait(TypeTrait Trait,3535 SourceLocation StartLoc,3536 ArrayRef<TypeSourceInfo *> Args,3537 SourceLocation RParenLoc) {3538 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);3539 }3540 3541 /// Build a new array type trait expression.3542 ///3543 /// By default, performs semantic analysis to build the new expression.3544 /// Subclasses may override this routine to provide different behavior.3545 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,3546 SourceLocation StartLoc,3547 TypeSourceInfo *TSInfo,3548 Expr *DimExpr,3549 SourceLocation RParenLoc) {3550 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);3551 }3552 3553 /// Build a new expression trait expression.3554 ///3555 /// By default, performs semantic analysis to build the new expression.3556 /// Subclasses may override this routine to provide different behavior.3557 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,3558 SourceLocation StartLoc,3559 Expr *Queried,3560 SourceLocation RParenLoc) {3561 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);3562 }3563 3564 /// Build a new (previously unresolved) declaration reference3565 /// expression.3566 ///3567 /// By default, performs semantic analysis to build the new expression.3568 /// Subclasses may override this routine to provide different behavior.3569 ExprResult RebuildDependentScopeDeclRefExpr(3570 NestedNameSpecifierLoc QualifierLoc,3571 SourceLocation TemplateKWLoc,3572 const DeclarationNameInfo &NameInfo,3573 const TemplateArgumentListInfo *TemplateArgs,3574 bool IsAddressOfOperand,3575 TypeSourceInfo **RecoveryTSI) {3576 CXXScopeSpec SS;3577 SS.Adopt(QualifierLoc);3578 3579 if (TemplateArgs || TemplateKWLoc.isValid())3580 return getSema().BuildQualifiedTemplateIdExpr(3581 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);3582 3583 return getSema().BuildQualifiedDeclarationNameExpr(3584 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);3585 }3586 3587 /// Build a new template-id expression.3588 ///3589 /// By default, performs semantic analysis to build the new expression.3590 /// Subclasses may override this routine to provide different behavior.3591 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,3592 SourceLocation TemplateKWLoc,3593 LookupResult &R,3594 bool RequiresADL,3595 const TemplateArgumentListInfo *TemplateArgs) {3596 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,3597 TemplateArgs);3598 }3599 3600 /// Build a new object-construction expression.3601 ///3602 /// By default, performs semantic analysis to build the new expression.3603 /// Subclasses may override this routine to provide different behavior.3604 ExprResult RebuildCXXConstructExpr(3605 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,3606 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,3607 bool ListInitialization, bool StdInitListInitialization,3608 bool RequiresZeroInit, CXXConstructionKind ConstructKind,3609 SourceRange ParenRange) {3610 // Reconstruct the constructor we originally found, which might be3611 // different if this is a call to an inherited constructor.3612 CXXConstructorDecl *FoundCtor = Constructor;3613 if (Constructor->isInheritingConstructor())3614 FoundCtor = Constructor->getInheritedConstructor().getConstructor();3615 3616 SmallVector<Expr *, 8> ConvertedArgs;3617 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,3618 ConvertedArgs))3619 return ExprError();3620 3621 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,3622 IsElidable,3623 ConvertedArgs,3624 HadMultipleCandidates,3625 ListInitialization,3626 StdInitListInitialization,3627 RequiresZeroInit, ConstructKind,3628 ParenRange);3629 }3630 3631 /// Build a new implicit construction via inherited constructor3632 /// expression.3633 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,3634 CXXConstructorDecl *Constructor,3635 bool ConstructsVBase,3636 bool InheritedFromVBase) {3637 return new (getSema().Context) CXXInheritedCtorInitExpr(3638 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);3639 }3640 3641 /// Build a new object-construction expression.3642 ///3643 /// By default, performs semantic analysis to build the new expression.3644 /// Subclasses may override this routine to provide different behavior.3645 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,3646 SourceLocation LParenOrBraceLoc,3647 MultiExprArg Args,3648 SourceLocation RParenOrBraceLoc,3649 bool ListInitialization) {3650 return getSema().BuildCXXTypeConstructExpr(3651 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);3652 }3653 3654 /// Build a new object-construction expression.3655 ///3656 /// By default, performs semantic analysis to build the new expression.3657 /// Subclasses may override this routine to provide different behavior.3658 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,3659 SourceLocation LParenLoc,3660 MultiExprArg Args,3661 SourceLocation RParenLoc,3662 bool ListInitialization) {3663 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,3664 RParenLoc, ListInitialization);3665 }3666 3667 /// Build a new member reference expression.3668 ///3669 /// By default, performs semantic analysis to build the new expression.3670 /// Subclasses may override this routine to provide different behavior.3671 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,3672 QualType BaseType,3673 bool IsArrow,3674 SourceLocation OperatorLoc,3675 NestedNameSpecifierLoc QualifierLoc,3676 SourceLocation TemplateKWLoc,3677 NamedDecl *FirstQualifierInScope,3678 const DeclarationNameInfo &MemberNameInfo,3679 const TemplateArgumentListInfo *TemplateArgs) {3680 CXXScopeSpec SS;3681 SS.Adopt(QualifierLoc);3682 3683 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,3684 OperatorLoc, IsArrow,3685 SS, TemplateKWLoc,3686 FirstQualifierInScope,3687 MemberNameInfo,3688 TemplateArgs, /*S*/nullptr);3689 }3690 3691 /// Build a new member reference expression.3692 ///3693 /// By default, performs semantic analysis to build the new expression.3694 /// Subclasses may override this routine to provide different behavior.3695 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,3696 SourceLocation OperatorLoc,3697 bool IsArrow,3698 NestedNameSpecifierLoc QualifierLoc,3699 SourceLocation TemplateKWLoc,3700 NamedDecl *FirstQualifierInScope,3701 LookupResult &R,3702 const TemplateArgumentListInfo *TemplateArgs) {3703 CXXScopeSpec SS;3704 SS.Adopt(QualifierLoc);3705 3706 return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,3707 OperatorLoc, IsArrow,3708 SS, TemplateKWLoc,3709 FirstQualifierInScope,3710 R, TemplateArgs, /*S*/nullptr);3711 }3712 3713 /// Build a new noexcept expression.3714 ///3715 /// By default, performs semantic analysis to build the new expression.3716 /// Subclasses may override this routine to provide different behavior.3717 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {3718 return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd());3719 }3720 3721 UnsignedOrNone3722 ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs);3723 3724 /// Build a new expression to compute the length of a parameter pack.3725 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,3726 SourceLocation PackLoc,3727 SourceLocation RParenLoc,3728 UnsignedOrNone Length,3729 ArrayRef<TemplateArgument> PartialArgs) {3730 return SizeOfPackExpr::Create(SemaRef.Context, OperatorLoc, Pack, PackLoc,3731 RParenLoc, Length, PartialArgs);3732 }3733 3734 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,3735 SourceLocation RSquareLoc,3736 Expr *PackIdExpression, Expr *IndexExpr,3737 ArrayRef<Expr *> ExpandedExprs,3738 bool FullySubstituted = false) {3739 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,3740 IndexExpr, RSquareLoc, ExpandedExprs,3741 FullySubstituted);3742 }3743 3744 /// Build a new expression representing a call to a source location3745 /// builtin.3746 ///3747 /// By default, performs semantic analysis to build the new expression.3748 /// Subclasses may override this routine to provide different behavior.3749 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,3750 SourceLocation BuiltinLoc,3751 SourceLocation RPLoc,3752 DeclContext *ParentContext) {3753 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,3754 ParentContext);3755 }3756 3757 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,3758 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,3759 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,3760 TemplateArgumentListInfo *TALI) {3761 CXXScopeSpec SS;3762 SS.Adopt(NNS);3763 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,3764 ConceptNameInfo,3765 FoundDecl,3766 NamedConcept, TALI);3767 if (Result.isInvalid())3768 return ExprError();3769 return Result;3770 }3771 3772 /// \brief Build a new requires expression.3773 ///3774 /// By default, performs semantic analysis to build the new expression.3775 /// Subclasses may override this routine to provide different behavior.3776 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,3777 RequiresExprBodyDecl *Body,3778 SourceLocation LParenLoc,3779 ArrayRef<ParmVarDecl *> LocalParameters,3780 SourceLocation RParenLoc,3781 ArrayRef<concepts::Requirement *> Requirements,3782 SourceLocation ClosingBraceLoc) {3783 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, LParenLoc,3784 LocalParameters, RParenLoc, Requirements,3785 ClosingBraceLoc);3786 }3787 3788 concepts::TypeRequirement *3789 RebuildTypeRequirement(3790 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {3791 return SemaRef.BuildTypeRequirement(SubstDiag);3792 }3793 3794 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {3795 return SemaRef.BuildTypeRequirement(T);3796 }3797 3798 concepts::ExprRequirement *3799 RebuildExprRequirement(3800 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,3801 SourceLocation NoexceptLoc,3802 concepts::ExprRequirement::ReturnTypeRequirement Ret) {3803 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,3804 std::move(Ret));3805 }3806 3807 concepts::ExprRequirement *3808 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,3809 concepts::ExprRequirement::ReturnTypeRequirement Ret) {3810 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,3811 std::move(Ret));3812 }3813 3814 concepts::NestedRequirement *3815 RebuildNestedRequirement(StringRef InvalidConstraintEntity,3816 const ASTConstraintSatisfaction &Satisfaction) {3817 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,3818 Satisfaction);3819 }3820 3821 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {3822 return SemaRef.BuildNestedRequirement(Constraint);3823 }3824 3825 /// \brief Build a new Objective-C boxed expression.3826 ///3827 /// By default, performs semantic analysis to build the new expression.3828 /// Subclasses may override this routine to provide different behavior.3829 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {3830 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);3831 }3832 3833 /// Build a new Objective-C array literal.3834 ///3835 /// By default, performs semantic analysis to build the new expression.3836 /// Subclasses may override this routine to provide different behavior.3837 ExprResult RebuildObjCArrayLiteral(SourceRange Range,3838 Expr **Elements, unsigned NumElements) {3839 return getSema().ObjC().BuildObjCArrayLiteral(3840 Range, MultiExprArg(Elements, NumElements));3841 }3842 3843 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,3844 Expr *Base, Expr *Key,3845 ObjCMethodDecl *getterMethod,3846 ObjCMethodDecl *setterMethod) {3847 return getSema().ObjC().BuildObjCSubscriptExpression(3848 RB, Base, Key, getterMethod, setterMethod);3849 }3850 3851 /// Build a new Objective-C dictionary literal.3852 ///3853 /// By default, performs semantic analysis to build the new expression.3854 /// Subclasses may override this routine to provide different behavior.3855 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,3856 MutableArrayRef<ObjCDictionaryElement> Elements) {3857 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);3858 }3859 3860 /// Build a new Objective-C \@encode expression.3861 ///3862 /// By default, performs semantic analysis to build the new expression.3863 /// Subclasses may override this routine to provide different behavior.3864 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,3865 TypeSourceInfo *EncodeTypeInfo,3866 SourceLocation RParenLoc) {3867 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,3868 RParenLoc);3869 }3870 3871 /// Build a new Objective-C class message.3872 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,3873 Selector Sel,3874 ArrayRef<SourceLocation> SelectorLocs,3875 ObjCMethodDecl *Method,3876 SourceLocation LBracLoc,3877 MultiExprArg Args,3878 SourceLocation RBracLoc) {3879 return SemaRef.ObjC().BuildClassMessage(3880 ReceiverTypeInfo, ReceiverTypeInfo->getType(),3881 /*SuperLoc=*/SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,3882 RBracLoc, Args);3883 }3884 3885 /// Build a new Objective-C instance message.3886 ExprResult RebuildObjCMessageExpr(Expr *Receiver,3887 Selector Sel,3888 ArrayRef<SourceLocation> SelectorLocs,3889 ObjCMethodDecl *Method,3890 SourceLocation LBracLoc,3891 MultiExprArg Args,3892 SourceLocation RBracLoc) {3893 return SemaRef.ObjC().BuildInstanceMessage(Receiver, Receiver->getType(),3894 /*SuperLoc=*/SourceLocation(),3895 Sel, Method, LBracLoc,3896 SelectorLocs, RBracLoc, Args);3897 }3898 3899 /// Build a new Objective-C instance/class message to 'super'.3900 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,3901 Selector Sel,3902 ArrayRef<SourceLocation> SelectorLocs,3903 QualType SuperType,3904 ObjCMethodDecl *Method,3905 SourceLocation LBracLoc,3906 MultiExprArg Args,3907 SourceLocation RBracLoc) {3908 return Method->isInstanceMethod()3909 ? SemaRef.ObjC().BuildInstanceMessage(3910 nullptr, SuperType, SuperLoc, Sel, Method, LBracLoc,3911 SelectorLocs, RBracLoc, Args)3912 : SemaRef.ObjC().BuildClassMessage(nullptr, SuperType, SuperLoc,3913 Sel, Method, LBracLoc,3914 SelectorLocs, RBracLoc, Args);3915 }3916 3917 /// Build a new Objective-C ivar reference expression.3918 ///3919 /// By default, performs semantic analysis to build the new expression.3920 /// Subclasses may override this routine to provide different behavior.3921 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,3922 SourceLocation IvarLoc,3923 bool IsArrow, bool IsFreeIvar) {3924 CXXScopeSpec SS;3925 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);3926 ExprResult Result = getSema().BuildMemberReferenceExpr(3927 BaseArg, BaseArg->getType(),3928 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),3929 /*FirstQualifierInScope=*/nullptr, NameInfo,3930 /*TemplateArgs=*/nullptr,3931 /*S=*/nullptr);3932 if (IsFreeIvar && Result.isUsable())3933 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);3934 return Result;3935 }3936 3937 /// Build a new Objective-C property reference expression.3938 ///3939 /// By default, performs semantic analysis to build the new expression.3940 /// Subclasses may override this routine to provide different behavior.3941 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,3942 ObjCPropertyDecl *Property,3943 SourceLocation PropertyLoc) {3944 CXXScopeSpec SS;3945 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);3946 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),3947 /*FIXME:*/PropertyLoc,3948 /*IsArrow=*/false,3949 SS, SourceLocation(),3950 /*FirstQualifierInScope=*/nullptr,3951 NameInfo,3952 /*TemplateArgs=*/nullptr,3953 /*S=*/nullptr);3954 }3955 3956 /// Build a new Objective-C property reference expression.3957 ///3958 /// By default, performs semantic analysis to build the new expression.3959 /// Subclasses may override this routine to provide different behavior.3960 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,3961 ObjCMethodDecl *Getter,3962 ObjCMethodDecl *Setter,3963 SourceLocation PropertyLoc) {3964 // Since these expressions can only be value-dependent, we do not3965 // need to perform semantic analysis again.3966 return Owned(3967 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,3968 VK_LValue, OK_ObjCProperty,3969 PropertyLoc, Base));3970 }3971 3972 /// Build a new Objective-C "isa" expression.3973 ///3974 /// By default, performs semantic analysis to build the new expression.3975 /// Subclasses may override this routine to provide different behavior.3976 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,3977 SourceLocation OpLoc, bool IsArrow) {3978 CXXScopeSpec SS;3979 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);3980 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),3981 OpLoc, IsArrow,3982 SS, SourceLocation(),3983 /*FirstQualifierInScope=*/nullptr,3984 NameInfo,3985 /*TemplateArgs=*/nullptr,3986 /*S=*/nullptr);3987 }3988 3989 /// Build a new shuffle vector expression.3990 ///3991 /// By default, performs semantic analysis to build the new expression.3992 /// Subclasses may override this routine to provide different behavior.3993 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,3994 MultiExprArg SubExprs,3995 SourceLocation RParenLoc) {3996 // Find the declaration for __builtin_shufflevector3997 const IdentifierInfo &Name3998 = SemaRef.Context.Idents.get("__builtin_shufflevector");3999 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();4000 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));4001 assert(!Lookup.empty() && "No __builtin_shufflevector?");4002 4003 // Build a reference to the __builtin_shufflevector builtin4004 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());4005 Expr *Callee = new (SemaRef.Context)4006 DeclRefExpr(SemaRef.Context, Builtin, false,4007 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);4008 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());4009 Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,4010 CK_BuiltinFnToFnPtr).get();4011 4012 // Build the CallExpr4013 ExprResult TheCall = CallExpr::Create(4014 SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(),4015 Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc,4016 FPOptionsOverride());4017 4018 // Type-check the __builtin_shufflevector expression.4019 return SemaRef.BuiltinShuffleVector(cast<CallExpr>(TheCall.get()));4020 }4021 4022 /// Build a new convert vector expression.4023 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,4024 Expr *SrcExpr, TypeSourceInfo *DstTInfo,4025 SourceLocation RParenLoc) {4026 return SemaRef.ConvertVectorExpr(SrcExpr, DstTInfo, BuiltinLoc, RParenLoc);4027 }4028 4029 /// Build a new template argument pack expansion.4030 ///4031 /// By default, performs semantic analysis to build a new pack expansion4032 /// for a template argument. Subclasses may override this routine to provide4033 /// different behavior.4034 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,4035 SourceLocation EllipsisLoc,4036 UnsignedOrNone NumExpansions) {4037 switch (Pattern.getArgument().getKind()) {4038 case TemplateArgument::Expression: {4039 ExprResult Result4040 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),4041 EllipsisLoc, NumExpansions);4042 if (Result.isInvalid())4043 return TemplateArgumentLoc();4044 4045 return TemplateArgumentLoc(TemplateArgument(Result.get(),4046 /*IsCanonical=*/false),4047 Result.get());4048 }4049 4050 case TemplateArgument::Template:4051 return TemplateArgumentLoc(4052 SemaRef.Context,4053 TemplateArgument(Pattern.getArgument().getAsTemplate(),4054 NumExpansions),4055 Pattern.getTemplateKWLoc(), Pattern.getTemplateQualifierLoc(),4056 Pattern.getTemplateNameLoc(), EllipsisLoc);4057 4058 case TemplateArgument::Null:4059 case TemplateArgument::Integral:4060 case TemplateArgument::Declaration:4061 case TemplateArgument::StructuralValue:4062 case TemplateArgument::Pack:4063 case TemplateArgument::TemplateExpansion:4064 case TemplateArgument::NullPtr:4065 llvm_unreachable("Pack expansion pattern has no parameter packs");4066 4067 case TemplateArgument::Type:4068 if (TypeSourceInfo *Expansion4069 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),4070 EllipsisLoc,4071 NumExpansions))4072 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),4073 Expansion);4074 break;4075 }4076 4077 return TemplateArgumentLoc();4078 }4079 4080 /// Build a new expression pack expansion.4081 ///4082 /// By default, performs semantic analysis to build a new pack expansion4083 /// for an expression. Subclasses may override this routine to provide4084 /// different behavior.4085 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,4086 UnsignedOrNone NumExpansions) {4087 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);4088 }4089 4090 /// Build a new C++1z fold-expression.4091 ///4092 /// By default, performs semantic analysis in order to build a new fold4093 /// expression.4094 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,4095 SourceLocation LParenLoc, Expr *LHS,4096 BinaryOperatorKind Operator,4097 SourceLocation EllipsisLoc, Expr *RHS,4098 SourceLocation RParenLoc,4099 UnsignedOrNone NumExpansions) {4100 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,4101 EllipsisLoc, RHS, RParenLoc,4102 NumExpansions);4103 }4104 4105 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,4106 LambdaScopeInfo *LSI) {4107 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {4108 if (Expr *Init = PVD->getInit())4109 LSI->ContainsUnexpandedParameterPack |=4110 Init->containsUnexpandedParameterPack();4111 else if (PVD->hasUninstantiatedDefaultArg())4112 LSI->ContainsUnexpandedParameterPack |=4113 PVD->getUninstantiatedDefaultArg()4114 ->containsUnexpandedParameterPack();4115 }4116 return getSema().BuildLambdaExpr(StartLoc, EndLoc);4117 }4118 4119 /// Build an empty C++1z fold-expression with the given operator.4120 ///4121 /// By default, produces the fallback value for the fold-expression, or4122 /// produce an error if there is no fallback value.4123 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,4124 BinaryOperatorKind Operator) {4125 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);4126 }4127 4128 /// Build a new atomic operation expression.4129 ///4130 /// By default, performs semantic analysis to build the new expression.4131 /// Subclasses may override this routine to provide different behavior.4132 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,4133 AtomicExpr::AtomicOp Op,4134 SourceLocation RParenLoc) {4135 // Use this for all of the locations, since we don't know the difference4136 // between the call and the expr at this point.4137 SourceRange Range{BuiltinLoc, RParenLoc};4138 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,4139 Sema::AtomicArgumentOrder::AST);4140 }4141 4142 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,4143 ArrayRef<Expr *> SubExprs, QualType Type) {4144 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);4145 }4146 4147 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,4148 SourceLocation BeginLoc,4149 SourceLocation DirLoc,4150 SourceLocation EndLoc,4151 ArrayRef<OpenACCClause *> Clauses,4152 StmtResult StrBlock) {4153 return getSema().OpenACC().ActOnEndStmtDirective(4154 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},4155 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, StrBlock);4156 }4157 4158 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,4159 SourceLocation DirLoc,4160 SourceLocation EndLoc,4161 ArrayRef<OpenACCClause *> Clauses,4162 StmtResult Loop) {4163 return getSema().OpenACC().ActOnEndStmtDirective(4164 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},4165 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,4166 Clauses, Loop);4167 }4168 4169 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,4170 SourceLocation BeginLoc,4171 SourceLocation DirLoc,4172 SourceLocation EndLoc,4173 ArrayRef<OpenACCClause *> Clauses,4174 StmtResult Loop) {4175 return getSema().OpenACC().ActOnEndStmtDirective(4176 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},4177 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, Loop);4178 }4179 4180 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,4181 SourceLocation DirLoc,4182 SourceLocation EndLoc,4183 ArrayRef<OpenACCClause *> Clauses,4184 StmtResult StrBlock) {4185 return getSema().OpenACC().ActOnEndStmtDirective(4186 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},4187 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,4188 Clauses, StrBlock);4189 }4190 4191 StmtResult4192 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,4193 SourceLocation DirLoc, SourceLocation EndLoc,4194 ArrayRef<OpenACCClause *> Clauses) {4195 return getSema().OpenACC().ActOnEndStmtDirective(4196 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},4197 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,4198 Clauses, {});4199 }4200 4201 StmtResult4202 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,4203 SourceLocation DirLoc, SourceLocation EndLoc,4204 ArrayRef<OpenACCClause *> Clauses) {4205 return getSema().OpenACC().ActOnEndStmtDirective(4206 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},4207 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,4208 Clauses, {});4209 }4210 4211 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,4212 SourceLocation DirLoc,4213 SourceLocation EndLoc,4214 ArrayRef<OpenACCClause *> Clauses,4215 StmtResult StrBlock) {4216 return getSema().OpenACC().ActOnEndStmtDirective(4217 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},4218 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,4219 Clauses, StrBlock);4220 }4221 4222 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,4223 SourceLocation DirLoc,4224 SourceLocation EndLoc,4225 ArrayRef<OpenACCClause *> Clauses) {4226 return getSema().OpenACC().ActOnEndStmtDirective(4227 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},4228 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,4229 Clauses, {});4230 }4231 4232 StmtResult4233 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,4234 SourceLocation DirLoc, SourceLocation EndLoc,4235 ArrayRef<OpenACCClause *> Clauses) {4236 return getSema().OpenACC().ActOnEndStmtDirective(4237 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},4238 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,4239 Clauses, {});4240 }4241 4242 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,4243 SourceLocation DirLoc,4244 SourceLocation EndLoc,4245 ArrayRef<OpenACCClause *> Clauses) {4246 return getSema().OpenACC().ActOnEndStmtDirective(4247 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},4248 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,4249 Clauses, {});4250 }4251 4252 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,4253 SourceLocation DirLoc,4254 SourceLocation EndLoc,4255 ArrayRef<OpenACCClause *> Clauses) {4256 return getSema().OpenACC().ActOnEndStmtDirective(4257 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},4258 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,4259 Clauses, {});4260 }4261 4262 StmtResult RebuildOpenACCWaitConstruct(4263 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,4264 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,4265 SourceLocation RParenLoc, SourceLocation EndLoc,4266 ArrayRef<OpenACCClause *> Clauses) {4267 llvm::SmallVector<Expr *> Exprs;4268 Exprs.push_back(DevNumExpr);4269 llvm::append_range(Exprs, QueueIdExprs);4270 return getSema().OpenACC().ActOnEndStmtDirective(4271 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,4272 Exprs, OpenACCAtomicKind::None, RParenLoc, EndLoc, Clauses, {});4273 }4274 4275 StmtResult RebuildOpenACCCacheConstruct(4276 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,4277 SourceLocation ReadOnlyLoc, ArrayRef<Expr *> VarList,4278 SourceLocation RParenLoc, SourceLocation EndLoc) {4279 return getSema().OpenACC().ActOnEndStmtDirective(4280 OpenACCDirectiveKind::Cache, BeginLoc, DirLoc, LParenLoc, ReadOnlyLoc,4281 VarList, OpenACCAtomicKind::None, RParenLoc, EndLoc, {}, {});4282 }4283 4284 StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,4285 SourceLocation DirLoc,4286 OpenACCAtomicKind AtKind,4287 SourceLocation EndLoc,4288 ArrayRef<OpenACCClause *> Clauses,4289 StmtResult AssociatedStmt) {4290 return getSema().OpenACC().ActOnEndStmtDirective(4291 OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{},4292 SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, Clauses,4293 AssociatedStmt);4294 }4295 4296 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {4297 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);4298 }4299 4300private:4301 QualType TransformTypeInObjectScope(TypeLocBuilder &TLB, TypeLoc TL,4302 QualType ObjectType,4303 NamedDecl *FirstQualifierInScope);4304 4305 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,4306 QualType ObjectType,4307 NamedDecl *FirstQualifierInScope) {4308 if (getDerived().AlreadyTransformed(TSInfo->getType()))4309 return TSInfo;4310 4311 TypeLocBuilder TLB;4312 QualType T = TransformTypeInObjectScope(TLB, TSInfo->getTypeLoc(),4313 ObjectType, FirstQualifierInScope);4314 if (T.isNull())4315 return nullptr;4316 return TLB.getTypeSourceInfo(SemaRef.Context, T);4317 }4318 4319 QualType TransformDependentNameType(TypeLocBuilder &TLB,4320 DependentNameTypeLoc TL,4321 bool DeducibleTSTContext,4322 QualType ObjectType = QualType(),4323 NamedDecl *UnqualLookup = nullptr);4324 4325 llvm::SmallVector<OpenACCClause *>4326 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,4327 ArrayRef<const OpenACCClause *> OldClauses);4328 4329 OpenACCClause *4330 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,4331 OpenACCDirectiveKind DirKind,4332 const OpenACCClause *OldClause);4333};4334 4335template <typename Derived>4336StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {4337 if (!S)4338 return S;4339 4340 switch (S->getStmtClass()) {4341 case Stmt::NoStmtClass: break;4342 4343 // Transform individual statement nodes4344 // Pass SDK into statements that can produce a value4345#define STMT(Node, Parent) \4346 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));4347#define VALUESTMT(Node, Parent) \4348 case Stmt::Node##Class: \4349 return getDerived().Transform##Node(cast<Node>(S), SDK);4350#define ABSTRACT_STMT(Node)4351#define EXPR(Node, Parent)4352#include "clang/AST/StmtNodes.inc"4353 4354 // Transform expressions by calling TransformExpr.4355#define STMT(Node, Parent)4356#define ABSTRACT_STMT(Stmt)4357#define EXPR(Node, Parent) case Stmt::Node##Class:4358#include "clang/AST/StmtNodes.inc"4359 {4360 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));4361 4362 if (SDK == StmtDiscardKind::StmtExprResult)4363 E = getSema().ActOnStmtExprResult(E);4364 return getSema().ActOnExprStmt(E, SDK == StmtDiscardKind::Discarded);4365 }4366 }4367 4368 return S;4369}4370 4371template<typename Derived>4372OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {4373 if (!S)4374 return S;4375 4376 switch (S->getClauseKind()) {4377 default: break;4378 // Transform individual clause nodes4379#define GEN_CLANG_CLAUSE_CLASS4380#define CLAUSE_CLASS(Enum, Str, Class) \4381 case Enum: \4382 return getDerived().Transform##Class(cast<Class>(S));4383#include "llvm/Frontend/OpenMP/OMP.inc"4384 }4385 4386 return S;4387}4388 4389 4390template<typename Derived>4391ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {4392 if (!E)4393 return E;4394 4395 switch (E->getStmtClass()) {4396 case Stmt::NoStmtClass: break;4397#define STMT(Node, Parent) case Stmt::Node##Class: break;4398#define ABSTRACT_STMT(Stmt)4399#define EXPR(Node, Parent) \4400 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));4401#include "clang/AST/StmtNodes.inc"4402 }4403 4404 return E;4405}4406 4407template<typename Derived>4408ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,4409 bool NotCopyInit) {4410 // Initializers are instantiated like expressions, except that various outer4411 // layers are stripped.4412 if (!Init)4413 return Init;4414 4415 if (auto *FE = dyn_cast<FullExpr>(Init))4416 Init = FE->getSubExpr();4417 4418 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {4419 OpaqueValueExpr *OVE = AIL->getCommonExpr();4420 Init = OVE->getSourceExpr();4421 }4422 4423 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))4424 Init = MTE->getSubExpr();4425 4426 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))4427 Init = Binder->getSubExpr();4428 4429 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))4430 Init = ICE->getSubExprAsWritten();4431 4432 if (CXXStdInitializerListExpr *ILE =4433 dyn_cast<CXXStdInitializerListExpr>(Init))4434 return TransformInitializer(ILE->getSubExpr(), NotCopyInit);4435 4436 // If this is copy-initialization, we only need to reconstruct4437 // InitListExprs. Other forms of copy-initialization will be a no-op if4438 // the initializer is already the right type.4439 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);4440 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))4441 return getDerived().TransformExpr(Init);4442 4443 // Revert value-initialization back to empty parens.4444 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {4445 SourceRange Parens = VIE->getSourceRange();4446 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},4447 Parens.getEnd());4448 }4449 4450 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.4451 if (isa<ImplicitValueInitExpr>(Init))4452 return getDerived().RebuildParenListExpr(SourceLocation(), {},4453 SourceLocation());4454 4455 // Revert initialization by constructor back to a parenthesized or braced list4456 // of expressions. Any other form of initializer can just be reused directly.4457 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))4458 return getDerived().TransformExpr(Init);4459 4460 // If the initialization implicitly converted an initializer list to a4461 // std::initializer_list object, unwrap the std::initializer_list too.4462 if (Construct && Construct->isStdInitListInitialization())4463 return TransformInitializer(Construct->getArg(0), NotCopyInit);4464 4465 // Enter a list-init context if this was list initialization.4466 EnterExpressionEvaluationContext Context(4467 getSema(), EnterExpressionEvaluationContext::InitList,4468 Construct->isListInitialization());4469 4470 getSema().currentEvaluationContext().InLifetimeExtendingContext =4471 getSema().parentEvaluationContext().InLifetimeExtendingContext;4472 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =4473 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;4474 SmallVector<Expr*, 8> NewArgs;4475 bool ArgChanged = false;4476 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),4477 /*IsCall*/true, NewArgs, &ArgChanged))4478 return ExprError();4479 4480 // If this was list initialization, revert to syntactic list form.4481 if (Construct->isListInitialization())4482 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,4483 Construct->getEndLoc());4484 4485 // Build a ParenListExpr to represent anything else.4486 SourceRange Parens = Construct->getParenOrBraceRange();4487 if (Parens.isInvalid()) {4488 // This was a variable declaration's initialization for which no initializer4489 // was specified.4490 assert(NewArgs.empty() &&4491 "no parens or braces but have direct init with arguments?");4492 return ExprEmpty();4493 }4494 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,4495 Parens.getEnd());4496}4497 4498template<typename Derived>4499bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,4500 unsigned NumInputs,4501 bool IsCall,4502 SmallVectorImpl<Expr *> &Outputs,4503 bool *ArgChanged) {4504 for (unsigned I = 0; I != NumInputs; ++I) {4505 // If requested, drop call arguments that need to be dropped.4506 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {4507 if (ArgChanged)4508 *ArgChanged = true;4509 4510 break;4511 }4512 4513 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {4514 Expr *Pattern = Expansion->getPattern();4515 4516 SmallVector<UnexpandedParameterPack, 2> Unexpanded;4517 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);4518 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");4519 4520 // Determine whether the set of unexpanded parameter packs can and should4521 // be expanded.4522 bool Expand = true;4523 bool RetainExpansion = false;4524 UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();4525 UnsignedOrNone NumExpansions = OrigNumExpansions;4526 if (getDerived().TryExpandParameterPacks(4527 Expansion->getEllipsisLoc(), Pattern->getSourceRange(),4528 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,4529 RetainExpansion, NumExpansions))4530 return true;4531 4532 if (!Expand) {4533 // The transform has determined that we should perform a simple4534 // transformation on the pack expansion, producing another pack4535 // expansion.4536 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);4537 ExprResult OutPattern = getDerived().TransformExpr(Pattern);4538 if (OutPattern.isInvalid())4539 return true;4540 4541 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),4542 Expansion->getEllipsisLoc(),4543 NumExpansions);4544 if (Out.isInvalid())4545 return true;4546 4547 if (ArgChanged)4548 *ArgChanged = true;4549 Outputs.push_back(Out.get());4550 continue;4551 }4552 4553 // Record right away that the argument was changed. This needs4554 // to happen even if the array expands to nothing.4555 if (ArgChanged) *ArgChanged = true;4556 4557 // The transform has determined that we should perform an elementwise4558 // expansion of the pattern. Do so.4559 for (unsigned I = 0; I != *NumExpansions; ++I) {4560 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);4561 ExprResult Out = getDerived().TransformExpr(Pattern);4562 if (Out.isInvalid())4563 return true;4564 4565 if (Out.get()->containsUnexpandedParameterPack()) {4566 Out = getDerived().RebuildPackExpansion(4567 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);4568 if (Out.isInvalid())4569 return true;4570 }4571 4572 Outputs.push_back(Out.get());4573 }4574 4575 // If we're supposed to retain a pack expansion, do so by temporarily4576 // forgetting the partially-substituted parameter pack.4577 if (RetainExpansion) {4578 ForgetPartiallySubstitutedPackRAII Forget(getDerived());4579 4580 ExprResult Out = getDerived().TransformExpr(Pattern);4581 if (Out.isInvalid())4582 return true;4583 4584 Out = getDerived().RebuildPackExpansion(4585 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);4586 if (Out.isInvalid())4587 return true;4588 4589 Outputs.push_back(Out.get());4590 }4591 4592 continue;4593 }4594 4595 ExprResult Result =4596 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)4597 : getDerived().TransformExpr(Inputs[I]);4598 if (Result.isInvalid())4599 return true;4600 4601 if (Result.get() != Inputs[I] && ArgChanged)4602 *ArgChanged = true;4603 4604 Outputs.push_back(Result.get());4605 }4606 4607 return false;4608}4609 4610template <typename Derived>4611Sema::ConditionResult TreeTransform<Derived>::TransformCondition(4612 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {4613 4614 EnterExpressionEvaluationContext Eval(4615 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,4616 /*LambdaContextDecl=*/nullptr,4617 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_Other,4618 /*ShouldEnter=*/Kind == Sema::ConditionKind::ConstexprIf);4619 4620 if (Var) {4621 VarDecl *ConditionVar = cast_or_null<VarDecl>(4622 getDerived().TransformDefinition(Var->getLocation(), Var));4623 4624 if (!ConditionVar)4625 return Sema::ConditionError();4626 4627 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);4628 }4629 4630 if (Expr) {4631 ExprResult CondExpr = getDerived().TransformExpr(Expr);4632 4633 if (CondExpr.isInvalid())4634 return Sema::ConditionError();4635 4636 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,4637 /*MissingOK=*/true);4638 }4639 4640 return Sema::ConditionResult();4641}4642 4643template <typename Derived>4644NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(4645 NestedNameSpecifierLoc NNS, QualType ObjectType,4646 NamedDecl *FirstQualifierInScope) {4647 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;4648 4649 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {4650 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;4651 Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix)4652 Qualifiers.push_back(Qualifier);4653 };4654 insertNNS(NNS);4655 4656 CXXScopeSpec SS;4657 while (!Qualifiers.empty()) {4658 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();4659 NestedNameSpecifier QNNS = Q.getNestedNameSpecifier();4660 4661 switch (QNNS.getKind()) {4662 case NestedNameSpecifier::Kind::Null:4663 llvm_unreachable("unexpected null nested name specifier");4664 4665 case NestedNameSpecifier::Kind::Namespace: {4666 auto *NS = cast<NamespaceBaseDecl>(getDerived().TransformDecl(4667 Q.getLocalBeginLoc(), const_cast<NamespaceBaseDecl *>(4668 QNNS.getAsNamespaceAndPrefix().Namespace)));4669 SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());4670 break;4671 }4672 4673 case NestedNameSpecifier::Kind::Global:4674 // There is no meaningful transformation that one could perform on the4675 // global scope.4676 SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());4677 break;4678 4679 case NestedNameSpecifier::Kind::MicrosoftSuper: {4680 CXXRecordDecl *RD = cast_or_null<CXXRecordDecl>(4681 getDerived().TransformDecl(SourceLocation(), QNNS.getAsRecordDecl()));4682 SS.MakeMicrosoftSuper(SemaRef.Context, RD, Q.getBeginLoc(),4683 Q.getEndLoc());4684 break;4685 }4686 4687 case NestedNameSpecifier::Kind::Type: {4688 assert(SS.isEmpty());4689 TypeLoc TL = Q.castAsTypeLoc();4690 4691 if (auto DNT = TL.getAs<DependentNameTypeLoc>()) {4692 NestedNameSpecifierLoc QualifierLoc = DNT.getQualifierLoc();4693 if (QualifierLoc) {4694 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(4695 QualifierLoc, ObjectType, FirstQualifierInScope);4696 if (!QualifierLoc)4697 return NestedNameSpecifierLoc();4698 ObjectType = QualType();4699 FirstQualifierInScope = nullptr;4700 }4701 SS.Adopt(QualifierLoc);4702 Sema::NestedNameSpecInfo IdInfo(4703 const_cast<IdentifierInfo *>(DNT.getTypePtr()->getIdentifier()),4704 DNT.getNameLoc(), Q.getLocalEndLoc(), ObjectType);4705 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo,4706 false, SS,4707 FirstQualifierInScope, false))4708 return NestedNameSpecifierLoc();4709 return SS.getWithLocInContext(SemaRef.Context);4710 }4711 4712 QualType T = TL.getType();4713 TypeLocBuilder TLB;4714 if (!getDerived().AlreadyTransformed(T)) {4715 T = TransformTypeInObjectScope(TLB, TL, ObjectType,4716 FirstQualifierInScope);4717 if (T.isNull())4718 return NestedNameSpecifierLoc();4719 TL = TLB.getTypeLocInContext(SemaRef.Context, T);4720 }4721 4722 if (T->isDependentType() || T->isRecordType() ||4723 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {4724 if (T->isEnumeralType())4725 SemaRef.Diag(TL.getBeginLoc(),4726 diag::warn_cxx98_compat_enum_nested_name_spec);4727 SS.Make(SemaRef.Context, TL, Q.getLocalEndLoc());4728 break;4729 }4730 // If the nested-name-specifier is an invalid type def, don't emit an4731 // error because a previous error should have already been emitted.4732 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();4733 if (!TTL || !TTL.getDecl()->isInvalidDecl()) {4734 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)4735 << T << SS.getRange();4736 }4737 return NestedNameSpecifierLoc();4738 }4739 }4740 }4741 4742 // Don't rebuild the nested-name-specifier if we don't have to.4743 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&4744 !getDerived().AlwaysRebuild())4745 return NNS;4746 4747 // If we can re-use the source-location data from the original4748 // nested-name-specifier, do so.4749 if (SS.location_size() == NNS.getDataLength() &&4750 memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)4751 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());4752 4753 // Allocate new nested-name-specifier location information.4754 return SS.getWithLocInContext(SemaRef.Context);4755}4756 4757template<typename Derived>4758DeclarationNameInfo4759TreeTransform<Derived>4760::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {4761 DeclarationName Name = NameInfo.getName();4762 if (!Name)4763 return DeclarationNameInfo();4764 4765 switch (Name.getNameKind()) {4766 case DeclarationName::Identifier:4767 case DeclarationName::ObjCZeroArgSelector:4768 case DeclarationName::ObjCOneArgSelector:4769 case DeclarationName::ObjCMultiArgSelector:4770 case DeclarationName::CXXOperatorName:4771 case DeclarationName::CXXLiteralOperatorName:4772 case DeclarationName::CXXUsingDirective:4773 return NameInfo;4774 4775 case DeclarationName::CXXDeductionGuideName: {4776 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();4777 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(4778 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));4779 if (!NewTemplate)4780 return DeclarationNameInfo();4781 4782 DeclarationNameInfo NewNameInfo(NameInfo);4783 NewNameInfo.setName(4784 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(NewTemplate));4785 return NewNameInfo;4786 }4787 4788 case DeclarationName::CXXConstructorName:4789 case DeclarationName::CXXDestructorName:4790 case DeclarationName::CXXConversionFunctionName: {4791 TypeSourceInfo *NewTInfo;4792 CanQualType NewCanTy;4793 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {4794 NewTInfo = getDerived().TransformType(OldTInfo);4795 if (!NewTInfo)4796 return DeclarationNameInfo();4797 NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());4798 }4799 else {4800 NewTInfo = nullptr;4801 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);4802 QualType NewT = getDerived().TransformType(Name.getCXXNameType());4803 if (NewT.isNull())4804 return DeclarationNameInfo();4805 NewCanTy = SemaRef.Context.getCanonicalType(NewT);4806 }4807 4808 DeclarationName NewName4809 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),4810 NewCanTy);4811 DeclarationNameInfo NewNameInfo(NameInfo);4812 NewNameInfo.setName(NewName);4813 NewNameInfo.setNamedTypeInfo(NewTInfo);4814 return NewNameInfo;4815 }4816 }4817 4818 llvm_unreachable("Unknown name kind.");4819}4820 4821template <typename Derived>4822TemplateName TreeTransform<Derived>::RebuildTemplateName(4823 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,4824 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,4825 QualType ObjectType, bool AllowInjectedClassName) {4826 if (const IdentifierInfo *II = IO.getIdentifier())4827 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,4828 ObjectType, AllowInjectedClassName);4829 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),4830 NameLoc, ObjectType,4831 AllowInjectedClassName);4832}4833 4834template <typename Derived>4835TemplateName TreeTransform<Derived>::TransformTemplateName(4836 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc,4837 TemplateName Name, SourceLocation NameLoc, QualType ObjectType,4838 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {4839 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {4840 TemplateName UnderlyingName = QTN->getUnderlyingTemplate();4841 4842 if (QualifierLoc) {4843 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(4844 QualifierLoc, ObjectType, FirstQualifierInScope);4845 if (!QualifierLoc)4846 return TemplateName();4847 }4848 4849 NestedNameSpecifierLoc UnderlyingQualifier;4850 TemplateName NewUnderlyingName = getDerived().TransformTemplateName(4851 UnderlyingQualifier, TemplateKWLoc, UnderlyingName, NameLoc, ObjectType,4852 FirstQualifierInScope, AllowInjectedClassName);4853 if (NewUnderlyingName.isNull())4854 return TemplateName();4855 assert(!UnderlyingQualifier && "unexpected qualifier");4856 4857 if (!getDerived().AlwaysRebuild() &&4858 QualifierLoc.getNestedNameSpecifier() == QTN->getQualifier() &&4859 NewUnderlyingName == UnderlyingName)4860 return Name;4861 CXXScopeSpec SS;4862 SS.Adopt(QualifierLoc);4863 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),4864 NewUnderlyingName);4865 }4866 4867 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {4868 if (QualifierLoc) {4869 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(4870 QualifierLoc, ObjectType, FirstQualifierInScope);4871 if (!QualifierLoc)4872 return TemplateName();4873 // The qualifier-in-scope and object type only apply to the leftmost4874 // entity.4875 ObjectType = QualType();4876 }4877 4878 if (!getDerived().AlwaysRebuild() &&4879 QualifierLoc.getNestedNameSpecifier() == DTN->getQualifier() &&4880 ObjectType.isNull())4881 return Name;4882 4883 CXXScopeSpec SS;4884 SS.Adopt(QualifierLoc);4885 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, DTN->getName(),4886 NameLoc, ObjectType,4887 AllowInjectedClassName);4888 }4889 4890 if (SubstTemplateTemplateParmStorage *S =4891 Name.getAsSubstTemplateTemplateParm()) {4892 assert(!QualifierLoc && "Unexpected qualified SubstTemplateTemplateParm");4893 4894 NestedNameSpecifierLoc ReplacementQualifierLoc;4895 TemplateName ReplacementName = S->getReplacement();4896 if (NestedNameSpecifier Qualifier = ReplacementName.getQualifier()) {4897 NestedNameSpecifierLocBuilder Builder;4898 Builder.MakeTrivial(SemaRef.Context, Qualifier, NameLoc);4899 ReplacementQualifierLoc = Builder.getWithLocInContext(SemaRef.Context);4900 }4901 4902 TemplateName NewName = getDerived().TransformTemplateName(4903 ReplacementQualifierLoc, TemplateKWLoc, ReplacementName, NameLoc,4904 ObjectType, FirstQualifierInScope, AllowInjectedClassName);4905 if (NewName.isNull())4906 return TemplateName();4907 Decl *AssociatedDecl =4908 getDerived().TransformDecl(NameLoc, S->getAssociatedDecl());4909 if (!getDerived().AlwaysRebuild() && NewName == S->getReplacement() &&4910 AssociatedDecl == S->getAssociatedDecl())4911 return Name;4912 return SemaRef.Context.getSubstTemplateTemplateParm(4913 NewName, AssociatedDecl, S->getIndex(), S->getPackIndex(),4914 S->getFinal());4915 }4916 4917 assert(!Name.getAsDeducedTemplateName() &&4918 "DeducedTemplateName should not escape partial ordering");4919 4920 // FIXME: Preserve UsingTemplateName.4921 if (auto *Template = Name.getAsTemplateDecl()) {4922 assert(!QualifierLoc && "Unexpected qualifier");4923 return TemplateName(cast_or_null<TemplateDecl>(4924 getDerived().TransformDecl(NameLoc, Template)));4925 }4926 4927 if (SubstTemplateTemplateParmPackStorage *SubstPack4928 = Name.getAsSubstTemplateTemplateParmPack()) {4929 assert(!QualifierLoc &&4930 "Unexpected qualified SubstTemplateTemplateParmPack");4931 return getDerived().RebuildTemplateName(4932 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),4933 SubstPack->getIndex(), SubstPack->getFinal());4934 }4935 4936 // These should be getting filtered out before they reach the AST.4937 llvm_unreachable("overloaded function decl survived to here");4938}4939 4940template <typename Derived>4941TemplateArgument TreeTransform<Derived>::TransformNamedTemplateTemplateArgument(4942 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,4943 TemplateName Name, SourceLocation NameLoc) {4944 TemplateName TN = getDerived().TransformTemplateName(4945 QualifierLoc, TemplateKeywordLoc, Name, NameLoc);4946 if (TN.isNull())4947 return TemplateArgument();4948 return TemplateArgument(TN);4949}4950 4951template<typename Derived>4952void TreeTransform<Derived>::InventTemplateArgumentLoc(4953 const TemplateArgument &Arg,4954 TemplateArgumentLoc &Output) {4955 Output = getSema().getTrivialTemplateArgumentLoc(4956 Arg, QualType(), getDerived().getBaseLocation());4957}4958 4959template <typename Derived>4960bool TreeTransform<Derived>::TransformTemplateArgument(4961 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,4962 bool Uneval) {4963 const TemplateArgument &Arg = Input.getArgument();4964 switch (Arg.getKind()) {4965 case TemplateArgument::Null:4966 case TemplateArgument::Pack:4967 llvm_unreachable("Unexpected TemplateArgument");4968 4969 case TemplateArgument::Integral:4970 case TemplateArgument::NullPtr:4971 case TemplateArgument::Declaration:4972 case TemplateArgument::StructuralValue: {4973 // Transform a resolved template argument straight to a resolved template4974 // argument. We get here when substituting into an already-substituted4975 // template type argument during concept satisfaction checking.4976 QualType T = Arg.getNonTypeTemplateArgumentType();4977 QualType NewT = getDerived().TransformType(T);4978 if (NewT.isNull())4979 return true;4980 4981 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration4982 ? Arg.getAsDecl()4983 : nullptr;4984 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(4985 getDerived().getBaseLocation(), D))4986 : nullptr;4987 if (D && !NewD)4988 return true;4989 4990 if (NewT == T && D == NewD)4991 Output = Input;4992 else if (Arg.getKind() == TemplateArgument::Integral)4993 Output = TemplateArgumentLoc(4994 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),4995 TemplateArgumentLocInfo());4996 else if (Arg.getKind() == TemplateArgument::NullPtr)4997 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),4998 TemplateArgumentLocInfo());4999 else if (Arg.getKind() == TemplateArgument::Declaration)5000 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),5001 TemplateArgumentLocInfo());5002 else if (Arg.getKind() == TemplateArgument::StructuralValue)5003 Output = TemplateArgumentLoc(5004 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),5005 TemplateArgumentLocInfo());5006 else5007 llvm_unreachable("unexpected template argument kind");5008 5009 return false;5010 }5011 5012 case TemplateArgument::Type: {5013 TypeSourceInfo *TSI = Input.getTypeSourceInfo();5014 if (!TSI)5015 TSI = InventTypeSourceInfo(Input.getArgument().getAsType());5016 5017 TSI = getDerived().TransformType(TSI);5018 if (!TSI)5019 return true;5020 5021 Output = TemplateArgumentLoc(TemplateArgument(TSI->getType()), TSI);5022 return false;5023 }5024 5025 case TemplateArgument::Template: {5026 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();5027 5028 TemplateArgument Out = getDerived().TransformNamedTemplateTemplateArgument(5029 QualifierLoc, Input.getTemplateKWLoc(), Arg.getAsTemplate(),5030 Input.getTemplateNameLoc());5031 if (Out.isNull())5032 return true;5033 Output = TemplateArgumentLoc(SemaRef.Context, Out, Input.getTemplateKWLoc(),5034 QualifierLoc, Input.getTemplateNameLoc());5035 return false;5036 }5037 5038 case TemplateArgument::TemplateExpansion:5039 llvm_unreachable("Caller should expand pack expansions");5040 5041 case TemplateArgument::Expression: {5042 // Template argument expressions are constant expressions.5043 EnterExpressionEvaluationContext Unevaluated(5044 getSema(),5045 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated5046 : Sema::ExpressionEvaluationContext::ConstantEvaluated,5047 Sema::ReuseLambdaContextDecl, /*ExprContext=*/5048 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);5049 5050 Expr *InputExpr = Input.getSourceExpression();5051 if (!InputExpr)5052 InputExpr = Input.getArgument().getAsExpr();5053 5054 ExprResult E = getDerived().TransformExpr(InputExpr);5055 E = SemaRef.ActOnConstantExpression(E);5056 if (E.isInvalid())5057 return true;5058 Output = TemplateArgumentLoc(5059 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());5060 return false;5061 }5062 }5063 5064 // Work around bogus GCC warning5065 return true;5066}5067 5068/// Iterator adaptor that invents template argument location information5069/// for each of the template arguments in its underlying iterator.5070template<typename Derived, typename InputIterator>5071class TemplateArgumentLocInventIterator {5072 TreeTransform<Derived> &Self;5073 InputIterator Iter;5074 5075public:5076 typedef TemplateArgumentLoc value_type;5077 typedef TemplateArgumentLoc reference;5078 typedef typename std::iterator_traits<InputIterator>::difference_type5079 difference_type;5080 typedef std::input_iterator_tag iterator_category;5081 5082 class pointer {5083 TemplateArgumentLoc Arg;5084 5085 public:5086 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }5087 5088 const TemplateArgumentLoc *operator->() const { return &Arg; }5089 };5090 5091 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,5092 InputIterator Iter)5093 : Self(Self), Iter(Iter) { }5094 5095 TemplateArgumentLocInventIterator &operator++() {5096 ++Iter;5097 return *this;5098 }5099 5100 TemplateArgumentLocInventIterator operator++(int) {5101 TemplateArgumentLocInventIterator Old(*this);5102 ++(*this);5103 return Old;5104 }5105 5106 reference operator*() const {5107 TemplateArgumentLoc Result;5108 Self.InventTemplateArgumentLoc(*Iter, Result);5109 return Result;5110 }5111 5112 pointer operator->() const { return pointer(**this); }5113 5114 friend bool operator==(const TemplateArgumentLocInventIterator &X,5115 const TemplateArgumentLocInventIterator &Y) {5116 return X.Iter == Y.Iter;5117 }5118 5119 friend bool operator!=(const TemplateArgumentLocInventIterator &X,5120 const TemplateArgumentLocInventIterator &Y) {5121 return X.Iter != Y.Iter;5122 }5123};5124 5125template<typename Derived>5126template<typename InputIterator>5127bool TreeTransform<Derived>::TransformTemplateArguments(5128 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,5129 bool Uneval) {5130 for (TemplateArgumentLoc In : llvm::make_range(First, Last)) {5131 TemplateArgumentLoc Out;5132 if (In.getArgument().getKind() == TemplateArgument::Pack) {5133 // Unpack argument packs, which we translate them into separate5134 // arguments.5135 // FIXME: We could do much better if we could guarantee that the5136 // TemplateArgumentLocInfo for the pack expansion would be usable for5137 // all of the template arguments in the argument pack.5138 typedef TemplateArgumentLocInventIterator<Derived,5139 TemplateArgument::pack_iterator>5140 PackLocIterator;5141 5142 TemplateArgumentListInfo *PackOutput = &Outputs;5143 TemplateArgumentListInfo New;5144 5145 if (TransformTemplateArguments(5146 PackLocIterator(*this, In.getArgument().pack_begin()),5147 PackLocIterator(*this, In.getArgument().pack_end()), *PackOutput,5148 Uneval))5149 return true;5150 5151 continue;5152 }5153 5154 if (In.getArgument().isPackExpansion()) {5155 UnexpandedInfo Info;5156 TemplateArgumentLoc Prepared;5157 if (PreparePackForExpansion(In, Uneval, Prepared, Info))5158 return true;5159 if (!Info.Expand) {5160 Outputs.addArgument(Prepared);5161 continue;5162 }5163 5164 // The transform has determined that we should perform an elementwise5165 // expansion of the pattern. Do so.5166 std::optional<ForgetSubstitutionRAII> ForgetSubst;5167 if (Info.ExpandUnderForgetSubstitions)5168 ForgetSubst.emplace(getDerived());5169 for (unsigned I = 0; I != *Info.NumExpansions; ++I) {5170 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);5171 5172 TemplateArgumentLoc Out;5173 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))5174 return true;5175 5176 if (Out.getArgument().containsUnexpandedParameterPack()) {5177 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,5178 Info.OrigNumExpansions);5179 if (Out.getArgument().isNull())5180 return true;5181 }5182 5183 Outputs.addArgument(Out);5184 }5185 5186 // If we're supposed to retain a pack expansion, do so by temporarily5187 // forgetting the partially-substituted parameter pack.5188 if (Info.RetainExpansion) {5189 ForgetPartiallySubstitutedPackRAII Forget(getDerived());5190 5191 TemplateArgumentLoc Out;5192 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))5193 return true;5194 5195 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,5196 Info.OrigNumExpansions);5197 if (Out.getArgument().isNull())5198 return true;5199 5200 Outputs.addArgument(Out);5201 }5202 5203 continue;5204 }5205 5206 // The simple case:5207 if (getDerived().TransformTemplateArgument(In, Out, Uneval))5208 return true;5209 5210 Outputs.addArgument(Out);5211 }5212 5213 return false;5214}5215 5216template <typename Derived>5217template <typename InputIterator>5218bool TreeTransform<Derived>::TransformConceptTemplateArguments(5219 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,5220 bool Uneval) {5221 5222 // [C++26][temp.constr.normal]5223 // any non-dependent concept template argument5224 // is substituted into the constraint-expression of C.5225 auto isNonDependentConceptArgument = [](const TemplateArgument &Arg) {5226 return !Arg.isDependent() && Arg.isConceptOrConceptTemplateParameter();5227 };5228 5229 for (; First != Last; ++First) {5230 TemplateArgumentLoc Out;5231 TemplateArgumentLoc In = *First;5232 5233 if (In.getArgument().getKind() == TemplateArgument::Pack) {5234 typedef TemplateArgumentLocInventIterator<Derived,5235 TemplateArgument::pack_iterator>5236 PackLocIterator;5237 if (TransformConceptTemplateArguments(5238 PackLocIterator(*this, In.getArgument().pack_begin()),5239 PackLocIterator(*this, In.getArgument().pack_end()), Outputs,5240 Uneval))5241 return true;5242 continue;5243 }5244 5245 if (!isNonDependentConceptArgument(In.getArgument())) {5246 Outputs.addArgument(In);5247 continue;5248 }5249 5250 if (getDerived().TransformTemplateArgument(In, Out, Uneval))5251 return true;5252 5253 Outputs.addArgument(Out);5254 }5255 5256 return false;5257}5258 5259// FIXME: Find ways to reduce code duplication for pack expansions.5260template <typename Derived>5261bool TreeTransform<Derived>::PreparePackForExpansion(TemplateArgumentLoc In,5262 bool Uneval,5263 TemplateArgumentLoc &Out,5264 UnexpandedInfo &Info) {5265 auto ComputeInfo = [this](TemplateArgumentLoc Arg,5266 bool IsLateExpansionAttempt, UnexpandedInfo &Info,5267 TemplateArgumentLoc &Pattern) {5268 assert(Arg.getArgument().isPackExpansion());5269 // We have a pack expansion, for which we will be substituting into the5270 // pattern.5271 Pattern = getSema().getTemplateArgumentPackExpansionPattern(5272 Arg, Info.Ellipsis, Info.OrigNumExpansions);5273 SmallVector<UnexpandedParameterPack, 2> Unexpanded;5274 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);5275 if (IsLateExpansionAttempt) {5276 // Request expansion only when there is an opportunity to expand a pack5277 // that required a substituion first.5278 bool SawPackTypes =5279 llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {5280 return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();5281 });5282 if (!SawPackTypes) {5283 Info.Expand = false;5284 return false;5285 }5286 }5287 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");5288 5289 // Determine whether the set of unexpanded parameter packs can and5290 // should be expanded.5291 Info.Expand = true;5292 Info.RetainExpansion = false;5293 Info.NumExpansions = Info.OrigNumExpansions;5294 return getDerived().TryExpandParameterPacks(5295 Info.Ellipsis, Pattern.getSourceRange(), Unexpanded,5296 /*FailOnPackProducingTemplates=*/false, Info.Expand,5297 Info.RetainExpansion, Info.NumExpansions);5298 };5299 5300 TemplateArgumentLoc Pattern;5301 if (ComputeInfo(In, false, Info, Pattern))5302 return true;5303 5304 if (Info.Expand) {5305 Out = Pattern;5306 return false;5307 }5308 5309 // The transform has determined that we should perform a simple5310 // transformation on the pack expansion, producing another pack5311 // expansion.5312 TemplateArgumentLoc OutPattern;5313 std::optional<Sema::ArgPackSubstIndexRAII> SubstIndex(5314 std::in_place, getSema(), std::nullopt);5315 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))5316 return true;5317 5318 Out = getDerived().RebuildPackExpansion(OutPattern, Info.Ellipsis,5319 Info.NumExpansions);5320 if (Out.getArgument().isNull())5321 return true;5322 SubstIndex.reset();5323 5324 if (!OutPattern.getArgument().containsUnexpandedParameterPack())5325 return false;5326 5327 // Some packs will learn their length after substitution, e.g.5328 // __builtin_dedup_pack<T,int> has size 1 or 2, depending on the substitution5329 // value of `T`.5330 //5331 // We only expand after we know sizes of all packs, check if this is the case5332 // or not. However, we avoid a full template substitution and only do5333 // expanstions after this point.5334 5335 // E.g. when substituting template arguments of tuple with {T -> int} in the5336 // following example:5337 // template <class T>5338 // struct TupleWithInt {5339 // using type = std::tuple<__builtin_dedup_pack<T, int>...>;5340 // };5341 // TupleWithInt<int>::type y;5342 // At this point we will see the `__builtin_dedup_pack<int, int>` with a known5343 // lenght and run `ComputeInfo()` to provide the necessary information to our5344 // caller.5345 //5346 // Note that we may still have situations where builtin is not going to be5347 // expanded. For example:5348 // template <class T>5349 // struct Foo {5350 // template <class U> using tuple_with_t =5351 // std::tuple<__builtin_dedup_pack<T, U, int>...>; using type =5352 // tuple_with_t<short>;5353 // }5354 // Because the substitution into `type` happens in dependent context, `type`5355 // will be `tuple<builtin_dedup_pack<T, short, int>...>` after substitution5356 // and the caller will not be able to expand it.5357 ForgetSubstitutionRAII ForgetSubst(getDerived());5358 if (ComputeInfo(Out, true, Info, OutPattern))5359 return true;5360 if (!Info.Expand)5361 return false;5362 Out = OutPattern;5363 Info.ExpandUnderForgetSubstitions = true;5364 return false;5365}5366 5367//===----------------------------------------------------------------------===//5368// Type transformation5369//===----------------------------------------------------------------------===//5370 5371template<typename Derived>5372QualType TreeTransform<Derived>::TransformType(QualType T) {5373 if (getDerived().AlreadyTransformed(T))5374 return T;5375 5376 // Temporary workaround. All of these transformations should5377 // eventually turn into transformations on TypeLocs.5378 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(5379 T, getDerived().getBaseLocation());5380 5381 TypeSourceInfo *NewTSI = getDerived().TransformType(TSI);5382 5383 if (!NewTSI)5384 return QualType();5385 5386 return NewTSI->getType();5387}5388 5389template <typename Derived>5390TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *TSI) {5391 // Refine the base location to the type's location.5392 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),5393 getDerived().getBaseEntity());5394 if (getDerived().AlreadyTransformed(TSI->getType()))5395 return TSI;5396 5397 TypeLocBuilder TLB;5398 5399 TypeLoc TL = TSI->getTypeLoc();5400 TLB.reserve(TL.getFullDataSize());5401 5402 QualType Result = getDerived().TransformType(TLB, TL);5403 if (Result.isNull())5404 return nullptr;5405 5406 return TLB.getTypeSourceInfo(SemaRef.Context, Result);5407}5408 5409template<typename Derived>5410QualType5411TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {5412 switch (T.getTypeLocClass()) {5413#define ABSTRACT_TYPELOC(CLASS, PARENT)5414#define TYPELOC(CLASS, PARENT) \5415 case TypeLoc::CLASS: \5416 return getDerived().Transform##CLASS##Type(TLB, \5417 T.castAs<CLASS##TypeLoc>());5418#include "clang/AST/TypeLocNodes.def"5419 }5420 5421 llvm_unreachable("unhandled type loc!");5422}5423 5424template<typename Derived>5425QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {5426 if (!isa<DependentNameType>(T))5427 return TransformType(T);5428 5429 if (getDerived().AlreadyTransformed(T))5430 return T;5431 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(5432 T, getDerived().getBaseLocation());5433 TypeSourceInfo *NewTSI = getDerived().TransformTypeWithDeducedTST(TSI);5434 return NewTSI ? NewTSI->getType() : QualType();5435}5436 5437template <typename Derived>5438TypeSourceInfo *5439TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *TSI) {5440 if (!isa<DependentNameType>(TSI->getType()))5441 return TransformType(TSI);5442 5443 // Refine the base location to the type's location.5444 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),5445 getDerived().getBaseEntity());5446 if (getDerived().AlreadyTransformed(TSI->getType()))5447 return TSI;5448 5449 TypeLocBuilder TLB;5450 5451 TypeLoc TL = TSI->getTypeLoc();5452 TLB.reserve(TL.getFullDataSize());5453 5454 auto QTL = TL.getAs<QualifiedTypeLoc>();5455 if (QTL)5456 TL = QTL.getUnqualifiedLoc();5457 5458 auto DNTL = TL.castAs<DependentNameTypeLoc>();5459 5460 QualType Result = getDerived().TransformDependentNameType(5461 TLB, DNTL, /*DeducedTSTContext*/true);5462 if (Result.isNull())5463 return nullptr;5464 5465 if (QTL) {5466 Result = getDerived().RebuildQualifiedType(Result, QTL);5467 if (Result.isNull())5468 return nullptr;5469 TLB.TypeWasModifiedSafely(Result);5470 }5471 5472 return TLB.getTypeSourceInfo(SemaRef.Context, Result);5473}5474 5475template<typename Derived>5476QualType5477TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,5478 QualifiedTypeLoc T) {5479 QualType Result;5480 TypeLoc UnqualTL = T.getUnqualifiedLoc();5481 auto SuppressObjCLifetime =5482 T.getType().getLocalQualifiers().hasObjCLifetime();5483 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {5484 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,5485 SuppressObjCLifetime);5486 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {5487 Result = getDerived().TransformSubstTemplateTypeParmPackType(5488 TLB, STTP, SuppressObjCLifetime);5489 } else {5490 Result = getDerived().TransformType(TLB, UnqualTL);5491 }5492 5493 if (Result.isNull())5494 return QualType();5495 5496 Result = getDerived().RebuildQualifiedType(Result, T);5497 5498 if (Result.isNull())5499 return QualType();5500 5501 // RebuildQualifiedType might have updated the type, but not in a way5502 // that invalidates the TypeLoc. (There's no location information for5503 // qualifiers.)5504 TLB.TypeWasModifiedSafely(Result);5505 5506 return Result;5507}5508 5509template <typename Derived>5510QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,5511 QualifiedTypeLoc TL) {5512 5513 SourceLocation Loc = TL.getBeginLoc();5514 Qualifiers Quals = TL.getType().getLocalQualifiers();5515 5516 if ((T.getAddressSpace() != LangAS::Default &&5517 Quals.getAddressSpace() != LangAS::Default) &&5518 T.getAddressSpace() != Quals.getAddressSpace()) {5519 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)5520 << TL.getType() << T;5521 return QualType();5522 }5523 5524 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();5525 if (LocalPointerAuth.isPresent()) {5526 if (T.getPointerAuth().isPresent()) {5527 SemaRef.Diag(Loc, diag::err_ptrauth_qualifier_redundant) << TL.getType();5528 return QualType();5529 }5530 if (!T->isDependentType()) {5531 if (!T->isSignableType(SemaRef.getASTContext())) {5532 SemaRef.Diag(Loc, diag::err_ptrauth_qualifier_invalid_target) << T;5533 return QualType();5534 }5535 }5536 }5537 // C++ [dcl.fct]p7:5538 // [When] adding cv-qualifications on top of the function type [...] the5539 // cv-qualifiers are ignored.5540 if (T->isFunctionType()) {5541 T = SemaRef.getASTContext().getAddrSpaceQualType(T,5542 Quals.getAddressSpace());5543 return T;5544 }5545 5546 // C++ [dcl.ref]p1:5547 // when the cv-qualifiers are introduced through the use of a typedef-name5548 // or decltype-specifier [...] the cv-qualifiers are ignored.5549 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be5550 // applied to a reference type.5551 if (T->isReferenceType()) {5552 // The only qualifier that applies to a reference type is restrict.5553 if (!Quals.hasRestrict())5554 return T;5555 Quals = Qualifiers::fromCVRMask(Qualifiers::Restrict);5556 }5557 5558 // Suppress Objective-C lifetime qualifiers if they don't make sense for the5559 // resulting type.5560 if (Quals.hasObjCLifetime()) {5561 if (!T->isObjCLifetimeType() && !T->isDependentType())5562 Quals.removeObjCLifetime();5563 else if (T.getObjCLifetime()) {5564 // Objective-C ARC:5565 // A lifetime qualifier applied to a substituted template parameter5566 // overrides the lifetime qualifier from the template argument.5567 const AutoType *AutoTy;5568 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {5569 // 'auto' types behave the same way as template parameters.5570 QualType Deduced = AutoTy->getDeducedType();5571 Qualifiers Qs = Deduced.getQualifiers();5572 Qs.removeObjCLifetime();5573 Deduced =5574 SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs);5575 T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(),5576 AutoTy->isDependentType(),5577 /*isPack=*/false,5578 AutoTy->getTypeConstraintConcept(),5579 AutoTy->getTypeConstraintArguments());5580 } else {5581 // Otherwise, complain about the addition of a qualifier to an5582 // already-qualified type.5583 // FIXME: Why is this check not in Sema::BuildQualifiedType?5584 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;5585 Quals.removeObjCLifetime();5586 }5587 }5588 }5589 5590 return SemaRef.BuildQualifiedType(T, Loc, Quals);5591}5592 5593template <typename Derived>5594QualType TreeTransform<Derived>::TransformTypeInObjectScope(5595 TypeLocBuilder &TLB, TypeLoc TL, QualType ObjectType,5596 NamedDecl *FirstQualifierInScope) {5597 assert(!getDerived().AlreadyTransformed(TL.getType()));5598 5599 switch (TL.getTypeLocClass()) {5600 case TypeLoc::TemplateSpecialization:5601 return getDerived().TransformTemplateSpecializationType(5602 TLB, TL.castAs<TemplateSpecializationTypeLoc>(), ObjectType,5603 FirstQualifierInScope, /*AllowInjectedClassName=*/true);5604 case TypeLoc::DependentName:5605 return getDerived().TransformDependentNameType(5606 TLB, TL.castAs<DependentNameTypeLoc>(), /*DeducedTSTContext=*/false,5607 ObjectType, FirstQualifierInScope);5608 default:5609 // Any dependent canonical type can appear here, through type alias5610 // templates.5611 return getDerived().TransformType(TLB, TL);5612 }5613}5614 5615template <class TyLoc> static inline5616QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {5617 TyLoc NewT = TLB.push<TyLoc>(T.getType());5618 NewT.setNameLoc(T.getNameLoc());5619 return T.getType();5620}5621 5622template<typename Derived>5623QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,5624 BuiltinTypeLoc T) {5625 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());5626 NewT.setBuiltinLoc(T.getBuiltinLoc());5627 if (T.needsExtraLocalData())5628 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();5629 return T.getType();5630}5631 5632template<typename Derived>5633QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,5634 ComplexTypeLoc T) {5635 // FIXME: recurse?5636 return TransformTypeSpecType(TLB, T);5637}5638 5639template <typename Derived>5640QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,5641 AdjustedTypeLoc TL) {5642 // Adjustments applied during transformation are handled elsewhere.5643 return getDerived().TransformType(TLB, TL.getOriginalLoc());5644}5645 5646template<typename Derived>5647QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,5648 DecayedTypeLoc TL) {5649 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());5650 if (OriginalType.isNull())5651 return QualType();5652 5653 QualType Result = TL.getType();5654 if (getDerived().AlwaysRebuild() ||5655 OriginalType != TL.getOriginalLoc().getType())5656 Result = SemaRef.Context.getDecayedType(OriginalType);5657 TLB.push<DecayedTypeLoc>(Result);5658 // Nothing to set for DecayedTypeLoc.5659 return Result;5660}5661 5662template <typename Derived>5663QualType5664TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,5665 ArrayParameterTypeLoc TL) {5666 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());5667 if (OriginalType.isNull())5668 return QualType();5669 5670 QualType Result = TL.getType();5671 if (getDerived().AlwaysRebuild() ||5672 OriginalType != TL.getElementLoc().getType())5673 Result = SemaRef.Context.getArrayParameterType(OriginalType);5674 TLB.push<ArrayParameterTypeLoc>(Result);5675 // Nothing to set for ArrayParameterTypeLoc.5676 return Result;5677}5678 5679template<typename Derived>5680QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,5681 PointerTypeLoc TL) {5682 QualType PointeeType5683 = getDerived().TransformType(TLB, TL.getPointeeLoc());5684 if (PointeeType.isNull())5685 return QualType();5686 5687 QualType Result = TL.getType();5688 if (PointeeType->getAs<ObjCObjectType>()) {5689 // A dependent pointer type 'T *' has is being transformed such5690 // that an Objective-C class type is being replaced for 'T'. The5691 // resulting pointer type is an ObjCObjectPointerType, not a5692 // PointerType.5693 Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);5694 5695 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);5696 NewT.setStarLoc(TL.getStarLoc());5697 return Result;5698 }5699 5700 if (getDerived().AlwaysRebuild() ||5701 PointeeType != TL.getPointeeLoc().getType()) {5702 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());5703 if (Result.isNull())5704 return QualType();5705 }5706 5707 // Objective-C ARC can add lifetime qualifiers to the type that we're5708 // pointing to.5709 TLB.TypeWasModifiedSafely(Result->getPointeeType());5710 5711 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);5712 NewT.setSigilLoc(TL.getSigilLoc());5713 return Result;5714}5715 5716template<typename Derived>5717QualType5718TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,5719 BlockPointerTypeLoc TL) {5720 QualType PointeeType5721 = getDerived().TransformType(TLB, TL.getPointeeLoc());5722 if (PointeeType.isNull())5723 return QualType();5724 5725 QualType Result = TL.getType();5726 if (getDerived().AlwaysRebuild() ||5727 PointeeType != TL.getPointeeLoc().getType()) {5728 Result = getDerived().RebuildBlockPointerType(PointeeType,5729 TL.getSigilLoc());5730 if (Result.isNull())5731 return QualType();5732 }5733 5734 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);5735 NewT.setSigilLoc(TL.getSigilLoc());5736 return Result;5737}5738 5739/// Transforms a reference type. Note that somewhat paradoxically we5740/// don't care whether the type itself is an l-value type or an r-value5741/// type; we only care if the type was *written* as an l-value type5742/// or an r-value type.5743template<typename Derived>5744QualType5745TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,5746 ReferenceTypeLoc TL) {5747 const ReferenceType *T = TL.getTypePtr();5748 5749 // Note that this works with the pointee-as-written.5750 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());5751 if (PointeeType.isNull())5752 return QualType();5753 5754 QualType Result = TL.getType();5755 if (getDerived().AlwaysRebuild() ||5756 PointeeType != T->getPointeeTypeAsWritten()) {5757 Result = getDerived().RebuildReferenceType(PointeeType,5758 T->isSpelledAsLValue(),5759 TL.getSigilLoc());5760 if (Result.isNull())5761 return QualType();5762 }5763 5764 // Objective-C ARC can add lifetime qualifiers to the type that we're5765 // referring to.5766 TLB.TypeWasModifiedSafely(5767 Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());5768 5769 // r-value references can be rebuilt as l-value references.5770 ReferenceTypeLoc NewTL;5771 if (isa<LValueReferenceType>(Result))5772 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);5773 else5774 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);5775 NewTL.setSigilLoc(TL.getSigilLoc());5776 5777 return Result;5778}5779 5780template<typename Derived>5781QualType5782TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,5783 LValueReferenceTypeLoc TL) {5784 return TransformReferenceType(TLB, TL);5785}5786 5787template<typename Derived>5788QualType5789TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,5790 RValueReferenceTypeLoc TL) {5791 return TransformReferenceType(TLB, TL);5792}5793 5794template<typename Derived>5795QualType5796TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,5797 MemberPointerTypeLoc TL) {5798 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());5799 if (PointeeType.isNull())5800 return QualType();5801 5802 const MemberPointerType *T = TL.getTypePtr();5803 5804 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();5805 NestedNameSpecifierLoc NewQualifierLoc =5806 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);5807 if (!NewQualifierLoc)5808 return QualType();5809 5810 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;5811 if (OldCls) {5812 NewCls = cast_or_null<CXXRecordDecl>(5813 getDerived().TransformDecl(TL.getStarLoc(), OldCls));5814 if (!NewCls)5815 return QualType();5816 }5817 5818 QualType Result = TL.getType();5819 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||5820 NewQualifierLoc.getNestedNameSpecifier() !=5821 OldQualifierLoc.getNestedNameSpecifier() ||5822 NewCls != OldCls) {5823 CXXScopeSpec SS;5824 SS.Adopt(NewQualifierLoc);5825 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,5826 TL.getStarLoc());5827 if (Result.isNull())5828 return QualType();5829 }5830 5831 // If we had to adjust the pointee type when building a member pointer, make5832 // sure to push TypeLoc info for it.5833 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();5834 if (MPT && PointeeType != MPT->getPointeeType()) {5835 assert(isa<AdjustedType>(MPT->getPointeeType()));5836 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());5837 }5838 5839 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);5840 NewTL.setSigilLoc(TL.getSigilLoc());5841 NewTL.setQualifierLoc(NewQualifierLoc);5842 5843 return Result;5844}5845 5846template<typename Derived>5847QualType5848TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,5849 ConstantArrayTypeLoc TL) {5850 const ConstantArrayType *T = TL.getTypePtr();5851 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());5852 if (ElementType.isNull())5853 return QualType();5854 5855 // Prefer the expression from the TypeLoc; the other may have been uniqued.5856 Expr *OldSize = TL.getSizeExpr();5857 if (!OldSize)5858 OldSize = const_cast<Expr*>(T->getSizeExpr());5859 Expr *NewSize = nullptr;5860 if (OldSize) {5861 EnterExpressionEvaluationContext Unevaluated(5862 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);5863 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();5864 NewSize = SemaRef.ActOnConstantExpression(NewSize).get();5865 }5866 5867 QualType Result = TL.getType();5868 if (getDerived().AlwaysRebuild() ||5869 ElementType != T->getElementType() ||5870 (T->getSizeExpr() && NewSize != OldSize)) {5871 Result = getDerived().RebuildConstantArrayType(ElementType,5872 T->getSizeModifier(),5873 T->getSize(), NewSize,5874 T->getIndexTypeCVRQualifiers(),5875 TL.getBracketsRange());5876 if (Result.isNull())5877 return QualType();5878 }5879 5880 // We might have either a ConstantArrayType or a VariableArrayType now:5881 // a ConstantArrayType is allowed to have an element type which is a5882 // VariableArrayType if the type is dependent. Fortunately, all array5883 // types have the same location layout.5884 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);5885 NewTL.setLBracketLoc(TL.getLBracketLoc());5886 NewTL.setRBracketLoc(TL.getRBracketLoc());5887 NewTL.setSizeExpr(NewSize);5888 5889 return Result;5890}5891 5892template<typename Derived>5893QualType TreeTransform<Derived>::TransformIncompleteArrayType(5894 TypeLocBuilder &TLB,5895 IncompleteArrayTypeLoc TL) {5896 const IncompleteArrayType *T = TL.getTypePtr();5897 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());5898 if (ElementType.isNull())5899 return QualType();5900 5901 QualType Result = TL.getType();5902 if (getDerived().AlwaysRebuild() ||5903 ElementType != T->getElementType()) {5904 Result = getDerived().RebuildIncompleteArrayType(ElementType,5905 T->getSizeModifier(),5906 T->getIndexTypeCVRQualifiers(),5907 TL.getBracketsRange());5908 if (Result.isNull())5909 return QualType();5910 }5911 5912 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);5913 NewTL.setLBracketLoc(TL.getLBracketLoc());5914 NewTL.setRBracketLoc(TL.getRBracketLoc());5915 NewTL.setSizeExpr(nullptr);5916 5917 return Result;5918}5919 5920template<typename Derived>5921QualType5922TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,5923 VariableArrayTypeLoc TL) {5924 const VariableArrayType *T = TL.getTypePtr();5925 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());5926 if (ElementType.isNull())5927 return QualType();5928 5929 ExprResult SizeResult;5930 {5931 EnterExpressionEvaluationContext Context(5932 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);5933 SizeResult = getDerived().TransformExpr(T->getSizeExpr());5934 }5935 if (SizeResult.isInvalid())5936 return QualType();5937 SizeResult =5938 SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false);5939 if (SizeResult.isInvalid())5940 return QualType();5941 5942 Expr *Size = SizeResult.get();5943 5944 QualType Result = TL.getType();5945 if (getDerived().AlwaysRebuild() ||5946 ElementType != T->getElementType() ||5947 Size != T->getSizeExpr()) {5948 Result = getDerived().RebuildVariableArrayType(ElementType,5949 T->getSizeModifier(),5950 Size,5951 T->getIndexTypeCVRQualifiers(),5952 TL.getBracketsRange());5953 if (Result.isNull())5954 return QualType();5955 }5956 5957 // We might have constant size array now, but fortunately it has the same5958 // location layout.5959 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);5960 NewTL.setLBracketLoc(TL.getLBracketLoc());5961 NewTL.setRBracketLoc(TL.getRBracketLoc());5962 NewTL.setSizeExpr(Size);5963 5964 return Result;5965}5966 5967template<typename Derived>5968QualType5969TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,5970 DependentSizedArrayTypeLoc TL) {5971 const DependentSizedArrayType *T = TL.getTypePtr();5972 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());5973 if (ElementType.isNull())5974 return QualType();5975 5976 // Array bounds are constant expressions.5977 EnterExpressionEvaluationContext Unevaluated(5978 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);5979 5980 // If we have a VLA then it won't be a constant.5981 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;5982 5983 // Prefer the expression from the TypeLoc; the other may have been uniqued.5984 Expr *origSize = TL.getSizeExpr();5985 if (!origSize) origSize = T->getSizeExpr();5986 5987 ExprResult sizeResult5988 = getDerived().TransformExpr(origSize);5989 sizeResult = SemaRef.ActOnConstantExpression(sizeResult);5990 if (sizeResult.isInvalid())5991 return QualType();5992 5993 Expr *size = sizeResult.get();5994 5995 QualType Result = TL.getType();5996 if (getDerived().AlwaysRebuild() ||5997 ElementType != T->getElementType() ||5998 size != origSize) {5999 Result = getDerived().RebuildDependentSizedArrayType(ElementType,6000 T->getSizeModifier(),6001 size,6002 T->getIndexTypeCVRQualifiers(),6003 TL.getBracketsRange());6004 if (Result.isNull())6005 return QualType();6006 }6007 6008 // We might have any sort of array type now, but fortunately they6009 // all have the same location layout.6010 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);6011 NewTL.setLBracketLoc(TL.getLBracketLoc());6012 NewTL.setRBracketLoc(TL.getRBracketLoc());6013 NewTL.setSizeExpr(size);6014 6015 return Result;6016}6017 6018template <typename Derived>6019QualType TreeTransform<Derived>::TransformDependentVectorType(6020 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {6021 const DependentVectorType *T = TL.getTypePtr();6022 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());6023 if (ElementType.isNull())6024 return QualType();6025 6026 EnterExpressionEvaluationContext Unevaluated(6027 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);6028 6029 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());6030 Size = SemaRef.ActOnConstantExpression(Size);6031 if (Size.isInvalid())6032 return QualType();6033 6034 QualType Result = TL.getType();6035 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||6036 Size.get() != T->getSizeExpr()) {6037 Result = getDerived().RebuildDependentVectorType(6038 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());6039 if (Result.isNull())6040 return QualType();6041 }6042 6043 // Result might be dependent or not.6044 if (isa<DependentVectorType>(Result)) {6045 DependentVectorTypeLoc NewTL =6046 TLB.push<DependentVectorTypeLoc>(Result);6047 NewTL.setNameLoc(TL.getNameLoc());6048 } else {6049 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);6050 NewTL.setNameLoc(TL.getNameLoc());6051 }6052 6053 return Result;6054}6055 6056template<typename Derived>6057QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(6058 TypeLocBuilder &TLB,6059 DependentSizedExtVectorTypeLoc TL) {6060 const DependentSizedExtVectorType *T = TL.getTypePtr();6061 6062 // FIXME: ext vector locs should be nested6063 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());6064 if (ElementType.isNull())6065 return QualType();6066 6067 // Vector sizes are constant expressions.6068 EnterExpressionEvaluationContext Unevaluated(6069 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);6070 6071 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());6072 Size = SemaRef.ActOnConstantExpression(Size);6073 if (Size.isInvalid())6074 return QualType();6075 6076 QualType Result = TL.getType();6077 if (getDerived().AlwaysRebuild() ||6078 ElementType != T->getElementType() ||6079 Size.get() != T->getSizeExpr()) {6080 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,6081 Size.get(),6082 T->getAttributeLoc());6083 if (Result.isNull())6084 return QualType();6085 }6086 6087 // Result might be dependent or not.6088 if (isa<DependentSizedExtVectorType>(Result)) {6089 DependentSizedExtVectorTypeLoc NewTL6090 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);6091 NewTL.setNameLoc(TL.getNameLoc());6092 } else {6093 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);6094 NewTL.setNameLoc(TL.getNameLoc());6095 }6096 6097 return Result;6098}6099 6100template <typename Derived>6101QualType6102TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,6103 ConstantMatrixTypeLoc TL) {6104 const ConstantMatrixType *T = TL.getTypePtr();6105 QualType ElementType = getDerived().TransformType(T->getElementType());6106 if (ElementType.isNull())6107 return QualType();6108 6109 QualType Result = TL.getType();6110 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {6111 Result = getDerived().RebuildConstantMatrixType(6112 ElementType, T->getNumRows(), T->getNumColumns());6113 if (Result.isNull())6114 return QualType();6115 }6116 6117 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);6118 NewTL.setAttrNameLoc(TL.getAttrNameLoc());6119 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());6120 NewTL.setAttrRowOperand(TL.getAttrRowOperand());6121 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());6122 6123 return Result;6124}6125 6126template <typename Derived>6127QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(6128 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {6129 const DependentSizedMatrixType *T = TL.getTypePtr();6130 6131 QualType ElementType = getDerived().TransformType(T->getElementType());6132 if (ElementType.isNull()) {6133 return QualType();6134 }6135 6136 // Matrix dimensions are constant expressions.6137 EnterExpressionEvaluationContext Unevaluated(6138 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);6139 6140 Expr *origRows = TL.getAttrRowOperand();6141 if (!origRows)6142 origRows = T->getRowExpr();6143 Expr *origColumns = TL.getAttrColumnOperand();6144 if (!origColumns)6145 origColumns = T->getColumnExpr();6146 6147 ExprResult rowResult = getDerived().TransformExpr(origRows);6148 rowResult = SemaRef.ActOnConstantExpression(rowResult);6149 if (rowResult.isInvalid())6150 return QualType();6151 6152 ExprResult columnResult = getDerived().TransformExpr(origColumns);6153 columnResult = SemaRef.ActOnConstantExpression(columnResult);6154 if (columnResult.isInvalid())6155 return QualType();6156 6157 Expr *rows = rowResult.get();6158 Expr *columns = columnResult.get();6159 6160 QualType Result = TL.getType();6161 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||6162 rows != origRows || columns != origColumns) {6163 Result = getDerived().RebuildDependentSizedMatrixType(6164 ElementType, rows, columns, T->getAttributeLoc());6165 6166 if (Result.isNull())6167 return QualType();6168 }6169 6170 // We might have any sort of matrix type now, but fortunately they6171 // all have the same location layout.6172 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);6173 NewTL.setAttrNameLoc(TL.getAttrNameLoc());6174 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());6175 NewTL.setAttrRowOperand(rows);6176 NewTL.setAttrColumnOperand(columns);6177 return Result;6178}6179 6180template <typename Derived>6181QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(6182 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {6183 const DependentAddressSpaceType *T = TL.getTypePtr();6184 6185 QualType pointeeType =6186 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());6187 6188 if (pointeeType.isNull())6189 return QualType();6190 6191 // Address spaces are constant expressions.6192 EnterExpressionEvaluationContext Unevaluated(6193 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);6194 6195 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());6196 AddrSpace = SemaRef.ActOnConstantExpression(AddrSpace);6197 if (AddrSpace.isInvalid())6198 return QualType();6199 6200 QualType Result = TL.getType();6201 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||6202 AddrSpace.get() != T->getAddrSpaceExpr()) {6203 Result = getDerived().RebuildDependentAddressSpaceType(6204 pointeeType, AddrSpace.get(), T->getAttributeLoc());6205 if (Result.isNull())6206 return QualType();6207 }6208 6209 // Result might be dependent or not.6210 if (isa<DependentAddressSpaceType>(Result)) {6211 DependentAddressSpaceTypeLoc NewTL =6212 TLB.push<DependentAddressSpaceTypeLoc>(Result);6213 6214 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());6215 NewTL.setAttrExprOperand(TL.getAttrExprOperand());6216 NewTL.setAttrNameLoc(TL.getAttrNameLoc());6217 6218 } else {6219 TLB.TypeWasModifiedSafely(Result);6220 }6221 6222 return Result;6223}6224 6225template <typename Derived>6226QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,6227 VectorTypeLoc TL) {6228 const VectorType *T = TL.getTypePtr();6229 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());6230 if (ElementType.isNull())6231 return QualType();6232 6233 QualType Result = TL.getType();6234 if (getDerived().AlwaysRebuild() ||6235 ElementType != T->getElementType()) {6236 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),6237 T->getVectorKind());6238 if (Result.isNull())6239 return QualType();6240 }6241 6242 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);6243 NewTL.setNameLoc(TL.getNameLoc());6244 6245 return Result;6246}6247 6248template<typename Derived>6249QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,6250 ExtVectorTypeLoc TL) {6251 const VectorType *T = TL.getTypePtr();6252 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());6253 if (ElementType.isNull())6254 return QualType();6255 6256 QualType Result = TL.getType();6257 if (getDerived().AlwaysRebuild() ||6258 ElementType != T->getElementType()) {6259 Result = getDerived().RebuildExtVectorType(ElementType,6260 T->getNumElements(),6261 /*FIXME*/ SourceLocation());6262 if (Result.isNull())6263 return QualType();6264 }6265 6266 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);6267 NewTL.setNameLoc(TL.getNameLoc());6268 6269 return Result;6270}6271 6272template <typename Derived>6273ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(6274 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,6275 bool ExpectParameterPack) {6276 TypeSourceInfo *OldTSI = OldParm->getTypeSourceInfo();6277 TypeSourceInfo *NewTSI = nullptr;6278 6279 if (NumExpansions && isa<PackExpansionType>(OldTSI->getType())) {6280 // If we're substituting into a pack expansion type and we know the6281 // length we want to expand to, just substitute for the pattern.6282 TypeLoc OldTL = OldTSI->getTypeLoc();6283 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();6284 6285 TypeLocBuilder TLB;6286 TypeLoc NewTL = OldTSI->getTypeLoc();6287 TLB.reserve(NewTL.getFullDataSize());6288 6289 QualType Result = getDerived().TransformType(TLB,6290 OldExpansionTL.getPatternLoc());6291 if (Result.isNull())6292 return nullptr;6293 6294 Result = RebuildPackExpansionType(Result,6295 OldExpansionTL.getPatternLoc().getSourceRange(),6296 OldExpansionTL.getEllipsisLoc(),6297 NumExpansions);6298 if (Result.isNull())6299 return nullptr;6300 6301 PackExpansionTypeLoc NewExpansionTL6302 = TLB.push<PackExpansionTypeLoc>(Result);6303 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());6304 NewTSI = TLB.getTypeSourceInfo(SemaRef.Context, Result);6305 } else6306 NewTSI = getDerived().TransformType(OldTSI);6307 if (!NewTSI)6308 return nullptr;6309 6310 if (NewTSI == OldTSI && indexAdjustment == 0)6311 return OldParm;6312 6313 ParmVarDecl *newParm = ParmVarDecl::Create(6314 SemaRef.Context, OldParm->getDeclContext(), OldParm->getInnerLocStart(),6315 OldParm->getLocation(), OldParm->getIdentifier(), NewTSI->getType(),6316 NewTSI, OldParm->getStorageClass(),6317 /* DefArg */ nullptr);6318 newParm->setScopeInfo(OldParm->getFunctionScopeDepth(),6319 OldParm->getFunctionScopeIndex() + indexAdjustment);6320 getDerived().transformedLocalDecl(OldParm, {newParm});6321 return newParm;6322}6323 6324template <typename Derived>6325bool TreeTransform<Derived>::TransformFunctionTypeParams(6326 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,6327 const QualType *ParamTypes,6328 const FunctionProtoType::ExtParameterInfo *ParamInfos,6329 SmallVectorImpl<QualType> &OutParamTypes,6330 SmallVectorImpl<ParmVarDecl *> *PVars,6331 Sema::ExtParameterInfoBuilder &PInfos,6332 unsigned *LastParamTransformed) {6333 int indexAdjustment = 0;6334 6335 unsigned NumParams = Params.size();6336 for (unsigned i = 0; i != NumParams; ++i) {6337 if (LastParamTransformed)6338 *LastParamTransformed = i;6339 if (ParmVarDecl *OldParm = Params[i]) {6340 assert(OldParm->getFunctionScopeIndex() == i);6341 6342 UnsignedOrNone NumExpansions = std::nullopt;6343 ParmVarDecl *NewParm = nullptr;6344 if (OldParm->isParameterPack()) {6345 // We have a function parameter pack that may need to be expanded.6346 SmallVector<UnexpandedParameterPack, 2> Unexpanded;6347 6348 // Find the parameter packs that could be expanded.6349 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();6350 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();6351 TypeLoc Pattern = ExpansionTL.getPatternLoc();6352 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);6353 6354 // Determine whether we should expand the parameter packs.6355 bool ShouldExpand = false;6356 bool RetainExpansion = false;6357 UnsignedOrNone OrigNumExpansions = std::nullopt;6358 if (Unexpanded.size() > 0) {6359 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();6360 NumExpansions = OrigNumExpansions;6361 if (getDerived().TryExpandParameterPacks(6362 ExpansionTL.getEllipsisLoc(), Pattern.getSourceRange(),6363 Unexpanded, /*FailOnPackProducingTemplates=*/true,6364 ShouldExpand, RetainExpansion, NumExpansions)) {6365 return true;6366 }6367 } else {6368#ifndef NDEBUG6369 const AutoType *AT =6370 Pattern.getType().getTypePtr()->getContainedAutoType();6371 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&6372 "Could not find parameter packs or undeduced auto type!");6373#endif6374 }6375 6376 if (ShouldExpand) {6377 // Expand the function parameter pack into multiple, separate6378 // parameters.6379 getDerived().ExpandingFunctionParameterPack(OldParm);6380 for (unsigned I = 0; I != *NumExpansions; ++I) {6381 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);6382 ParmVarDecl *NewParm6383 = getDerived().TransformFunctionTypeParam(OldParm,6384 indexAdjustment++,6385 OrigNumExpansions,6386 /*ExpectParameterPack=*/false);6387 if (!NewParm)6388 return true;6389 6390 if (ParamInfos)6391 PInfos.set(OutParamTypes.size(), ParamInfos[i]);6392 OutParamTypes.push_back(NewParm->getType());6393 if (PVars)6394 PVars->push_back(NewParm);6395 }6396 6397 // If we're supposed to retain a pack expansion, do so by temporarily6398 // forgetting the partially-substituted parameter pack.6399 if (RetainExpansion) {6400 ForgetPartiallySubstitutedPackRAII Forget(getDerived());6401 ParmVarDecl *NewParm6402 = getDerived().TransformFunctionTypeParam(OldParm,6403 indexAdjustment++,6404 OrigNumExpansions,6405 /*ExpectParameterPack=*/false);6406 if (!NewParm)6407 return true;6408 6409 if (ParamInfos)6410 PInfos.set(OutParamTypes.size(), ParamInfos[i]);6411 OutParamTypes.push_back(NewParm->getType());6412 if (PVars)6413 PVars->push_back(NewParm);6414 }6415 6416 // The next parameter should have the same adjustment as the6417 // last thing we pushed, but we post-incremented indexAdjustment6418 // on every push. Also, if we push nothing, the adjustment should6419 // go down by one.6420 indexAdjustment--;6421 6422 // We're done with the pack expansion.6423 continue;6424 }6425 6426 // We'll substitute the parameter now without expanding the pack6427 // expansion.6428 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);6429 NewParm = getDerived().TransformFunctionTypeParam(OldParm,6430 indexAdjustment,6431 NumExpansions,6432 /*ExpectParameterPack=*/true);6433 assert(NewParm->isParameterPack() &&6434 "Parameter pack no longer a parameter pack after "6435 "transformation.");6436 } else {6437 NewParm = getDerived().TransformFunctionTypeParam(6438 OldParm, indexAdjustment, std::nullopt,6439 /*ExpectParameterPack=*/false);6440 }6441 6442 if (!NewParm)6443 return true;6444 6445 if (ParamInfos)6446 PInfos.set(OutParamTypes.size(), ParamInfos[i]);6447 OutParamTypes.push_back(NewParm->getType());6448 if (PVars)6449 PVars->push_back(NewParm);6450 continue;6451 }6452 6453 // Deal with the possibility that we don't have a parameter6454 // declaration for this parameter.6455 assert(ParamTypes);6456 QualType OldType = ParamTypes[i];6457 bool IsPackExpansion = false;6458 UnsignedOrNone NumExpansions = std::nullopt;6459 QualType NewType;6460 if (const PackExpansionType *Expansion6461 = dyn_cast<PackExpansionType>(OldType)) {6462 // We have a function parameter pack that may need to be expanded.6463 QualType Pattern = Expansion->getPattern();6464 SmallVector<UnexpandedParameterPack, 2> Unexpanded;6465 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);6466 6467 // Determine whether we should expand the parameter packs.6468 bool ShouldExpand = false;6469 bool RetainExpansion = false;6470 if (getDerived().TryExpandParameterPacks(6471 Loc, SourceRange(), Unexpanded,6472 /*FailOnPackProducingTemplates=*/true, ShouldExpand,6473 RetainExpansion, NumExpansions)) {6474 return true;6475 }6476 6477 if (ShouldExpand) {6478 // Expand the function parameter pack into multiple, separate6479 // parameters.6480 for (unsigned I = 0; I != *NumExpansions; ++I) {6481 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);6482 QualType NewType = getDerived().TransformType(Pattern);6483 if (NewType.isNull())6484 return true;6485 6486 if (NewType->containsUnexpandedParameterPack()) {6487 NewType = getSema().getASTContext().getPackExpansionType(6488 NewType, std::nullopt);6489 6490 if (NewType.isNull())6491 return true;6492 }6493 6494 if (ParamInfos)6495 PInfos.set(OutParamTypes.size(), ParamInfos[i]);6496 OutParamTypes.push_back(NewType);6497 if (PVars)6498 PVars->push_back(nullptr);6499 }6500 6501 // We're done with the pack expansion.6502 continue;6503 }6504 6505 // If we're supposed to retain a pack expansion, do so by temporarily6506 // forgetting the partially-substituted parameter pack.6507 if (RetainExpansion) {6508 ForgetPartiallySubstitutedPackRAII Forget(getDerived());6509 QualType NewType = getDerived().TransformType(Pattern);6510 if (NewType.isNull())6511 return true;6512 6513 if (ParamInfos)6514 PInfos.set(OutParamTypes.size(), ParamInfos[i]);6515 OutParamTypes.push_back(NewType);6516 if (PVars)6517 PVars->push_back(nullptr);6518 }6519 6520 // We'll substitute the parameter now without expanding the pack6521 // expansion.6522 OldType = Expansion->getPattern();6523 IsPackExpansion = true;6524 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);6525 NewType = getDerived().TransformType(OldType);6526 } else {6527 NewType = getDerived().TransformType(OldType);6528 }6529 6530 if (NewType.isNull())6531 return true;6532 6533 if (IsPackExpansion)6534 NewType = getSema().Context.getPackExpansionType(NewType,6535 NumExpansions);6536 6537 if (ParamInfos)6538 PInfos.set(OutParamTypes.size(), ParamInfos[i]);6539 OutParamTypes.push_back(NewType);6540 if (PVars)6541 PVars->push_back(nullptr);6542 }6543 6544#ifndef NDEBUG6545 if (PVars) {6546 for (unsigned i = 0, e = PVars->size(); i != e; ++i)6547 if (ParmVarDecl *parm = (*PVars)[i])6548 assert(parm->getFunctionScopeIndex() == i);6549 }6550#endif6551 6552 return false;6553}6554 6555template<typename Derived>6556QualType6557TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,6558 FunctionProtoTypeLoc TL) {6559 SmallVector<QualType, 4> ExceptionStorage;6560 return getDerived().TransformFunctionProtoType(6561 TLB, TL, nullptr, Qualifiers(),6562 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {6563 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,6564 ExceptionStorage, Changed);6565 });6566}6567 6568template<typename Derived> template<typename Fn>6569QualType TreeTransform<Derived>::TransformFunctionProtoType(6570 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,6571 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {6572 6573 // Transform the parameters and return type.6574 //6575 // We are required to instantiate the params and return type in source order.6576 // When the function has a trailing return type, we instantiate the6577 // parameters before the return type, since the return type can then refer6578 // to the parameters themselves (via decltype, sizeof, etc.).6579 //6580 SmallVector<QualType, 4> ParamTypes;6581 SmallVector<ParmVarDecl*, 4> ParamDecls;6582 Sema::ExtParameterInfoBuilder ExtParamInfos;6583 const FunctionProtoType *T = TL.getTypePtr();6584 6585 QualType ResultType;6586 6587 if (T->hasTrailingReturn()) {6588 if (getDerived().TransformFunctionTypeParams(6589 TL.getBeginLoc(), TL.getParams(),6590 TL.getTypePtr()->param_type_begin(),6591 T->getExtParameterInfosOrNull(),6592 ParamTypes, &ParamDecls, ExtParamInfos))6593 return QualType();6594 6595 {6596 // C++11 [expr.prim.general]p3:6597 // If a declaration declares a member function or member function6598 // template of a class X, the expression this is a prvalue of type6599 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq6600 // and the end of the function-definition, member-declarator, or6601 // declarator.6602 auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.getCurLexicalContext());6603 Sema::CXXThisScopeRAII ThisScope(6604 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);6605 6606 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());6607 if (ResultType.isNull())6608 return QualType();6609 }6610 }6611 else {6612 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());6613 if (ResultType.isNull())6614 return QualType();6615 6616 if (getDerived().TransformFunctionTypeParams(6617 TL.getBeginLoc(), TL.getParams(),6618 TL.getTypePtr()->param_type_begin(),6619 T->getExtParameterInfosOrNull(),6620 ParamTypes, &ParamDecls, ExtParamInfos))6621 return QualType();6622 }6623 6624 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();6625 6626 bool EPIChanged = false;6627 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))6628 return QualType();6629 6630 // Handle extended parameter information.6631 if (auto NewExtParamInfos =6632 ExtParamInfos.getPointerOrNull(ParamTypes.size())) {6633 if (!EPI.ExtParameterInfos ||6634 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=6635 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {6636 EPIChanged = true;6637 }6638 EPI.ExtParameterInfos = NewExtParamInfos;6639 } else if (EPI.ExtParameterInfos) {6640 EPIChanged = true;6641 EPI.ExtParameterInfos = nullptr;6642 }6643 6644 // Transform any function effects with unevaluated conditions.6645 // Hold this set in a local for the rest of this function, since EPI6646 // may need to hold a FunctionEffectsRef pointing into it.6647 std::optional<FunctionEffectSet> NewFX;6648 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {6649 NewFX.emplace();6650 EnterExpressionEvaluationContext Unevaluated(6651 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);6652 6653 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {6654 FunctionEffectWithCondition NewEC = PrevEC;6655 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {6656 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);6657 if (NewExpr.isInvalid())6658 return QualType();6659 std::optional<FunctionEffectMode> Mode =6660 SemaRef.ActOnEffectExpression(NewExpr.get(), PrevEC.Effect.name());6661 if (!Mode)6662 return QualType();6663 6664 // The condition expression has been transformed, and re-evaluated.6665 // It may or may not have become constant.6666 switch (*Mode) {6667 case FunctionEffectMode::True:6668 NewEC.Cond = {};6669 break;6670 case FunctionEffectMode::False:6671 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());6672 NewEC.Cond = {};6673 break;6674 case FunctionEffectMode::Dependent:6675 NewEC.Cond = EffectConditionExpr(NewExpr.get());6676 break;6677 case FunctionEffectMode::None:6678 llvm_unreachable(6679 "FunctionEffectMode::None shouldn't be possible here");6680 }6681 }6682 if (!SemaRef.diagnoseConflictingFunctionEffect(*NewFX, NewEC,6683 TL.getBeginLoc())) {6684 FunctionEffectSet::Conflicts Errs;6685 NewFX->insert(NewEC, Errs);6686 assert(Errs.empty());6687 }6688 }6689 EPI.FunctionEffects = *NewFX;6690 EPIChanged = true;6691 }6692 6693 QualType Result = TL.getType();6694 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||6695 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {6696 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);6697 if (Result.isNull())6698 return QualType();6699 }6700 6701 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);6702 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());6703 NewTL.setLParenLoc(TL.getLParenLoc());6704 NewTL.setRParenLoc(TL.getRParenLoc());6705 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());6706 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());6707 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)6708 NewTL.setParam(i, ParamDecls[i]);6709 6710 return Result;6711}6712 6713template<typename Derived>6714bool TreeTransform<Derived>::TransformExceptionSpec(6715 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,6716 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {6717 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);6718 6719 // Instantiate a dynamic noexcept expression, if any.6720 if (isComputedNoexcept(ESI.Type)) {6721 // Update this scrope because ContextDecl in Sema will be used in6722 // TransformExpr.6723 auto *Method = dyn_cast_if_present<CXXMethodDecl>(ESI.SourceTemplate);6724 Sema::CXXThisScopeRAII ThisScope(6725 SemaRef, Method ? Method->getParent() : nullptr,6726 Method ? Method->getMethodQualifiers() : Qualifiers{},6727 Method != nullptr);6728 EnterExpressionEvaluationContext Unevaluated(6729 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);6730 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);6731 if (NoexceptExpr.isInvalid())6732 return true;6733 6734 ExceptionSpecificationType EST = ESI.Type;6735 NoexceptExpr =6736 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);6737 if (NoexceptExpr.isInvalid())6738 return true;6739 6740 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)6741 Changed = true;6742 ESI.NoexceptExpr = NoexceptExpr.get();6743 ESI.Type = EST;6744 }6745 6746 if (ESI.Type != EST_Dynamic)6747 return false;6748 6749 // Instantiate a dynamic exception specification's type.6750 for (QualType T : ESI.Exceptions) {6751 if (const PackExpansionType *PackExpansion =6752 T->getAs<PackExpansionType>()) {6753 Changed = true;6754 6755 // We have a pack expansion. Instantiate it.6756 SmallVector<UnexpandedParameterPack, 2> Unexpanded;6757 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),6758 Unexpanded);6759 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");6760 6761 // Determine whether the set of unexpanded parameter packs can and6762 // should6763 // be expanded.6764 bool Expand = false;6765 bool RetainExpansion = false;6766 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();6767 // FIXME: Track the location of the ellipsis (and track source location6768 // information for the types in the exception specification in general).6769 if (getDerived().TryExpandParameterPacks(6770 Loc, SourceRange(), Unexpanded,6771 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,6772 NumExpansions))6773 return true;6774 6775 if (!Expand) {6776 // We can't expand this pack expansion into separate arguments yet;6777 // just substitute into the pattern and create a new pack expansion6778 // type.6779 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);6780 QualType U = getDerived().TransformType(PackExpansion->getPattern());6781 if (U.isNull())6782 return true;6783 6784 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);6785 Exceptions.push_back(U);6786 continue;6787 }6788 6789 // Substitute into the pack expansion pattern for each slice of the6790 // pack.6791 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {6792 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);6793 6794 QualType U = getDerived().TransformType(PackExpansion->getPattern());6795 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))6796 return true;6797 6798 Exceptions.push_back(U);6799 }6800 } else {6801 QualType U = getDerived().TransformType(T);6802 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))6803 return true;6804 if (T != U)6805 Changed = true;6806 6807 Exceptions.push_back(U);6808 }6809 }6810 6811 ESI.Exceptions = Exceptions;6812 if (ESI.Exceptions.empty())6813 ESI.Type = EST_DynamicNone;6814 return false;6815}6816 6817template<typename Derived>6818QualType TreeTransform<Derived>::TransformFunctionNoProtoType(6819 TypeLocBuilder &TLB,6820 FunctionNoProtoTypeLoc TL) {6821 const FunctionNoProtoType *T = TL.getTypePtr();6822 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());6823 if (ResultType.isNull())6824 return QualType();6825 6826 QualType Result = TL.getType();6827 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())6828 Result = getDerived().RebuildFunctionNoProtoType(ResultType);6829 6830 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);6831 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());6832 NewTL.setLParenLoc(TL.getLParenLoc());6833 NewTL.setRParenLoc(TL.getRParenLoc());6834 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());6835 6836 return Result;6837}6838 6839template <typename Derived>6840QualType TreeTransform<Derived>::TransformUnresolvedUsingType(6841 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {6842 6843 const UnresolvedUsingType *T = TL.getTypePtr();6844 bool Changed = false;6845 6846 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();6847 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {6848 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);6849 if (!QualifierLoc)6850 return QualType();6851 Changed |= QualifierLoc != OldQualifierLoc;6852 }6853 6854 auto *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());6855 if (!D)6856 return QualType();6857 Changed |= D != T->getDecl();6858 6859 QualType Result = TL.getType();6860 if (getDerived().AlwaysRebuild() || Changed) {6861 Result = getDerived().RebuildUnresolvedUsingType(6862 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TL.getNameLoc(),6863 D);6864 if (Result.isNull())6865 return QualType();6866 }6867 6868 if (isa<UsingType>(Result))6869 TLB.push<UsingTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(),6870 QualifierLoc, TL.getNameLoc());6871 else6872 TLB.push<UnresolvedUsingTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(),6873 QualifierLoc, TL.getNameLoc());6874 return Result;6875}6876 6877template <typename Derived>6878QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,6879 UsingTypeLoc TL) {6880 const UsingType *T = TL.getTypePtr();6881 bool Changed = false;6882 6883 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();6884 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {6885 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);6886 if (!QualifierLoc)6887 return QualType();6888 Changed |= QualifierLoc != OldQualifierLoc;6889 }6890 6891 auto *D = cast_or_null<UsingShadowDecl>(6892 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));6893 if (!D)6894 return QualType();6895 Changed |= D != T->getDecl();6896 6897 QualType UnderlyingType = getDerived().TransformType(T->desugar());6898 if (UnderlyingType.isNull())6899 return QualType();6900 Changed |= UnderlyingType != T->desugar();6901 6902 QualType Result = TL.getType();6903 if (getDerived().AlwaysRebuild() || Changed) {6904 Result = getDerived().RebuildUsingType(6905 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), D,6906 UnderlyingType);6907 if (Result.isNull())6908 return QualType();6909 }6910 TLB.push<UsingTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(), QualifierLoc,6911 TL.getNameLoc());6912 return Result;6913}6914 6915template<typename Derived>6916QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,6917 TypedefTypeLoc TL) {6918 const TypedefType *T = TL.getTypePtr();6919 bool Changed = false;6920 6921 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();6922 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {6923 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);6924 if (!QualifierLoc)6925 return QualType();6926 Changed |= QualifierLoc != OldQualifierLoc;6927 }6928 6929 auto *Typedef = cast_or_null<TypedefNameDecl>(6930 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));6931 if (!Typedef)6932 return QualType();6933 Changed |= Typedef != T->getDecl();6934 6935 // FIXME: Transform the UnderlyingType if different from decl.6936 6937 QualType Result = TL.getType();6938 if (getDerived().AlwaysRebuild() || Changed) {6939 Result = getDerived().RebuildTypedefType(6940 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Typedef);6941 if (Result.isNull())6942 return QualType();6943 }6944 6945 TLB.push<TypedefTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(),6946 QualifierLoc, TL.getNameLoc());6947 return Result;6948}6949 6950template<typename Derived>6951QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,6952 TypeOfExprTypeLoc TL) {6953 // typeof expressions are not potentially evaluated contexts6954 EnterExpressionEvaluationContext Unevaluated(6955 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,6956 Sema::ReuseLambdaContextDecl);6957 6958 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());6959 if (E.isInvalid())6960 return QualType();6961 6962 E = SemaRef.HandleExprEvaluationContextForTypeof(E.get());6963 if (E.isInvalid())6964 return QualType();6965 6966 QualType Result = TL.getType();6967 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();6968 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {6969 Result =6970 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);6971 if (Result.isNull())6972 return QualType();6973 }6974 6975 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);6976 NewTL.setTypeofLoc(TL.getTypeofLoc());6977 NewTL.setLParenLoc(TL.getLParenLoc());6978 NewTL.setRParenLoc(TL.getRParenLoc());6979 6980 return Result;6981}6982 6983template<typename Derived>6984QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,6985 TypeOfTypeLoc TL) {6986 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();6987 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);6988 if (!New_Under_TI)6989 return QualType();6990 6991 QualType Result = TL.getType();6992 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();6993 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {6994 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);6995 if (Result.isNull())6996 return QualType();6997 }6998 6999 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);7000 NewTL.setTypeofLoc(TL.getTypeofLoc());7001 NewTL.setLParenLoc(TL.getLParenLoc());7002 NewTL.setRParenLoc(TL.getRParenLoc());7003 NewTL.setUnmodifiedTInfo(New_Under_TI);7004 7005 return Result;7006}7007 7008template<typename Derived>7009QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,7010 DecltypeTypeLoc TL) {7011 const DecltypeType *T = TL.getTypePtr();7012 7013 // decltype expressions are not potentially evaluated contexts7014 EnterExpressionEvaluationContext Unevaluated(7015 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,7016 Sema::ExpressionEvaluationContextRecord::EK_Decltype);7017 7018 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());7019 if (E.isInvalid())7020 return QualType();7021 7022 E = getSema().ActOnDecltypeExpression(E.get());7023 if (E.isInvalid())7024 return QualType();7025 7026 QualType Result = TL.getType();7027 if (getDerived().AlwaysRebuild() ||7028 E.get() != T->getUnderlyingExpr()) {7029 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());7030 if (Result.isNull())7031 return QualType();7032 }7033 else E.get();7034 7035 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);7036 NewTL.setDecltypeLoc(TL.getDecltypeLoc());7037 NewTL.setRParenLoc(TL.getRParenLoc());7038 return Result;7039}7040 7041template <typename Derived>7042QualType7043TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,7044 PackIndexingTypeLoc TL) {7045 // Transform the index7046 ExprResult IndexExpr;7047 {7048 EnterExpressionEvaluationContext ConstantContext(7049 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);7050 7051 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());7052 if (IndexExpr.isInvalid())7053 return QualType();7054 }7055 QualType Pattern = TL.getPattern();7056 7057 const PackIndexingType *PIT = TL.getTypePtr();7058 SmallVector<QualType, 5> SubtitutedTypes;7059 llvm::ArrayRef<QualType> Types = PIT->getExpansions();7060 7061 bool NotYetExpanded = Types.empty();7062 bool FullySubstituted = true;7063 7064 if (Types.empty() && !PIT->expandsToEmptyPack())7065 Types = llvm::ArrayRef<QualType>(&Pattern, 1);7066 7067 for (QualType T : Types) {7068 if (!T->containsUnexpandedParameterPack()) {7069 QualType Transformed = getDerived().TransformType(T);7070 if (Transformed.isNull())7071 return QualType();7072 SubtitutedTypes.push_back(Transformed);7073 continue;7074 }7075 7076 SmallVector<UnexpandedParameterPack, 2> Unexpanded;7077 getSema().collectUnexpandedParameterPacks(T, Unexpanded);7078 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");7079 // Determine whether the set of unexpanded parameter packs can and should7080 // be expanded.7081 bool ShouldExpand = true;7082 bool RetainExpansion = false;7083 UnsignedOrNone NumExpansions = std::nullopt;7084 if (getDerived().TryExpandParameterPacks(7085 TL.getEllipsisLoc(), SourceRange(), Unexpanded,7086 /*FailOnPackProducingTemplates=*/true, ShouldExpand,7087 RetainExpansion, NumExpansions))7088 return QualType();7089 if (!ShouldExpand) {7090 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);7091 // FIXME: should we keep TypeLoc for individual expansions in7092 // PackIndexingTypeLoc?7093 TypeSourceInfo *TI =7094 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, TL.getBeginLoc());7095 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());7096 if (Pack.isNull())7097 return QualType();7098 if (NotYetExpanded) {7099 FullySubstituted = false;7100 QualType Out = getDerived().RebuildPackIndexingType(7101 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),7102 FullySubstituted);7103 if (Out.isNull())7104 return QualType();7105 7106 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);7107 Loc.setEllipsisLoc(TL.getEllipsisLoc());7108 return Out;7109 }7110 SubtitutedTypes.push_back(Pack);7111 continue;7112 }7113 for (unsigned I = 0; I != *NumExpansions; ++I) {7114 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);7115 QualType Out = getDerived().TransformType(T);7116 if (Out.isNull())7117 return QualType();7118 SubtitutedTypes.push_back(Out);7119 FullySubstituted &= !Out->containsUnexpandedParameterPack();7120 }7121 // If we're supposed to retain a pack expansion, do so by temporarily7122 // forgetting the partially-substituted parameter pack.7123 if (RetainExpansion) {7124 FullySubstituted = false;7125 ForgetPartiallySubstitutedPackRAII Forget(getDerived());7126 QualType Out = getDerived().TransformType(T);7127 if (Out.isNull())7128 return QualType();7129 SubtitutedTypes.push_back(Out);7130 }7131 }7132 7133 // A pack indexing type can appear in a larger pack expansion,7134 // e.g. `Pack...[pack_of_indexes]...`7135 // so we need to temporarily disable substitution of pack elements7136 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);7137 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());7138 7139 QualType Out = getDerived().RebuildPackIndexingType(7140 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),7141 FullySubstituted, SubtitutedTypes);7142 if (Out.isNull())7143 return Out;7144 7145 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);7146 Loc.setEllipsisLoc(TL.getEllipsisLoc());7147 return Out;7148}7149 7150template<typename Derived>7151QualType TreeTransform<Derived>::TransformUnaryTransformType(7152 TypeLocBuilder &TLB,7153 UnaryTransformTypeLoc TL) {7154 QualType Result = TL.getType();7155 TypeSourceInfo *NewBaseTSI = TL.getUnderlyingTInfo();7156 if (Result->isDependentType()) {7157 const UnaryTransformType *T = TL.getTypePtr();7158 7159 NewBaseTSI = getDerived().TransformType(TL.getUnderlyingTInfo());7160 if (!NewBaseTSI)7161 return QualType();7162 QualType NewBase = NewBaseTSI->getType();7163 7164 Result = getDerived().RebuildUnaryTransformType(NewBase,7165 T->getUTTKind(),7166 TL.getKWLoc());7167 if (Result.isNull())7168 return QualType();7169 }7170 7171 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);7172 NewTL.setKWLoc(TL.getKWLoc());7173 NewTL.setParensRange(TL.getParensRange());7174 NewTL.setUnderlyingTInfo(NewBaseTSI);7175 return Result;7176}7177 7178template<typename Derived>7179QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(7180 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {7181 const DeducedTemplateSpecializationType *T = TL.getTypePtr();7182 7183 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();7184 TemplateName TemplateName = getDerived().TransformTemplateName(7185 QualifierLoc, /*TemplateKELoc=*/SourceLocation(), T->getTemplateName(),7186 TL.getTemplateNameLoc());7187 if (TemplateName.isNull())7188 return QualType();7189 7190 QualType OldDeduced = T->getDeducedType();7191 QualType NewDeduced;7192 if (!OldDeduced.isNull()) {7193 NewDeduced = getDerived().TransformType(OldDeduced);7194 if (NewDeduced.isNull())7195 return QualType();7196 }7197 7198 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(7199 T->getKeyword(), TemplateName, NewDeduced);7200 if (Result.isNull())7201 return QualType();7202 7203 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);7204 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());7205 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());7206 NewTL.setQualifierLoc(QualifierLoc);7207 return Result;7208}7209 7210template <typename Derived>7211QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB,7212 TagTypeLoc TL) {7213 const TagType *T = TL.getTypePtr();7214 7215 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();7216 if (QualifierLoc) {7217 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);7218 if (!QualifierLoc)7219 return QualType();7220 }7221 7222 auto *TD = cast_or_null<TagDecl>(7223 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));7224 if (!TD)7225 return QualType();7226 7227 QualType Result = TL.getType();7228 if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() ||7229 TD != T->getDecl()) {7230 if (T->isCanonicalUnqualified())7231 Result = getDerived().RebuildCanonicalTagType(TD);7232 else7233 Result = getDerived().RebuildTagType(7234 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TD);7235 if (Result.isNull())7236 return QualType();7237 }7238 7239 TagTypeLoc NewTL = TLB.push<TagTypeLoc>(Result);7240 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());7241 NewTL.setQualifierLoc(QualifierLoc);7242 NewTL.setNameLoc(TL.getNameLoc());7243 7244 return Result;7245}7246 7247template <typename Derived>7248QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,7249 EnumTypeLoc TL) {7250 return getDerived().TransformTagType(TLB, TL);7251}7252 7253template <typename Derived>7254QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,7255 RecordTypeLoc TL) {7256 return getDerived().TransformTagType(TLB, TL);7257}7258 7259template<typename Derived>7260QualType TreeTransform<Derived>::TransformInjectedClassNameType(7261 TypeLocBuilder &TLB,7262 InjectedClassNameTypeLoc TL) {7263 return getDerived().TransformTagType(TLB, TL);7264}7265 7266template<typename Derived>7267QualType TreeTransform<Derived>::TransformTemplateTypeParmType(7268 TypeLocBuilder &TLB,7269 TemplateTypeParmTypeLoc TL) {7270 return getDerived().TransformTemplateTypeParmType(7271 TLB, TL,7272 /*SuppressObjCLifetime=*/false);7273}7274 7275template <typename Derived>7276QualType TreeTransform<Derived>::TransformTemplateTypeParmType(7277 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {7278 return TransformTypeSpecType(TLB, TL);7279}7280 7281template<typename Derived>7282QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(7283 TypeLocBuilder &TLB,7284 SubstTemplateTypeParmTypeLoc TL) {7285 const SubstTemplateTypeParmType *T = TL.getTypePtr();7286 7287 Decl *NewReplaced =7288 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());7289 7290 // Substitute into the replacement type, which itself might involve something7291 // that needs to be transformed. This only tends to occur with default7292 // template arguments of template template parameters.7293 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());7294 QualType Replacement = getDerived().TransformType(T->getReplacementType());7295 if (Replacement.isNull())7296 return QualType();7297 7298 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(7299 Replacement, NewReplaced, T->getIndex(), T->getPackIndex(),7300 T->getFinal());7301 7302 // Propagate type-source information.7303 SubstTemplateTypeParmTypeLoc NewTL7304 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);7305 NewTL.setNameLoc(TL.getNameLoc());7306 return Result;7307 7308}7309template <typename Derived>7310QualType TreeTransform<Derived>::TransformSubstBuiltinTemplatePackType(7311 TypeLocBuilder &TLB, SubstBuiltinTemplatePackTypeLoc TL) {7312 return TransformTypeSpecType(TLB, TL);7313}7314 7315template<typename Derived>7316QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(7317 TypeLocBuilder &TLB,7318 SubstTemplateTypeParmPackTypeLoc TL) {7319 return getDerived().TransformSubstTemplateTypeParmPackType(7320 TLB, TL, /*SuppressObjCLifetime=*/false);7321}7322 7323template <typename Derived>7324QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(7325 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {7326 return TransformTypeSpecType(TLB, TL);7327}7328 7329template<typename Derived>7330QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,7331 AtomicTypeLoc TL) {7332 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());7333 if (ValueType.isNull())7334 return QualType();7335 7336 QualType Result = TL.getType();7337 if (getDerived().AlwaysRebuild() ||7338 ValueType != TL.getValueLoc().getType()) {7339 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());7340 if (Result.isNull())7341 return QualType();7342 }7343 7344 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);7345 NewTL.setKWLoc(TL.getKWLoc());7346 NewTL.setLParenLoc(TL.getLParenLoc());7347 NewTL.setRParenLoc(TL.getRParenLoc());7348 7349 return Result;7350}7351 7352template <typename Derived>7353QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,7354 PipeTypeLoc TL) {7355 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());7356 if (ValueType.isNull())7357 return QualType();7358 7359 QualType Result = TL.getType();7360 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {7361 const PipeType *PT = Result->castAs<PipeType>();7362 bool isReadPipe = PT->isReadOnly();7363 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);7364 if (Result.isNull())7365 return QualType();7366 }7367 7368 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);7369 NewTL.setKWLoc(TL.getKWLoc());7370 7371 return Result;7372}7373 7374template <typename Derived>7375QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,7376 BitIntTypeLoc TL) {7377 const BitIntType *EIT = TL.getTypePtr();7378 QualType Result = TL.getType();7379 7380 if (getDerived().AlwaysRebuild()) {7381 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),7382 EIT->getNumBits(), TL.getNameLoc());7383 if (Result.isNull())7384 return QualType();7385 }7386 7387 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);7388 NewTL.setNameLoc(TL.getNameLoc());7389 return Result;7390}7391 7392template <typename Derived>7393QualType TreeTransform<Derived>::TransformDependentBitIntType(7394 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {7395 const DependentBitIntType *EIT = TL.getTypePtr();7396 7397 EnterExpressionEvaluationContext Unevaluated(7398 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);7399 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());7400 BitsExpr = SemaRef.ActOnConstantExpression(BitsExpr);7401 7402 if (BitsExpr.isInvalid())7403 return QualType();7404 7405 QualType Result = TL.getType();7406 7407 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {7408 Result = getDerived().RebuildDependentBitIntType(7409 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());7410 7411 if (Result.isNull())7412 return QualType();7413 }7414 7415 if (isa<DependentBitIntType>(Result)) {7416 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);7417 NewTL.setNameLoc(TL.getNameLoc());7418 } else {7419 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);7420 NewTL.setNameLoc(TL.getNameLoc());7421 }7422 return Result;7423}7424 7425template <typename Derived>7426QualType TreeTransform<Derived>::TransformPredefinedSugarType(7427 TypeLocBuilder &TLB, PredefinedSugarTypeLoc TL) {7428 llvm_unreachable("This type does not need to be transformed.");7429}7430 7431 /// Simple iterator that traverses the template arguments in a7432 /// container that provides a \c getArgLoc() member function.7433 ///7434 /// This iterator is intended to be used with the iterator form of7435 /// \c TreeTransform<Derived>::TransformTemplateArguments().7436 template<typename ArgLocContainer>7437 class TemplateArgumentLocContainerIterator {7438 ArgLocContainer *Container;7439 unsigned Index;7440 7441 public:7442 typedef TemplateArgumentLoc value_type;7443 typedef TemplateArgumentLoc reference;7444 typedef int difference_type;7445 typedef std::input_iterator_tag iterator_category;7446 7447 class pointer {7448 TemplateArgumentLoc Arg;7449 7450 public:7451 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }7452 7453 const TemplateArgumentLoc *operator->() const {7454 return &Arg;7455 }7456 };7457 7458 7459 TemplateArgumentLocContainerIterator() {}7460 7461 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,7462 unsigned Index)7463 : Container(&Container), Index(Index) { }7464 7465 TemplateArgumentLocContainerIterator &operator++() {7466 ++Index;7467 return *this;7468 }7469 7470 TemplateArgumentLocContainerIterator operator++(int) {7471 TemplateArgumentLocContainerIterator Old(*this);7472 ++(*this);7473 return Old;7474 }7475 7476 TemplateArgumentLoc operator*() const {7477 return Container->getArgLoc(Index);7478 }7479 7480 pointer operator->() const {7481 return pointer(Container->getArgLoc(Index));7482 }7483 7484 friend bool operator==(const TemplateArgumentLocContainerIterator &X,7485 const TemplateArgumentLocContainerIterator &Y) {7486 return X.Container == Y.Container && X.Index == Y.Index;7487 }7488 7489 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,7490 const TemplateArgumentLocContainerIterator &Y) {7491 return !(X == Y);7492 }7493 };7494 7495template<typename Derived>7496QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,7497 AutoTypeLoc TL) {7498 const AutoType *T = TL.getTypePtr();7499 QualType OldDeduced = T->getDeducedType();7500 QualType NewDeduced;7501 if (!OldDeduced.isNull()) {7502 NewDeduced = getDerived().TransformType(OldDeduced);7503 if (NewDeduced.isNull())7504 return QualType();7505 }7506 7507 ConceptDecl *NewCD = nullptr;7508 TemplateArgumentListInfo NewTemplateArgs;7509 NestedNameSpecifierLoc NewNestedNameSpec;7510 if (T->isConstrained()) {7511 assert(TL.getConceptReference());7512 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(7513 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));7514 7515 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());7516 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());7517 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;7518 if (getDerived().TransformTemplateArguments(7519 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),7520 NewTemplateArgs))7521 return QualType();7522 7523 if (TL.getNestedNameSpecifierLoc()) {7524 NewNestedNameSpec7525 = getDerived().TransformNestedNameSpecifierLoc(7526 TL.getNestedNameSpecifierLoc());7527 if (!NewNestedNameSpec)7528 return QualType();7529 }7530 }7531 7532 QualType Result = TL.getType();7533 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||7534 T->isDependentType() || T->isConstrained()) {7535 // FIXME: Maybe don't rebuild if all template arguments are the same.7536 llvm::SmallVector<TemplateArgument, 4> NewArgList;7537 NewArgList.reserve(NewTemplateArgs.size());7538 for (const auto &ArgLoc : NewTemplateArgs.arguments())7539 NewArgList.push_back(ArgLoc.getArgument());7540 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,7541 NewArgList);7542 if (Result.isNull())7543 return QualType();7544 }7545 7546 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);7547 NewTL.setNameLoc(TL.getNameLoc());7548 NewTL.setRParenLoc(TL.getRParenLoc());7549 NewTL.setConceptReference(nullptr);7550 7551 if (T->isConstrained()) {7552 DeclarationNameInfo DNI = DeclarationNameInfo(7553 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),7554 TL.getConceptNameLoc(),7555 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());7556 auto *CR = ConceptReference::Create(7557 SemaRef.Context, NewNestedNameSpec, TL.getTemplateKWLoc(), DNI,7558 TL.getFoundDecl(), TL.getTypePtr()->getTypeConstraintConcept(),7559 ASTTemplateArgumentListInfo::Create(SemaRef.Context, NewTemplateArgs));7560 NewTL.setConceptReference(CR);7561 }7562 7563 return Result;7564}7565 7566template <typename Derived>7567QualType TreeTransform<Derived>::TransformTemplateSpecializationType(7568 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL) {7569 return getDerived().TransformTemplateSpecializationType(7570 TLB, TL, /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,7571 /*AllowInjectedClassName=*/false);7572}7573 7574template <typename Derived>7575QualType TreeTransform<Derived>::TransformTemplateSpecializationType(7576 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL, QualType ObjectType,7577 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {7578 const TemplateSpecializationType *T = TL.getTypePtr();7579 7580 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();7581 TemplateName Template = getDerived().TransformTemplateName(7582 QualifierLoc, TL.getTemplateKeywordLoc(), T->getTemplateName(),7583 TL.getTemplateNameLoc(), ObjectType, FirstQualifierInScope,7584 AllowInjectedClassName);7585 if (Template.isNull())7586 return QualType();7587 7588 TemplateArgumentListInfo NewTemplateArgs;7589 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());7590 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());7591 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>7592 ArgIterator;7593 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),7594 ArgIterator(TL, TL.getNumArgs()),7595 NewTemplateArgs))7596 return QualType();7597 7598 // This needs to be rebuilt if either the arguments changed, or if the7599 // original template changed. If the template changed, and even if the7600 // arguments didn't change, these arguments might not correspond to their7601 // respective parameters, therefore needing conversions.7602 QualType Result = getDerived().RebuildTemplateSpecializationType(7603 TL.getTypePtr()->getKeyword(), Template, TL.getTemplateNameLoc(),7604 NewTemplateArgs);7605 7606 if (!Result.isNull()) {7607 TLB.push<TemplateSpecializationTypeLoc>(Result).set(7608 TL.getElaboratedKeywordLoc(), QualifierLoc, TL.getTemplateKeywordLoc(),7609 TL.getTemplateNameLoc(), NewTemplateArgs);7610 }7611 7612 return Result;7613}7614 7615template <typename Derived>7616QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,7617 AttributedTypeLoc TL) {7618 const AttributedType *oldType = TL.getTypePtr();7619 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());7620 if (modifiedType.isNull())7621 return QualType();7622 7623 // oldAttr can be null if we started with a QualType rather than a TypeLoc.7624 const Attr *oldAttr = TL.getAttr();7625 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;7626 if (oldAttr && !newAttr)7627 return QualType();7628 7629 QualType result = TL.getType();7630 7631 // FIXME: dependent operand expressions?7632 if (getDerived().AlwaysRebuild() ||7633 modifiedType != oldType->getModifiedType()) {7634 // If the equivalent type is equal to the modified type, we don't want to7635 // transform it as well because:7636 //7637 // 1. The transformation would yield the same result and is therefore7638 // superfluous, and7639 //7640 // 2. Transforming the same type twice can cause problems, e.g. if it7641 // is a FunctionProtoType, we may end up instantiating the function7642 // parameters twice, which causes an assertion since the parameters7643 // are already bound to their counterparts in the template for this7644 // instantiation.7645 //7646 QualType equivalentType = modifiedType;7647 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {7648 TypeLocBuilder AuxiliaryTLB;7649 AuxiliaryTLB.reserve(TL.getFullDataSize());7650 equivalentType =7651 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());7652 if (equivalentType.isNull())7653 return QualType();7654 }7655 7656 // Check whether we can add nullability; it is only represented as7657 // type sugar, and therefore cannot be diagnosed in any other way.7658 if (auto nullability = oldType->getImmediateNullability()) {7659 if (!modifiedType->canHaveNullability()) {7660 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()7661 : TL.getModifiedLoc().getBeginLoc()),7662 diag::err_nullability_nonpointer)7663 << DiagNullabilityKind(*nullability, false) << modifiedType;7664 return QualType();7665 }7666 }7667 7668 result = SemaRef.Context.getAttributedType(TL.getAttrKind(),7669 modifiedType,7670 equivalentType,7671 TL.getAttr());7672 }7673 7674 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);7675 newTL.setAttr(newAttr);7676 return result;7677}7678 7679template <typename Derived>7680QualType TreeTransform<Derived>::TransformCountAttributedType(7681 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {7682 const CountAttributedType *OldTy = TL.getTypePtr();7683 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());7684 if (InnerTy.isNull())7685 return QualType();7686 7687 Expr *OldCount = TL.getCountExpr();7688 Expr *NewCount = nullptr;7689 if (OldCount) {7690 ExprResult CountResult = getDerived().TransformExpr(OldCount);7691 if (CountResult.isInvalid())7692 return QualType();7693 NewCount = CountResult.get();7694 }7695 7696 QualType Result = TL.getType();7697 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||7698 OldCount != NewCount) {7699 // Currently, CountAttributedType can only wrap incomplete array types.7700 Result = SemaRef.BuildCountAttributedArrayOrPointerType(7701 InnerTy, NewCount, OldTy->isCountInBytes(), OldTy->isOrNull());7702 }7703 7704 TLB.push<CountAttributedTypeLoc>(Result);7705 return Result;7706}7707 7708template <typename Derived>7709QualType TreeTransform<Derived>::TransformBTFTagAttributedType(7710 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {7711 // The BTFTagAttributedType is available for C only.7712 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");7713}7714 7715template <typename Derived>7716QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(7717 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {7718 7719 const HLSLAttributedResourceType *oldType = TL.getTypePtr();7720 7721 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());7722 if (WrappedTy.isNull())7723 return QualType();7724 7725 QualType ContainedTy = QualType();7726 QualType OldContainedTy = oldType->getContainedType();7727 if (!OldContainedTy.isNull()) {7728 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();7729 if (!oldContainedTSI)7730 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(7731 OldContainedTy, SourceLocation());7732 TypeSourceInfo *ContainedTSI = getDerived().TransformType(oldContainedTSI);7733 if (!ContainedTSI)7734 return QualType();7735 ContainedTy = ContainedTSI->getType();7736 }7737 7738 QualType Result = TL.getType();7739 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||7740 ContainedTy != oldType->getContainedType()) {7741 Result = SemaRef.Context.getHLSLAttributedResourceType(7742 WrappedTy, ContainedTy, oldType->getAttrs());7743 }7744 7745 TLB.push<HLSLAttributedResourceTypeLoc>(Result);7746 return Result;7747}7748 7749template <typename Derived>7750QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(7751 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {7752 // No transformations needed.7753 return TL.getType();7754}7755 7756template<typename Derived>7757QualType7758TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,7759 ParenTypeLoc TL) {7760 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());7761 if (Inner.isNull())7762 return QualType();7763 7764 QualType Result = TL.getType();7765 if (getDerived().AlwaysRebuild() ||7766 Inner != TL.getInnerLoc().getType()) {7767 Result = getDerived().RebuildParenType(Inner);7768 if (Result.isNull())7769 return QualType();7770 }7771 7772 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);7773 NewTL.setLParenLoc(TL.getLParenLoc());7774 NewTL.setRParenLoc(TL.getRParenLoc());7775 return Result;7776}7777 7778template <typename Derived>7779QualType7780TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,7781 MacroQualifiedTypeLoc TL) {7782 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());7783 if (Inner.isNull())7784 return QualType();7785 7786 QualType Result = TL.getType();7787 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {7788 Result =7789 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());7790 if (Result.isNull())7791 return QualType();7792 }7793 7794 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);7795 NewTL.setExpansionLoc(TL.getExpansionLoc());7796 return Result;7797}7798 7799template<typename Derived>7800QualType TreeTransform<Derived>::TransformDependentNameType(7801 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {7802 return TransformDependentNameType(TLB, TL, false);7803}7804 7805template <typename Derived>7806QualType TreeTransform<Derived>::TransformDependentNameType(7807 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext,7808 QualType ObjectType, NamedDecl *UnqualLookup) {7809 const DependentNameType *T = TL.getTypePtr();7810 7811 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();7812 if (QualifierLoc) {7813 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(7814 QualifierLoc, ObjectType, UnqualLookup);7815 if (!QualifierLoc)7816 return QualType();7817 } else {7818 assert((ObjectType.isNull() && !UnqualLookup) &&7819 "must be transformed by TransformNestedNameSpecifierLoc");7820 }7821 7822 QualType Result7823 = getDerived().RebuildDependentNameType(T->getKeyword(),7824 TL.getElaboratedKeywordLoc(),7825 QualifierLoc,7826 T->getIdentifier(),7827 TL.getNameLoc(),7828 DeducedTSTContext);7829 if (Result.isNull())7830 return QualType();7831 7832 if (isa<TagType>(Result)) {7833 auto NewTL = TLB.push<TagTypeLoc>(Result);7834 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());7835 NewTL.setQualifierLoc(QualifierLoc);7836 NewTL.setNameLoc(TL.getNameLoc());7837 } else if (isa<DeducedTemplateSpecializationType>(Result)) {7838 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);7839 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());7840 NewTL.setTemplateNameLoc(TL.getNameLoc());7841 NewTL.setQualifierLoc(QualifierLoc);7842 } else if (isa<TypedefType>(Result)) {7843 TLB.push<TypedefTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(),7844 QualifierLoc, TL.getNameLoc());7845 } else if (isa<UnresolvedUsingType>(Result)) {7846 auto NewTL = TLB.push<UnresolvedUsingTypeLoc>(Result);7847 NewTL.set(TL.getElaboratedKeywordLoc(), QualifierLoc, TL.getNameLoc());7848 } else {7849 auto NewTL = TLB.push<DependentNameTypeLoc>(Result);7850 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());7851 NewTL.setQualifierLoc(QualifierLoc);7852 NewTL.setNameLoc(TL.getNameLoc());7853 }7854 return Result;7855}7856 7857template<typename Derived>7858QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,7859 PackExpansionTypeLoc TL) {7860 QualType Pattern7861 = getDerived().TransformType(TLB, TL.getPatternLoc());7862 if (Pattern.isNull())7863 return QualType();7864 7865 QualType Result = TL.getType();7866 if (getDerived().AlwaysRebuild() ||7867 Pattern != TL.getPatternLoc().getType()) {7868 Result = getDerived().RebuildPackExpansionType(Pattern,7869 TL.getPatternLoc().getSourceRange(),7870 TL.getEllipsisLoc(),7871 TL.getTypePtr()->getNumExpansions());7872 if (Result.isNull())7873 return QualType();7874 }7875 7876 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);7877 NewT.setEllipsisLoc(TL.getEllipsisLoc());7878 return Result;7879}7880 7881template<typename Derived>7882QualType7883TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,7884 ObjCInterfaceTypeLoc TL) {7885 // ObjCInterfaceType is never dependent.7886 TLB.pushFullCopy(TL);7887 return TL.getType();7888}7889 7890template<typename Derived>7891QualType7892TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,7893 ObjCTypeParamTypeLoc TL) {7894 const ObjCTypeParamType *T = TL.getTypePtr();7895 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(7896 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));7897 if (!OTP)7898 return QualType();7899 7900 QualType Result = TL.getType();7901 if (getDerived().AlwaysRebuild() ||7902 OTP != T->getDecl()) {7903 Result = getDerived().RebuildObjCTypeParamType(7904 OTP, TL.getProtocolLAngleLoc(),7905 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),7906 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());7907 if (Result.isNull())7908 return QualType();7909 }7910 7911 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);7912 if (TL.getNumProtocols()) {7913 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());7914 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)7915 NewTL.setProtocolLoc(i, TL.getProtocolLoc(i));7916 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());7917 }7918 return Result;7919}7920 7921template<typename Derived>7922QualType7923TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,7924 ObjCObjectTypeLoc TL) {7925 // Transform base type.7926 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());7927 if (BaseType.isNull())7928 return QualType();7929 7930 bool AnyChanged = BaseType != TL.getBaseLoc().getType();7931 7932 // Transform type arguments.7933 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;7934 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {7935 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);7936 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();7937 QualType TypeArg = TypeArgInfo->getType();7938 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {7939 AnyChanged = true;7940 7941 // We have a pack expansion. Instantiate it.7942 const auto *PackExpansion = PackExpansionLoc.getType()7943 ->castAs<PackExpansionType>();7944 SmallVector<UnexpandedParameterPack, 2> Unexpanded;7945 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),7946 Unexpanded);7947 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");7948 7949 // Determine whether the set of unexpanded parameter packs can7950 // and should be expanded.7951 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();7952 bool Expand = false;7953 bool RetainExpansion = false;7954 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();7955 if (getDerived().TryExpandParameterPacks(7956 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),7957 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,7958 RetainExpansion, NumExpansions))7959 return QualType();7960 7961 if (!Expand) {7962 // We can't expand this pack expansion into separate arguments yet;7963 // just substitute into the pattern and create a new pack expansion7964 // type.7965 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);7966 7967 TypeLocBuilder TypeArgBuilder;7968 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());7969 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,7970 PatternLoc);7971 if (NewPatternType.isNull())7972 return QualType();7973 7974 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(7975 NewPatternType, NumExpansions);7976 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);7977 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());7978 NewTypeArgInfos.push_back(7979 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewExpansionType));7980 continue;7981 }7982 7983 // Substitute into the pack expansion pattern for each slice of the7984 // pack.7985 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {7986 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);7987 7988 TypeLocBuilder TypeArgBuilder;7989 TypeArgBuilder.reserve(PatternLoc.getFullDataSize());7990 7991 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,7992 PatternLoc);7993 if (NewTypeArg.isNull())7994 return QualType();7995 7996 NewTypeArgInfos.push_back(7997 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));7998 }7999 8000 continue;8001 }8002 8003 TypeLocBuilder TypeArgBuilder;8004 TypeArgBuilder.reserve(TypeArgLoc.getFullDataSize());8005 QualType NewTypeArg =8006 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);8007 if (NewTypeArg.isNull())8008 return QualType();8009 8010 // If nothing changed, just keep the old TypeSourceInfo.8011 if (NewTypeArg == TypeArg) {8012 NewTypeArgInfos.push_back(TypeArgInfo);8013 continue;8014 }8015 8016 NewTypeArgInfos.push_back(8017 TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg));8018 AnyChanged = true;8019 }8020 8021 QualType Result = TL.getType();8022 if (getDerived().AlwaysRebuild() || AnyChanged) {8023 // Rebuild the type.8024 Result = getDerived().RebuildObjCObjectType(8025 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,8026 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),8027 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),8028 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());8029 8030 if (Result.isNull())8031 return QualType();8032 }8033 8034 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);8035 NewT.setHasBaseTypeAsWritten(true);8036 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());8037 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)8038 NewT.setTypeArgTInfo(i, NewTypeArgInfos[i]);8039 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());8040 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());8041 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)8042 NewT.setProtocolLoc(i, TL.getProtocolLoc(i));8043 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());8044 return Result;8045}8046 8047template<typename Derived>8048QualType8049TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,8050 ObjCObjectPointerTypeLoc TL) {8051 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());8052 if (PointeeType.isNull())8053 return QualType();8054 8055 QualType Result = TL.getType();8056 if (getDerived().AlwaysRebuild() ||8057 PointeeType != TL.getPointeeLoc().getType()) {8058 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,8059 TL.getStarLoc());8060 if (Result.isNull())8061 return QualType();8062 }8063 8064 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);8065 NewT.setStarLoc(TL.getStarLoc());8066 return Result;8067}8068 8069//===----------------------------------------------------------------------===//8070// Statement transformation8071//===----------------------------------------------------------------------===//8072template<typename Derived>8073StmtResult8074TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {8075 return S;8076}8077 8078template<typename Derived>8079StmtResult8080TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {8081 return getDerived().TransformCompoundStmt(S, false);8082}8083 8084template<typename Derived>8085StmtResult8086TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,8087 bool IsStmtExpr) {8088 Sema::CompoundScopeRAII CompoundScope(getSema());8089 Sema::FPFeaturesStateRAII FPSave(getSema());8090 if (S->hasStoredFPFeatures())8091 getSema().resetFPOptions(8092 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));8093 8094 bool SubStmtInvalid = false;8095 bool SubStmtChanged = false;8096 SmallVector<Stmt*, 8> Statements;8097 for (auto *B : S->body()) {8098 StmtResult Result = getDerived().TransformStmt(8099 B, IsStmtExpr && B == S->body_back() ? StmtDiscardKind::StmtExprResult8100 : StmtDiscardKind::Discarded);8101 8102 if (Result.isInvalid()) {8103 // Immediately fail if this was a DeclStmt, since it's very8104 // likely that this will cause problems for future statements.8105 if (isa<DeclStmt>(B))8106 return StmtError();8107 8108 // Otherwise, just keep processing substatements and fail later.8109 SubStmtInvalid = true;8110 continue;8111 }8112 8113 SubStmtChanged = SubStmtChanged || Result.get() != B;8114 Statements.push_back(Result.getAs<Stmt>());8115 }8116 8117 if (SubStmtInvalid)8118 return StmtError();8119 8120 if (!getDerived().AlwaysRebuild() &&8121 !SubStmtChanged)8122 return S;8123 8124 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),8125 Statements,8126 S->getRBracLoc(),8127 IsStmtExpr);8128}8129 8130template<typename Derived>8131StmtResult8132TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {8133 ExprResult LHS, RHS;8134 {8135 EnterExpressionEvaluationContext Unevaluated(8136 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);8137 8138 // Transform the left-hand case value.8139 LHS = getDerived().TransformExpr(S->getLHS());8140 LHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), LHS);8141 if (LHS.isInvalid())8142 return StmtError();8143 8144 // Transform the right-hand case value (for the GNU case-range extension).8145 RHS = getDerived().TransformExpr(S->getRHS());8146 RHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), RHS);8147 if (RHS.isInvalid())8148 return StmtError();8149 }8150 8151 // Build the case statement.8152 // Case statements are always rebuilt so that they will attached to their8153 // transformed switch statement.8154 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),8155 LHS.get(),8156 S->getEllipsisLoc(),8157 RHS.get(),8158 S->getColonLoc());8159 if (Case.isInvalid())8160 return StmtError();8161 8162 // Transform the statement following the case8163 StmtResult SubStmt =8164 getDerived().TransformStmt(S->getSubStmt());8165 if (SubStmt.isInvalid())8166 return StmtError();8167 8168 // Attach the body to the case statement8169 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());8170}8171 8172template <typename Derived>8173StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {8174 // Transform the statement following the default case8175 StmtResult SubStmt =8176 getDerived().TransformStmt(S->getSubStmt());8177 if (SubStmt.isInvalid())8178 return StmtError();8179 8180 // Default statements are always rebuilt8181 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),8182 SubStmt.get());8183}8184 8185template<typename Derived>8186StmtResult8187TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {8188 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);8189 if (SubStmt.isInvalid())8190 return StmtError();8191 8192 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),8193 S->getDecl());8194 if (!LD)8195 return StmtError();8196 8197 // If we're transforming "in-place" (we're not creating new local8198 // declarations), assume we're replacing the old label statement8199 // and clear out the reference to it.8200 if (LD == S->getDecl())8201 S->getDecl()->setStmt(nullptr);8202 8203 // FIXME: Pass the real colon location in.8204 return getDerived().RebuildLabelStmt(S->getIdentLoc(),8205 cast<LabelDecl>(LD), SourceLocation(),8206 SubStmt.get());8207}8208 8209template <typename Derived>8210const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {8211 if (!R)8212 return R;8213 8214 switch (R->getKind()) {8215// Transform attributes by calling TransformXXXAttr.8216#define ATTR(X) \8217 case attr::X: \8218 return getDerived().Transform##X##Attr(cast<X##Attr>(R));8219#include "clang/Basic/AttrList.inc"8220 }8221 return R;8222}8223 8224template <typename Derived>8225const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,8226 const Stmt *InstS,8227 const Attr *R) {8228 if (!R)8229 return R;8230 8231 switch (R->getKind()) {8232// Transform attributes by calling TransformStmtXXXAttr.8233#define ATTR(X) \8234 case attr::X: \8235 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));8236#include "clang/Basic/AttrList.inc"8237 }8238 return TransformAttr(R);8239}8240 8241template <typename Derived>8242StmtResult8243TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,8244 StmtDiscardKind SDK) {8245 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);8246 if (SubStmt.isInvalid())8247 return StmtError();8248 8249 bool AttrsChanged = false;8250 SmallVector<const Attr *, 1> Attrs;8251 8252 // Visit attributes and keep track if any are transformed.8253 for (const auto *I : S->getAttrs()) {8254 const Attr *R =8255 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);8256 AttrsChanged |= (I != R);8257 if (R)8258 Attrs.push_back(R);8259 }8260 8261 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)8262 return S;8263 8264 // If transforming the attributes failed for all of the attributes in the8265 // statement, don't make an AttributedStmt without attributes.8266 if (Attrs.empty())8267 return SubStmt;8268 8269 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,8270 SubStmt.get());8271}8272 8273template<typename Derived>8274StmtResult8275TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {8276 // Transform the initialization statement8277 StmtResult Init = getDerived().TransformStmt(S->getInit());8278 if (Init.isInvalid())8279 return StmtError();8280 8281 Sema::ConditionResult Cond;8282 if (!S->isConsteval()) {8283 // Transform the condition8284 Cond = getDerived().TransformCondition(8285 S->getIfLoc(), S->getConditionVariable(), S->getCond(),8286 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf8287 : Sema::ConditionKind::Boolean);8288 if (Cond.isInvalid())8289 return StmtError();8290 }8291 8292 // If this is a constexpr if, determine which arm we should instantiate.8293 std::optional<bool> ConstexprConditionValue;8294 if (S->isConstexpr())8295 ConstexprConditionValue = Cond.getKnownValue();8296 8297 // Transform the "then" branch.8298 StmtResult Then;8299 if (!ConstexprConditionValue || *ConstexprConditionValue) {8300 EnterExpressionEvaluationContext Ctx(8301 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,8302 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,8303 S->isNonNegatedConsteval());8304 8305 Then = getDerived().TransformStmt(S->getThen());8306 if (Then.isInvalid())8307 return StmtError();8308 } else {8309 // Discarded branch is replaced with empty CompoundStmt so we can keep8310 // proper source location for start and end of original branch, so8311 // subsequent transformations like CoverageMapping work properly8312 Then = new (getSema().Context)8313 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());8314 }8315 8316 // Transform the "else" branch.8317 StmtResult Else;8318 if (!ConstexprConditionValue || !*ConstexprConditionValue) {8319 EnterExpressionEvaluationContext Ctx(8320 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,8321 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,8322 S->isNegatedConsteval());8323 8324 Else = getDerived().TransformStmt(S->getElse());8325 if (Else.isInvalid())8326 return StmtError();8327 } else if (S->getElse() && ConstexprConditionValue &&8328 *ConstexprConditionValue) {8329 // Same thing here as with <then> branch, we are discarding it, we can't8330 // replace it with NULL nor NullStmt as we need to keep for source location8331 // range, for CoverageMapping8332 Else = new (getSema().Context)8333 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());8334 }8335 8336 if (!getDerived().AlwaysRebuild() &&8337 Init.get() == S->getInit() &&8338 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&8339 Then.get() == S->getThen() &&8340 Else.get() == S->getElse())8341 return S;8342 8343 return getDerived().RebuildIfStmt(8344 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,8345 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());8346}8347 8348template<typename Derived>8349StmtResult8350TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {8351 // Transform the initialization statement8352 StmtResult Init = getDerived().TransformStmt(S->getInit());8353 if (Init.isInvalid())8354 return StmtError();8355 8356 // Transform the condition.8357 Sema::ConditionResult Cond = getDerived().TransformCondition(8358 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),8359 Sema::ConditionKind::Switch);8360 if (Cond.isInvalid())8361 return StmtError();8362 8363 // Rebuild the switch statement.8364 StmtResult Switch =8365 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),8366 Init.get(), Cond, S->getRParenLoc());8367 if (Switch.isInvalid())8368 return StmtError();8369 8370 // Transform the body of the switch statement.8371 StmtResult Body = getDerived().TransformStmt(S->getBody());8372 if (Body.isInvalid())8373 return StmtError();8374 8375 // Complete the switch statement.8376 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),8377 Body.get());8378}8379 8380template<typename Derived>8381StmtResult8382TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {8383 // Transform the condition8384 Sema::ConditionResult Cond = getDerived().TransformCondition(8385 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),8386 Sema::ConditionKind::Boolean);8387 if (Cond.isInvalid())8388 return StmtError();8389 8390 // OpenACC Restricts a while-loop inside of certain construct/clause8391 // combinations, so diagnose that here in OpenACC mode.8392 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};8393 SemaRef.OpenACC().ActOnWhileStmt(S->getBeginLoc());8394 8395 // Transform the body8396 StmtResult Body = getDerived().TransformStmt(S->getBody());8397 if (Body.isInvalid())8398 return StmtError();8399 8400 if (!getDerived().AlwaysRebuild() &&8401 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&8402 Body.get() == S->getBody())8403 return Owned(S);8404 8405 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),8406 Cond, S->getRParenLoc(), Body.get());8407}8408 8409template<typename Derived>8410StmtResult8411TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {8412 // OpenACC Restricts a do-loop inside of certain construct/clause8413 // combinations, so diagnose that here in OpenACC mode.8414 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};8415 SemaRef.OpenACC().ActOnDoStmt(S->getBeginLoc());8416 8417 // Transform the body8418 StmtResult Body = getDerived().TransformStmt(S->getBody());8419 if (Body.isInvalid())8420 return StmtError();8421 8422 // Transform the condition8423 ExprResult Cond = getDerived().TransformExpr(S->getCond());8424 if (Cond.isInvalid())8425 return StmtError();8426 8427 if (!getDerived().AlwaysRebuild() &&8428 Cond.get() == S->getCond() &&8429 Body.get() == S->getBody())8430 return S;8431 8432 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),8433 /*FIXME:*/S->getWhileLoc(), Cond.get(),8434 S->getRParenLoc());8435}8436 8437template<typename Derived>8438StmtResult8439TreeTransform<Derived>::TransformForStmt(ForStmt *S) {8440 if (getSema().getLangOpts().OpenMP)8441 getSema().OpenMP().startOpenMPLoop();8442 8443 // Transform the initialization statement8444 StmtResult Init = getDerived().TransformStmt(S->getInit());8445 if (Init.isInvalid())8446 return StmtError();8447 8448 // In OpenMP loop region loop control variable must be captured and be8449 // private. Perform analysis of first part (if any).8450 if (getSema().getLangOpts().OpenMP && Init.isUsable())8451 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),8452 Init.get());8453 8454 // Transform the condition8455 Sema::ConditionResult Cond = getDerived().TransformCondition(8456 S->getForLoc(), S->getConditionVariable(), S->getCond(),8457 Sema::ConditionKind::Boolean);8458 if (Cond.isInvalid())8459 return StmtError();8460 8461 // Transform the increment8462 ExprResult Inc = getDerived().TransformExpr(S->getInc());8463 if (Inc.isInvalid())8464 return StmtError();8465 8466 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));8467 if (S->getInc() && !FullInc.get())8468 return StmtError();8469 8470 // OpenACC Restricts a for-loop inside of certain construct/clause8471 // combinations, so diagnose that here in OpenACC mode.8472 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};8473 SemaRef.OpenACC().ActOnForStmtBegin(8474 S->getBeginLoc(), S->getInit(), Init.get(), S->getCond(),8475 Cond.get().second, S->getInc(), Inc.get());8476 8477 // Transform the body8478 StmtResult Body = getDerived().TransformStmt(S->getBody());8479 if (Body.isInvalid())8480 return StmtError();8481 8482 SemaRef.OpenACC().ActOnForStmtEnd(S->getBeginLoc(), Body);8483 8484 if (!getDerived().AlwaysRebuild() &&8485 Init.get() == S->getInit() &&8486 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&8487 Inc.get() == S->getInc() &&8488 Body.get() == S->getBody())8489 return S;8490 8491 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),8492 Init.get(), Cond, FullInc,8493 S->getRParenLoc(), Body.get());8494}8495 8496template<typename Derived>8497StmtResult8498TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {8499 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),8500 S->getLabel());8501 if (!LD)8502 return StmtError();8503 8504 // Goto statements must always be rebuilt, to resolve the label.8505 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),8506 cast<LabelDecl>(LD));8507}8508 8509template<typename Derived>8510StmtResult8511TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {8512 ExprResult Target = getDerived().TransformExpr(S->getTarget());8513 if (Target.isInvalid())8514 return StmtError();8515 Target = SemaRef.MaybeCreateExprWithCleanups(Target.get());8516 8517 if (!getDerived().AlwaysRebuild() &&8518 Target.get() == S->getTarget())8519 return S;8520 8521 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),8522 Target.get());8523}8524 8525template<typename Derived>8526StmtResult8527TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {8528 if (!S->hasLabelTarget())8529 return S;8530 8531 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),8532 S->getLabelDecl());8533 if (!LD)8534 return StmtError();8535 8536 return new (SemaRef.Context)8537 ContinueStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(LD));8538}8539 8540template<typename Derived>8541StmtResult8542TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {8543 if (!S->hasLabelTarget())8544 return S;8545 8546 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),8547 S->getLabelDecl());8548 if (!LD)8549 return StmtError();8550 8551 return new (SemaRef.Context)8552 BreakStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(LD));8553}8554 8555template<typename Derived>8556StmtResult8557TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {8558 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),8559 /*NotCopyInit*/false);8560 if (Result.isInvalid())8561 return StmtError();8562 8563 // FIXME: We always rebuild the return statement because there is no way8564 // to tell whether the return type of the function has changed.8565 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());8566}8567 8568template<typename Derived>8569StmtResult8570TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {8571 bool DeclChanged = false;8572 SmallVector<Decl *, 4> Decls;8573 LambdaScopeInfo *LSI = getSema().getCurLambda();8574 for (auto *D : S->decls()) {8575 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);8576 if (!Transformed)8577 return StmtError();8578 8579 if (Transformed != D)8580 DeclChanged = true;8581 8582 if (LSI) {8583 if (auto *TD = dyn_cast<TypeDecl>(Transformed)) {8584 if (auto *TN = dyn_cast<TypedefNameDecl>(TD)) {8585 LSI->ContainsUnexpandedParameterPack |=8586 TN->getUnderlyingType()->containsUnexpandedParameterPack();8587 } else {8588 LSI->ContainsUnexpandedParameterPack |=8589 getSema()8590 .getASTContext()8591 .getTypeDeclType(TD)8592 ->containsUnexpandedParameterPack();8593 }8594 }8595 if (auto *VD = dyn_cast<VarDecl>(Transformed))8596 LSI->ContainsUnexpandedParameterPack |=8597 VD->getType()->containsUnexpandedParameterPack();8598 }8599 8600 Decls.push_back(Transformed);8601 }8602 8603 if (!getDerived().AlwaysRebuild() && !DeclChanged)8604 return S;8605 8606 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());8607}8608 8609template<typename Derived>8610StmtResult8611TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {8612 8613 SmallVector<Expr*, 8> Constraints;8614 SmallVector<Expr*, 8> Exprs;8615 SmallVector<IdentifierInfo *, 4> Names;8616 8617 SmallVector<Expr*, 8> Clobbers;8618 8619 bool ExprsChanged = false;8620 8621 auto RebuildString = [&](Expr *E) {8622 ExprResult Result = getDerived().TransformExpr(E);8623 if (!Result.isUsable())8624 return Result;8625 if (Result.get() != E) {8626 ExprsChanged = true;8627 Result = SemaRef.ActOnGCCAsmStmtString(Result.get(), /*ForLabel=*/false);8628 }8629 return Result;8630 };8631 8632 // Go through the outputs.8633 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {8634 Names.push_back(S->getOutputIdentifier(I));8635 8636 ExprResult Result = RebuildString(S->getOutputConstraintExpr(I));8637 if (Result.isInvalid())8638 return StmtError();8639 8640 Constraints.push_back(Result.get());8641 8642 // Transform the output expr.8643 Expr *OutputExpr = S->getOutputExpr(I);8644 Result = getDerived().TransformExpr(OutputExpr);8645 if (Result.isInvalid())8646 return StmtError();8647 8648 ExprsChanged |= Result.get() != OutputExpr;8649 8650 Exprs.push_back(Result.get());8651 }8652 8653 // Go through the inputs.8654 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {8655 Names.push_back(S->getInputIdentifier(I));8656 8657 ExprResult Result = RebuildString(S->getInputConstraintExpr(I));8658 if (Result.isInvalid())8659 return StmtError();8660 8661 Constraints.push_back(Result.get());8662 8663 // Transform the input expr.8664 Expr *InputExpr = S->getInputExpr(I);8665 Result = getDerived().TransformExpr(InputExpr);8666 if (Result.isInvalid())8667 return StmtError();8668 8669 ExprsChanged |= Result.get() != InputExpr;8670 8671 Exprs.push_back(Result.get());8672 }8673 8674 // Go through the Labels.8675 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {8676 Names.push_back(S->getLabelIdentifier(I));8677 8678 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(I));8679 if (Result.isInvalid())8680 return StmtError();8681 ExprsChanged |= Result.get() != S->getLabelExpr(I);8682 Exprs.push_back(Result.get());8683 }8684 8685 // Go through the clobbers.8686 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {8687 ExprResult Result = RebuildString(S->getClobberExpr(I));8688 if (Result.isInvalid())8689 return StmtError();8690 Clobbers.push_back(Result.get());8691 }8692 8693 ExprResult AsmString = RebuildString(S->getAsmStringExpr());8694 if (AsmString.isInvalid())8695 return StmtError();8696 8697 if (!getDerived().AlwaysRebuild() && !ExprsChanged)8698 return S;8699 8700 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),8701 S->isVolatile(), S->getNumOutputs(),8702 S->getNumInputs(), Names.data(),8703 Constraints, Exprs, AsmString.get(),8704 Clobbers, S->getNumLabels(),8705 S->getRParenLoc());8706}8707 8708template<typename Derived>8709StmtResult8710TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {8711 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());8712 8713 bool HadError = false, HadChange = false;8714 8715 ArrayRef<Expr*> SrcExprs = S->getAllExprs();8716 SmallVector<Expr*, 8> TransformedExprs;8717 TransformedExprs.reserve(SrcExprs.size());8718 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {8719 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);8720 if (!Result.isUsable()) {8721 HadError = true;8722 } else {8723 HadChange |= (Result.get() != SrcExprs[i]);8724 TransformedExprs.push_back(Result.get());8725 }8726 }8727 8728 if (HadError) return StmtError();8729 if (!HadChange && !getDerived().AlwaysRebuild())8730 return Owned(S);8731 8732 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),8733 AsmToks, S->getAsmString(),8734 S->getNumOutputs(), S->getNumInputs(),8735 S->getAllConstraints(), S->getClobbers(),8736 TransformedExprs, S->getEndLoc());8737}8738 8739// C++ Coroutines8740template<typename Derived>8741StmtResult8742TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {8743 auto *ScopeInfo = SemaRef.getCurFunction();8744 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);8745 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&8746 ScopeInfo->NeedsCoroutineSuspends &&8747 ScopeInfo->CoroutineSuspends.first == nullptr &&8748 ScopeInfo->CoroutineSuspends.second == nullptr &&8749 "expected clean scope info");8750 8751 // Set that we have (possibly-invalid) suspend points before we do anything8752 // that may fail.8753 ScopeInfo->setNeedsCoroutineSuspends(false);8754 8755 // We re-build the coroutine promise object (and the coroutine parameters its8756 // type and constructor depend on) based on the types used in our current8757 // function. We must do so, and set it on the current FunctionScopeInfo,8758 // before attempting to transform the other parts of the coroutine body8759 // statement, such as the implicit suspend statements (because those8760 // statements reference the FunctionScopeInfo::CoroutinePromise).8761 if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation()))8762 return StmtError();8763 auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation());8764 if (!Promise)8765 return StmtError();8766 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});8767 ScopeInfo->CoroutinePromise = Promise;8768 8769 // Transform the implicit coroutine statements constructed using dependent8770 // types during the previous parse: initial and final suspensions, the return8771 // object, and others. We also transform the coroutine function's body.8772 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());8773 if (InitSuspend.isInvalid())8774 return StmtError();8775 StmtResult FinalSuspend =8776 getDerived().TransformStmt(S->getFinalSuspendStmt());8777 if (FinalSuspend.isInvalid() ||8778 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend.get()))8779 return StmtError();8780 ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get());8781 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));8782 8783 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());8784 if (BodyRes.isInvalid())8785 return StmtError();8786 8787 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());8788 if (Builder.isInvalid())8789 return StmtError();8790 8791 Expr *ReturnObject = S->getReturnValueInit();8792 assert(ReturnObject && "the return object is expected to be valid");8793 ExprResult Res = getDerived().TransformInitializer(ReturnObject,8794 /*NoCopyInit*/ false);8795 if (Res.isInvalid())8796 return StmtError();8797 Builder.ReturnValue = Res.get();8798 8799 // If during the previous parse the coroutine still had a dependent promise8800 // statement, we may need to build some implicit coroutine statements8801 // (such as exception and fallthrough handlers) for the first time.8802 if (S->hasDependentPromiseType()) {8803 // We can only build these statements, however, if the current promise type8804 // is not dependent.8805 if (!Promise->getType()->isDependentType()) {8806 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&8807 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&8808 "these nodes should not have been built yet");8809 if (!Builder.buildDependentStatements())8810 return StmtError();8811 }8812 } else {8813 if (auto *OnFallthrough = S->getFallthroughHandler()) {8814 StmtResult Res = getDerived().TransformStmt(OnFallthrough);8815 if (Res.isInvalid())8816 return StmtError();8817 Builder.OnFallthrough = Res.get();8818 }8819 8820 if (auto *OnException = S->getExceptionHandler()) {8821 StmtResult Res = getDerived().TransformStmt(OnException);8822 if (Res.isInvalid())8823 return StmtError();8824 Builder.OnException = Res.get();8825 }8826 8827 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {8828 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);8829 if (Res.isInvalid())8830 return StmtError();8831 Builder.ReturnStmtOnAllocFailure = Res.get();8832 }8833 8834 // Transform any additional statements we may have already built8835 assert(S->getAllocate() && S->getDeallocate() &&8836 "allocation and deallocation calls must already be built");8837 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());8838 if (AllocRes.isInvalid())8839 return StmtError();8840 Builder.Allocate = AllocRes.get();8841 8842 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());8843 if (DeallocRes.isInvalid())8844 return StmtError();8845 Builder.Deallocate = DeallocRes.get();8846 8847 if (auto *ResultDecl = S->getResultDecl()) {8848 StmtResult Res = getDerived().TransformStmt(ResultDecl);8849 if (Res.isInvalid())8850 return StmtError();8851 Builder.ResultDecl = Res.get();8852 }8853 8854 if (auto *ReturnStmt = S->getReturnStmt()) {8855 StmtResult Res = getDerived().TransformStmt(ReturnStmt);8856 if (Res.isInvalid())8857 return StmtError();8858 Builder.ReturnStmt = Res.get();8859 }8860 }8861 8862 return getDerived().RebuildCoroutineBodyStmt(Builder);8863}8864 8865template<typename Derived>8866StmtResult8867TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {8868 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),8869 /*NotCopyInit*/false);8870 if (Result.isInvalid())8871 return StmtError();8872 8873 // Always rebuild; we don't know if this needs to be injected into a new8874 // context or if the promise type has changed.8875 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),8876 S->isImplicit());8877}8878 8879template <typename Derived>8880ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {8881 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),8882 /*NotCopyInit*/ false);8883 if (Operand.isInvalid())8884 return ExprError();8885 8886 // Rebuild the common-expr from the operand rather than transforming it8887 // separately.8888 8889 // FIXME: getCurScope() should not be used during template instantiation.8890 // We should pick up the set of unqualified lookup results for operator8891 // co_await during the initial parse.8892 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(8893 getSema().getCurScope(), E->getKeywordLoc());8894 8895 // Always rebuild; we don't know if this needs to be injected into a new8896 // context or if the promise type has changed.8897 return getDerived().RebuildCoawaitExpr(8898 E->getKeywordLoc(), Operand.get(),8899 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());8900}8901 8902template <typename Derived>8903ExprResult8904TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {8905 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),8906 /*NotCopyInit*/ false);8907 if (OperandResult.isInvalid())8908 return ExprError();8909 8910 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(8911 E->getOperatorCoawaitLookup());8912 8913 if (LookupResult.isInvalid())8914 return ExprError();8915 8916 // Always rebuild; we don't know if this needs to be injected into a new8917 // context or if the promise type has changed.8918 return getDerived().RebuildDependentCoawaitExpr(8919 E->getKeywordLoc(), OperandResult.get(),8920 cast<UnresolvedLookupExpr>(LookupResult.get()));8921}8922 8923template<typename Derived>8924ExprResult8925TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {8926 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),8927 /*NotCopyInit*/false);8928 if (Result.isInvalid())8929 return ExprError();8930 8931 // Always rebuild; we don't know if this needs to be injected into a new8932 // context or if the promise type has changed.8933 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());8934}8935 8936// Objective-C Statements.8937 8938template<typename Derived>8939StmtResult8940TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {8941 // Transform the body of the @try.8942 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());8943 if (TryBody.isInvalid())8944 return StmtError();8945 8946 // Transform the @catch statements (if present).8947 bool AnyCatchChanged = false;8948 SmallVector<Stmt*, 8> CatchStmts;8949 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {8950 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));8951 if (Catch.isInvalid())8952 return StmtError();8953 if (Catch.get() != S->getCatchStmt(I))8954 AnyCatchChanged = true;8955 CatchStmts.push_back(Catch.get());8956 }8957 8958 // Transform the @finally statement (if present).8959 StmtResult Finally;8960 if (S->getFinallyStmt()) {8961 Finally = getDerived().TransformStmt(S->getFinallyStmt());8962 if (Finally.isInvalid())8963 return StmtError();8964 }8965 8966 // If nothing changed, just retain this statement.8967 if (!getDerived().AlwaysRebuild() &&8968 TryBody.get() == S->getTryBody() &&8969 !AnyCatchChanged &&8970 Finally.get() == S->getFinallyStmt())8971 return S;8972 8973 // Build a new statement.8974 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),8975 CatchStmts, Finally.get());8976}8977 8978template<typename Derived>8979StmtResult8980TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {8981 // Transform the @catch parameter, if there is one.8982 VarDecl *Var = nullptr;8983 if (VarDecl *FromVar = S->getCatchParamDecl()) {8984 TypeSourceInfo *TSInfo = nullptr;8985 if (FromVar->getTypeSourceInfo()) {8986 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());8987 if (!TSInfo)8988 return StmtError();8989 }8990 8991 QualType T;8992 if (TSInfo)8993 T = TSInfo->getType();8994 else {8995 T = getDerived().TransformType(FromVar->getType());8996 if (T.isNull())8997 return StmtError();8998 }8999 9000 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);9001 if (!Var)9002 return StmtError();9003 }9004 9005 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());9006 if (Body.isInvalid())9007 return StmtError();9008 9009 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),9010 S->getRParenLoc(),9011 Var, Body.get());9012}9013 9014template<typename Derived>9015StmtResult9016TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {9017 // Transform the body.9018 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());9019 if (Body.isInvalid())9020 return StmtError();9021 9022 // If nothing changed, just retain this statement.9023 if (!getDerived().AlwaysRebuild() &&9024 Body.get() == S->getFinallyBody())9025 return S;9026 9027 // Build a new statement.9028 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),9029 Body.get());9030}9031 9032template<typename Derived>9033StmtResult9034TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {9035 ExprResult Operand;9036 if (S->getThrowExpr()) {9037 Operand = getDerived().TransformExpr(S->getThrowExpr());9038 if (Operand.isInvalid())9039 return StmtError();9040 }9041 9042 if (!getDerived().AlwaysRebuild() &&9043 Operand.get() == S->getThrowExpr())9044 return S;9045 9046 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());9047}9048 9049template<typename Derived>9050StmtResult9051TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(9052 ObjCAtSynchronizedStmt *S) {9053 // Transform the object we are locking.9054 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());9055 if (Object.isInvalid())9056 return StmtError();9057 Object =9058 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),9059 Object.get());9060 if (Object.isInvalid())9061 return StmtError();9062 9063 // Transform the body.9064 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());9065 if (Body.isInvalid())9066 return StmtError();9067 9068 // If nothing change, just retain the current statement.9069 if (!getDerived().AlwaysRebuild() &&9070 Object.get() == S->getSynchExpr() &&9071 Body.get() == S->getSynchBody())9072 return S;9073 9074 // Build a new statement.9075 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),9076 Object.get(), Body.get());9077}9078 9079template<typename Derived>9080StmtResult9081TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(9082 ObjCAutoreleasePoolStmt *S) {9083 // Transform the body.9084 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());9085 if (Body.isInvalid())9086 return StmtError();9087 9088 // If nothing changed, just retain this statement.9089 if (!getDerived().AlwaysRebuild() &&9090 Body.get() == S->getSubStmt())9091 return S;9092 9093 // Build a new statement.9094 return getDerived().RebuildObjCAutoreleasePoolStmt(9095 S->getAtLoc(), Body.get());9096}9097 9098template<typename Derived>9099StmtResult9100TreeTransform<Derived>::TransformObjCForCollectionStmt(9101 ObjCForCollectionStmt *S) {9102 // Transform the element statement.9103 StmtResult Element = getDerived().TransformStmt(9104 S->getElement(), StmtDiscardKind::NotDiscarded);9105 if (Element.isInvalid())9106 return StmtError();9107 9108 // Transform the collection expression.9109 ExprResult Collection = getDerived().TransformExpr(S->getCollection());9110 if (Collection.isInvalid())9111 return StmtError();9112 9113 // Transform the body.9114 StmtResult Body = getDerived().TransformStmt(S->getBody());9115 if (Body.isInvalid())9116 return StmtError();9117 9118 // If nothing changed, just retain this statement.9119 if (!getDerived().AlwaysRebuild() &&9120 Element.get() == S->getElement() &&9121 Collection.get() == S->getCollection() &&9122 Body.get() == S->getBody())9123 return S;9124 9125 // Build a new statement.9126 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),9127 Element.get(),9128 Collection.get(),9129 S->getRParenLoc(),9130 Body.get());9131}9132 9133template <typename Derived>9134StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {9135 // Transform the exception declaration, if any.9136 VarDecl *Var = nullptr;9137 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {9138 TypeSourceInfo *T =9139 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());9140 if (!T)9141 return StmtError();9142 9143 Var = getDerived().RebuildExceptionDecl(9144 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),9145 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());9146 if (!Var || Var->isInvalidDecl())9147 return StmtError();9148 }9149 9150 // Transform the actual exception handler.9151 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());9152 if (Handler.isInvalid())9153 return StmtError();9154 9155 if (!getDerived().AlwaysRebuild() && !Var &&9156 Handler.get() == S->getHandlerBlock())9157 return S;9158 9159 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());9160}9161 9162template <typename Derived>9163StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {9164 // Transform the try block itself.9165 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());9166 if (TryBlock.isInvalid())9167 return StmtError();9168 9169 // Transform the handlers.9170 bool HandlerChanged = false;9171 SmallVector<Stmt *, 8> Handlers;9172 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {9173 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I));9174 if (Handler.isInvalid())9175 return StmtError();9176 9177 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);9178 Handlers.push_back(Handler.getAs<Stmt>());9179 }9180 9181 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);9182 9183 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&9184 !HandlerChanged)9185 return S;9186 9187 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),9188 Handlers);9189}9190 9191template<typename Derived>9192StmtResult9193TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {9194 EnterExpressionEvaluationContext ForRangeInitContext(9195 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,9196 /*LambdaContextDecl=*/nullptr,9197 Sema::ExpressionEvaluationContextRecord::EK_Other,9198 getSema().getLangOpts().CPlusPlus23);9199 9200 // P2718R0 - Lifetime extension in range-based for loops.9201 if (getSema().getLangOpts().CPlusPlus23) {9202 auto &LastRecord = getSema().currentEvaluationContext();9203 LastRecord.InLifetimeExtendingContext = true;9204 LastRecord.RebuildDefaultArgOrDefaultInit = true;9205 }9206 StmtResult Init =9207 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();9208 if (Init.isInvalid())9209 return StmtError();9210 9211 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());9212 if (Range.isInvalid())9213 return StmtError();9214 9215 // Before c++23, ForRangeLifetimeExtendTemps should be empty.9216 assert(getSema().getLangOpts().CPlusPlus23 ||9217 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());9218 auto ForRangeLifetimeExtendTemps =9219 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;9220 9221 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());9222 if (Begin.isInvalid())9223 return StmtError();9224 StmtResult End = getDerived().TransformStmt(S->getEndStmt());9225 if (End.isInvalid())9226 return StmtError();9227 9228 ExprResult Cond = getDerived().TransformExpr(S->getCond());9229 if (Cond.isInvalid())9230 return StmtError();9231 if (Cond.get())9232 Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get());9233 if (Cond.isInvalid())9234 return StmtError();9235 if (Cond.get())9236 Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get());9237 9238 ExprResult Inc = getDerived().TransformExpr(S->getInc());9239 if (Inc.isInvalid())9240 return StmtError();9241 if (Inc.get())9242 Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get());9243 9244 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());9245 if (LoopVar.isInvalid())9246 return StmtError();9247 9248 StmtResult NewStmt = S;9249 if (getDerived().AlwaysRebuild() ||9250 Init.get() != S->getInit() ||9251 Range.get() != S->getRangeStmt() ||9252 Begin.get() != S->getBeginStmt() ||9253 End.get() != S->getEndStmt() ||9254 Cond.get() != S->getCond() ||9255 Inc.get() != S->getInc() ||9256 LoopVar.get() != S->getLoopVarStmt()) {9257 NewStmt = getDerived().RebuildCXXForRangeStmt(9258 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),9259 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),9260 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);9261 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {9262 // Might not have attached any initializer to the loop variable.9263 getSema().ActOnInitializerError(9264 cast<DeclStmt>(LoopVar.get())->getSingleDecl());9265 return StmtError();9266 }9267 }9268 9269 // OpenACC Restricts a while-loop inside of certain construct/clause9270 // combinations, so diagnose that here in OpenACC mode.9271 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};9272 SemaRef.OpenACC().ActOnRangeForStmtBegin(S->getBeginLoc(), S, NewStmt.get());9273 9274 StmtResult Body = getDerived().TransformStmt(S->getBody());9275 if (Body.isInvalid())9276 return StmtError();9277 9278 SemaRef.OpenACC().ActOnForStmtEnd(S->getBeginLoc(), Body);9279 9280 // Body has changed but we didn't rebuild the for-range statement. Rebuild9281 // it now so we have a new statement to attach the body to.9282 if (Body.get() != S->getBody() && NewStmt.get() == S) {9283 NewStmt = getDerived().RebuildCXXForRangeStmt(9284 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),9285 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),9286 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);9287 if (NewStmt.isInvalid())9288 return StmtError();9289 }9290 9291 if (NewStmt.get() == S)9292 return S;9293 9294 return FinishCXXForRangeStmt(NewStmt.get(), Body.get());9295}9296 9297template<typename Derived>9298StmtResult9299TreeTransform<Derived>::TransformMSDependentExistsStmt(9300 MSDependentExistsStmt *S) {9301 // Transform the nested-name-specifier, if any.9302 NestedNameSpecifierLoc QualifierLoc;9303 if (S->getQualifierLoc()) {9304 QualifierLoc9305 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());9306 if (!QualifierLoc)9307 return StmtError();9308 }9309 9310 // Transform the declaration name.9311 DeclarationNameInfo NameInfo = S->getNameInfo();9312 if (NameInfo.getName()) {9313 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);9314 if (!NameInfo.getName())9315 return StmtError();9316 }9317 9318 // Check whether anything changed.9319 if (!getDerived().AlwaysRebuild() &&9320 QualifierLoc == S->getQualifierLoc() &&9321 NameInfo.getName() == S->getNameInfo().getName())9322 return S;9323 9324 // Determine whether this name exists, if we can.9325 CXXScopeSpec SS;9326 SS.Adopt(QualifierLoc);9327 bool Dependent = false;9328 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {9329 case IfExistsResult::Exists:9330 if (S->isIfExists())9331 break;9332 9333 return new (getSema().Context) NullStmt(S->getKeywordLoc());9334 9335 case IfExistsResult::DoesNotExist:9336 if (S->isIfNotExists())9337 break;9338 9339 return new (getSema().Context) NullStmt(S->getKeywordLoc());9340 9341 case IfExistsResult::Dependent:9342 Dependent = true;9343 break;9344 9345 case IfExistsResult::Error:9346 return StmtError();9347 }9348 9349 // We need to continue with the instantiation, so do so now.9350 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());9351 if (SubStmt.isInvalid())9352 return StmtError();9353 9354 // If we have resolved the name, just transform to the substatement.9355 if (!Dependent)9356 return SubStmt;9357 9358 // The name is still dependent, so build a dependent expression again.9359 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),9360 S->isIfExists(),9361 QualifierLoc,9362 NameInfo,9363 SubStmt.get());9364}9365 9366template<typename Derived>9367ExprResult9368TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {9369 NestedNameSpecifierLoc QualifierLoc;9370 if (E->getQualifierLoc()) {9371 QualifierLoc9372 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());9373 if (!QualifierLoc)9374 return ExprError();9375 }9376 9377 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(9378 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));9379 if (!PD)9380 return ExprError();9381 9382 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());9383 if (Base.isInvalid())9384 return ExprError();9385 9386 return new (SemaRef.getASTContext())9387 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),9388 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,9389 QualifierLoc, E->getMemberLoc());9390}9391 9392template <typename Derived>9393ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(9394 MSPropertySubscriptExpr *E) {9395 auto BaseRes = getDerived().TransformExpr(E->getBase());9396 if (BaseRes.isInvalid())9397 return ExprError();9398 auto IdxRes = getDerived().TransformExpr(E->getIdx());9399 if (IdxRes.isInvalid())9400 return ExprError();9401 9402 if (!getDerived().AlwaysRebuild() &&9403 BaseRes.get() == E->getBase() &&9404 IdxRes.get() == E->getIdx())9405 return E;9406 9407 return getDerived().RebuildArraySubscriptExpr(9408 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());9409}9410 9411template <typename Derived>9412StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {9413 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());9414 if (TryBlock.isInvalid())9415 return StmtError();9416 9417 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());9418 if (Handler.isInvalid())9419 return StmtError();9420 9421 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&9422 Handler.get() == S->getHandler())9423 return S;9424 9425 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),9426 TryBlock.get(), Handler.get());9427}9428 9429template <typename Derived>9430StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {9431 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());9432 if (Block.isInvalid())9433 return StmtError();9434 9435 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());9436}9437 9438template <typename Derived>9439StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {9440 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());9441 if (FilterExpr.isInvalid())9442 return StmtError();9443 9444 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());9445 if (Block.isInvalid())9446 return StmtError();9447 9448 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),9449 Block.get());9450}9451 9452template <typename Derived>9453StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {9454 if (isa<SEHFinallyStmt>(Handler))9455 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));9456 else9457 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));9458}9459 9460template<typename Derived>9461StmtResult9462TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {9463 return S;9464}9465 9466//===----------------------------------------------------------------------===//9467// OpenMP directive transformation9468//===----------------------------------------------------------------------===//9469 9470template <typename Derived>9471StmtResult9472TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {9473 // OMPCanonicalLoops are eliminated during transformation, since they will be9474 // recomputed by semantic analysis of the associated OMPLoopBasedDirective9475 // after transformation.9476 return getDerived().TransformStmt(L->getLoopStmt());9477}9478 9479template <typename Derived>9480StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(9481 OMPExecutableDirective *D) {9482 9483 // Transform the clauses9484 llvm::SmallVector<OMPClause *, 16> TClauses;9485 ArrayRef<OMPClause *> Clauses = D->clauses();9486 TClauses.reserve(Clauses.size());9487 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();9488 I != E; ++I) {9489 if (*I) {9490 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());9491 OMPClause *Clause = getDerived().TransformOMPClause(*I);9492 getDerived().getSema().OpenMP().EndOpenMPClause();9493 if (Clause)9494 TClauses.push_back(Clause);9495 } else {9496 TClauses.push_back(nullptr);9497 }9498 }9499 StmtResult AssociatedStmt;9500 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {9501 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(9502 D->getDirectiveKind(),9503 /*CurScope=*/nullptr);9504 StmtResult Body;9505 {9506 Sema::CompoundScopeRAII CompoundScope(getSema());9507 Stmt *CS;9508 if (D->getDirectiveKind() == OMPD_atomic ||9509 D->getDirectiveKind() == OMPD_critical ||9510 D->getDirectiveKind() == OMPD_section ||9511 D->getDirectiveKind() == OMPD_master)9512 CS = D->getAssociatedStmt();9513 else9514 CS = D->getRawStmt();9515 Body = getDerived().TransformStmt(CS);9516 if (Body.isUsable() && isOpenMPLoopDirective(D->getDirectiveKind()) &&9517 getSema().getLangOpts().OpenMPIRBuilder)9518 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());9519 }9520 AssociatedStmt =9521 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);9522 if (AssociatedStmt.isInvalid()) {9523 return StmtError();9524 }9525 }9526 if (TClauses.size() != Clauses.size()) {9527 return StmtError();9528 }9529 9530 // Transform directive name for 'omp critical' directive.9531 DeclarationNameInfo DirName;9532 if (D->getDirectiveKind() == OMPD_critical) {9533 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();9534 DirName = getDerived().TransformDeclarationNameInfo(DirName);9535 }9536 OpenMPDirectiveKind CancelRegion = OMPD_unknown;9537 if (D->getDirectiveKind() == OMPD_cancellation_point) {9538 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();9539 } else if (D->getDirectiveKind() == OMPD_cancel) {9540 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();9541 }9542 9543 return getDerived().RebuildOMPExecutableDirective(9544 D->getDirectiveKind(), DirName, CancelRegion, TClauses,9545 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());9546}9547 9548/// This is mostly the same as above, but allows 'informational' class9549/// directives when rebuilding the stmt. It still takes an9550/// OMPExecutableDirective-type argument because we're reusing that as the9551/// superclass for the 'assume' directive at present, instead of defining a9552/// mostly-identical OMPInformationalDirective parent class.9553template <typename Derived>9554StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(9555 OMPExecutableDirective *D) {9556 9557 // Transform the clauses9558 llvm::SmallVector<OMPClause *, 16> TClauses;9559 ArrayRef<OMPClause *> Clauses = D->clauses();9560 TClauses.reserve(Clauses.size());9561 for (OMPClause *C : Clauses) {9562 if (C) {9563 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());9564 OMPClause *Clause = getDerived().TransformOMPClause(C);9565 getDerived().getSema().OpenMP().EndOpenMPClause();9566 if (Clause)9567 TClauses.push_back(Clause);9568 } else {9569 TClauses.push_back(nullptr);9570 }9571 }9572 StmtResult AssociatedStmt;9573 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {9574 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(9575 D->getDirectiveKind(),9576 /*CurScope=*/nullptr);9577 StmtResult Body;9578 {9579 Sema::CompoundScopeRAII CompoundScope(getSema());9580 assert(D->getDirectiveKind() == OMPD_assume &&9581 "Unexpected informational directive");9582 Stmt *CS = D->getAssociatedStmt();9583 Body = getDerived().TransformStmt(CS);9584 }9585 AssociatedStmt =9586 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);9587 if (AssociatedStmt.isInvalid())9588 return StmtError();9589 }9590 if (TClauses.size() != Clauses.size())9591 return StmtError();9592 9593 DeclarationNameInfo DirName;9594 9595 return getDerived().RebuildOMPInformationalDirective(9596 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),9597 D->getBeginLoc(), D->getEndLoc());9598}9599 9600template <typename Derived>9601StmtResult9602TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {9603 // TODO: Fix This9604 unsigned OMPVersion = getDerived().getSema().getLangOpts().OpenMP;9605 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)9606 << getOpenMPDirectiveName(D->getDirectiveKind(), OMPVersion);9607 return StmtError();9608}9609 9610template <typename Derived>9611StmtResult9612TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {9613 DeclarationNameInfo DirName;9614 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9615 OMPD_parallel, DirName, nullptr, D->getBeginLoc());9616 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9617 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9618 return Res;9619}9620 9621template <typename Derived>9622StmtResult9623TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {9624 DeclarationNameInfo DirName;9625 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9626 OMPD_simd, DirName, nullptr, D->getBeginLoc());9627 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9628 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9629 return Res;9630}9631 9632template <typename Derived>9633StmtResult9634TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {9635 DeclarationNameInfo DirName;9636 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9637 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());9638 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9639 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9640 return Res;9641}9642 9643template <typename Derived>9644StmtResult9645TreeTransform<Derived>::TransformOMPStripeDirective(OMPStripeDirective *D) {9646 DeclarationNameInfo DirName;9647 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9648 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());9649 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9650 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9651 return Res;9652}9653 9654template <typename Derived>9655StmtResult9656TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {9657 DeclarationNameInfo DirName;9658 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9659 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());9660 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9661 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9662 return Res;9663}9664 9665template <typename Derived>9666StmtResult9667TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {9668 DeclarationNameInfo DirName;9669 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9670 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());9671 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9672 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9673 return Res;9674}9675 9676template <typename Derived>9677StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(9678 OMPInterchangeDirective *D) {9679 DeclarationNameInfo DirName;9680 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9681 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());9682 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9683 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9684 return Res;9685}9686 9687template <typename Derived>9688StmtResult9689TreeTransform<Derived>::TransformOMPFuseDirective(OMPFuseDirective *D) {9690 DeclarationNameInfo DirName;9691 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9692 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());9693 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9694 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9695 return Res;9696}9697 9698template <typename Derived>9699StmtResult9700TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {9701 DeclarationNameInfo DirName;9702 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9703 OMPD_for, DirName, nullptr, D->getBeginLoc());9704 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9705 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9706 return Res;9707}9708 9709template <typename Derived>9710StmtResult9711TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {9712 DeclarationNameInfo DirName;9713 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9714 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());9715 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9716 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9717 return Res;9718}9719 9720template <typename Derived>9721StmtResult9722TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {9723 DeclarationNameInfo DirName;9724 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9725 OMPD_sections, DirName, nullptr, D->getBeginLoc());9726 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9727 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9728 return Res;9729}9730 9731template <typename Derived>9732StmtResult9733TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {9734 DeclarationNameInfo DirName;9735 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9736 OMPD_section, DirName, nullptr, D->getBeginLoc());9737 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9738 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9739 return Res;9740}9741 9742template <typename Derived>9743StmtResult9744TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {9745 DeclarationNameInfo DirName;9746 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9747 OMPD_scope, DirName, nullptr, D->getBeginLoc());9748 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9749 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9750 return Res;9751}9752 9753template <typename Derived>9754StmtResult9755TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {9756 DeclarationNameInfo DirName;9757 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9758 OMPD_single, DirName, nullptr, D->getBeginLoc());9759 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9760 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9761 return Res;9762}9763 9764template <typename Derived>9765StmtResult9766TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {9767 DeclarationNameInfo DirName;9768 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9769 OMPD_master, DirName, nullptr, D->getBeginLoc());9770 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9771 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9772 return Res;9773}9774 9775template <typename Derived>9776StmtResult9777TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {9778 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9779 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());9780 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9781 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9782 return Res;9783}9784 9785template <typename Derived>9786StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(9787 OMPParallelForDirective *D) {9788 DeclarationNameInfo DirName;9789 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9790 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());9791 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9792 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9793 return Res;9794}9795 9796template <typename Derived>9797StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(9798 OMPParallelForSimdDirective *D) {9799 DeclarationNameInfo DirName;9800 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9801 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());9802 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9803 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9804 return Res;9805}9806 9807template <typename Derived>9808StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(9809 OMPParallelMasterDirective *D) {9810 DeclarationNameInfo DirName;9811 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9812 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());9813 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9814 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9815 return Res;9816}9817 9818template <typename Derived>9819StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(9820 OMPParallelMaskedDirective *D) {9821 DeclarationNameInfo DirName;9822 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9823 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());9824 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9825 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9826 return Res;9827}9828 9829template <typename Derived>9830StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(9831 OMPParallelSectionsDirective *D) {9832 DeclarationNameInfo DirName;9833 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9834 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());9835 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9836 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9837 return Res;9838}9839 9840template <typename Derived>9841StmtResult9842TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {9843 DeclarationNameInfo DirName;9844 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9845 OMPD_task, DirName, nullptr, D->getBeginLoc());9846 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9847 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9848 return Res;9849}9850 9851template <typename Derived>9852StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(9853 OMPTaskyieldDirective *D) {9854 DeclarationNameInfo DirName;9855 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9856 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());9857 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9858 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9859 return Res;9860}9861 9862template <typename Derived>9863StmtResult9864TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {9865 DeclarationNameInfo DirName;9866 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9867 OMPD_barrier, DirName, nullptr, D->getBeginLoc());9868 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9869 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9870 return Res;9871}9872 9873template <typename Derived>9874StmtResult9875TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {9876 DeclarationNameInfo DirName;9877 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9878 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());9879 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9880 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9881 return Res;9882}9883 9884template <typename Derived>9885StmtResult9886TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {9887 DeclarationNameInfo DirName;9888 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9889 OMPD_assume, DirName, nullptr, D->getBeginLoc());9890 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);9891 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9892 return Res;9893}9894 9895template <typename Derived>9896StmtResult9897TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {9898 DeclarationNameInfo DirName;9899 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9900 OMPD_error, DirName, nullptr, D->getBeginLoc());9901 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9902 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9903 return Res;9904}9905 9906template <typename Derived>9907StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(9908 OMPTaskgroupDirective *D) {9909 DeclarationNameInfo DirName;9910 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9911 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());9912 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9913 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9914 return Res;9915}9916 9917template <typename Derived>9918StmtResult9919TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {9920 DeclarationNameInfo DirName;9921 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9922 OMPD_flush, DirName, nullptr, D->getBeginLoc());9923 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9924 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9925 return Res;9926}9927 9928template <typename Derived>9929StmtResult9930TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {9931 DeclarationNameInfo DirName;9932 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9933 OMPD_depobj, DirName, nullptr, D->getBeginLoc());9934 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9935 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9936 return Res;9937}9938 9939template <typename Derived>9940StmtResult9941TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {9942 DeclarationNameInfo DirName;9943 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9944 OMPD_scan, DirName, nullptr, D->getBeginLoc());9945 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9946 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9947 return Res;9948}9949 9950template <typename Derived>9951StmtResult9952TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {9953 DeclarationNameInfo DirName;9954 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9955 OMPD_ordered, DirName, nullptr, D->getBeginLoc());9956 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9957 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9958 return Res;9959}9960 9961template <typename Derived>9962StmtResult9963TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {9964 DeclarationNameInfo DirName;9965 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9966 OMPD_atomic, DirName, nullptr, D->getBeginLoc());9967 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9968 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9969 return Res;9970}9971 9972template <typename Derived>9973StmtResult9974TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {9975 DeclarationNameInfo DirName;9976 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9977 OMPD_target, DirName, nullptr, D->getBeginLoc());9978 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9979 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9980 return Res;9981}9982 9983template <typename Derived>9984StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(9985 OMPTargetDataDirective *D) {9986 DeclarationNameInfo DirName;9987 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9988 OMPD_target_data, DirName, nullptr, D->getBeginLoc());9989 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);9990 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());9991 return Res;9992}9993 9994template <typename Derived>9995StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(9996 OMPTargetEnterDataDirective *D) {9997 DeclarationNameInfo DirName;9998 getDerived().getSema().OpenMP().StartOpenMPDSABlock(9999 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());10000 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10001 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10002 return Res;10003}10004 10005template <typename Derived>10006StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(10007 OMPTargetExitDataDirective *D) {10008 DeclarationNameInfo DirName;10009 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10010 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());10011 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10012 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10013 return Res;10014}10015 10016template <typename Derived>10017StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(10018 OMPTargetParallelDirective *D) {10019 DeclarationNameInfo DirName;10020 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10021 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());10022 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10023 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10024 return Res;10025}10026 10027template <typename Derived>10028StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(10029 OMPTargetParallelForDirective *D) {10030 DeclarationNameInfo DirName;10031 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10032 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());10033 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10034 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10035 return Res;10036}10037 10038template <typename Derived>10039StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(10040 OMPTargetUpdateDirective *D) {10041 DeclarationNameInfo DirName;10042 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10043 OMPD_target_update, DirName, nullptr, D->getBeginLoc());10044 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10045 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10046 return Res;10047}10048 10049template <typename Derived>10050StmtResult10051TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {10052 DeclarationNameInfo DirName;10053 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10054 OMPD_teams, DirName, nullptr, D->getBeginLoc());10055 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10056 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10057 return Res;10058}10059 10060template <typename Derived>10061StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(10062 OMPCancellationPointDirective *D) {10063 DeclarationNameInfo DirName;10064 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10065 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());10066 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10067 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10068 return Res;10069}10070 10071template <typename Derived>10072StmtResult10073TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {10074 DeclarationNameInfo DirName;10075 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10076 OMPD_cancel, DirName, nullptr, D->getBeginLoc());10077 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10078 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10079 return Res;10080}10081 10082template <typename Derived>10083StmtResult10084TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {10085 DeclarationNameInfo DirName;10086 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10087 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());10088 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10089 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10090 return Res;10091}10092 10093template <typename Derived>10094StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(10095 OMPTaskLoopSimdDirective *D) {10096 DeclarationNameInfo DirName;10097 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10098 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());10099 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10100 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10101 return Res;10102}10103 10104template <typename Derived>10105StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(10106 OMPMasterTaskLoopDirective *D) {10107 DeclarationNameInfo DirName;10108 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10109 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());10110 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10111 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10112 return Res;10113}10114 10115template <typename Derived>10116StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(10117 OMPMaskedTaskLoopDirective *D) {10118 DeclarationNameInfo DirName;10119 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10120 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());10121 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10122 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10123 return Res;10124}10125 10126template <typename Derived>10127StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(10128 OMPMasterTaskLoopSimdDirective *D) {10129 DeclarationNameInfo DirName;10130 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10131 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());10132 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10133 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10134 return Res;10135}10136 10137template <typename Derived>10138StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(10139 OMPMaskedTaskLoopSimdDirective *D) {10140 DeclarationNameInfo DirName;10141 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10142 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());10143 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10144 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10145 return Res;10146}10147 10148template <typename Derived>10149StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(10150 OMPParallelMasterTaskLoopDirective *D) {10151 DeclarationNameInfo DirName;10152 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10153 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());10154 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10155 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10156 return Res;10157}10158 10159template <typename Derived>10160StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(10161 OMPParallelMaskedTaskLoopDirective *D) {10162 DeclarationNameInfo DirName;10163 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10164 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());10165 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10166 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10167 return Res;10168}10169 10170template <typename Derived>10171StmtResult10172TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(10173 OMPParallelMasterTaskLoopSimdDirective *D) {10174 DeclarationNameInfo DirName;10175 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10176 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());10177 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10178 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10179 return Res;10180}10181 10182template <typename Derived>10183StmtResult10184TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(10185 OMPParallelMaskedTaskLoopSimdDirective *D) {10186 DeclarationNameInfo DirName;10187 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10188 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());10189 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10190 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10191 return Res;10192}10193 10194template <typename Derived>10195StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(10196 OMPDistributeDirective *D) {10197 DeclarationNameInfo DirName;10198 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10199 OMPD_distribute, DirName, nullptr, D->getBeginLoc());10200 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10201 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10202 return Res;10203}10204 10205template <typename Derived>10206StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(10207 OMPDistributeParallelForDirective *D) {10208 DeclarationNameInfo DirName;10209 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10210 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());10211 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10212 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10213 return Res;10214}10215 10216template <typename Derived>10217StmtResult10218TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(10219 OMPDistributeParallelForSimdDirective *D) {10220 DeclarationNameInfo DirName;10221 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10222 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());10223 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10224 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10225 return Res;10226}10227 10228template <typename Derived>10229StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(10230 OMPDistributeSimdDirective *D) {10231 DeclarationNameInfo DirName;10232 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10233 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());10234 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10235 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10236 return Res;10237}10238 10239template <typename Derived>10240StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(10241 OMPTargetParallelForSimdDirective *D) {10242 DeclarationNameInfo DirName;10243 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10244 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());10245 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10246 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10247 return Res;10248}10249 10250template <typename Derived>10251StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(10252 OMPTargetSimdDirective *D) {10253 DeclarationNameInfo DirName;10254 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10255 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());10256 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10257 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10258 return Res;10259}10260 10261template <typename Derived>10262StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(10263 OMPTeamsDistributeDirective *D) {10264 DeclarationNameInfo DirName;10265 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10266 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());10267 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10268 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10269 return Res;10270}10271 10272template <typename Derived>10273StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(10274 OMPTeamsDistributeSimdDirective *D) {10275 DeclarationNameInfo DirName;10276 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10277 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());10278 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10279 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10280 return Res;10281}10282 10283template <typename Derived>10284StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(10285 OMPTeamsDistributeParallelForSimdDirective *D) {10286 DeclarationNameInfo DirName;10287 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10288 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,10289 D->getBeginLoc());10290 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10291 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10292 return Res;10293}10294 10295template <typename Derived>10296StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(10297 OMPTeamsDistributeParallelForDirective *D) {10298 DeclarationNameInfo DirName;10299 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10300 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());10301 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10302 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10303 return Res;10304}10305 10306template <typename Derived>10307StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(10308 OMPTargetTeamsDirective *D) {10309 DeclarationNameInfo DirName;10310 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10311 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());10312 auto Res = getDerived().TransformOMPExecutableDirective(D);10313 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10314 return Res;10315}10316 10317template <typename Derived>10318StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(10319 OMPTargetTeamsDistributeDirective *D) {10320 DeclarationNameInfo DirName;10321 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10322 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());10323 auto Res = getDerived().TransformOMPExecutableDirective(D);10324 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10325 return Res;10326}10327 10328template <typename Derived>10329StmtResult10330TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(10331 OMPTargetTeamsDistributeParallelForDirective *D) {10332 DeclarationNameInfo DirName;10333 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10334 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,10335 D->getBeginLoc());10336 auto Res = getDerived().TransformOMPExecutableDirective(D);10337 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10338 return Res;10339}10340 10341template <typename Derived>10342StmtResult TreeTransform<Derived>::10343 TransformOMPTargetTeamsDistributeParallelForSimdDirective(10344 OMPTargetTeamsDistributeParallelForSimdDirective *D) {10345 DeclarationNameInfo DirName;10346 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10347 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,10348 D->getBeginLoc());10349 auto Res = getDerived().TransformOMPExecutableDirective(D);10350 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10351 return Res;10352}10353 10354template <typename Derived>10355StmtResult10356TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(10357 OMPTargetTeamsDistributeSimdDirective *D) {10358 DeclarationNameInfo DirName;10359 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10360 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());10361 auto Res = getDerived().TransformOMPExecutableDirective(D);10362 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10363 return Res;10364}10365 10366template <typename Derived>10367StmtResult10368TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {10369 DeclarationNameInfo DirName;10370 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10371 OMPD_interop, DirName, nullptr, D->getBeginLoc());10372 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10373 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10374 return Res;10375}10376 10377template <typename Derived>10378StmtResult10379TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {10380 DeclarationNameInfo DirName;10381 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10382 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());10383 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10384 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10385 return Res;10386}10387 10388template <typename Derived>10389StmtResult10390TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {10391 DeclarationNameInfo DirName;10392 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10393 OMPD_masked, DirName, nullptr, D->getBeginLoc());10394 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10395 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10396 return Res;10397}10398 10399template <typename Derived>10400StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(10401 OMPGenericLoopDirective *D) {10402 DeclarationNameInfo DirName;10403 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10404 OMPD_loop, DirName, nullptr, D->getBeginLoc());10405 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10406 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10407 return Res;10408}10409 10410template <typename Derived>10411StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(10412 OMPTeamsGenericLoopDirective *D) {10413 DeclarationNameInfo DirName;10414 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10415 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());10416 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10417 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10418 return Res;10419}10420 10421template <typename Derived>10422StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(10423 OMPTargetTeamsGenericLoopDirective *D) {10424 DeclarationNameInfo DirName;10425 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10426 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());10427 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10428 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10429 return Res;10430}10431 10432template <typename Derived>10433StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(10434 OMPParallelGenericLoopDirective *D) {10435 DeclarationNameInfo DirName;10436 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10437 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());10438 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10439 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10440 return Res;10441}10442 10443template <typename Derived>10444StmtResult10445TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(10446 OMPTargetParallelGenericLoopDirective *D) {10447 DeclarationNameInfo DirName;10448 getDerived().getSema().OpenMP().StartOpenMPDSABlock(10449 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());10450 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);10451 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());10452 return Res;10453}10454 10455//===----------------------------------------------------------------------===//10456// OpenMP clause transformation10457//===----------------------------------------------------------------------===//10458template <typename Derived>10459OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {10460 ExprResult Cond = getDerived().TransformExpr(C->getCondition());10461 if (Cond.isInvalid())10462 return nullptr;10463 return getDerived().RebuildOMPIfClause(10464 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),10465 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());10466}10467 10468template <typename Derived>10469OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {10470 ExprResult Cond = getDerived().TransformExpr(C->getCondition());10471 if (Cond.isInvalid())10472 return nullptr;10473 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),10474 C->getLParenLoc(), C->getEndLoc());10475}10476 10477template <typename Derived>10478OMPClause *10479TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {10480 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());10481 if (NumThreads.isInvalid())10482 return nullptr;10483 return getDerived().RebuildOMPNumThreadsClause(10484 C->getModifier(), NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(),10485 C->getModifierLoc(), C->getEndLoc());10486}10487 10488template <typename Derived>10489OMPClause *10490TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {10491 ExprResult E = getDerived().TransformExpr(C->getSafelen());10492 if (E.isInvalid())10493 return nullptr;10494 return getDerived().RebuildOMPSafelenClause(10495 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());10496}10497 10498template <typename Derived>10499OMPClause *10500TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {10501 ExprResult E = getDerived().TransformExpr(C->getAllocator());10502 if (E.isInvalid())10503 return nullptr;10504 return getDerived().RebuildOMPAllocatorClause(10505 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());10506}10507 10508template <typename Derived>10509OMPClause *10510TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {10511 ExprResult E = getDerived().TransformExpr(C->getSimdlen());10512 if (E.isInvalid())10513 return nullptr;10514 return getDerived().RebuildOMPSimdlenClause(10515 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());10516}10517 10518template <typename Derived>10519OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {10520 SmallVector<Expr *, 4> TransformedSizes;10521 TransformedSizes.reserve(C->getNumSizes());10522 bool Changed = false;10523 for (Expr *E : C->getSizesRefs()) {10524 if (!E) {10525 TransformedSizes.push_back(nullptr);10526 continue;10527 }10528 10529 ExprResult T = getDerived().TransformExpr(E);10530 if (T.isInvalid())10531 return nullptr;10532 if (E != T.get())10533 Changed = true;10534 TransformedSizes.push_back(T.get());10535 }10536 10537 if (!Changed && !getDerived().AlwaysRebuild())10538 return C;10539 return RebuildOMPSizesClause(TransformedSizes, C->getBeginLoc(),10540 C->getLParenLoc(), C->getEndLoc());10541}10542 10543template <typename Derived>10544OMPClause *10545TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {10546 SmallVector<Expr *> TransformedArgs;10547 TransformedArgs.reserve(C->getNumLoops());10548 bool Changed = false;10549 for (Expr *E : C->getArgsRefs()) {10550 if (!E) {10551 TransformedArgs.push_back(nullptr);10552 continue;10553 }10554 10555 ExprResult T = getDerived().TransformExpr(E);10556 if (T.isInvalid())10557 return nullptr;10558 if (E != T.get())10559 Changed = true;10560 TransformedArgs.push_back(T.get());10561 }10562 10563 if (!Changed && !getDerived().AlwaysRebuild())10564 return C;10565 return RebuildOMPPermutationClause(TransformedArgs, C->getBeginLoc(),10566 C->getLParenLoc(), C->getEndLoc());10567}10568 10569template <typename Derived>10570OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {10571 if (!getDerived().AlwaysRebuild())10572 return C;10573 return RebuildOMPFullClause(C->getBeginLoc(), C->getEndLoc());10574}10575 10576template <typename Derived>10577OMPClause *10578TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {10579 ExprResult T = getDerived().TransformExpr(C->getFactor());10580 if (T.isInvalid())10581 return nullptr;10582 Expr *Factor = T.get();10583 bool Changed = Factor != C->getFactor();10584 10585 if (!Changed && !getDerived().AlwaysRebuild())10586 return C;10587 return RebuildOMPPartialClause(Factor, C->getBeginLoc(), C->getLParenLoc(),10588 C->getEndLoc());10589}10590 10591template <typename Derived>10592OMPClause *10593TreeTransform<Derived>::TransformOMPLoopRangeClause(OMPLoopRangeClause *C) {10594 ExprResult F = getDerived().TransformExpr(C->getFirst());10595 if (F.isInvalid())10596 return nullptr;10597 10598 ExprResult Cn = getDerived().TransformExpr(C->getCount());10599 if (Cn.isInvalid())10600 return nullptr;10601 10602 Expr *First = F.get();10603 Expr *Count = Cn.get();10604 10605 bool Changed = (First != C->getFirst()) || (Count != C->getCount());10606 10607 // If no changes and AlwaysRebuild() is false, return the original clause10608 if (!Changed && !getDerived().AlwaysRebuild())10609 return C;10610 10611 return RebuildOMPLoopRangeClause(First, Count, C->getBeginLoc(),10612 C->getLParenLoc(), C->getFirstLoc(),10613 C->getCountLoc(), C->getEndLoc());10614}10615 10616template <typename Derived>10617OMPClause *10618TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {10619 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());10620 if (E.isInvalid())10621 return nullptr;10622 return getDerived().RebuildOMPCollapseClause(10623 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());10624}10625 10626template <typename Derived>10627OMPClause *10628TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {10629 return getDerived().RebuildOMPDefaultClause(10630 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getDefaultVC(),10631 C->getDefaultVCLoc(), C->getBeginLoc(), C->getLParenLoc(),10632 C->getEndLoc());10633}10634 10635template <typename Derived>10636OMPClause *10637TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {10638 // No need to rebuild this clause, no template-dependent parameters.10639 return C;10640}10641 10642template <typename Derived>10643OMPClause *10644TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {10645 return getDerived().RebuildOMPProcBindClause(10646 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),10647 C->getLParenLoc(), C->getEndLoc());10648}10649 10650template <typename Derived>10651OMPClause *10652TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {10653 ExprResult E = getDerived().TransformExpr(C->getChunkSize());10654 if (E.isInvalid())10655 return nullptr;10656 return getDerived().RebuildOMPScheduleClause(10657 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),10658 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),10659 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),10660 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());10661}10662 10663template <typename Derived>10664OMPClause *10665TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {10666 ExprResult E;10667 if (auto *Num = C->getNumForLoops()) {10668 E = getDerived().TransformExpr(Num);10669 if (E.isInvalid())10670 return nullptr;10671 }10672 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),10673 C->getLParenLoc(), E.get());10674}10675 10676template <typename Derived>10677OMPClause *10678TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {10679 ExprResult E;10680 if (Expr *Evt = C->getEventHandler()) {10681 E = getDerived().TransformExpr(Evt);10682 if (E.isInvalid())10683 return nullptr;10684 }10685 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),10686 C->getLParenLoc(), C->getEndLoc());10687}10688 10689template <typename Derived>10690OMPClause *10691TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {10692 ExprResult Cond;10693 if (auto *Condition = C->getCondition()) {10694 Cond = getDerived().TransformExpr(Condition);10695 if (Cond.isInvalid())10696 return nullptr;10697 }10698 return getDerived().RebuildOMPNowaitClause(Cond.get(), C->getBeginLoc(),10699 C->getLParenLoc(), C->getEndLoc());10700}10701 10702template <typename Derived>10703OMPClause *10704TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {10705 // No need to rebuild this clause, no template-dependent parameters.10706 return C;10707}10708 10709template <typename Derived>10710OMPClause *10711TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {10712 // No need to rebuild this clause, no template-dependent parameters.10713 return C;10714}10715 10716template <typename Derived>10717OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {10718 // No need to rebuild this clause, no template-dependent parameters.10719 return C;10720}10721 10722template <typename Derived>10723OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {10724 // No need to rebuild this clause, no template-dependent parameters.10725 return C;10726}10727 10728template <typename Derived>10729OMPClause *10730TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {10731 // No need to rebuild this clause, no template-dependent parameters.10732 return C;10733}10734 10735template <typename Derived>10736OMPClause *10737TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {10738 // No need to rebuild this clause, no template-dependent parameters.10739 return C;10740}10741 10742template <typename Derived>10743OMPClause *10744TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {10745 // No need to rebuild this clause, no template-dependent parameters.10746 return C;10747}10748 10749template <typename Derived>10750OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {10751 // No need to rebuild this clause, no template-dependent parameters.10752 return C;10753}10754 10755template <typename Derived>10756OMPClause *10757TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {10758 return C;10759}10760 10761template <typename Derived>10762OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {10763 ExprResult E = getDerived().TransformExpr(C->getExpr());10764 if (E.isInvalid())10765 return nullptr;10766 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),10767 C->getLParenLoc(), C->getEndLoc());10768}10769 10770template <typename Derived>10771OMPClause *10772TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {10773 return C;10774}10775 10776template <typename Derived>10777OMPClause *10778TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {10779 return C;10780}10781template <typename Derived>10782OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(10783 OMPNoOpenMPRoutinesClause *C) {10784 return C;10785}10786template <typename Derived>10787OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(10788 OMPNoOpenMPConstructsClause *C) {10789 return C;10790}10791template <typename Derived>10792OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(10793 OMPNoParallelismClause *C) {10794 return C;10795}10796 10797template <typename Derived>10798OMPClause *10799TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {10800 // No need to rebuild this clause, no template-dependent parameters.10801 return C;10802}10803 10804template <typename Derived>10805OMPClause *10806TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {10807 // No need to rebuild this clause, no template-dependent parameters.10808 return C;10809}10810 10811template <typename Derived>10812OMPClause *10813TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {10814 // No need to rebuild this clause, no template-dependent parameters.10815 return C;10816}10817 10818template <typename Derived>10819OMPClause *10820TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {10821 // No need to rebuild this clause, no template-dependent parameters.10822 return C;10823}10824 10825template <typename Derived>10826OMPClause *10827TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {10828 // No need to rebuild this clause, no template-dependent parameters.10829 return C;10830}10831 10832template <typename Derived>10833OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {10834 // No need to rebuild this clause, no template-dependent parameters.10835 return C;10836}10837 10838template <typename Derived>10839OMPClause *10840TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {10841 // No need to rebuild this clause, no template-dependent parameters.10842 return C;10843}10844 10845template <typename Derived>10846OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {10847 // No need to rebuild this clause, no template-dependent parameters.10848 return C;10849}10850 10851template <typename Derived>10852OMPClause *10853TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {10854 // No need to rebuild this clause, no template-dependent parameters.10855 return C;10856}10857 10858template <typename Derived>10859OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {10860 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());10861 if (IVR.isInvalid())10862 return nullptr;10863 10864 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());10865 InteropInfo.PreferTypes.reserve(C->varlist_size() - 1);10866 for (Expr *E : llvm::drop_begin(C->varlist())) {10867 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));10868 if (ER.isInvalid())10869 return nullptr;10870 InteropInfo.PreferTypes.push_back(ER.get());10871 }10872 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,10873 C->getBeginLoc(), C->getLParenLoc(),10874 C->getVarLoc(), C->getEndLoc());10875}10876 10877template <typename Derived>10878OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {10879 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());10880 if (ER.isInvalid())10881 return nullptr;10882 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),10883 C->getLParenLoc(), C->getVarLoc(),10884 C->getEndLoc());10885}10886 10887template <typename Derived>10888OMPClause *10889TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {10890 ExprResult ER;10891 if (Expr *IV = C->getInteropVar()) {10892 ER = getDerived().TransformExpr(IV);10893 if (ER.isInvalid())10894 return nullptr;10895 }10896 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),10897 C->getLParenLoc(), C->getVarLoc(),10898 C->getEndLoc());10899}10900 10901template <typename Derived>10902OMPClause *10903TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {10904 ExprResult Cond = getDerived().TransformExpr(C->getCondition());10905 if (Cond.isInvalid())10906 return nullptr;10907 return getDerived().RebuildOMPNovariantsClause(10908 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());10909}10910 10911template <typename Derived>10912OMPClause *10913TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {10914 ExprResult Cond = getDerived().TransformExpr(C->getCondition());10915 if (Cond.isInvalid())10916 return nullptr;10917 return getDerived().RebuildOMPNocontextClause(10918 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());10919}10920 10921template <typename Derived>10922OMPClause *10923TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {10924 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());10925 if (ThreadID.isInvalid())10926 return nullptr;10927 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),10928 C->getLParenLoc(), C->getEndLoc());10929}10930 10931template <typename Derived>10932OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {10933 ExprResult E = getDerived().TransformExpr(C->getAlignment());10934 if (E.isInvalid())10935 return nullptr;10936 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),10937 C->getLParenLoc(), C->getEndLoc());10938}10939 10940template <typename Derived>10941OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(10942 OMPUnifiedAddressClause *C) {10943 llvm_unreachable("unified_address clause cannot appear in dependent context");10944}10945 10946template <typename Derived>10947OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(10948 OMPUnifiedSharedMemoryClause *C) {10949 llvm_unreachable(10950 "unified_shared_memory clause cannot appear in dependent context");10951}10952 10953template <typename Derived>10954OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(10955 OMPReverseOffloadClause *C) {10956 llvm_unreachable("reverse_offload clause cannot appear in dependent context");10957}10958 10959template <typename Derived>10960OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(10961 OMPDynamicAllocatorsClause *C) {10962 llvm_unreachable(10963 "dynamic_allocators clause cannot appear in dependent context");10964}10965 10966template <typename Derived>10967OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(10968 OMPAtomicDefaultMemOrderClause *C) {10969 llvm_unreachable(10970 "atomic_default_mem_order clause cannot appear in dependent context");10971}10972 10973template <typename Derived>10974OMPClause *10975TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {10976 llvm_unreachable("self_maps clause cannot appear in dependent context");10977}10978 10979template <typename Derived>10980OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {10981 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),10982 C->getBeginLoc(), C->getLParenLoc(),10983 C->getEndLoc());10984}10985 10986template <typename Derived>10987OMPClause *10988TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {10989 return getDerived().RebuildOMPSeverityClause(10990 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),10991 C->getLParenLoc(), C->getEndLoc());10992}10993 10994template <typename Derived>10995OMPClause *10996TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {10997 ExprResult E = getDerived().TransformExpr(C->getMessageString());10998 if (E.isInvalid())10999 return nullptr;11000 return getDerived().RebuildOMPMessageClause(11001 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11002}11003 11004template <typename Derived>11005OMPClause *11006TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {11007 llvm::SmallVector<Expr *, 16> Vars;11008 Vars.reserve(C->varlist_size());11009 for (auto *VE : C->varlist()) {11010 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11011 if (EVar.isInvalid())11012 return nullptr;11013 Vars.push_back(EVar.get());11014 }11015 return getDerived().RebuildOMPPrivateClause(11016 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11017}11018 11019template <typename Derived>11020OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(11021 OMPFirstprivateClause *C) {11022 llvm::SmallVector<Expr *, 16> Vars;11023 Vars.reserve(C->varlist_size());11024 for (auto *VE : C->varlist()) {11025 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11026 if (EVar.isInvalid())11027 return nullptr;11028 Vars.push_back(EVar.get());11029 }11030 return getDerived().RebuildOMPFirstprivateClause(11031 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11032}11033 11034template <typename Derived>11035OMPClause *11036TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {11037 llvm::SmallVector<Expr *, 16> Vars;11038 Vars.reserve(C->varlist_size());11039 for (auto *VE : C->varlist()) {11040 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11041 if (EVar.isInvalid())11042 return nullptr;11043 Vars.push_back(EVar.get());11044 }11045 return getDerived().RebuildOMPLastprivateClause(11046 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),11047 C->getLParenLoc(), C->getEndLoc());11048}11049 11050template <typename Derived>11051OMPClause *11052TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {11053 llvm::SmallVector<Expr *, 16> Vars;11054 Vars.reserve(C->varlist_size());11055 for (auto *VE : C->varlist()) {11056 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11057 if (EVar.isInvalid())11058 return nullptr;11059 Vars.push_back(EVar.get());11060 }11061 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),11062 C->getLParenLoc(), C->getEndLoc());11063}11064 11065template <typename Derived>11066OMPClause *11067TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {11068 llvm::SmallVector<Expr *, 16> Vars;11069 Vars.reserve(C->varlist_size());11070 for (auto *VE : C->varlist()) {11071 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11072 if (EVar.isInvalid())11073 return nullptr;11074 Vars.push_back(EVar.get());11075 }11076 CXXScopeSpec ReductionIdScopeSpec;11077 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());11078 11079 DeclarationNameInfo NameInfo = C->getNameInfo();11080 if (NameInfo.getName()) {11081 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);11082 if (!NameInfo.getName())11083 return nullptr;11084 }11085 // Build a list of all UDR decls with the same names ranged by the Scopes.11086 // The Scope boundary is a duplication of the previous decl.11087 llvm::SmallVector<Expr *, 16> UnresolvedReductions;11088 for (auto *E : C->reduction_ops()) {11089 // Transform all the decls.11090 if (E) {11091 auto *ULE = cast<UnresolvedLookupExpr>(E);11092 UnresolvedSet<8> Decls;11093 for (auto *D : ULE->decls()) {11094 NamedDecl *InstD =11095 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));11096 Decls.addDecl(InstD, InstD->getAccess());11097 }11098 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(11099 SemaRef.Context, /*NamingClass=*/nullptr,11100 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,11101 /*ADL=*/true, Decls.begin(), Decls.end(),11102 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));11103 } else11104 UnresolvedReductions.push_back(nullptr);11105 }11106 return getDerived().RebuildOMPReductionClause(11107 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),11108 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),11109 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);11110}11111 11112template <typename Derived>11113OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(11114 OMPTaskReductionClause *C) {11115 llvm::SmallVector<Expr *, 16> Vars;11116 Vars.reserve(C->varlist_size());11117 for (auto *VE : C->varlist()) {11118 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11119 if (EVar.isInvalid())11120 return nullptr;11121 Vars.push_back(EVar.get());11122 }11123 CXXScopeSpec ReductionIdScopeSpec;11124 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());11125 11126 DeclarationNameInfo NameInfo = C->getNameInfo();11127 if (NameInfo.getName()) {11128 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);11129 if (!NameInfo.getName())11130 return nullptr;11131 }11132 // Build a list of all UDR decls with the same names ranged by the Scopes.11133 // The Scope boundary is a duplication of the previous decl.11134 llvm::SmallVector<Expr *, 16> UnresolvedReductions;11135 for (auto *E : C->reduction_ops()) {11136 // Transform all the decls.11137 if (E) {11138 auto *ULE = cast<UnresolvedLookupExpr>(E);11139 UnresolvedSet<8> Decls;11140 for (auto *D : ULE->decls()) {11141 NamedDecl *InstD =11142 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));11143 Decls.addDecl(InstD, InstD->getAccess());11144 }11145 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(11146 SemaRef.Context, /*NamingClass=*/nullptr,11147 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,11148 /*ADL=*/true, Decls.begin(), Decls.end(),11149 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));11150 } else11151 UnresolvedReductions.push_back(nullptr);11152 }11153 return getDerived().RebuildOMPTaskReductionClause(11154 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),11155 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);11156}11157 11158template <typename Derived>11159OMPClause *11160TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {11161 llvm::SmallVector<Expr *, 16> Vars;11162 Vars.reserve(C->varlist_size());11163 for (auto *VE : C->varlist()) {11164 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11165 if (EVar.isInvalid())11166 return nullptr;11167 Vars.push_back(EVar.get());11168 }11169 CXXScopeSpec ReductionIdScopeSpec;11170 ReductionIdScopeSpec.Adopt(C->getQualifierLoc());11171 11172 DeclarationNameInfo NameInfo = C->getNameInfo();11173 if (NameInfo.getName()) {11174 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);11175 if (!NameInfo.getName())11176 return nullptr;11177 }11178 // Build a list of all UDR decls with the same names ranged by the Scopes.11179 // The Scope boundary is a duplication of the previous decl.11180 llvm::SmallVector<Expr *, 16> UnresolvedReductions;11181 for (auto *E : C->reduction_ops()) {11182 // Transform all the decls.11183 if (E) {11184 auto *ULE = cast<UnresolvedLookupExpr>(E);11185 UnresolvedSet<8> Decls;11186 for (auto *D : ULE->decls()) {11187 NamedDecl *InstD =11188 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));11189 Decls.addDecl(InstD, InstD->getAccess());11190 }11191 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(11192 SemaRef.Context, /*NamingClass=*/nullptr,11193 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,11194 /*ADL=*/true, Decls.begin(), Decls.end(),11195 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));11196 } else11197 UnresolvedReductions.push_back(nullptr);11198 }11199 return getDerived().RebuildOMPInReductionClause(11200 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),11201 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);11202}11203 11204template <typename Derived>11205OMPClause *11206TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {11207 llvm::SmallVector<Expr *, 16> Vars;11208 Vars.reserve(C->varlist_size());11209 for (auto *VE : C->varlist()) {11210 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11211 if (EVar.isInvalid())11212 return nullptr;11213 Vars.push_back(EVar.get());11214 }11215 ExprResult Step = getDerived().TransformExpr(C->getStep());11216 if (Step.isInvalid())11217 return nullptr;11218 return getDerived().RebuildOMPLinearClause(11219 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),11220 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),11221 C->getEndLoc());11222}11223 11224template <typename Derived>11225OMPClause *11226TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {11227 llvm::SmallVector<Expr *, 16> Vars;11228 Vars.reserve(C->varlist_size());11229 for (auto *VE : C->varlist()) {11230 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11231 if (EVar.isInvalid())11232 return nullptr;11233 Vars.push_back(EVar.get());11234 }11235 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());11236 if (Alignment.isInvalid())11237 return nullptr;11238 return getDerived().RebuildOMPAlignedClause(11239 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),11240 C->getColonLoc(), C->getEndLoc());11241}11242 11243template <typename Derived>11244OMPClause *11245TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {11246 llvm::SmallVector<Expr *, 16> Vars;11247 Vars.reserve(C->varlist_size());11248 for (auto *VE : C->varlist()) {11249 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11250 if (EVar.isInvalid())11251 return nullptr;11252 Vars.push_back(EVar.get());11253 }11254 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),11255 C->getLParenLoc(), C->getEndLoc());11256}11257 11258template <typename Derived>11259OMPClause *11260TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {11261 llvm::SmallVector<Expr *, 16> Vars;11262 Vars.reserve(C->varlist_size());11263 for (auto *VE : C->varlist()) {11264 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11265 if (EVar.isInvalid())11266 return nullptr;11267 Vars.push_back(EVar.get());11268 }11269 return getDerived().RebuildOMPCopyprivateClause(11270 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11271}11272 11273template <typename Derived>11274OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {11275 llvm::SmallVector<Expr *, 16> Vars;11276 Vars.reserve(C->varlist_size());11277 for (auto *VE : C->varlist()) {11278 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11279 if (EVar.isInvalid())11280 return nullptr;11281 Vars.push_back(EVar.get());11282 }11283 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),11284 C->getLParenLoc(), C->getEndLoc());11285}11286 11287template <typename Derived>11288OMPClause *11289TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {11290 ExprResult E = getDerived().TransformExpr(C->getDepobj());11291 if (E.isInvalid())11292 return nullptr;11293 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),11294 C->getLParenLoc(), C->getEndLoc());11295}11296 11297template <typename Derived>11298OMPClause *11299TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {11300 llvm::SmallVector<Expr *, 16> Vars;11301 Expr *DepModifier = C->getModifier();11302 if (DepModifier) {11303 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);11304 if (DepModRes.isInvalid())11305 return nullptr;11306 DepModifier = DepModRes.get();11307 }11308 Vars.reserve(C->varlist_size());11309 for (auto *VE : C->varlist()) {11310 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11311 if (EVar.isInvalid())11312 return nullptr;11313 Vars.push_back(EVar.get());11314 }11315 return getDerived().RebuildOMPDependClause(11316 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),11317 C->getOmpAllMemoryLoc()},11318 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11319}11320 11321template <typename Derived>11322OMPClause *11323TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {11324 ExprResult E = getDerived().TransformExpr(C->getDevice());11325 if (E.isInvalid())11326 return nullptr;11327 return getDerived().RebuildOMPDeviceClause(11328 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),11329 C->getModifierLoc(), C->getEndLoc());11330}11331 11332template <typename Derived, class T>11333bool transformOMPMappableExprListClause(11334 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,11335 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,11336 DeclarationNameInfo &MapperIdInfo,11337 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {11338 // Transform expressions in the list.11339 Vars.reserve(C->varlist_size());11340 for (auto *VE : C->varlist()) {11341 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));11342 if (EVar.isInvalid())11343 return true;11344 Vars.push_back(EVar.get());11345 }11346 // Transform mapper scope specifier and identifier.11347 NestedNameSpecifierLoc QualifierLoc;11348 if (C->getMapperQualifierLoc()) {11349 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(11350 C->getMapperQualifierLoc());11351 if (!QualifierLoc)11352 return true;11353 }11354 MapperIdScopeSpec.Adopt(QualifierLoc);11355 MapperIdInfo = C->getMapperIdInfo();11356 if (MapperIdInfo.getName()) {11357 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);11358 if (!MapperIdInfo.getName())11359 return true;11360 }11361 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by11362 // the previous user-defined mapper lookup in dependent environment.11363 for (auto *E : C->mapperlists()) {11364 // Transform all the decls.11365 if (E) {11366 auto *ULE = cast<UnresolvedLookupExpr>(E);11367 UnresolvedSet<8> Decls;11368 for (auto *D : ULE->decls()) {11369 NamedDecl *InstD =11370 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));11371 Decls.addDecl(InstD, InstD->getAccess());11372 }11373 UnresolvedMappers.push_back(UnresolvedLookupExpr::Create(11374 TT.getSema().Context, /*NamingClass=*/nullptr,11375 MapperIdScopeSpec.getWithLocInContext(TT.getSema().Context),11376 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),11377 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));11378 } else {11379 UnresolvedMappers.push_back(nullptr);11380 }11381 }11382 return false;11383}11384 11385template <typename Derived>11386OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {11387 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11388 llvm::SmallVector<Expr *, 16> Vars;11389 Expr *IteratorModifier = C->getIteratorModifier();11390 if (IteratorModifier) {11391 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);11392 if (MapModRes.isInvalid())11393 return nullptr;11394 IteratorModifier = MapModRes.get();11395 }11396 CXXScopeSpec MapperIdScopeSpec;11397 DeclarationNameInfo MapperIdInfo;11398 llvm::SmallVector<Expr *, 16> UnresolvedMappers;11399 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(11400 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))11401 return nullptr;11402 return getDerived().RebuildOMPMapClause(11403 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),11404 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),11405 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);11406}11407 11408template <typename Derived>11409OMPClause *11410TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {11411 Expr *Allocator = C->getAllocator();11412 if (Allocator) {11413 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);11414 if (AllocatorRes.isInvalid())11415 return nullptr;11416 Allocator = AllocatorRes.get();11417 }11418 Expr *Alignment = C->getAlignment();11419 if (Alignment) {11420 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);11421 if (AlignmentRes.isInvalid())11422 return nullptr;11423 Alignment = AlignmentRes.get();11424 }11425 llvm::SmallVector<Expr *, 16> Vars;11426 Vars.reserve(C->varlist_size());11427 for (auto *VE : C->varlist()) {11428 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11429 if (EVar.isInvalid())11430 return nullptr;11431 Vars.push_back(EVar.get());11432 }11433 return getDerived().RebuildOMPAllocateClause(11434 Allocator, Alignment, C->getFirstAllocateModifier(),11435 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),11436 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),11437 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());11438}11439 11440template <typename Derived>11441OMPClause *11442TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {11443 llvm::SmallVector<Expr *, 3> Vars;11444 Vars.reserve(C->varlist_size());11445 for (auto *VE : C->varlist()) {11446 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11447 if (EVar.isInvalid())11448 return nullptr;11449 Vars.push_back(EVar.get());11450 }11451 return getDerived().RebuildOMPNumTeamsClause(11452 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11453}11454 11455template <typename Derived>11456OMPClause *11457TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {11458 llvm::SmallVector<Expr *, 3> Vars;11459 Vars.reserve(C->varlist_size());11460 for (auto *VE : C->varlist()) {11461 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11462 if (EVar.isInvalid())11463 return nullptr;11464 Vars.push_back(EVar.get());11465 }11466 return getDerived().RebuildOMPThreadLimitClause(11467 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11468}11469 11470template <typename Derived>11471OMPClause *11472TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {11473 ExprResult E = getDerived().TransformExpr(C->getPriority());11474 if (E.isInvalid())11475 return nullptr;11476 return getDerived().RebuildOMPPriorityClause(11477 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11478}11479 11480template <typename Derived>11481OMPClause *11482TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {11483 ExprResult E = getDerived().TransformExpr(C->getGrainsize());11484 if (E.isInvalid())11485 return nullptr;11486 return getDerived().RebuildOMPGrainsizeClause(11487 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),11488 C->getModifierLoc(), C->getEndLoc());11489}11490 11491template <typename Derived>11492OMPClause *11493TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {11494 ExprResult E = getDerived().TransformExpr(C->getNumTasks());11495 if (E.isInvalid())11496 return nullptr;11497 return getDerived().RebuildOMPNumTasksClause(11498 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),11499 C->getModifierLoc(), C->getEndLoc());11500}11501 11502template <typename Derived>11503OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {11504 ExprResult E = getDerived().TransformExpr(C->getHint());11505 if (E.isInvalid())11506 return nullptr;11507 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),11508 C->getLParenLoc(), C->getEndLoc());11509}11510 11511template <typename Derived>11512OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(11513 OMPDistScheduleClause *C) {11514 ExprResult E = getDerived().TransformExpr(C->getChunkSize());11515 if (E.isInvalid())11516 return nullptr;11517 return getDerived().RebuildOMPDistScheduleClause(11518 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),11519 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());11520}11521 11522template <typename Derived>11523OMPClause *11524TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {11525 // Rebuild Defaultmap Clause since we need to invoke the checking of11526 // defaultmap(none:variable-category) after template initialization.11527 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),11528 C->getDefaultmapKind(),11529 C->getBeginLoc(),11530 C->getLParenLoc(),11531 C->getDefaultmapModifierLoc(),11532 C->getDefaultmapKindLoc(),11533 C->getEndLoc());11534}11535 11536template <typename Derived>11537OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {11538 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11539 llvm::SmallVector<Expr *, 16> Vars;11540 Expr *IteratorModifier = C->getIteratorModifier();11541 if (IteratorModifier) {11542 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);11543 if (MapModRes.isInvalid())11544 return nullptr;11545 IteratorModifier = MapModRes.get();11546 }11547 CXXScopeSpec MapperIdScopeSpec;11548 DeclarationNameInfo MapperIdInfo;11549 llvm::SmallVector<Expr *, 16> UnresolvedMappers;11550 if (transformOMPMappableExprListClause<Derived, OMPToClause>(11551 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))11552 return nullptr;11553 return getDerived().RebuildOMPToClause(11554 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,11555 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,11556 UnresolvedMappers);11557}11558 11559template <typename Derived>11560OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {11561 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11562 llvm::SmallVector<Expr *, 16> Vars;11563 Expr *IteratorModifier = C->getIteratorModifier();11564 if (IteratorModifier) {11565 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);11566 if (MapModRes.isInvalid())11567 return nullptr;11568 IteratorModifier = MapModRes.get();11569 }11570 CXXScopeSpec MapperIdScopeSpec;11571 DeclarationNameInfo MapperIdInfo;11572 llvm::SmallVector<Expr *, 16> UnresolvedMappers;11573 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(11574 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))11575 return nullptr;11576 return getDerived().RebuildOMPFromClause(11577 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,11578 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,11579 UnresolvedMappers);11580}11581 11582template <typename Derived>11583OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(11584 OMPUseDevicePtrClause *C) {11585 llvm::SmallVector<Expr *, 16> Vars;11586 Vars.reserve(C->varlist_size());11587 for (auto *VE : C->varlist()) {11588 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11589 if (EVar.isInvalid())11590 return nullptr;11591 Vars.push_back(EVar.get());11592 }11593 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11594 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);11595}11596 11597template <typename Derived>11598OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(11599 OMPUseDeviceAddrClause *C) {11600 llvm::SmallVector<Expr *, 16> Vars;11601 Vars.reserve(C->varlist_size());11602 for (auto *VE : C->varlist()) {11603 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11604 if (EVar.isInvalid())11605 return nullptr;11606 Vars.push_back(EVar.get());11607 }11608 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11609 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);11610}11611 11612template <typename Derived>11613OMPClause *11614TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {11615 llvm::SmallVector<Expr *, 16> Vars;11616 Vars.reserve(C->varlist_size());11617 for (auto *VE : C->varlist()) {11618 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11619 if (EVar.isInvalid())11620 return nullptr;11621 Vars.push_back(EVar.get());11622 }11623 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11624 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);11625}11626 11627template <typename Derived>11628OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(11629 OMPHasDeviceAddrClause *C) {11630 llvm::SmallVector<Expr *, 16> Vars;11631 Vars.reserve(C->varlist_size());11632 for (auto *VE : C->varlist()) {11633 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11634 if (EVar.isInvalid())11635 return nullptr;11636 Vars.push_back(EVar.get());11637 }11638 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11639 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);11640}11641 11642template <typename Derived>11643OMPClause *11644TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {11645 llvm::SmallVector<Expr *, 16> Vars;11646 Vars.reserve(C->varlist_size());11647 for (auto *VE : C->varlist()) {11648 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11649 if (EVar.isInvalid())11650 return nullptr;11651 Vars.push_back(EVar.get());11652 }11653 return getDerived().RebuildOMPNontemporalClause(11654 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11655}11656 11657template <typename Derived>11658OMPClause *11659TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {11660 llvm::SmallVector<Expr *, 16> Vars;11661 Vars.reserve(C->varlist_size());11662 for (auto *VE : C->varlist()) {11663 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11664 if (EVar.isInvalid())11665 return nullptr;11666 Vars.push_back(EVar.get());11667 }11668 return getDerived().RebuildOMPInclusiveClause(11669 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11670}11671 11672template <typename Derived>11673OMPClause *11674TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {11675 llvm::SmallVector<Expr *, 16> Vars;11676 Vars.reserve(C->varlist_size());11677 for (auto *VE : C->varlist()) {11678 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11679 if (EVar.isInvalid())11680 return nullptr;11681 Vars.push_back(EVar.get());11682 }11683 return getDerived().RebuildOMPExclusiveClause(11684 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11685}11686 11687template <typename Derived>11688OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(11689 OMPUsesAllocatorsClause *C) {11690 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;11691 Data.reserve(C->getNumberOfAllocators());11692 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {11693 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);11694 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);11695 if (Allocator.isInvalid())11696 continue;11697 ExprResult AllocatorTraits;11698 if (Expr *AT = D.AllocatorTraits) {11699 AllocatorTraits = getDerived().TransformExpr(AT);11700 if (AllocatorTraits.isInvalid())11701 continue;11702 }11703 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();11704 NewD.Allocator = Allocator.get();11705 NewD.AllocatorTraits = AllocatorTraits.get();11706 NewD.LParenLoc = D.LParenLoc;11707 NewD.RParenLoc = D.RParenLoc;11708 }11709 return getDerived().RebuildOMPUsesAllocatorsClause(11710 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11711}11712 11713template <typename Derived>11714OMPClause *11715TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {11716 SmallVector<Expr *, 4> Locators;11717 Locators.reserve(C->varlist_size());11718 ExprResult ModifierRes;11719 if (Expr *Modifier = C->getModifier()) {11720 ModifierRes = getDerived().TransformExpr(Modifier);11721 if (ModifierRes.isInvalid())11722 return nullptr;11723 }11724 for (Expr *E : C->varlist()) {11725 ExprResult Locator = getDerived().TransformExpr(E);11726 if (Locator.isInvalid())11727 continue;11728 Locators.push_back(Locator.get());11729 }11730 return getDerived().RebuildOMPAffinityClause(11731 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),11732 ModifierRes.get(), Locators);11733}11734 11735template <typename Derived>11736OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {11737 return getDerived().RebuildOMPOrderClause(11738 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),11739 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());11740}11741 11742template <typename Derived>11743OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {11744 return getDerived().RebuildOMPBindClause(11745 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),11746 C->getLParenLoc(), C->getEndLoc());11747}11748 11749template <typename Derived>11750OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(11751 OMPXDynCGroupMemClause *C) {11752 ExprResult Size = getDerived().TransformExpr(C->getSize());11753 if (Size.isInvalid())11754 return nullptr;11755 return getDerived().RebuildOMPXDynCGroupMemClause(11756 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11757}11758 11759template <typename Derived>11760OMPClause *TreeTransform<Derived>::TransformOMPDynGroupprivateClause(11761 OMPDynGroupprivateClause *C) {11762 ExprResult Size = getDerived().TransformExpr(C->getSize());11763 if (Size.isInvalid())11764 return nullptr;11765 return getDerived().RebuildOMPDynGroupprivateClause(11766 C->getDynGroupprivateModifier(), C->getDynGroupprivateFallbackModifier(),11767 Size.get(), C->getBeginLoc(), C->getLParenLoc(),11768 C->getDynGroupprivateModifierLoc(),11769 C->getDynGroupprivateFallbackModifierLoc(), C->getEndLoc());11770}11771 11772template <typename Derived>11773OMPClause *11774TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {11775 llvm::SmallVector<Expr *, 16> Vars;11776 Vars.reserve(C->varlist_size());11777 for (auto *VE : C->varlist()) {11778 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));11779 if (EVar.isInvalid())11780 return nullptr;11781 Vars.push_back(EVar.get());11782 }11783 return getDerived().RebuildOMPDoacrossClause(11784 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,11785 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11786}11787 11788template <typename Derived>11789OMPClause *11790TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {11791 SmallVector<const Attr *> NewAttrs;11792 for (auto *A : C->getAttrs())11793 NewAttrs.push_back(getDerived().TransformAttr(A));11794 return getDerived().RebuildOMPXAttributeClause(11795 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());11796}11797 11798template <typename Derived>11799OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {11800 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());11801}11802 11803//===----------------------------------------------------------------------===//11804// OpenACC transformation11805//===----------------------------------------------------------------------===//11806namespace {11807template <typename Derived>11808class OpenACCClauseTransform final11809 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {11810 TreeTransform<Derived> &Self;11811 ArrayRef<const OpenACCClause *> ExistingClauses;11812 SemaOpenACC::OpenACCParsedClause &ParsedClause;11813 OpenACCClause *NewClause = nullptr;11814 11815 ExprResult VisitVar(Expr *VarRef) {11816 ExprResult Res = Self.TransformExpr(VarRef);11817 11818 if (!Res.isUsable())11819 return Res;11820 11821 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),11822 ParsedClause.getClauseKind(),11823 Res.get());11824 11825 return Res;11826 }11827 11828 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {11829 llvm::SmallVector<Expr *> InstantiatedVarList;11830 for (Expr *CurVar : VarList) {11831 ExprResult VarRef = VisitVar(CurVar);11832 11833 if (VarRef.isUsable())11834 InstantiatedVarList.push_back(VarRef.get());11835 }11836 11837 return InstantiatedVarList;11838 }11839 11840public:11841 OpenACCClauseTransform(TreeTransform<Derived> &Self,11842 ArrayRef<const OpenACCClause *> ExistingClauses,11843 SemaOpenACC::OpenACCParsedClause &PC)11844 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}11845 11846 OpenACCClause *CreatedClause() const { return NewClause; }11847 11848#define VISIT_CLAUSE(CLAUSE_NAME) \11849 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);11850#include "clang/Basic/OpenACCClauses.def"11851};11852 11853template <typename Derived>11854void OpenACCClauseTransform<Derived>::VisitDefaultClause(11855 const OpenACCDefaultClause &C) {11856 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());11857 11858 NewClause = OpenACCDefaultClause::Create(11859 Self.getSema().getASTContext(), ParsedClause.getDefaultClauseKind(),11860 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),11861 ParsedClause.getEndLoc());11862}11863 11864template <typename Derived>11865void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {11866 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());11867 assert(Cond && "If constructed with invalid Condition");11868 Sema::ConditionResult Res = Self.TransformCondition(11869 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);11870 11871 if (Res.isInvalid() || !Res.get().second)11872 return;11873 11874 ParsedClause.setConditionDetails(Res.get().second);11875 11876 NewClause = OpenACCIfClause::Create(11877 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),11878 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),11879 ParsedClause.getEndLoc());11880}11881 11882template <typename Derived>11883void OpenACCClauseTransform<Derived>::VisitSelfClause(11884 const OpenACCSelfClause &C) {11885 11886 // If this is an 'update' 'self' clause, this is actually a var list instead.11887 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {11888 llvm::SmallVector<Expr *> InstantiatedVarList;11889 for (Expr *CurVar : C.getVarList()) {11890 ExprResult Res = Self.TransformExpr(CurVar);11891 11892 if (!Res.isUsable())11893 continue;11894 11895 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),11896 ParsedClause.getClauseKind(),11897 Res.get());11898 11899 if (Res.isUsable())11900 InstantiatedVarList.push_back(Res.get());11901 }11902 11903 ParsedClause.setVarListDetails(InstantiatedVarList,11904 OpenACCModifierKind::Invalid);11905 11906 NewClause = OpenACCSelfClause::Create(11907 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),11908 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),11909 ParsedClause.getEndLoc());11910 } else {11911 11912 if (C.hasConditionExpr()) {11913 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());11914 Sema::ConditionResult Res =11915 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,11916 Sema::ConditionKind::Boolean);11917 11918 if (Res.isInvalid() || !Res.get().second)11919 return;11920 11921 ParsedClause.setConditionDetails(Res.get().second);11922 }11923 11924 NewClause = OpenACCSelfClause::Create(11925 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),11926 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),11927 ParsedClause.getEndLoc());11928 }11929}11930 11931template <typename Derived>11932void OpenACCClauseTransform<Derived>::VisitNumGangsClause(11933 const OpenACCNumGangsClause &C) {11934 llvm::SmallVector<Expr *> InstantiatedIntExprs;11935 11936 for (Expr *CurIntExpr : C.getIntExprs()) {11937 ExprResult Res = Self.TransformExpr(CurIntExpr);11938 11939 if (!Res.isUsable())11940 return;11941 11942 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,11943 C.getClauseKind(),11944 C.getBeginLoc(), Res.get());11945 if (!Res.isUsable())11946 return;11947 11948 InstantiatedIntExprs.push_back(Res.get());11949 }11950 11951 ParsedClause.setIntExprDetails(InstantiatedIntExprs);11952 NewClause = OpenACCNumGangsClause::Create(11953 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),11954 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs(),11955 ParsedClause.getEndLoc());11956}11957 11958template <typename Derived>11959void OpenACCClauseTransform<Derived>::VisitPrivateClause(11960 const OpenACCPrivateClause &C) {11961 llvm::SmallVector<Expr *> InstantiatedVarList;11962 llvm::SmallVector<OpenACCPrivateRecipe> InitRecipes;11963 11964 for (const auto [RefExpr, InitRecipe] :11965 llvm::zip(C.getVarList(), C.getInitRecipes())) {11966 ExprResult VarRef = VisitVar(RefExpr);11967 11968 if (VarRef.isUsable()) {11969 InstantiatedVarList.push_back(VarRef.get());11970 11971 // We only have to create a new one if it is dependent, and Sema won't11972 // make one of these unless the type is non-dependent.11973 if (InitRecipe.isSet())11974 InitRecipes.push_back(InitRecipe);11975 else11976 InitRecipes.push_back(11977 Self.getSema().OpenACC().CreatePrivateInitRecipe(VarRef.get()));11978 }11979 }11980 ParsedClause.setVarListDetails(InstantiatedVarList,11981 OpenACCModifierKind::Invalid);11982 11983 NewClause = OpenACCPrivateClause::Create(11984 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),11985 ParsedClause.getLParenLoc(), ParsedClause.getVarList(), InitRecipes,11986 ParsedClause.getEndLoc());11987}11988 11989template <typename Derived>11990void OpenACCClauseTransform<Derived>::VisitHostClause(11991 const OpenACCHostClause &C) {11992 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),11993 OpenACCModifierKind::Invalid);11994 11995 NewClause = OpenACCHostClause::Create(11996 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),11997 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),11998 ParsedClause.getEndLoc());11999}12000 12001template <typename Derived>12002void OpenACCClauseTransform<Derived>::VisitDeviceClause(12003 const OpenACCDeviceClause &C) {12004 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),12005 OpenACCModifierKind::Invalid);12006 12007 NewClause = OpenACCDeviceClause::Create(12008 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12009 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),12010 ParsedClause.getEndLoc());12011}12012 12013template <typename Derived>12014void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(12015 const OpenACCFirstPrivateClause &C) {12016 llvm::SmallVector<Expr *> InstantiatedVarList;12017 llvm::SmallVector<OpenACCFirstPrivateRecipe> InitRecipes;12018 12019 for (const auto [RefExpr, InitRecipe] :12020 llvm::zip(C.getVarList(), C.getInitRecipes())) {12021 ExprResult VarRef = VisitVar(RefExpr);12022 12023 if (VarRef.isUsable()) {12024 InstantiatedVarList.push_back(VarRef.get());12025 12026 // We only have to create a new one if it is dependent, and Sema won't12027 // make one of these unless the type is non-dependent.12028 if (InitRecipe.isSet())12029 InitRecipes.push_back(InitRecipe);12030 else12031 InitRecipes.push_back(12032 Self.getSema().OpenACC().CreateFirstPrivateInitRecipe(12033 VarRef.get()));12034 }12035 }12036 ParsedClause.setVarListDetails(InstantiatedVarList,12037 OpenACCModifierKind::Invalid);12038 12039 NewClause = OpenACCFirstPrivateClause::Create(12040 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12041 ParsedClause.getLParenLoc(), ParsedClause.getVarList(), InitRecipes,12042 ParsedClause.getEndLoc());12043}12044 12045template <typename Derived>12046void OpenACCClauseTransform<Derived>::VisitNoCreateClause(12047 const OpenACCNoCreateClause &C) {12048 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),12049 OpenACCModifierKind::Invalid);12050 12051 NewClause = OpenACCNoCreateClause::Create(12052 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12053 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),12054 ParsedClause.getEndLoc());12055}12056 12057template <typename Derived>12058void OpenACCClauseTransform<Derived>::VisitPresentClause(12059 const OpenACCPresentClause &C) {12060 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),12061 OpenACCModifierKind::Invalid);12062 12063 NewClause = OpenACCPresentClause::Create(12064 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12065 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),12066 ParsedClause.getEndLoc());12067}12068 12069template <typename Derived>12070void OpenACCClauseTransform<Derived>::VisitCopyClause(12071 const OpenACCCopyClause &C) {12072 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),12073 C.getModifierList());12074 12075 NewClause = OpenACCCopyClause::Create(12076 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),12077 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),12078 ParsedClause.getModifierList(), ParsedClause.getVarList(),12079 ParsedClause.getEndLoc());12080}12081 12082template <typename Derived>12083void OpenACCClauseTransform<Derived>::VisitLinkClause(12084 const OpenACCLinkClause &C) {12085 llvm_unreachable("link clause not valid unless a decl transform");12086}12087 12088template <typename Derived>12089void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(12090 const OpenACCDeviceResidentClause &C) {12091 llvm_unreachable("device_resident clause not valid unless a decl transform");12092}12093template <typename Derived>12094void OpenACCClauseTransform<Derived>::VisitNoHostClause(12095 const OpenACCNoHostClause &C) {12096 llvm_unreachable("nohost clause not valid unless a decl transform");12097}12098template <typename Derived>12099void OpenACCClauseTransform<Derived>::VisitBindClause(12100 const OpenACCBindClause &C) {12101 llvm_unreachable("bind clause not valid unless a decl transform");12102}12103 12104template <typename Derived>12105void OpenACCClauseTransform<Derived>::VisitCopyInClause(12106 const OpenACCCopyInClause &C) {12107 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),12108 C.getModifierList());12109 12110 NewClause = OpenACCCopyInClause::Create(12111 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),12112 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),12113 ParsedClause.getModifierList(), ParsedClause.getVarList(),12114 ParsedClause.getEndLoc());12115}12116 12117template <typename Derived>12118void OpenACCClauseTransform<Derived>::VisitCopyOutClause(12119 const OpenACCCopyOutClause &C) {12120 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),12121 C.getModifierList());12122 12123 NewClause = OpenACCCopyOutClause::Create(12124 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),12125 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),12126 ParsedClause.getModifierList(), ParsedClause.getVarList(),12127 ParsedClause.getEndLoc());12128}12129 12130template <typename Derived>12131void OpenACCClauseTransform<Derived>::VisitCreateClause(12132 const OpenACCCreateClause &C) {12133 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),12134 C.getModifierList());12135 12136 NewClause = OpenACCCreateClause::Create(12137 Self.getSema().getASTContext(), ParsedClause.getClauseKind(),12138 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),12139 ParsedClause.getModifierList(), ParsedClause.getVarList(),12140 ParsedClause.getEndLoc());12141}12142template <typename Derived>12143void OpenACCClauseTransform<Derived>::VisitAttachClause(12144 const OpenACCAttachClause &C) {12145 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());12146 12147 // Ensure each var is a pointer type.12148 llvm::erase_if(VarList, [&](Expr *E) {12149 return Self.getSema().OpenACC().CheckVarIsPointerType(12150 OpenACCClauseKind::Attach, E);12151 });12152 12153 ParsedClause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);12154 NewClause = OpenACCAttachClause::Create(12155 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12156 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),12157 ParsedClause.getEndLoc());12158}12159 12160template <typename Derived>12161void OpenACCClauseTransform<Derived>::VisitDetachClause(12162 const OpenACCDetachClause &C) {12163 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());12164 12165 // Ensure each var is a pointer type.12166 llvm::erase_if(VarList, [&](Expr *E) {12167 return Self.getSema().OpenACC().CheckVarIsPointerType(12168 OpenACCClauseKind::Detach, E);12169 });12170 12171 ParsedClause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);12172 NewClause = OpenACCDetachClause::Create(12173 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12174 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),12175 ParsedClause.getEndLoc());12176}12177 12178template <typename Derived>12179void OpenACCClauseTransform<Derived>::VisitDeleteClause(12180 const OpenACCDeleteClause &C) {12181 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),12182 OpenACCModifierKind::Invalid);12183 NewClause = OpenACCDeleteClause::Create(12184 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12185 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),12186 ParsedClause.getEndLoc());12187}12188 12189template <typename Derived>12190void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(12191 const OpenACCUseDeviceClause &C) {12192 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),12193 OpenACCModifierKind::Invalid);12194 NewClause = OpenACCUseDeviceClause::Create(12195 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12196 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),12197 ParsedClause.getEndLoc());12198}12199 12200template <typename Derived>12201void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(12202 const OpenACCDevicePtrClause &C) {12203 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());12204 12205 // Ensure each var is a pointer type.12206 llvm::erase_if(VarList, [&](Expr *E) {12207 return Self.getSema().OpenACC().CheckVarIsPointerType(12208 OpenACCClauseKind::DevicePtr, E);12209 });12210 12211 ParsedClause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);12212 NewClause = OpenACCDevicePtrClause::Create(12213 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12214 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),12215 ParsedClause.getEndLoc());12216}12217 12218template <typename Derived>12219void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(12220 const OpenACCNumWorkersClause &C) {12221 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());12222 assert(IntExpr && "num_workers clause constructed with invalid int expr");12223 12224 ExprResult Res = Self.TransformExpr(IntExpr);12225 if (!Res.isUsable())12226 return;12227 12228 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,12229 C.getClauseKind(),12230 C.getBeginLoc(), Res.get());12231 if (!Res.isUsable())12232 return;12233 12234 ParsedClause.setIntExprDetails(Res.get());12235 NewClause = OpenACCNumWorkersClause::Create(12236 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12237 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],12238 ParsedClause.getEndLoc());12239}12240 12241template <typename Derived>12242void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (12243 const OpenACCDeviceNumClause &C) {12244 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());12245 assert(IntExpr && "device_num clause constructed with invalid int expr");12246 12247 ExprResult Res = Self.TransformExpr(IntExpr);12248 if (!Res.isUsable())12249 return;12250 12251 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,12252 C.getClauseKind(),12253 C.getBeginLoc(), Res.get());12254 if (!Res.isUsable())12255 return;12256 12257 ParsedClause.setIntExprDetails(Res.get());12258 NewClause = OpenACCDeviceNumClause::Create(12259 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12260 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],12261 ParsedClause.getEndLoc());12262}12263 12264template <typename Derived>12265void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(12266 const OpenACCDefaultAsyncClause &C) {12267 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());12268 assert(IntExpr && "default_async clause constructed with invalid int expr");12269 12270 ExprResult Res = Self.TransformExpr(IntExpr);12271 if (!Res.isUsable())12272 return;12273 12274 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,12275 C.getClauseKind(),12276 C.getBeginLoc(), Res.get());12277 if (!Res.isUsable())12278 return;12279 12280 ParsedClause.setIntExprDetails(Res.get());12281 NewClause = OpenACCDefaultAsyncClause::Create(12282 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12283 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],12284 ParsedClause.getEndLoc());12285}12286 12287template <typename Derived>12288void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(12289 const OpenACCVectorLengthClause &C) {12290 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());12291 assert(IntExpr && "vector_length clause constructed with invalid int expr");12292 12293 ExprResult Res = Self.TransformExpr(IntExpr);12294 if (!Res.isUsable())12295 return;12296 12297 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,12298 C.getClauseKind(),12299 C.getBeginLoc(), Res.get());12300 if (!Res.isUsable())12301 return;12302 12303 ParsedClause.setIntExprDetails(Res.get());12304 NewClause = OpenACCVectorLengthClause::Create(12305 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12306 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs()[0],12307 ParsedClause.getEndLoc());12308}12309 12310template <typename Derived>12311void OpenACCClauseTransform<Derived>::VisitAsyncClause(12312 const OpenACCAsyncClause &C) {12313 if (C.hasIntExpr()) {12314 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));12315 if (!Res.isUsable())12316 return;12317 12318 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,12319 C.getClauseKind(),12320 C.getBeginLoc(), Res.get());12321 if (!Res.isUsable())12322 return;12323 ParsedClause.setIntExprDetails(Res.get());12324 }12325 12326 NewClause = OpenACCAsyncClause::Create(12327 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12328 ParsedClause.getLParenLoc(),12329 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]12330 : nullptr,12331 ParsedClause.getEndLoc());12332}12333 12334template <typename Derived>12335void OpenACCClauseTransform<Derived>::VisitWorkerClause(12336 const OpenACCWorkerClause &C) {12337 if (C.hasIntExpr()) {12338 // restrictions on this expression are all "does it exist in certain12339 // situations" that are not possible to be dependent, so the only check we12340 // have is that it transforms, and is an int expression.12341 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));12342 if (!Res.isUsable())12343 return;12344 12345 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,12346 C.getClauseKind(),12347 C.getBeginLoc(), Res.get());12348 if (!Res.isUsable())12349 return;12350 ParsedClause.setIntExprDetails(Res.get());12351 }12352 12353 NewClause = OpenACCWorkerClause::Create(12354 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12355 ParsedClause.getLParenLoc(),12356 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]12357 : nullptr,12358 ParsedClause.getEndLoc());12359}12360 12361template <typename Derived>12362void OpenACCClauseTransform<Derived>::VisitVectorClause(12363 const OpenACCVectorClause &C) {12364 if (C.hasIntExpr()) {12365 // restrictions on this expression are all "does it exist in certain12366 // situations" that are not possible to be dependent, so the only check we12367 // have is that it transforms, and is an int expression.12368 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));12369 if (!Res.isUsable())12370 return;12371 12372 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,12373 C.getClauseKind(),12374 C.getBeginLoc(), Res.get());12375 if (!Res.isUsable())12376 return;12377 ParsedClause.setIntExprDetails(Res.get());12378 }12379 12380 NewClause = OpenACCVectorClause::Create(12381 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12382 ParsedClause.getLParenLoc(),12383 ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]12384 : nullptr,12385 ParsedClause.getEndLoc());12386}12387 12388template <typename Derived>12389void OpenACCClauseTransform<Derived>::VisitWaitClause(12390 const OpenACCWaitClause &C) {12391 if (C.hasExprs()) {12392 Expr *DevNumExpr = nullptr;12393 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;12394 12395 // Instantiate devnum expr if it exists.12396 if (C.getDevNumExpr()) {12397 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());12398 if (!Res.isUsable())12399 return;12400 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,12401 C.getClauseKind(),12402 C.getBeginLoc(), Res.get());12403 if (!Res.isUsable())12404 return;12405 12406 DevNumExpr = Res.get();12407 }12408 12409 // Instantiate queue ids.12410 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {12411 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);12412 if (!Res.isUsable())12413 return;12414 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,12415 C.getClauseKind(),12416 C.getBeginLoc(), Res.get());12417 if (!Res.isUsable())12418 return;12419 12420 InstantiatedQueueIdExprs.push_back(Res.get());12421 }12422 12423 ParsedClause.setWaitDetails(DevNumExpr, C.getQueuesLoc(),12424 std::move(InstantiatedQueueIdExprs));12425 }12426 12427 NewClause = OpenACCWaitClause::Create(12428 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12429 ParsedClause.getLParenLoc(), ParsedClause.getDevNumExpr(),12430 ParsedClause.getQueuesLoc(), ParsedClause.getQueueIdExprs(),12431 ParsedClause.getEndLoc());12432}12433 12434template <typename Derived>12435void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(12436 const OpenACCDeviceTypeClause &C) {12437 // Nothing to transform here, just create a new version of 'C'.12438 NewClause = OpenACCDeviceTypeClause::Create(12439 Self.getSema().getASTContext(), C.getClauseKind(),12440 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),12441 C.getArchitectures(), ParsedClause.getEndLoc());12442}12443 12444template <typename Derived>12445void OpenACCClauseTransform<Derived>::VisitAutoClause(12446 const OpenACCAutoClause &C) {12447 // Nothing to do, so just create a new node.12448 NewClause = OpenACCAutoClause::Create(Self.getSema().getASTContext(),12449 ParsedClause.getBeginLoc(),12450 ParsedClause.getEndLoc());12451}12452 12453template <typename Derived>12454void OpenACCClauseTransform<Derived>::VisitIndependentClause(12455 const OpenACCIndependentClause &C) {12456 NewClause = OpenACCIndependentClause::Create(Self.getSema().getASTContext(),12457 ParsedClause.getBeginLoc(),12458 ParsedClause.getEndLoc());12459}12460 12461template <typename Derived>12462void OpenACCClauseTransform<Derived>::VisitSeqClause(12463 const OpenACCSeqClause &C) {12464 NewClause = OpenACCSeqClause::Create(Self.getSema().getASTContext(),12465 ParsedClause.getBeginLoc(),12466 ParsedClause.getEndLoc());12467}12468template <typename Derived>12469void OpenACCClauseTransform<Derived>::VisitFinalizeClause(12470 const OpenACCFinalizeClause &C) {12471 NewClause = OpenACCFinalizeClause::Create(Self.getSema().getASTContext(),12472 ParsedClause.getBeginLoc(),12473 ParsedClause.getEndLoc());12474}12475 12476template <typename Derived>12477void OpenACCClauseTransform<Derived>::VisitIfPresentClause(12478 const OpenACCIfPresentClause &C) {12479 NewClause = OpenACCIfPresentClause::Create(Self.getSema().getASTContext(),12480 ParsedClause.getBeginLoc(),12481 ParsedClause.getEndLoc());12482}12483 12484template <typename Derived>12485void OpenACCClauseTransform<Derived>::VisitReductionClause(12486 const OpenACCReductionClause &C) {12487 SmallVector<Expr *> TransformedVars = VisitVarList(C.getVarList());12488 SmallVector<Expr *> ValidVars;12489 llvm::SmallVector<OpenACCReductionRecipeWithStorage> Recipes;12490 12491 for (const auto [Var, OrigRecipe] :12492 llvm::zip(TransformedVars, C.getRecipes())) {12493 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(12494 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);12495 if (Res.isUsable()) {12496 ValidVars.push_back(Res.get());12497 12498 if (OrigRecipe.isSet())12499 Recipes.emplace_back(OrigRecipe.AllocaDecl, OrigRecipe.CombinerRecipes);12500 else12501 Recipes.push_back(Self.getSema().OpenACC().CreateReductionInitRecipe(12502 C.getReductionOp(), Res.get()));12503 }12504 }12505 12506 NewClause = Self.getSema().OpenACC().CheckReductionClause(12507 ExistingClauses, ParsedClause.getDirectiveKind(),12508 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),12509 C.getReductionOp(), ValidVars, Recipes, ParsedClause.getEndLoc());12510}12511 12512template <typename Derived>12513void OpenACCClauseTransform<Derived>::VisitCollapseClause(12514 const OpenACCCollapseClause &C) {12515 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());12516 assert(LoopCount && "collapse clause constructed with invalid loop count");12517 12518 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);12519 12520 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(12521 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),12522 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());12523 12524 NewLoopCount =12525 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());12526 12527 ParsedClause.setCollapseDetails(C.hasForce(), NewLoopCount.get());12528 NewClause = OpenACCCollapseClause::Create(12529 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12530 ParsedClause.getLParenLoc(), ParsedClause.isForce(),12531 ParsedClause.getLoopCount(), ParsedClause.getEndLoc());12532}12533 12534template <typename Derived>12535void OpenACCClauseTransform<Derived>::VisitTileClause(12536 const OpenACCTileClause &C) {12537 12538 llvm::SmallVector<Expr *> TransformedExprs;12539 12540 for (Expr *E : C.getSizeExprs()) {12541 ExprResult NewSizeExpr = Self.TransformExpr(E);12542 12543 if (!NewSizeExpr.isUsable())12544 return;12545 12546 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(12547 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),12548 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());12549 12550 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());12551 12552 if (!NewSizeExpr.isUsable())12553 return;12554 TransformedExprs.push_back(NewSizeExpr.get());12555 }12556 12557 ParsedClause.setIntExprDetails(TransformedExprs);12558 NewClause = OpenACCTileClause::Create(12559 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),12560 ParsedClause.getLParenLoc(), ParsedClause.getIntExprs(),12561 ParsedClause.getEndLoc());12562}12563template <typename Derived>12564void OpenACCClauseTransform<Derived>::VisitGangClause(12565 const OpenACCGangClause &C) {12566 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;12567 llvm::SmallVector<Expr *> TransformedIntExprs;12568 12569 for (unsigned I = 0; I < C.getNumExprs(); ++I) {12570 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));12571 if (!ER.isUsable())12572 continue;12573 12574 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,12575 ParsedClause.getDirectiveKind(),12576 C.getExpr(I).first, ER.get());12577 if (!ER.isUsable())12578 continue;12579 TransformedGangKinds.push_back(C.getExpr(I).first);12580 TransformedIntExprs.push_back(ER.get());12581 }12582 12583 NewClause = Self.getSema().OpenACC().CheckGangClause(12584 ParsedClause.getDirectiveKind(), ExistingClauses,12585 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),12586 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());12587}12588} // namespace12589template <typename Derived>12590OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(12591 ArrayRef<const OpenACCClause *> ExistingClauses,12592 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {12593 12594 SemaOpenACC::OpenACCParsedClause ParsedClause(12595 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());12596 ParsedClause.setEndLoc(OldClause->getEndLoc());12597 12598 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(OldClause))12599 ParsedClause.setLParenLoc(WithParms->getLParenLoc());12600 12601 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,12602 ParsedClause};12603 Transform.Visit(OldClause);12604 12605 return Transform.CreatedClause();12606}12607 12608template <typename Derived>12609llvm::SmallVector<OpenACCClause *>12610TreeTransform<Derived>::TransformOpenACCClauseList(12611 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {12612 llvm::SmallVector<OpenACCClause *> TransformedClauses;12613 for (const auto *Clause : OldClauses) {12614 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(12615 TransformedClauses, DirKind, Clause))12616 TransformedClauses.push_back(TransformedClause);12617 }12618 return TransformedClauses;12619}12620 12621template <typename Derived>12622StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(12623 OpenACCComputeConstruct *C) {12624 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12625 12626 llvm::SmallVector<OpenACCClause *> TransformedClauses =12627 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),12628 C->clauses());12629 12630 if (getSema().OpenACC().ActOnStartStmtDirective(12631 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))12632 return StmtError();12633 12634 // Transform Structured Block.12635 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(12636 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),12637 C->clauses(), TransformedClauses);12638 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());12639 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(12640 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);12641 12642 return getDerived().RebuildOpenACCComputeConstruct(12643 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),12644 C->getEndLoc(), TransformedClauses, StrBlock);12645}12646 12647template <typename Derived>12648StmtResult12649TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {12650 12651 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12652 12653 llvm::SmallVector<OpenACCClause *> TransformedClauses =12654 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),12655 C->clauses());12656 12657 if (getSema().OpenACC().ActOnStartStmtDirective(12658 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))12659 return StmtError();12660 12661 // Transform Loop.12662 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(12663 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),12664 C->clauses(), TransformedClauses);12665 StmtResult Loop = getDerived().TransformStmt(C->getLoop());12666 Loop = getSema().OpenACC().ActOnAssociatedStmt(12667 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);12668 12669 return getDerived().RebuildOpenACCLoopConstruct(12670 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),12671 TransformedClauses, Loop);12672}12673 12674template <typename Derived>12675StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(12676 OpenACCCombinedConstruct *C) {12677 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12678 12679 llvm::SmallVector<OpenACCClause *> TransformedClauses =12680 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),12681 C->clauses());12682 12683 if (getSema().OpenACC().ActOnStartStmtDirective(12684 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))12685 return StmtError();12686 12687 // Transform Loop.12688 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(12689 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),12690 C->clauses(), TransformedClauses);12691 StmtResult Loop = getDerived().TransformStmt(C->getLoop());12692 Loop = getSema().OpenACC().ActOnAssociatedStmt(12693 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);12694 12695 return getDerived().RebuildOpenACCCombinedConstruct(12696 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),12697 C->getEndLoc(), TransformedClauses, Loop);12698}12699 12700template <typename Derived>12701StmtResult12702TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {12703 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12704 12705 llvm::SmallVector<OpenACCClause *> TransformedClauses =12706 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),12707 C->clauses());12708 if (getSema().OpenACC().ActOnStartStmtDirective(12709 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))12710 return StmtError();12711 12712 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(12713 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),12714 C->clauses(), TransformedClauses);12715 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());12716 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(12717 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);12718 12719 return getDerived().RebuildOpenACCDataConstruct(12720 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),12721 TransformedClauses, StrBlock);12722}12723 12724template <typename Derived>12725StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(12726 OpenACCEnterDataConstruct *C) {12727 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12728 12729 llvm::SmallVector<OpenACCClause *> TransformedClauses =12730 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),12731 C->clauses());12732 if (getSema().OpenACC().ActOnStartStmtDirective(12733 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))12734 return StmtError();12735 12736 return getDerived().RebuildOpenACCEnterDataConstruct(12737 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),12738 TransformedClauses);12739}12740 12741template <typename Derived>12742StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(12743 OpenACCExitDataConstruct *C) {12744 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12745 12746 llvm::SmallVector<OpenACCClause *> TransformedClauses =12747 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),12748 C->clauses());12749 if (getSema().OpenACC().ActOnStartStmtDirective(12750 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))12751 return StmtError();12752 12753 return getDerived().RebuildOpenACCExitDataConstruct(12754 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),12755 TransformedClauses);12756}12757 12758template <typename Derived>12759StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(12760 OpenACCHostDataConstruct *C) {12761 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12762 12763 llvm::SmallVector<OpenACCClause *> TransformedClauses =12764 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),12765 C->clauses());12766 if (getSema().OpenACC().ActOnStartStmtDirective(12767 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))12768 return StmtError();12769 12770 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(12771 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),12772 C->clauses(), TransformedClauses);12773 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());12774 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(12775 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);12776 12777 return getDerived().RebuildOpenACCHostDataConstruct(12778 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),12779 TransformedClauses, StrBlock);12780}12781 12782template <typename Derived>12783StmtResult12784TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {12785 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12786 12787 llvm::SmallVector<OpenACCClause *> TransformedClauses =12788 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),12789 C->clauses());12790 if (getSema().OpenACC().ActOnStartStmtDirective(12791 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))12792 return StmtError();12793 12794 return getDerived().RebuildOpenACCInitConstruct(12795 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),12796 TransformedClauses);12797}12798 12799template <typename Derived>12800StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(12801 OpenACCShutdownConstruct *C) {12802 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12803 12804 llvm::SmallVector<OpenACCClause *> TransformedClauses =12805 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),12806 C->clauses());12807 if (getSema().OpenACC().ActOnStartStmtDirective(12808 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))12809 return StmtError();12810 12811 return getDerived().RebuildOpenACCShutdownConstruct(12812 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),12813 TransformedClauses);12814}12815template <typename Derived>12816StmtResult12817TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {12818 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12819 12820 llvm::SmallVector<OpenACCClause *> TransformedClauses =12821 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),12822 C->clauses());12823 if (getSema().OpenACC().ActOnStartStmtDirective(12824 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))12825 return StmtError();12826 12827 return getDerived().RebuildOpenACCSetConstruct(12828 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),12829 TransformedClauses);12830}12831 12832template <typename Derived>12833StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(12834 OpenACCUpdateConstruct *C) {12835 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12836 12837 llvm::SmallVector<OpenACCClause *> TransformedClauses =12838 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),12839 C->clauses());12840 if (getSema().OpenACC().ActOnStartStmtDirective(12841 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))12842 return StmtError();12843 12844 return getDerived().RebuildOpenACCUpdateConstruct(12845 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),12846 TransformedClauses);12847}12848 12849template <typename Derived>12850StmtResult12851TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {12852 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12853 12854 ExprResult DevNumExpr;12855 if (C->hasDevNumExpr()) {12856 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());12857 12858 if (DevNumExpr.isUsable())12859 DevNumExpr = getSema().OpenACC().ActOnIntExpr(12860 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,12861 C->getBeginLoc(), DevNumExpr.get());12862 }12863 12864 llvm::SmallVector<Expr *> QueueIdExprs;12865 12866 for (Expr *QE : C->getQueueIdExprs()) {12867 assert(QE && "Null queue id expr?");12868 ExprResult NewEQ = getDerived().TransformExpr(QE);12869 12870 if (!NewEQ.isUsable())12871 break;12872 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,12873 OpenACCClauseKind::Invalid,12874 C->getBeginLoc(), NewEQ.get());12875 if (NewEQ.isUsable())12876 QueueIdExprs.push_back(NewEQ.get());12877 }12878 12879 llvm::SmallVector<OpenACCClause *> TransformedClauses =12880 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),12881 C->clauses());12882 12883 if (getSema().OpenACC().ActOnStartStmtDirective(12884 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))12885 return StmtError();12886 12887 return getDerived().RebuildOpenACCWaitConstruct(12888 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),12889 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),12890 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);12891}12892template <typename Derived>12893StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(12894 OpenACCCacheConstruct *C) {12895 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12896 12897 llvm::SmallVector<Expr *> TransformedVarList;12898 for (Expr *Var : C->getVarList()) {12899 assert(Var && "Null var listexpr?");12900 12901 ExprResult NewVar = getDerived().TransformExpr(Var);12902 12903 if (!NewVar.isUsable())12904 break;12905 12906 NewVar = getSema().OpenACC().ActOnVar(12907 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());12908 if (!NewVar.isUsable())12909 break;12910 12911 TransformedVarList.push_back(NewVar.get());12912 }12913 12914 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),12915 C->getBeginLoc(), {}))12916 return StmtError();12917 12918 return getDerived().RebuildOpenACCCacheConstruct(12919 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),12920 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),12921 C->getEndLoc());12922}12923 12924template <typename Derived>12925StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(12926 OpenACCAtomicConstruct *C) {12927 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());12928 12929 llvm::SmallVector<OpenACCClause *> TransformedClauses =12930 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),12931 C->clauses());12932 12933 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),12934 C->getBeginLoc(), {}))12935 return StmtError();12936 12937 // Transform Associated Stmt.12938 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(12939 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});12940 12941 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());12942 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(12943 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},12944 AssocStmt);12945 12946 return getDerived().RebuildOpenACCAtomicConstruct(12947 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),12948 C->getEndLoc(), TransformedClauses, AssocStmt);12949}12950 12951template <typename Derived>12952ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(12953 OpenACCAsteriskSizeExpr *E) {12954 if (getDerived().AlwaysRebuild())12955 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());12956 // Nothing can ever change, so there is never anything to transform.12957 return E;12958}12959 12960//===----------------------------------------------------------------------===//12961// Expression transformation12962//===----------------------------------------------------------------------===//12963template<typename Derived>12964ExprResult12965TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {12966 return TransformExpr(E->getSubExpr());12967}12968 12969template <typename Derived>12970ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(12971 SYCLUniqueStableNameExpr *E) {12972 if (!E->isTypeDependent())12973 return E;12974 12975 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());12976 12977 if (!NewT)12978 return ExprError();12979 12980 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)12981 return E;12982 12983 return getDerived().RebuildSYCLUniqueStableNameExpr(12984 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);12985}12986 12987template<typename Derived>12988ExprResult12989TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {12990 if (!E->isTypeDependent())12991 return E;12992 12993 return getDerived().RebuildPredefinedExpr(E->getLocation(),12994 E->getIdentKind());12995}12996 12997template<typename Derived>12998ExprResult12999TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {13000 NestedNameSpecifierLoc QualifierLoc;13001 if (E->getQualifierLoc()) {13002 QualifierLoc13003 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());13004 if (!QualifierLoc)13005 return ExprError();13006 }13007 13008 ValueDecl *ND13009 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),13010 E->getDecl()));13011 if (!ND || ND->isInvalidDecl())13012 return ExprError();13013 13014 NamedDecl *Found = ND;13015 if (E->getFoundDecl() != E->getDecl()) {13016 Found = cast_or_null<NamedDecl>(13017 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));13018 if (!Found)13019 return ExprError();13020 }13021 13022 DeclarationNameInfo NameInfo = E->getNameInfo();13023 if (NameInfo.getName()) {13024 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);13025 if (!NameInfo.getName())13026 return ExprError();13027 }13028 13029 if (!getDerived().AlwaysRebuild() &&13030 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&13031 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&13032 Found == E->getFoundDecl() &&13033 NameInfo.getName() == E->getDecl()->getDeclName() &&13034 !E->hasExplicitTemplateArgs()) {13035 13036 // Mark it referenced in the new context regardless.13037 // FIXME: this is a bit instantiation-specific.13038 SemaRef.MarkDeclRefReferenced(E);13039 13040 return E;13041 }13042 13043 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;13044 if (E->hasExplicitTemplateArgs()) {13045 TemplateArgs = &TransArgs;13046 TransArgs.setLAngleLoc(E->getLAngleLoc());13047 TransArgs.setRAngleLoc(E->getRAngleLoc());13048 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),13049 E->getNumTemplateArgs(),13050 TransArgs))13051 return ExprError();13052 }13053 13054 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,13055 Found, TemplateArgs);13056}13057 13058template<typename Derived>13059ExprResult13060TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {13061 return E;13062}13063 13064template <typename Derived>13065ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(13066 FixedPointLiteral *E) {13067 return E;13068}13069 13070template<typename Derived>13071ExprResult13072TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {13073 return E;13074}13075 13076template<typename Derived>13077ExprResult13078TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {13079 return E;13080}13081 13082template<typename Derived>13083ExprResult13084TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {13085 return E;13086}13087 13088template<typename Derived>13089ExprResult13090TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {13091 return E;13092}13093 13094template<typename Derived>13095ExprResult13096TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {13097 return getDerived().TransformCallExpr(E);13098}13099 13100template<typename Derived>13101ExprResult13102TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {13103 ExprResult ControllingExpr;13104 TypeSourceInfo *ControllingType = nullptr;13105 if (E->isExprPredicate())13106 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());13107 else13108 ControllingType = getDerived().TransformType(E->getControllingType());13109 13110 if (ControllingExpr.isInvalid() && !ControllingType)13111 return ExprError();13112 13113 SmallVector<Expr *, 4> AssocExprs;13114 SmallVector<TypeSourceInfo *, 4> AssocTypes;13115 for (const GenericSelectionExpr::Association Assoc : E->associations()) {13116 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();13117 if (TSI) {13118 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);13119 if (!AssocType)13120 return ExprError();13121 AssocTypes.push_back(AssocType);13122 } else {13123 AssocTypes.push_back(nullptr);13124 }13125 13126 ExprResult AssocExpr =13127 getDerived().TransformExpr(Assoc.getAssociationExpr());13128 if (AssocExpr.isInvalid())13129 return ExprError();13130 AssocExprs.push_back(AssocExpr.get());13131 }13132 13133 if (!ControllingType)13134 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),13135 E->getDefaultLoc(),13136 E->getRParenLoc(),13137 ControllingExpr.get(),13138 AssocTypes,13139 AssocExprs);13140 return getDerived().RebuildGenericSelectionExpr(13141 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),13142 ControllingType, AssocTypes, AssocExprs);13143}13144 13145template<typename Derived>13146ExprResult13147TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {13148 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());13149 if (SubExpr.isInvalid())13150 return ExprError();13151 13152 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())13153 return E;13154 13155 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),13156 E->getRParen());13157}13158 13159/// The operand of a unary address-of operator has special rules: it's13160/// allowed to refer to a non-static member of a class even if there's no 'this'13161/// object available.13162template<typename Derived>13163ExprResult13164TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {13165 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))13166 return getDerived().TransformDependentScopeDeclRefExpr(13167 DRE, /*IsAddressOfOperand=*/true, nullptr);13168 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E))13169 return getDerived().TransformUnresolvedLookupExpr(13170 ULE, /*IsAddressOfOperand=*/true);13171 else13172 return getDerived().TransformExpr(E);13173}13174 13175template<typename Derived>13176ExprResult13177TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {13178 ExprResult SubExpr;13179 if (E->getOpcode() == UO_AddrOf)13180 SubExpr = TransformAddressOfOperand(E->getSubExpr());13181 else13182 SubExpr = TransformExpr(E->getSubExpr());13183 if (SubExpr.isInvalid())13184 return ExprError();13185 13186 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())13187 return E;13188 13189 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),13190 E->getOpcode(),13191 SubExpr.get());13192}13193 13194template<typename Derived>13195ExprResult13196TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {13197 // Transform the type.13198 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());13199 if (!Type)13200 return ExprError();13201 13202 // Transform all of the components into components similar to what the13203 // parser uses.13204 // FIXME: It would be slightly more efficient in the non-dependent case to13205 // just map FieldDecls, rather than requiring the rebuilder to look for13206 // the fields again. However, __builtin_offsetof is rare enough in13207 // template code that we don't care.13208 bool ExprChanged = false;13209 typedef Sema::OffsetOfComponent Component;13210 SmallVector<Component, 4> Components;13211 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {13212 const OffsetOfNode &ON = E->getComponent(I);13213 Component Comp;13214 Comp.isBrackets = true;13215 Comp.LocStart = ON.getSourceRange().getBegin();13216 Comp.LocEnd = ON.getSourceRange().getEnd();13217 switch (ON.getKind()) {13218 case OffsetOfNode::Array: {13219 Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());13220 ExprResult Index = getDerived().TransformExpr(FromIndex);13221 if (Index.isInvalid())13222 return ExprError();13223 13224 ExprChanged = ExprChanged || Index.get() != FromIndex;13225 Comp.isBrackets = true;13226 Comp.U.E = Index.get();13227 break;13228 }13229 13230 case OffsetOfNode::Field:13231 case OffsetOfNode::Identifier:13232 Comp.isBrackets = false;13233 Comp.U.IdentInfo = ON.getFieldName();13234 if (!Comp.U.IdentInfo)13235 continue;13236 13237 break;13238 13239 case OffsetOfNode::Base:13240 // Will be recomputed during the rebuild.13241 continue;13242 }13243 13244 Components.push_back(Comp);13245 }13246 13247 // If nothing changed, retain the existing expression.13248 if (!getDerived().AlwaysRebuild() &&13249 Type == E->getTypeSourceInfo() &&13250 !ExprChanged)13251 return E;13252 13253 // Build a new offsetof expression.13254 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,13255 Components, E->getRParenLoc());13256}13257 13258template<typename Derived>13259ExprResult13260TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {13261 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&13262 "opaque value expression requires transformation");13263 return E;13264}13265 13266template <typename Derived>13267ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {13268 llvm::SmallVector<Expr *, 8> Children;13269 bool Changed = false;13270 for (Expr *C : E->subExpressions()) {13271 ExprResult NewC = getDerived().TransformExpr(C);13272 if (NewC.isInvalid())13273 return ExprError();13274 Children.push_back(NewC.get());13275 13276 Changed |= NewC.get() != C;13277 }13278 if (!getDerived().AlwaysRebuild() && !Changed)13279 return E;13280 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),13281 Children, E->getType());13282}13283 13284template<typename Derived>13285ExprResult13286TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {13287 // Rebuild the syntactic form. The original syntactic form has13288 // opaque-value expressions in it, so strip those away and rebuild13289 // the result. This is a really awful way of doing this, but the13290 // better solution (rebuilding the semantic expressions and13291 // rebinding OVEs as necessary) doesn't work; we'd need13292 // TreeTransform to not strip away implicit conversions.13293 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);13294 ExprResult result = getDerived().TransformExpr(newSyntacticForm);13295 if (result.isInvalid()) return ExprError();13296 13297 // If that gives us a pseudo-object result back, the pseudo-object13298 // expression must have been an lvalue-to-rvalue conversion which we13299 // should reapply.13300 if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))13301 result = SemaRef.PseudoObject().checkRValue(result.get());13302 13303 return result;13304}13305 13306template<typename Derived>13307ExprResult13308TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(13309 UnaryExprOrTypeTraitExpr *E) {13310 if (E->isArgumentType()) {13311 TypeSourceInfo *OldT = E->getArgumentTypeInfo();13312 13313 TypeSourceInfo *NewT = getDerived().TransformType(OldT);13314 if (!NewT)13315 return ExprError();13316 13317 if (!getDerived().AlwaysRebuild() && OldT == NewT)13318 return E;13319 13320 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),13321 E->getKind(),13322 E->getSourceRange());13323 }13324 13325 // C++0x [expr.sizeof]p1:13326 // The operand is either an expression, which is an unevaluated operand13327 // [...]13328 EnterExpressionEvaluationContext Unevaluated(13329 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,13330 Sema::ReuseLambdaContextDecl);13331 13332 // Try to recover if we have something like sizeof(T::X) where X is a type.13333 // Notably, there must be *exactly* one set of parens if X is a type.13334 TypeSourceInfo *RecoveryTSI = nullptr;13335 ExprResult SubExpr;13336 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());13337 if (auto *DRE =13338 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)13339 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(13340 PE, DRE, false, &RecoveryTSI);13341 else13342 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());13343 13344 if (RecoveryTSI) {13345 return getDerived().RebuildUnaryExprOrTypeTrait(13346 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());13347 } else if (SubExpr.isInvalid())13348 return ExprError();13349 13350 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())13351 return E;13352 13353 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),13354 E->getOperatorLoc(),13355 E->getKind(),13356 E->getSourceRange());13357}13358 13359template<typename Derived>13360ExprResult13361TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {13362 ExprResult LHS = getDerived().TransformExpr(E->getLHS());13363 if (LHS.isInvalid())13364 return ExprError();13365 13366 ExprResult RHS = getDerived().TransformExpr(E->getRHS());13367 if (RHS.isInvalid())13368 return ExprError();13369 13370 13371 if (!getDerived().AlwaysRebuild() &&13372 LHS.get() == E->getLHS() &&13373 RHS.get() == E->getRHS())13374 return E;13375 13376 return getDerived().RebuildArraySubscriptExpr(13377 LHS.get(),13378 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());13379}13380 13381template <typename Derived>13382ExprResult13383TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {13384 ExprResult Base = getDerived().TransformExpr(E->getBase());13385 if (Base.isInvalid())13386 return ExprError();13387 13388 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());13389 if (RowIdx.isInvalid())13390 return ExprError();13391 13392 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());13393 if (ColumnIdx.isInvalid())13394 return ExprError();13395 13396 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&13397 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())13398 return E;13399 13400 return getDerived().RebuildMatrixSubscriptExpr(13401 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());13402}13403 13404template <typename Derived>13405ExprResult13406TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {13407 ExprResult Base = getDerived().TransformExpr(E->getBase());13408 if (Base.isInvalid())13409 return ExprError();13410 13411 ExprResult LowerBound;13412 if (E->getLowerBound()) {13413 LowerBound = getDerived().TransformExpr(E->getLowerBound());13414 if (LowerBound.isInvalid())13415 return ExprError();13416 }13417 13418 ExprResult Length;13419 if (E->getLength()) {13420 Length = getDerived().TransformExpr(E->getLength());13421 if (Length.isInvalid())13422 return ExprError();13423 }13424 13425 ExprResult Stride;13426 if (E->isOMPArraySection()) {13427 if (Expr *Str = E->getStride()) {13428 Stride = getDerived().TransformExpr(Str);13429 if (Stride.isInvalid())13430 return ExprError();13431 }13432 }13433 13434 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&13435 LowerBound.get() == E->getLowerBound() &&13436 Length.get() == E->getLength() &&13437 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))13438 return E;13439 13440 return getDerived().RebuildArraySectionExpr(13441 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),13442 LowerBound.get(), E->getColonLocFirst(),13443 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},13444 Length.get(), Stride.get(), E->getRBracketLoc());13445}13446 13447template <typename Derived>13448ExprResult13449TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {13450 ExprResult Base = getDerived().TransformExpr(E->getBase());13451 if (Base.isInvalid())13452 return ExprError();13453 13454 SmallVector<Expr *, 4> Dims;13455 bool ErrorFound = false;13456 for (Expr *Dim : E->getDimensions()) {13457 ExprResult DimRes = getDerived().TransformExpr(Dim);13458 if (DimRes.isInvalid()) {13459 ErrorFound = true;13460 continue;13461 }13462 Dims.push_back(DimRes.get());13463 }13464 13465 if (ErrorFound)13466 return ExprError();13467 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),13468 E->getRParenLoc(), Dims,13469 E->getBracketsRanges());13470}13471 13472template <typename Derived>13473ExprResult13474TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {13475 unsigned NumIterators = E->numOfIterators();13476 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);13477 13478 bool ErrorFound = false;13479 bool NeedToRebuild = getDerived().AlwaysRebuild();13480 for (unsigned I = 0; I < NumIterators; ++I) {13481 auto *D = cast<VarDecl>(E->getIteratorDecl(I));13482 Data[I].DeclIdent = D->getIdentifier();13483 Data[I].DeclIdentLoc = D->getLocation();13484 if (D->getLocation() == D->getBeginLoc()) {13485 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&13486 "Implicit type must be int.");13487 } else {13488 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());13489 QualType DeclTy = getDerived().TransformType(D->getType());13490 Data[I].Type = SemaRef.CreateParsedType(DeclTy, TSI);13491 }13492 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);13493 ExprResult Begin = getDerived().TransformExpr(Range.Begin);13494 ExprResult End = getDerived().TransformExpr(Range.End);13495 ExprResult Step = getDerived().TransformExpr(Range.Step);13496 ErrorFound = ErrorFound ||13497 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&13498 !Data[I].Type.get().isNull())) ||13499 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();13500 if (ErrorFound)13501 continue;13502 Data[I].Range.Begin = Begin.get();13503 Data[I].Range.End = End.get();13504 Data[I].Range.Step = Step.get();13505 Data[I].AssignLoc = E->getAssignLoc(I);13506 Data[I].ColonLoc = E->getColonLoc(I);13507 Data[I].SecColonLoc = E->getSecondColonLoc(I);13508 NeedToRebuild =13509 NeedToRebuild ||13510 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=13511 D->getType().getTypePtrOrNull()) ||13512 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||13513 Range.Step != Data[I].Range.Step;13514 }13515 if (ErrorFound)13516 return ExprError();13517 if (!NeedToRebuild)13518 return E;13519 13520 ExprResult Res = getDerived().RebuildOMPIteratorExpr(13521 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);13522 if (!Res.isUsable())13523 return Res;13524 auto *IE = cast<OMPIteratorExpr>(Res.get());13525 for (unsigned I = 0; I < NumIterators; ++I)13526 getDerived().transformedLocalDecl(E->getIteratorDecl(I),13527 IE->getIteratorDecl(I));13528 return Res;13529}13530 13531template<typename Derived>13532ExprResult13533TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {13534 // Transform the callee.13535 ExprResult Callee = getDerived().TransformExpr(E->getCallee());13536 if (Callee.isInvalid())13537 return ExprError();13538 13539 // Transform arguments.13540 bool ArgChanged = false;13541 SmallVector<Expr*, 8> Args;13542 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,13543 &ArgChanged))13544 return ExprError();13545 13546 if (!getDerived().AlwaysRebuild() &&13547 Callee.get() == E->getCallee() &&13548 !ArgChanged)13549 return SemaRef.MaybeBindToTemporary(E);13550 13551 // FIXME: Wrong source location information for the '('.13552 SourceLocation FakeLParenLoc13553 = ((Expr *)Callee.get())->getSourceRange().getBegin();13554 13555 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());13556 if (E->hasStoredFPFeatures()) {13557 FPOptionsOverride NewOverrides = E->getFPFeatures();13558 getSema().CurFPFeatures =13559 NewOverrides.applyOverrides(getSema().getLangOpts());13560 getSema().FpPragmaStack.CurrentValue = NewOverrides;13561 }13562 13563 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,13564 Args,13565 E->getRParenLoc());13566}13567 13568template<typename Derived>13569ExprResult13570TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {13571 ExprResult Base = getDerived().TransformExpr(E->getBase());13572 if (Base.isInvalid())13573 return ExprError();13574 13575 NestedNameSpecifierLoc QualifierLoc;13576 if (E->hasQualifier()) {13577 QualifierLoc13578 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());13579 13580 if (!QualifierLoc)13581 return ExprError();13582 }13583 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();13584 13585 ValueDecl *Member13586 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),13587 E->getMemberDecl()));13588 if (!Member)13589 return ExprError();13590 13591 NamedDecl *FoundDecl = E->getFoundDecl();13592 if (FoundDecl == E->getMemberDecl()) {13593 FoundDecl = Member;13594 } else {13595 FoundDecl = cast_or_null<NamedDecl>(13596 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));13597 if (!FoundDecl)13598 return ExprError();13599 }13600 13601 if (!getDerived().AlwaysRebuild() &&13602 Base.get() == E->getBase() &&13603 QualifierLoc == E->getQualifierLoc() &&13604 Member == E->getMemberDecl() &&13605 FoundDecl == E->getFoundDecl() &&13606 !E->hasExplicitTemplateArgs()) {13607 13608 // Skip for member expression of (this->f), rebuilt thisi->f is needed13609 // for Openmp where the field need to be privatizized in the case.13610 if (!(isa<CXXThisExpr>(E->getBase()) &&13611 getSema().OpenMP().isOpenMPRebuildMemberExpr(13612 cast<ValueDecl>(Member)))) {13613 // Mark it referenced in the new context regardless.13614 // FIXME: this is a bit instantiation-specific.13615 SemaRef.MarkMemberReferenced(E);13616 return E;13617 }13618 }13619 13620 TemplateArgumentListInfo TransArgs;13621 if (E->hasExplicitTemplateArgs()) {13622 TransArgs.setLAngleLoc(E->getLAngleLoc());13623 TransArgs.setRAngleLoc(E->getRAngleLoc());13624 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),13625 E->getNumTemplateArgs(),13626 TransArgs))13627 return ExprError();13628 }13629 13630 // FIXME: Bogus source location for the operator13631 SourceLocation FakeOperatorLoc =13632 SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());13633 13634 // FIXME: to do this check properly, we will need to preserve the13635 // first-qualifier-in-scope here, just in case we had a dependent13636 // base (and therefore couldn't do the check) and a13637 // nested-name-qualifier (and therefore could do the lookup).13638 NamedDecl *FirstQualifierInScope = nullptr;13639 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();13640 if (MemberNameInfo.getName()) {13641 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);13642 if (!MemberNameInfo.getName())13643 return ExprError();13644 }13645 13646 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,13647 E->isArrow(),13648 QualifierLoc,13649 TemplateKWLoc,13650 MemberNameInfo,13651 Member,13652 FoundDecl,13653 (E->hasExplicitTemplateArgs()13654 ? &TransArgs : nullptr),13655 FirstQualifierInScope);13656}13657 13658template<typename Derived>13659ExprResult13660TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {13661 ExprResult LHS = getDerived().TransformExpr(E->getLHS());13662 if (LHS.isInvalid())13663 return ExprError();13664 13665 ExprResult RHS =13666 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);13667 if (RHS.isInvalid())13668 return ExprError();13669 13670 if (!getDerived().AlwaysRebuild() &&13671 LHS.get() == E->getLHS() &&13672 RHS.get() == E->getRHS())13673 return E;13674 13675 if (E->isCompoundAssignmentOp())13676 // FPFeatures has already been established from trailing storage13677 return getDerived().RebuildBinaryOperator(13678 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());13679 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());13680 FPOptionsOverride NewOverrides(E->getFPFeatures());13681 getSema().CurFPFeatures =13682 NewOverrides.applyOverrides(getSema().getLangOpts());13683 getSema().FpPragmaStack.CurrentValue = NewOverrides;13684 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),13685 LHS.get(), RHS.get());13686}13687 13688template <typename Derived>13689ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(13690 CXXRewrittenBinaryOperator *E) {13691 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();13692 13693 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));13694 if (LHS.isInvalid())13695 return ExprError();13696 13697 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));13698 if (RHS.isInvalid())13699 return ExprError();13700 13701 // Extract the already-resolved callee declarations so that we can restrict13702 // ourselves to using them as the unqualified lookup results when rebuilding.13703 UnresolvedSet<2> UnqualLookups;13704 bool ChangedAnyLookups = false;13705 Expr *PossibleBinOps[] = {E->getSemanticForm(),13706 const_cast<Expr *>(Decomp.InnerBinOp)};13707 for (Expr *PossibleBinOp : PossibleBinOps) {13708 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());13709 if (!Op)13710 continue;13711 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());13712 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))13713 continue;13714 13715 // Transform the callee in case we built a call to a local extern13716 // declaration.13717 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(13718 E->getOperatorLoc(), Callee->getFoundDecl()));13719 if (!Found)13720 return ExprError();13721 if (Found != Callee->getFoundDecl())13722 ChangedAnyLookups = true;13723 UnqualLookups.addDecl(Found);13724 }13725 13726 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&13727 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {13728 // Mark all functions used in the rewrite as referenced. Note that when13729 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be13730 // function calls, and/or there might be a user-defined conversion sequence13731 // applied to the operands of the <.13732 // FIXME: this is a bit instantiation-specific.13733 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};13734 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);13735 return E;13736 }13737 13738 return getDerived().RebuildCXXRewrittenBinaryOperator(13739 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());13740}13741 13742template<typename Derived>13743ExprResult13744TreeTransform<Derived>::TransformCompoundAssignOperator(13745 CompoundAssignOperator *E) {13746 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());13747 FPOptionsOverride NewOverrides(E->getFPFeatures());13748 getSema().CurFPFeatures =13749 NewOverrides.applyOverrides(getSema().getLangOpts());13750 getSema().FpPragmaStack.CurrentValue = NewOverrides;13751 return getDerived().TransformBinaryOperator(E);13752}13753 13754template<typename Derived>13755ExprResult TreeTransform<Derived>::13756TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {13757 // Just rebuild the common and RHS expressions and see whether we13758 // get any changes.13759 13760 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());13761 if (commonExpr.isInvalid())13762 return ExprError();13763 13764 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());13765 if (rhs.isInvalid())13766 return ExprError();13767 13768 if (!getDerived().AlwaysRebuild() &&13769 commonExpr.get() == e->getCommon() &&13770 rhs.get() == e->getFalseExpr())13771 return e;13772 13773 return getDerived().RebuildConditionalOperator(commonExpr.get(),13774 e->getQuestionLoc(),13775 nullptr,13776 e->getColonLoc(),13777 rhs.get());13778}13779 13780template<typename Derived>13781ExprResult13782TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {13783 ExprResult Cond = getDerived().TransformExpr(E->getCond());13784 if (Cond.isInvalid())13785 return ExprError();13786 13787 ExprResult LHS = getDerived().TransformExpr(E->getLHS());13788 if (LHS.isInvalid())13789 return ExprError();13790 13791 ExprResult RHS = getDerived().TransformExpr(E->getRHS());13792 if (RHS.isInvalid())13793 return ExprError();13794 13795 if (!getDerived().AlwaysRebuild() &&13796 Cond.get() == E->getCond() &&13797 LHS.get() == E->getLHS() &&13798 RHS.get() == E->getRHS())13799 return E;13800 13801 return getDerived().RebuildConditionalOperator(Cond.get(),13802 E->getQuestionLoc(),13803 LHS.get(),13804 E->getColonLoc(),13805 RHS.get());13806}13807 13808template<typename Derived>13809ExprResult13810TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {13811 // Implicit casts are eliminated during transformation, since they13812 // will be recomputed by semantic analysis after transformation.13813 return getDerived().TransformExpr(E->getSubExprAsWritten());13814}13815 13816template<typename Derived>13817ExprResult13818TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {13819 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());13820 if (!Type)13821 return ExprError();13822 13823 ExprResult SubExpr13824 = getDerived().TransformExpr(E->getSubExprAsWritten());13825 if (SubExpr.isInvalid())13826 return ExprError();13827 13828 if (!getDerived().AlwaysRebuild() &&13829 Type == E->getTypeInfoAsWritten() &&13830 SubExpr.get() == E->getSubExpr())13831 return E;13832 13833 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),13834 Type,13835 E->getRParenLoc(),13836 SubExpr.get());13837}13838 13839template<typename Derived>13840ExprResult13841TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {13842 TypeSourceInfo *OldT = E->getTypeSourceInfo();13843 TypeSourceInfo *NewT = getDerived().TransformType(OldT);13844 if (!NewT)13845 return ExprError();13846 13847 ExprResult Init = getDerived().TransformExpr(E->getInitializer());13848 if (Init.isInvalid())13849 return ExprError();13850 13851 if (!getDerived().AlwaysRebuild() &&13852 OldT == NewT &&13853 Init.get() == E->getInitializer())13854 return SemaRef.MaybeBindToTemporary(E);13855 13856 // Note: the expression type doesn't necessarily match the13857 // type-as-written, but that's okay, because it should always be13858 // derivable from the initializer.13859 13860 return getDerived().RebuildCompoundLiteralExpr(13861 E->getLParenLoc(), NewT,13862 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());13863}13864 13865template<typename Derived>13866ExprResult13867TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {13868 ExprResult Base = getDerived().TransformExpr(E->getBase());13869 if (Base.isInvalid())13870 return ExprError();13871 13872 if (!getDerived().AlwaysRebuild() &&13873 Base.get() == E->getBase())13874 return E;13875 13876 // FIXME: Bad source location13877 SourceLocation FakeOperatorLoc =13878 SemaRef.getLocForEndOfToken(E->getBase()->getEndLoc());13879 return getDerived().RebuildExtVectorElementExpr(13880 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),13881 E->getAccessor());13882}13883 13884template<typename Derived>13885ExprResult13886TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {13887 if (InitListExpr *Syntactic = E->getSyntacticForm())13888 E = Syntactic;13889 13890 bool InitChanged = false;13891 13892 EnterExpressionEvaluationContext Context(13893 getSema(), EnterExpressionEvaluationContext::InitList);13894 13895 SmallVector<Expr*, 4> Inits;13896 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,13897 Inits, &InitChanged))13898 return ExprError();13899 13900 if (!getDerived().AlwaysRebuild() && !InitChanged) {13901 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr13902 // in some cases. We can't reuse it in general, because the syntactic and13903 // semantic forms are linked, and we can't know that semantic form will13904 // match even if the syntactic form does.13905 }13906 13907 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,13908 E->getRBraceLoc());13909}13910 13911template<typename Derived>13912ExprResult13913TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {13914 Designation Desig;13915 13916 // transform the initializer value13917 ExprResult Init = getDerived().TransformExpr(E->getInit());13918 if (Init.isInvalid())13919 return ExprError();13920 13921 // transform the designators.13922 SmallVector<Expr*, 4> ArrayExprs;13923 bool ExprChanged = false;13924 for (const DesignatedInitExpr::Designator &D : E->designators()) {13925 if (D.isFieldDesignator()) {13926 if (D.getFieldDecl()) {13927 FieldDecl *Field = cast_or_null<FieldDecl>(13928 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));13929 if (Field != D.getFieldDecl())13930 // Rebuild the expression when the transformed FieldDecl is13931 // different to the already assigned FieldDecl.13932 ExprChanged = true;13933 if (Field->isAnonymousStructOrUnion())13934 continue;13935 } else {13936 // Ensure that the designator expression is rebuilt when there isn't13937 // a resolved FieldDecl in the designator as we don't want to assign13938 // a FieldDecl to a pattern designator that will be instantiated again.13939 ExprChanged = true;13940 }13941 Desig.AddDesignator(Designator::CreateFieldDesignator(13942 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));13943 continue;13944 }13945 13946 if (D.isArrayDesignator()) {13947 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));13948 if (Index.isInvalid())13949 return ExprError();13950 13951 Desig.AddDesignator(13952 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));13953 13954 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);13955 ArrayExprs.push_back(Index.get());13956 continue;13957 }13958 13959 assert(D.isArrayRangeDesignator() && "New kind of designator?");13960 ExprResult Start13961 = getDerived().TransformExpr(E->getArrayRangeStart(D));13962 if (Start.isInvalid())13963 return ExprError();13964 13965 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));13966 if (End.isInvalid())13967 return ExprError();13968 13969 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(13970 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));13971 13972 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||13973 End.get() != E->getArrayRangeEnd(D);13974 13975 ArrayExprs.push_back(Start.get());13976 ArrayExprs.push_back(End.get());13977 }13978 13979 if (!getDerived().AlwaysRebuild() &&13980 Init.get() == E->getInit() &&13981 !ExprChanged)13982 return E;13983 13984 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,13985 E->getEqualOrColonLoc(),13986 E->usesGNUSyntax(), Init.get());13987}13988 13989// Seems that if TransformInitListExpr() only works on the syntactic form of an13990// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.13991template<typename Derived>13992ExprResult13993TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(13994 DesignatedInitUpdateExpr *E) {13995 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "13996 "initializer");13997 return ExprError();13998}13999 14000template<typename Derived>14001ExprResult14002TreeTransform<Derived>::TransformNoInitExpr(14003 NoInitExpr *E) {14004 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");14005 return ExprError();14006}14007 14008template<typename Derived>14009ExprResult14010TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {14011 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");14012 return ExprError();14013}14014 14015template<typename Derived>14016ExprResult14017TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {14018 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");14019 return ExprError();14020}14021 14022template<typename Derived>14023ExprResult14024TreeTransform<Derived>::TransformImplicitValueInitExpr(14025 ImplicitValueInitExpr *E) {14026 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());14027 14028 // FIXME: Will we ever have proper type location here? Will we actually14029 // need to transform the type?14030 QualType T = getDerived().TransformType(E->getType());14031 if (T.isNull())14032 return ExprError();14033 14034 if (!getDerived().AlwaysRebuild() &&14035 T == E->getType())14036 return E;14037 14038 return getDerived().RebuildImplicitValueInitExpr(T);14039}14040 14041template<typename Derived>14042ExprResult14043TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {14044 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());14045 if (!TInfo)14046 return ExprError();14047 14048 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());14049 if (SubExpr.isInvalid())14050 return ExprError();14051 14052 if (!getDerived().AlwaysRebuild() &&14053 TInfo == E->getWrittenTypeInfo() &&14054 SubExpr.get() == E->getSubExpr())14055 return E;14056 14057 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),14058 TInfo, E->getRParenLoc());14059}14060 14061template<typename Derived>14062ExprResult14063TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {14064 bool ArgumentChanged = false;14065 SmallVector<Expr*, 4> Inits;14066 if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits,14067 &ArgumentChanged))14068 return ExprError();14069 14070 return getDerived().RebuildParenListExpr(E->getLParenLoc(),14071 Inits,14072 E->getRParenLoc());14073}14074 14075/// Transform an address-of-label expression.14076///14077/// By default, the transformation of an address-of-label expression always14078/// rebuilds the expression, so that the label identifier can be resolved to14079/// the corresponding label statement by semantic analysis.14080template<typename Derived>14081ExprResult14082TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {14083 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),14084 E->getLabel());14085 if (!LD)14086 return ExprError();14087 14088 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),14089 cast<LabelDecl>(LD));14090}14091 14092template<typename Derived>14093ExprResult14094TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {14095 SemaRef.ActOnStartStmtExpr();14096 StmtResult SubStmt14097 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);14098 if (SubStmt.isInvalid()) {14099 SemaRef.ActOnStmtExprError();14100 return ExprError();14101 }14102 14103 unsigned OldDepth = E->getTemplateDepth();14104 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);14105 14106 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&14107 SubStmt.get() == E->getSubStmt()) {14108 // Calling this an 'error' is unintuitive, but it does the right thing.14109 SemaRef.ActOnStmtExprError();14110 return SemaRef.MaybeBindToTemporary(E);14111 }14112 14113 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),14114 E->getRParenLoc(), NewDepth);14115}14116 14117template<typename Derived>14118ExprResult14119TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {14120 ExprResult Cond = getDerived().TransformExpr(E->getCond());14121 if (Cond.isInvalid())14122 return ExprError();14123 14124 ExprResult LHS = getDerived().TransformExpr(E->getLHS());14125 if (LHS.isInvalid())14126 return ExprError();14127 14128 ExprResult RHS = getDerived().TransformExpr(E->getRHS());14129 if (RHS.isInvalid())14130 return ExprError();14131 14132 if (!getDerived().AlwaysRebuild() &&14133 Cond.get() == E->getCond() &&14134 LHS.get() == E->getLHS() &&14135 RHS.get() == E->getRHS())14136 return E;14137 14138 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),14139 Cond.get(), LHS.get(), RHS.get(),14140 E->getRParenLoc());14141}14142 14143template<typename Derived>14144ExprResult14145TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {14146 return E;14147}14148 14149template<typename Derived>14150ExprResult14151TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {14152 switch (E->getOperator()) {14153 case OO_New:14154 case OO_Delete:14155 case OO_Array_New:14156 case OO_Array_Delete:14157 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");14158 14159 case OO_Subscript:14160 case OO_Call: {14161 // This is a call to an object's operator().14162 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");14163 14164 // Transform the object itself.14165 ExprResult Object = getDerived().TransformExpr(E->getArg(0));14166 if (Object.isInvalid())14167 return ExprError();14168 14169 // FIXME: Poor location information. Also, if the location for the end of14170 // the token is within a macro expansion, getLocForEndOfToken() will return14171 // an invalid source location. If that happens and we have an otherwise14172 // valid end location, use the valid one instead of the invalid one.14173 SourceLocation EndLoc = static_cast<Expr *>(Object.get())->getEndLoc();14174 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(EndLoc);14175 if (FakeLParenLoc.isInvalid() && EndLoc.isValid())14176 FakeLParenLoc = EndLoc;14177 14178 // Transform the call arguments.14179 SmallVector<Expr*, 8> Args;14180 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,14181 Args))14182 return ExprError();14183 14184 if (E->getOperator() == OO_Subscript)14185 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,14186 Args, E->getEndLoc());14187 14188 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,14189 E->getEndLoc());14190 }14191 14192#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \14193 case OO_##Name: \14194 break;14195 14196#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)14197#include "clang/Basic/OperatorKinds.def"14198 14199 case OO_Conditional:14200 llvm_unreachable("conditional operator is not actually overloadable");14201 14202 case OO_None:14203 case NUM_OVERLOADED_OPERATORS:14204 llvm_unreachable("not an overloaded operator?");14205 }14206 14207 ExprResult First;14208 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)14209 First = getDerived().TransformAddressOfOperand(E->getArg(0));14210 else14211 First = getDerived().TransformExpr(E->getArg(0));14212 if (First.isInvalid())14213 return ExprError();14214 14215 ExprResult Second;14216 if (E->getNumArgs() == 2) {14217 Second =14218 getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);14219 if (Second.isInvalid())14220 return ExprError();14221 }14222 14223 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());14224 FPOptionsOverride NewOverrides(E->getFPFeatures());14225 getSema().CurFPFeatures =14226 NewOverrides.applyOverrides(getSema().getLangOpts());14227 getSema().FpPragmaStack.CurrentValue = NewOverrides;14228 14229 Expr *Callee = E->getCallee();14230 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {14231 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),14232 Sema::LookupOrdinaryName);14233 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))14234 return ExprError();14235 14236 return getDerived().RebuildCXXOperatorCallExpr(14237 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),14238 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());14239 }14240 14241 UnresolvedSet<1> Functions;14242 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))14243 Callee = ICE->getSubExprAsWritten();14244 NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();14245 ValueDecl *VD = cast_or_null<ValueDecl>(14246 getDerived().TransformDecl(DR->getLocation(), DR));14247 if (!VD)14248 return ExprError();14249 14250 if (!isa<CXXMethodDecl>(VD))14251 Functions.addDecl(VD);14252 14253 return getDerived().RebuildCXXOperatorCallExpr(14254 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),14255 /*RequiresADL=*/false, Functions, First.get(), Second.get());14256}14257 14258template<typename Derived>14259ExprResult14260TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {14261 return getDerived().TransformCallExpr(E);14262}14263 14264template <typename Derived>14265ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {14266 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(E->getIdentKind()) &&14267 getSema().CurContext != E->getParentContext();14268 14269 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)14270 return E;14271 14272 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),14273 E->getBeginLoc(), E->getEndLoc(),14274 getSema().CurContext);14275}14276 14277template <typename Derived>14278ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {14279 return E;14280}14281 14282template<typename Derived>14283ExprResult14284TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {14285 // Transform the callee.14286 ExprResult Callee = getDerived().TransformExpr(E->getCallee());14287 if (Callee.isInvalid())14288 return ExprError();14289 14290 // Transform exec config.14291 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());14292 if (EC.isInvalid())14293 return ExprError();14294 14295 // Transform arguments.14296 bool ArgChanged = false;14297 SmallVector<Expr*, 8> Args;14298 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,14299 &ArgChanged))14300 return ExprError();14301 14302 if (!getDerived().AlwaysRebuild() &&14303 Callee.get() == E->getCallee() &&14304 !ArgChanged)14305 return SemaRef.MaybeBindToTemporary(E);14306 14307 // FIXME: Wrong source location information for the '('.14308 SourceLocation FakeLParenLoc14309 = ((Expr *)Callee.get())->getSourceRange().getBegin();14310 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,14311 Args,14312 E->getRParenLoc(), EC.get());14313}14314 14315template<typename Derived>14316ExprResult14317TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {14318 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());14319 if (!Type)14320 return ExprError();14321 14322 ExprResult SubExpr14323 = getDerived().TransformExpr(E->getSubExprAsWritten());14324 if (SubExpr.isInvalid())14325 return ExprError();14326 14327 if (!getDerived().AlwaysRebuild() &&14328 Type == E->getTypeInfoAsWritten() &&14329 SubExpr.get() == E->getSubExpr())14330 return E;14331 return getDerived().RebuildCXXNamedCastExpr(14332 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),14333 Type, E->getAngleBrackets().getEnd(),14334 // FIXME. this should be '(' location14335 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());14336}14337 14338template<typename Derived>14339ExprResult14340TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {14341 TypeSourceInfo *TSI =14342 getDerived().TransformType(BCE->getTypeInfoAsWritten());14343 if (!TSI)14344 return ExprError();14345 14346 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());14347 if (Sub.isInvalid())14348 return ExprError();14349 14350 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,14351 Sub.get(), BCE->getEndLoc());14352}14353 14354template<typename Derived>14355ExprResult14356TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {14357 return getDerived().TransformCXXNamedCastExpr(E);14358}14359 14360template<typename Derived>14361ExprResult14362TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {14363 return getDerived().TransformCXXNamedCastExpr(E);14364}14365 14366template<typename Derived>14367ExprResult14368TreeTransform<Derived>::TransformCXXReinterpretCastExpr(14369 CXXReinterpretCastExpr *E) {14370 return getDerived().TransformCXXNamedCastExpr(E);14371}14372 14373template<typename Derived>14374ExprResult14375TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {14376 return getDerived().TransformCXXNamedCastExpr(E);14377}14378 14379template<typename Derived>14380ExprResult14381TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {14382 return getDerived().TransformCXXNamedCastExpr(E);14383}14384 14385template<typename Derived>14386ExprResult14387TreeTransform<Derived>::TransformCXXFunctionalCastExpr(14388 CXXFunctionalCastExpr *E) {14389 TypeSourceInfo *Type =14390 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());14391 if (!Type)14392 return ExprError();14393 14394 ExprResult SubExpr14395 = getDerived().TransformExpr(E->getSubExprAsWritten());14396 if (SubExpr.isInvalid())14397 return ExprError();14398 14399 if (!getDerived().AlwaysRebuild() &&14400 Type == E->getTypeInfoAsWritten() &&14401 SubExpr.get() == E->getSubExpr())14402 return E;14403 14404 return getDerived().RebuildCXXFunctionalCastExpr(Type,14405 E->getLParenLoc(),14406 SubExpr.get(),14407 E->getRParenLoc(),14408 E->isListInitialization());14409}14410 14411template<typename Derived>14412ExprResult14413TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {14414 if (E->isTypeOperand()) {14415 TypeSourceInfo *TInfo14416 = getDerived().TransformType(E->getTypeOperandSourceInfo());14417 if (!TInfo)14418 return ExprError();14419 14420 if (!getDerived().AlwaysRebuild() &&14421 TInfo == E->getTypeOperandSourceInfo())14422 return E;14423 14424 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),14425 TInfo, E->getEndLoc());14426 }14427 14428 // Typeid's operand is an unevaluated context, unless it's a polymorphic14429 // type. We must not unilaterally enter unevaluated context here, as then14430 // semantic processing can re-transform an already transformed operand.14431 Expr *Op = E->getExprOperand();14432 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;14433 if (E->isGLValue())14434 if (auto *RD = Op->getType()->getAsCXXRecordDecl();14435 RD && RD->isPolymorphic())14436 EvalCtx = SemaRef.ExprEvalContexts.back().Context;14437 14438 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,14439 Sema::ReuseLambdaContextDecl);14440 14441 ExprResult SubExpr = getDerived().TransformExpr(Op);14442 if (SubExpr.isInvalid())14443 return ExprError();14444 14445 if (!getDerived().AlwaysRebuild() &&14446 SubExpr.get() == E->getExprOperand())14447 return E;14448 14449 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),14450 SubExpr.get(), E->getEndLoc());14451}14452 14453template<typename Derived>14454ExprResult14455TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {14456 if (E->isTypeOperand()) {14457 TypeSourceInfo *TInfo14458 = getDerived().TransformType(E->getTypeOperandSourceInfo());14459 if (!TInfo)14460 return ExprError();14461 14462 if (!getDerived().AlwaysRebuild() &&14463 TInfo == E->getTypeOperandSourceInfo())14464 return E;14465 14466 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),14467 TInfo, E->getEndLoc());14468 }14469 14470 EnterExpressionEvaluationContext Unevaluated(14471 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);14472 14473 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());14474 if (SubExpr.isInvalid())14475 return ExprError();14476 14477 if (!getDerived().AlwaysRebuild() &&14478 SubExpr.get() == E->getExprOperand())14479 return E;14480 14481 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),14482 SubExpr.get(), E->getEndLoc());14483}14484 14485template<typename Derived>14486ExprResult14487TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {14488 return E;14489}14490 14491template<typename Derived>14492ExprResult14493TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(14494 CXXNullPtrLiteralExpr *E) {14495 return E;14496}14497 14498template<typename Derived>14499ExprResult14500TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {14501 14502 // In lambdas, the qualifiers of the type depends of where in14503 // the call operator `this` appear, and we do not have a good way to14504 // rebuild this information, so we transform the type.14505 //14506 // In other contexts, the type of `this` may be overrided14507 // for type deduction, so we need to recompute it.14508 //14509 // Always recompute the type if we're in the body of a lambda, and14510 // 'this' is dependent on a lambda's explicit object parameter; we14511 // also need to always rebuild the expression in this case to clear14512 // the flag.14513 QualType T = [&]() {14514 auto &S = getSema();14515 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())14516 return S.getCurrentThisType();14517 if (S.getCurLambda())14518 return getDerived().TransformType(E->getType());14519 return S.getCurrentThisType();14520 }();14521 14522 if (!getDerived().AlwaysRebuild() && T == E->getType() &&14523 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter()) {14524 // Mark it referenced in the new context regardless.14525 // FIXME: this is a bit instantiation-specific.14526 getSema().MarkThisReferenced(E);14527 return E;14528 }14529 14530 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());14531}14532 14533template<typename Derived>14534ExprResult14535TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {14536 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());14537 if (SubExpr.isInvalid())14538 return ExprError();14539 14540 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);14541 14542 if (!getDerived().AlwaysRebuild() &&14543 SubExpr.get() == E->getSubExpr())14544 return E;14545 14546 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),14547 E->isThrownVariableInScope());14548}14549 14550template<typename Derived>14551ExprResult14552TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {14553 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(14554 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));14555 if (!Param)14556 return ExprError();14557 14558 ExprResult InitRes;14559 if (E->hasRewrittenInit()) {14560 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());14561 if (InitRes.isInvalid())14562 return ExprError();14563 }14564 14565 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&14566 E->getUsedContext() == SemaRef.CurContext &&14567 InitRes.get() == E->getRewrittenExpr())14568 return E;14569 14570 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,14571 InitRes.get());14572}14573 14574template<typename Derived>14575ExprResult14576TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {14577 FieldDecl *Field = cast_or_null<FieldDecl>(14578 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));14579 if (!Field)14580 return ExprError();14581 14582 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&14583 E->getUsedContext() == SemaRef.CurContext)14584 return E;14585 14586 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);14587}14588 14589template<typename Derived>14590ExprResult14591TreeTransform<Derived>::TransformCXXScalarValueInitExpr(14592 CXXScalarValueInitExpr *E) {14593 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());14594 if (!T)14595 return ExprError();14596 14597 if (!getDerived().AlwaysRebuild() &&14598 T == E->getTypeSourceInfo())14599 return E;14600 14601 return getDerived().RebuildCXXScalarValueInitExpr(T,14602 /*FIXME:*/T->getTypeLoc().getEndLoc(),14603 E->getRParenLoc());14604}14605 14606template<typename Derived>14607ExprResult14608TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {14609 // Transform the type that we're allocating14610 TypeSourceInfo *AllocTypeInfo =14611 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());14612 if (!AllocTypeInfo)14613 return ExprError();14614 14615 // Transform the size of the array we're allocating (if any).14616 std::optional<Expr *> ArraySize;14617 if (E->isArray()) {14618 ExprResult NewArraySize;14619 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {14620 NewArraySize = getDerived().TransformExpr(*OldArraySize);14621 if (NewArraySize.isInvalid())14622 return ExprError();14623 }14624 ArraySize = NewArraySize.get();14625 }14626 14627 // Transform the placement arguments (if any).14628 bool ArgumentChanged = false;14629 SmallVector<Expr*, 8> PlacementArgs;14630 if (getDerived().TransformExprs(E->getPlacementArgs(),14631 E->getNumPlacementArgs(), true,14632 PlacementArgs, &ArgumentChanged))14633 return ExprError();14634 14635 // Transform the initializer (if any).14636 Expr *OldInit = E->getInitializer();14637 ExprResult NewInit;14638 if (OldInit)14639 NewInit = getDerived().TransformInitializer(OldInit, true);14640 if (NewInit.isInvalid())14641 return ExprError();14642 14643 // Transform new operator and delete operator.14644 FunctionDecl *OperatorNew = nullptr;14645 if (E->getOperatorNew()) {14646 OperatorNew = cast_or_null<FunctionDecl>(14647 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));14648 if (!OperatorNew)14649 return ExprError();14650 }14651 14652 FunctionDecl *OperatorDelete = nullptr;14653 if (E->getOperatorDelete()) {14654 OperatorDelete = cast_or_null<FunctionDecl>(14655 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));14656 if (!OperatorDelete)14657 return ExprError();14658 }14659 14660 if (!getDerived().AlwaysRebuild() &&14661 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&14662 ArraySize == E->getArraySize() &&14663 NewInit.get() == OldInit &&14664 OperatorNew == E->getOperatorNew() &&14665 OperatorDelete == E->getOperatorDelete() &&14666 !ArgumentChanged) {14667 // Mark any declarations we need as referenced.14668 // FIXME: instantiation-specific.14669 if (OperatorNew)14670 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorNew);14671 if (OperatorDelete)14672 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);14673 14674 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {14675 QualType ElementType14676 = SemaRef.Context.getBaseElementType(E->getAllocatedType());14677 if (CXXRecordDecl *Record = ElementType->getAsCXXRecordDecl()) {14678 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record))14679 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor);14680 }14681 }14682 14683 return E;14684 }14685 14686 QualType AllocType = AllocTypeInfo->getType();14687 if (!ArraySize) {14688 // If no array size was specified, but the new expression was14689 // instantiated with an array type (e.g., "new T" where T is14690 // instantiated with "int[4]"), extract the outer bound from the14691 // array type as our array size. We do this with constant and14692 // dependently-sized array types.14693 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);14694 if (!ArrayT) {14695 // Do nothing14696 } else if (const ConstantArrayType *ConsArrayT14697 = dyn_cast<ConstantArrayType>(ArrayT)) {14698 ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(),14699 SemaRef.Context.getSizeType(),14700 /*FIXME:*/ E->getBeginLoc());14701 AllocType = ConsArrayT->getElementType();14702 } else if (const DependentSizedArrayType *DepArrayT14703 = dyn_cast<DependentSizedArrayType>(ArrayT)) {14704 if (DepArrayT->getSizeExpr()) {14705 ArraySize = DepArrayT->getSizeExpr();14706 AllocType = DepArrayT->getElementType();14707 }14708 }14709 }14710 14711 return getDerived().RebuildCXXNewExpr(14712 E->getBeginLoc(), E->isGlobalNew(),14713 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,14714 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,14715 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());14716}14717 14718template<typename Derived>14719ExprResult14720TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {14721 ExprResult Operand = getDerived().TransformExpr(E->getArgument());14722 if (Operand.isInvalid())14723 return ExprError();14724 14725 // Transform the delete operator, if known.14726 FunctionDecl *OperatorDelete = nullptr;14727 if (E->getOperatorDelete()) {14728 OperatorDelete = cast_or_null<FunctionDecl>(14729 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));14730 if (!OperatorDelete)14731 return ExprError();14732 }14733 14734 if (!getDerived().AlwaysRebuild() &&14735 Operand.get() == E->getArgument() &&14736 OperatorDelete == E->getOperatorDelete()) {14737 // Mark any declarations we need as referenced.14738 // FIXME: instantiation-specific.14739 if (OperatorDelete)14740 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete);14741 14742 if (!E->getArgument()->isTypeDependent()) {14743 QualType Destroyed = SemaRef.Context.getBaseElementType(14744 E->getDestroyedType());14745 if (auto *Record = Destroyed->getAsCXXRecordDecl())14746 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),14747 SemaRef.LookupDestructor(Record));14748 }14749 14750 return E;14751 }14752 14753 return getDerived().RebuildCXXDeleteExpr(14754 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());14755}14756 14757template<typename Derived>14758ExprResult14759TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(14760 CXXPseudoDestructorExpr *E) {14761 ExprResult Base = getDerived().TransformExpr(E->getBase());14762 if (Base.isInvalid())14763 return ExprError();14764 14765 ParsedType ObjectTypePtr;14766 bool MayBePseudoDestructor = false;14767 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),14768 E->getOperatorLoc(),14769 E->isArrow()? tok::arrow : tok::period,14770 ObjectTypePtr,14771 MayBePseudoDestructor);14772 if (Base.isInvalid())14773 return ExprError();14774 14775 QualType ObjectType = ObjectTypePtr.get();14776 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();14777 if (QualifierLoc) {14778 QualifierLoc14779 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);14780 if (!QualifierLoc)14781 return ExprError();14782 }14783 CXXScopeSpec SS;14784 SS.Adopt(QualifierLoc);14785 14786 PseudoDestructorTypeStorage Destroyed;14787 if (E->getDestroyedTypeInfo()) {14788 TypeSourceInfo *DestroyedTypeInfo = getDerived().TransformTypeInObjectScope(14789 E->getDestroyedTypeInfo(), ObjectType,14790 /*FirstQualifierInScope=*/nullptr);14791 if (!DestroyedTypeInfo)14792 return ExprError();14793 Destroyed = DestroyedTypeInfo;14794 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {14795 // We aren't likely to be able to resolve the identifier down to a type14796 // now anyway, so just retain the identifier.14797 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),14798 E->getDestroyedTypeLoc());14799 } else {14800 // Look for a destructor known with the given name.14801 ParsedType T = SemaRef.getDestructorName(14802 *E->getDestroyedTypeIdentifier(), E->getDestroyedTypeLoc(),14803 /*Scope=*/nullptr, SS, ObjectTypePtr, false);14804 if (!T)14805 return ExprError();14806 14807 Destroyed14808 = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),14809 E->getDestroyedTypeLoc());14810 }14811 14812 TypeSourceInfo *ScopeTypeInfo = nullptr;14813 if (E->getScopeTypeInfo()) {14814 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(14815 E->getScopeTypeInfo(), ObjectType, nullptr);14816 if (!ScopeTypeInfo)14817 return ExprError();14818 }14819 14820 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),14821 E->getOperatorLoc(),14822 E->isArrow(),14823 SS,14824 ScopeTypeInfo,14825 E->getColonColonLoc(),14826 E->getTildeLoc(),14827 Destroyed);14828}14829 14830template <typename Derived>14831bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,14832 bool RequiresADL,14833 LookupResult &R) {14834 // Transform all the decls.14835 bool AllEmptyPacks = true;14836 for (auto *OldD : Old->decls()) {14837 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);14838 if (!InstD) {14839 // Silently ignore these if a UsingShadowDecl instantiated to nothing.14840 // This can happen because of dependent hiding.14841 if (isa<UsingShadowDecl>(OldD))14842 continue;14843 else {14844 R.clear();14845 return true;14846 }14847 }14848 14849 // Expand using pack declarations.14850 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);14851 ArrayRef<NamedDecl*> Decls = SingleDecl;14852 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))14853 Decls = UPD->expansions();14854 14855 // Expand using declarations.14856 for (auto *D : Decls) {14857 if (auto *UD = dyn_cast<UsingDecl>(D)) {14858 for (auto *SD : UD->shadows())14859 R.addDecl(SD);14860 } else {14861 R.addDecl(D);14862 }14863 }14864 14865 AllEmptyPacks &= Decls.empty();14866 }14867 14868 // C++ [temp.res]/8.4.2:14869 // The program is ill-formed, no diagnostic required, if [...] lookup for14870 // a name in the template definition found a using-declaration, but the14871 // lookup in the corresponding scope in the instantiation odoes not find14872 // any declarations because the using-declaration was a pack expansion and14873 // the corresponding pack is empty14874 if (AllEmptyPacks && !RequiresADL) {14875 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)14876 << isa<UnresolvedMemberExpr>(Old) << Old->getName();14877 return true;14878 }14879 14880 // Resolve a kind, but don't do any further analysis. If it's14881 // ambiguous, the callee needs to deal with it.14882 R.resolveKind();14883 14884 if (Old->hasTemplateKeyword() && !R.empty()) {14885 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();14886 getSema().FilterAcceptableTemplateNames(R,14887 /*AllowFunctionTemplates=*/true,14888 /*AllowDependent=*/true);14889 if (R.empty()) {14890 // If a 'template' keyword was used, a lookup that finds only non-template14891 // names is an error.14892 getSema().Diag(R.getNameLoc(),14893 diag::err_template_kw_refers_to_non_template)14894 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()14895 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();14896 getSema().Diag(FoundDecl->getLocation(),14897 diag::note_template_kw_refers_to_non_template)14898 << R.getLookupName();14899 return true;14900 }14901 }14902 14903 return false;14904}14905 14906template <typename Derived>14907ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(14908 UnresolvedLookupExpr *Old) {14909 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);14910}14911 14912template <typename Derived>14913ExprResult14914TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,14915 bool IsAddressOfOperand) {14916 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),14917 Sema::LookupOrdinaryName);14918 14919 // Transform the declaration set.14920 if (TransformOverloadExprDecls(Old, Old->requiresADL(), R))14921 return ExprError();14922 14923 // Rebuild the nested-name qualifier, if present.14924 CXXScopeSpec SS;14925 if (Old->getQualifierLoc()) {14926 NestedNameSpecifierLoc QualifierLoc14927 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());14928 if (!QualifierLoc)14929 return ExprError();14930 14931 SS.Adopt(QualifierLoc);14932 }14933 14934 if (Old->getNamingClass()) {14935 CXXRecordDecl *NamingClass14936 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(14937 Old->getNameLoc(),14938 Old->getNamingClass()));14939 if (!NamingClass) {14940 R.clear();14941 return ExprError();14942 }14943 14944 R.setNamingClass(NamingClass);14945 }14946 14947 // Rebuild the template arguments, if any.14948 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();14949 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());14950 if (Old->hasExplicitTemplateArgs() &&14951 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),14952 Old->getNumTemplateArgs(),14953 TransArgs)) {14954 R.clear();14955 return ExprError();14956 }14957 14958 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when14959 // a non-static data member is named in an unevaluated operand, or when14960 // a member is named in a dependent class scope function template explicit14961 // specialization that is neither declared static nor with an explicit object14962 // parameter.14963 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))14964 return SemaRef.BuildPossibleImplicitMemberExpr(14965 SS, TemplateKWLoc, R,14966 Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,14967 /*S=*/nullptr);14968 14969 // If we have neither explicit template arguments, nor the template keyword,14970 // it's a normal declaration name or member reference.14971 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())14972 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());14973 14974 // If we have template arguments, then rebuild the template-id expression.14975 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,14976 Old->requiresADL(), &TransArgs);14977}14978 14979template<typename Derived>14980ExprResult14981TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {14982 bool ArgChanged = false;14983 SmallVector<TypeSourceInfo *, 4> Args;14984 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {14985 TypeSourceInfo *From = E->getArg(I);14986 TypeLoc FromTL = From->getTypeLoc();14987 if (!FromTL.getAs<PackExpansionTypeLoc>()) {14988 TypeLocBuilder TLB;14989 TLB.reserve(FromTL.getFullDataSize());14990 QualType To = getDerived().TransformType(TLB, FromTL);14991 if (To.isNull())14992 return ExprError();14993 14994 if (To == From->getType())14995 Args.push_back(From);14996 else {14997 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));14998 ArgChanged = true;14999 }15000 continue;15001 }15002 15003 ArgChanged = true;15004 15005 // We have a pack expansion. Instantiate it.15006 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();15007 TypeLoc PatternTL = ExpansionTL.getPatternLoc();15008 SmallVector<UnexpandedParameterPack, 2> Unexpanded;15009 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);15010 15011 // Determine whether the set of unexpanded parameter packs can and should15012 // be expanded.15013 bool Expand = true;15014 bool RetainExpansion = false;15015 UnsignedOrNone OrigNumExpansions =15016 ExpansionTL.getTypePtr()->getNumExpansions();15017 UnsignedOrNone NumExpansions = OrigNumExpansions;15018 if (getDerived().TryExpandParameterPacks(15019 ExpansionTL.getEllipsisLoc(), PatternTL.getSourceRange(),15020 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,15021 RetainExpansion, NumExpansions))15022 return ExprError();15023 15024 if (!Expand) {15025 // The transform has determined that we should perform a simple15026 // transformation on the pack expansion, producing another pack15027 // expansion.15028 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);15029 15030 TypeLocBuilder TLB;15031 TLB.reserve(From->getTypeLoc().getFullDataSize());15032 15033 QualType To = getDerived().TransformType(TLB, PatternTL);15034 if (To.isNull())15035 return ExprError();15036 15037 To = getDerived().RebuildPackExpansionType(To,15038 PatternTL.getSourceRange(),15039 ExpansionTL.getEllipsisLoc(),15040 NumExpansions);15041 if (To.isNull())15042 return ExprError();15043 15044 PackExpansionTypeLoc ToExpansionTL15045 = TLB.push<PackExpansionTypeLoc>(To);15046 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());15047 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));15048 continue;15049 }15050 15051 // Expand the pack expansion by substituting for each argument in the15052 // pack(s).15053 for (unsigned I = 0; I != *NumExpansions; ++I) {15054 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);15055 TypeLocBuilder TLB;15056 TLB.reserve(PatternTL.getFullDataSize());15057 QualType To = getDerived().TransformType(TLB, PatternTL);15058 if (To.isNull())15059 return ExprError();15060 15061 if (To->containsUnexpandedParameterPack()) {15062 To = getDerived().RebuildPackExpansionType(To,15063 PatternTL.getSourceRange(),15064 ExpansionTL.getEllipsisLoc(),15065 NumExpansions);15066 if (To.isNull())15067 return ExprError();15068 15069 PackExpansionTypeLoc ToExpansionTL15070 = TLB.push<PackExpansionTypeLoc>(To);15071 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());15072 }15073 15074 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));15075 }15076 15077 if (!RetainExpansion)15078 continue;15079 15080 // If we're supposed to retain a pack expansion, do so by temporarily15081 // forgetting the partially-substituted parameter pack.15082 ForgetPartiallySubstitutedPackRAII Forget(getDerived());15083 15084 TypeLocBuilder TLB;15085 TLB.reserve(From->getTypeLoc().getFullDataSize());15086 15087 QualType To = getDerived().TransformType(TLB, PatternTL);15088 if (To.isNull())15089 return ExprError();15090 15091 To = getDerived().RebuildPackExpansionType(To,15092 PatternTL.getSourceRange(),15093 ExpansionTL.getEllipsisLoc(),15094 NumExpansions);15095 if (To.isNull())15096 return ExprError();15097 15098 PackExpansionTypeLoc ToExpansionTL15099 = TLB.push<PackExpansionTypeLoc>(To);15100 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());15101 Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));15102 }15103 15104 if (!getDerived().AlwaysRebuild() && !ArgChanged)15105 return E;15106 15107 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,15108 E->getEndLoc());15109}15110 15111template<typename Derived>15112ExprResult15113TreeTransform<Derived>::TransformConceptSpecializationExpr(15114 ConceptSpecializationExpr *E) {15115 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();15116 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);15117 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),15118 Old->NumTemplateArgs, TransArgs))15119 return ExprError();15120 15121 return getDerived().RebuildConceptSpecializationExpr(15122 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),15123 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),15124 &TransArgs);15125}15126 15127template<typename Derived>15128ExprResult15129TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {15130 SmallVector<ParmVarDecl*, 4> TransParams;15131 SmallVector<QualType, 4> TransParamTypes;15132 Sema::ExtParameterInfoBuilder ExtParamInfos;15133 15134 // C++2a [expr.prim.req]p215135 // Expressions appearing within a requirement-body are unevaluated operands.15136 EnterExpressionEvaluationContext Ctx(15137 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,15138 Sema::ReuseLambdaContextDecl);15139 15140 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(15141 getSema().Context, getSema().CurContext,15142 E->getBody()->getBeginLoc());15143 15144 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);15145 15146 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(15147 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,15148 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);15149 15150 for (ParmVarDecl *Param : TransParams)15151 if (Param)15152 Param->setDeclContext(Body);15153 15154 // On failure to transform, TransformRequiresTypeParams returns an expression15155 // in the event that the transformation of the type params failed in some way.15156 // It is expected that this will result in a 'not satisfied' Requires clause15157 // when instantiating.15158 if (!TypeParamResult.isUnset())15159 return TypeParamResult;15160 15161 SmallVector<concepts::Requirement *, 4> TransReqs;15162 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),15163 TransReqs))15164 return ExprError();15165 15166 for (concepts::Requirement *Req : TransReqs) {15167 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {15168 if (ER->getReturnTypeRequirement().isTypeConstraint()) {15169 ER->getReturnTypeRequirement()15170 .getTypeConstraintTemplateParameterList()->getParam(0)15171 ->setDeclContext(Body);15172 }15173 }15174 }15175 15176 return getDerived().RebuildRequiresExpr(15177 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,15178 E->getRParenLoc(), TransReqs, E->getRBraceLoc());15179}15180 15181template<typename Derived>15182bool TreeTransform<Derived>::TransformRequiresExprRequirements(15183 ArrayRef<concepts::Requirement *> Reqs,15184 SmallVectorImpl<concepts::Requirement *> &Transformed) {15185 for (concepts::Requirement *Req : Reqs) {15186 concepts::Requirement *TransReq = nullptr;15187 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))15188 TransReq = getDerived().TransformTypeRequirement(TypeReq);15189 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))15190 TransReq = getDerived().TransformExprRequirement(ExprReq);15191 else15192 TransReq = getDerived().TransformNestedRequirement(15193 cast<concepts::NestedRequirement>(Req));15194 if (!TransReq)15195 return true;15196 Transformed.push_back(TransReq);15197 }15198 return false;15199}15200 15201template<typename Derived>15202concepts::TypeRequirement *15203TreeTransform<Derived>::TransformTypeRequirement(15204 concepts::TypeRequirement *Req) {15205 if (Req->isSubstitutionFailure()) {15206 if (getDerived().AlwaysRebuild())15207 return getDerived().RebuildTypeRequirement(15208 Req->getSubstitutionDiagnostic());15209 return Req;15210 }15211 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());15212 if (!TransType)15213 return nullptr;15214 return getDerived().RebuildTypeRequirement(TransType);15215}15216 15217template<typename Derived>15218concepts::ExprRequirement *15219TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {15220 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;15221 if (Req->isExprSubstitutionFailure())15222 TransExpr = Req->getExprSubstitutionDiagnostic();15223 else {15224 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());15225 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())15226 TransExprRes = SemaRef.CheckPlaceholderExpr(TransExprRes.get());15227 if (TransExprRes.isInvalid())15228 return nullptr;15229 TransExpr = TransExprRes.get();15230 }15231 15232 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;15233 const auto &RetReq = Req->getReturnTypeRequirement();15234 if (RetReq.isEmpty())15235 TransRetReq.emplace();15236 else if (RetReq.isSubstitutionFailure())15237 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());15238 else if (RetReq.isTypeConstraint()) {15239 TemplateParameterList *OrigTPL =15240 RetReq.getTypeConstraintTemplateParameterList();15241 TemplateParameterList *TPL =15242 getDerived().TransformTemplateParameterList(OrigTPL);15243 if (!TPL)15244 return nullptr;15245 TransRetReq.emplace(TPL);15246 }15247 assert(TransRetReq && "All code paths leading here must set TransRetReq");15248 if (Expr *E = dyn_cast<Expr *>(TransExpr))15249 return getDerived().RebuildExprRequirement(E, Req->isSimple(),15250 Req->getNoexceptLoc(),15251 std::move(*TransRetReq));15252 return getDerived().RebuildExprRequirement(15253 cast<concepts::Requirement::SubstitutionDiagnostic *>(TransExpr),15254 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));15255}15256 15257template<typename Derived>15258concepts::NestedRequirement *15259TreeTransform<Derived>::TransformNestedRequirement(15260 concepts::NestedRequirement *Req) {15261 if (Req->hasInvalidConstraint()) {15262 if (getDerived().AlwaysRebuild())15263 return getDerived().RebuildNestedRequirement(15264 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());15265 return Req;15266 }15267 ExprResult TransConstraint =15268 getDerived().TransformExpr(Req->getConstraintExpr());15269 if (TransConstraint.isInvalid())15270 return nullptr;15271 return getDerived().RebuildNestedRequirement(TransConstraint.get());15272}15273 15274template<typename Derived>15275ExprResult15276TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {15277 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());15278 if (!T)15279 return ExprError();15280 15281 if (!getDerived().AlwaysRebuild() &&15282 T == E->getQueriedTypeSourceInfo())15283 return E;15284 15285 ExprResult SubExpr;15286 {15287 EnterExpressionEvaluationContext Unevaluated(15288 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);15289 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());15290 if (SubExpr.isInvalid())15291 return ExprError();15292 }15293 15294 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,15295 SubExpr.get(), E->getEndLoc());15296}15297 15298template<typename Derived>15299ExprResult15300TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {15301 ExprResult SubExpr;15302 {15303 EnterExpressionEvaluationContext Unevaluated(15304 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);15305 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());15306 if (SubExpr.isInvalid())15307 return ExprError();15308 15309 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())15310 return E;15311 }15312 15313 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),15314 SubExpr.get(), E->getEndLoc());15315}15316 15317template <typename Derived>15318ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(15319 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,15320 TypeSourceInfo **RecoveryTSI) {15321 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(15322 DRE, AddrTaken, RecoveryTSI);15323 15324 // Propagate both errors and recovered types, which return ExprEmpty.15325 if (!NewDRE.isUsable())15326 return NewDRE;15327 15328 // We got an expr, wrap it up in parens.15329 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)15330 return PE;15331 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),15332 PE->getRParen());15333}15334 15335template <typename Derived>15336ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(15337 DependentScopeDeclRefExpr *E) {15338 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,15339 nullptr);15340}15341 15342template <typename Derived>15343ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(15344 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,15345 TypeSourceInfo **RecoveryTSI) {15346 assert(E->getQualifierLoc());15347 NestedNameSpecifierLoc QualifierLoc =15348 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());15349 if (!QualifierLoc)15350 return ExprError();15351 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();15352 15353 // TODO: If this is a conversion-function-id, verify that the15354 // destination type name (if present) resolves the same way after15355 // instantiation as it did in the local scope.15356 15357 DeclarationNameInfo NameInfo =15358 getDerived().TransformDeclarationNameInfo(E->getNameInfo());15359 if (!NameInfo.getName())15360 return ExprError();15361 15362 if (!E->hasExplicitTemplateArgs()) {15363 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&15364 // Note: it is sufficient to compare the Name component of NameInfo:15365 // if name has not changed, DNLoc has not changed either.15366 NameInfo.getName() == E->getDeclName())15367 return E;15368 15369 return getDerived().RebuildDependentScopeDeclRefExpr(15370 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,15371 IsAddressOfOperand, RecoveryTSI);15372 }15373 15374 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());15375 if (getDerived().TransformTemplateArguments(15376 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))15377 return ExprError();15378 15379 return getDerived().RebuildDependentScopeDeclRefExpr(15380 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,15381 RecoveryTSI);15382}15383 15384template<typename Derived>15385ExprResult15386TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {15387 // CXXConstructExprs other than for list-initialization and15388 // CXXTemporaryObjectExpr are always implicit, so when we have15389 // a 1-argument construction we just transform that argument.15390 if (getDerived().AllowSkippingCXXConstructExpr() &&15391 ((E->getNumArgs() == 1 ||15392 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) &&15393 (!getDerived().DropCallArgument(E->getArg(0))) &&15394 !E->isListInitialization()))15395 return getDerived().TransformInitializer(E->getArg(0),15396 /*DirectInit*/ false);15397 15398 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());15399 15400 QualType T = getDerived().TransformType(E->getType());15401 if (T.isNull())15402 return ExprError();15403 15404 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(15405 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));15406 if (!Constructor)15407 return ExprError();15408 15409 bool ArgumentChanged = false;15410 SmallVector<Expr*, 8> Args;15411 {15412 EnterExpressionEvaluationContext Context(15413 getSema(), EnterExpressionEvaluationContext::InitList,15414 E->isListInitialization());15415 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,15416 &ArgumentChanged))15417 return ExprError();15418 }15419 15420 if (!getDerived().AlwaysRebuild() &&15421 T == E->getType() &&15422 Constructor == E->getConstructor() &&15423 !ArgumentChanged) {15424 // Mark the constructor as referenced.15425 // FIXME: Instantiation-specific15426 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);15427 return E;15428 }15429 15430 return getDerived().RebuildCXXConstructExpr(15431 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,15432 E->hadMultipleCandidates(), E->isListInitialization(),15433 E->isStdInitListInitialization(), E->requiresZeroInitialization(),15434 E->getConstructionKind(), E->getParenOrBraceRange());15435}15436 15437template<typename Derived>15438ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(15439 CXXInheritedCtorInitExpr *E) {15440 QualType T = getDerived().TransformType(E->getType());15441 if (T.isNull())15442 return ExprError();15443 15444 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(15445 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));15446 if (!Constructor)15447 return ExprError();15448 15449 if (!getDerived().AlwaysRebuild() &&15450 T == E->getType() &&15451 Constructor == E->getConstructor()) {15452 // Mark the constructor as referenced.15453 // FIXME: Instantiation-specific15454 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);15455 return E;15456 }15457 15458 return getDerived().RebuildCXXInheritedCtorInitExpr(15459 T, E->getLocation(), Constructor,15460 E->constructsVBase(), E->inheritedFromVBase());15461}15462 15463/// Transform a C++ temporary-binding expression.15464///15465/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just15466/// transform the subexpression and return that.15467template<typename Derived>15468ExprResult15469TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {15470 if (auto *Dtor = E->getTemporary()->getDestructor())15471 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),15472 const_cast<CXXDestructorDecl *>(Dtor));15473 return getDerived().TransformExpr(E->getSubExpr());15474}15475 15476/// Transform a C++ expression that contains cleanups that should15477/// be run after the expression is evaluated.15478///15479/// Since ExprWithCleanups nodes are implicitly generated, we15480/// just transform the subexpression and return that.15481template<typename Derived>15482ExprResult15483TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {15484 return getDerived().TransformExpr(E->getSubExpr());15485}15486 15487template<typename Derived>15488ExprResult15489TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(15490 CXXTemporaryObjectExpr *E) {15491 TypeSourceInfo *T =15492 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());15493 if (!T)15494 return ExprError();15495 15496 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(15497 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));15498 if (!Constructor)15499 return ExprError();15500 15501 bool ArgumentChanged = false;15502 SmallVector<Expr*, 8> Args;15503 Args.reserve(E->getNumArgs());15504 {15505 EnterExpressionEvaluationContext Context(15506 getSema(), EnterExpressionEvaluationContext::InitList,15507 E->isListInitialization());15508 if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,15509 &ArgumentChanged))15510 return ExprError();15511 15512 if (E->isListInitialization() && !E->isStdInitListInitialization()) {15513 ExprResult Res = RebuildInitList(E->getBeginLoc(), Args, E->getEndLoc());15514 if (Res.isInvalid())15515 return ExprError();15516 Args = {Res.get()};15517 }15518 }15519 15520 if (!getDerived().AlwaysRebuild() &&15521 T == E->getTypeSourceInfo() &&15522 Constructor == E->getConstructor() &&15523 !ArgumentChanged) {15524 // FIXME: Instantiation-specific15525 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);15526 return SemaRef.MaybeBindToTemporary(E);15527 }15528 15529 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();15530 return getDerived().RebuildCXXTemporaryObjectExpr(15531 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());15532}15533 15534template<typename Derived>15535ExprResult15536TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {15537 // Transform any init-capture expressions before entering the scope of the15538 // lambda body, because they are not semantically within that scope.15539 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;15540 struct TransformedInitCapture {15541 // The location of the ... if the result is retaining a pack expansion.15542 SourceLocation EllipsisLoc;15543 // Zero or more expansions of the init-capture.15544 SmallVector<InitCaptureInfoTy, 4> Expansions;15545 };15546 SmallVector<TransformedInitCapture, 4> InitCaptures;15547 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());15548 for (LambdaExpr::capture_iterator C = E->capture_begin(),15549 CEnd = E->capture_end();15550 C != CEnd; ++C) {15551 if (!E->isInitCapture(C))15552 continue;15553 15554 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];15555 auto *OldVD = cast<VarDecl>(C->getCapturedVar());15556 15557 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,15558 UnsignedOrNone NumExpansions) {15559 ExprResult NewExprInitResult = getDerived().TransformInitializer(15560 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);15561 15562 if (NewExprInitResult.isInvalid()) {15563 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));15564 return;15565 }15566 Expr *NewExprInit = NewExprInitResult.get();15567 15568 QualType NewInitCaptureType =15569 getSema().buildLambdaInitCaptureInitialization(15570 C->getLocation(), C->getCaptureKind() == LCK_ByRef,15571 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),15572 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=15573 VarDecl::CInit,15574 NewExprInit);15575 Result.Expansions.push_back(15576 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));15577 };15578 15579 // If this is an init-capture pack, consider expanding the pack now.15580 if (OldVD->isParameterPack()) {15581 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()15582 ->getTypeLoc()15583 .castAs<PackExpansionTypeLoc>();15584 SmallVector<UnexpandedParameterPack, 2> Unexpanded;15585 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);15586 15587 // Determine whether the set of unexpanded parameter packs can and should15588 // be expanded.15589 bool Expand = true;15590 bool RetainExpansion = false;15591 UnsignedOrNone OrigNumExpansions =15592 ExpansionTL.getTypePtr()->getNumExpansions();15593 UnsignedOrNone NumExpansions = OrigNumExpansions;15594 if (getDerived().TryExpandParameterPacks(15595 ExpansionTL.getEllipsisLoc(), OldVD->getInit()->getSourceRange(),15596 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,15597 RetainExpansion, NumExpansions))15598 return ExprError();15599 assert(!RetainExpansion && "Should not need to retain expansion after a "15600 "capture since it cannot be extended");15601 if (Expand) {15602 for (unsigned I = 0; I != *NumExpansions; ++I) {15603 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);15604 SubstInitCapture(SourceLocation(), std::nullopt);15605 }15606 } else {15607 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);15608 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();15609 }15610 } else {15611 SubstInitCapture(SourceLocation(), std::nullopt);15612 }15613 }15614 15615 LambdaScopeInfo *LSI = getSema().PushLambdaScope();15616 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());15617 15618 // Create the local class that will describe the lambda.15619 15620 // FIXME: DependencyKind below is wrong when substituting inside a templated15621 // context that isn't a DeclContext (such as a variable template), or when15622 // substituting an unevaluated lambda inside of a function's parameter's type15623 // - as parameter types are not instantiated from within a function's DC. We15624 // use evaluation contexts to distinguish the function parameter case.15625 CXXRecordDecl::LambdaDependencyKind DependencyKind =15626 CXXRecordDecl::LDK_Unknown;15627 DeclContext *DC = getSema().CurContext;15628 // A RequiresExprBodyDecl is not interesting for dependencies.15629 // For the following case,15630 //15631 // template <typename>15632 // concept C = requires { [] {}; };15633 //15634 // template <class F>15635 // struct Widget;15636 //15637 // template <C F>15638 // struct Widget<F> {};15639 //15640 // While we are substituting Widget<F>, the parent of DC would be15641 // the template specialization itself. Thus, the lambda expression15642 // will be deemed as dependent even if there are no dependent template15643 // arguments.15644 // (A ClassTemplateSpecializationDecl is always a dependent context.)15645 while (DC->isRequiresExprBody())15646 DC = DC->getParent();15647 if ((getSema().isUnevaluatedContext() ||15648 getSema().isConstantEvaluatedContext()) &&15649 !(dyn_cast_or_null<CXXRecordDecl>(DC->getParent()) &&15650 cast<CXXRecordDecl>(DC->getParent())->isGenericLambda()) &&15651 (DC->isFileContext() || !DC->getParent()->isDependentContext()))15652 DependencyKind = CXXRecordDecl::LDK_NeverDependent;15653 15654 CXXRecordDecl *OldClass = E->getLambdaClass();15655 CXXRecordDecl *Class = getSema().createLambdaClosureType(15656 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,15657 E->getCaptureDefault());15658 getDerived().transformedLocalDecl(OldClass, {Class});15659 15660 CXXMethodDecl *NewCallOperator =15661 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);15662 15663 // Enter the scope of the lambda.15664 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),15665 E->getCaptureDefault(), E->getCaptureDefaultLoc(),15666 E->hasExplicitParameters(), E->isMutable());15667 15668 // Introduce the context of the call operator.15669 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,15670 /*NewThisContext*/false);15671 15672 bool Invalid = false;15673 15674 // Transform captures.15675 for (LambdaExpr::capture_iterator C = E->capture_begin(),15676 CEnd = E->capture_end();15677 C != CEnd; ++C) {15678 // When we hit the first implicit capture, tell Sema that we've finished15679 // the list of explicit captures.15680 if (C->isImplicit())15681 break;15682 15683 // Capturing 'this' is trivial.15684 if (C->capturesThis()) {15685 // If this is a lambda that is part of a default member initialiser15686 // and which we're instantiating outside the class that 'this' is15687 // supposed to refer to, adjust the type of 'this' accordingly.15688 //15689 // Otherwise, leave the type of 'this' as-is.15690 Sema::CXXThisScopeRAII ThisScope(15691 getSema(),15692 dyn_cast_if_present<CXXRecordDecl>(15693 getSema().getFunctionLevelDeclContext()),15694 Qualifiers());15695 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),15696 /*BuildAndDiagnose*/ true, nullptr,15697 C->getCaptureKind() == LCK_StarThis);15698 continue;15699 }15700 // Captured expression will be recaptured during captured variables15701 // rebuilding.15702 if (C->capturesVLAType())15703 continue;15704 15705 // Rebuild init-captures, including the implied field declaration.15706 if (E->isInitCapture(C)) {15707 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];15708 15709 auto *OldVD = cast<VarDecl>(C->getCapturedVar());15710 llvm::SmallVector<Decl*, 4> NewVDs;15711 15712 for (InitCaptureInfoTy &Info : NewC.Expansions) {15713 ExprResult Init = Info.first;15714 QualType InitQualType = Info.second;15715 if (Init.isInvalid() || InitQualType.isNull()) {15716 Invalid = true;15717 break;15718 }15719 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(15720 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,15721 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),15722 getSema().CurContext);15723 if (!NewVD) {15724 Invalid = true;15725 break;15726 }15727 NewVDs.push_back(NewVD);15728 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);15729 // Cases we want to tackle:15730 // ([C(Pack)] {}, ...)15731 // But rule out cases e.g.15732 // [...C = Pack()] {}15733 if (NewC.EllipsisLoc.isInvalid())15734 LSI->ContainsUnexpandedParameterPack |=15735 Init.get()->containsUnexpandedParameterPack();15736 }15737 15738 if (Invalid)15739 break;15740 15741 getDerived().transformedLocalDecl(OldVD, NewVDs);15742 continue;15743 }15744 15745 assert(C->capturesVariable() && "unexpected kind of lambda capture");15746 15747 // Determine the capture kind for Sema.15748 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit15749 : C->getCaptureKind() == LCK_ByCopy15750 ? TryCaptureKind::ExplicitByVal15751 : TryCaptureKind::ExplicitByRef;15752 SourceLocation EllipsisLoc;15753 if (C->isPackExpansion()) {15754 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());15755 bool ShouldExpand = false;15756 bool RetainExpansion = false;15757 UnsignedOrNone NumExpansions = std::nullopt;15758 if (getDerived().TryExpandParameterPacks(15759 C->getEllipsisLoc(), C->getLocation(), Unexpanded,15760 /*FailOnPackProducingTemplates=*/true, ShouldExpand,15761 RetainExpansion, NumExpansions)) {15762 Invalid = true;15763 continue;15764 }15765 15766 if (ShouldExpand) {15767 // The transform has determined that we should perform an expansion;15768 // transform and capture each of the arguments.15769 // expansion of the pattern. Do so.15770 auto *Pack = cast<ValueDecl>(C->getCapturedVar());15771 for (unsigned I = 0; I != *NumExpansions; ++I) {15772 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);15773 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(15774 getDerived().TransformDecl(C->getLocation(), Pack));15775 if (!CapturedVar) {15776 Invalid = true;15777 continue;15778 }15779 15780 // Capture the transformed variable.15781 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);15782 }15783 15784 // FIXME: Retain a pack expansion if RetainExpansion is true.15785 15786 continue;15787 }15788 15789 EllipsisLoc = C->getEllipsisLoc();15790 }15791 15792 // Transform the captured variable.15793 auto *CapturedVar = cast_or_null<ValueDecl>(15794 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));15795 if (!CapturedVar || CapturedVar->isInvalidDecl()) {15796 Invalid = true;15797 continue;15798 }15799 15800 // This is not an init-capture; however it contains an unexpanded pack e.g.15801 // ([Pack] {}(), ...)15802 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())15803 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();15804 15805 // Capture the transformed variable.15806 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,15807 EllipsisLoc);15808 }15809 getSema().finishLambdaExplicitCaptures(LSI);15810 15811 // Transform the template parameters, and add them to the current15812 // instantiation scope. The null case is handled correctly.15813 auto TPL = getDerived().TransformTemplateParameterList(15814 E->getTemplateParameterList());15815 LSI->GLTemplateParameterList = TPL;15816 if (TPL) {15817 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,15818 TPL);15819 LSI->ContainsUnexpandedParameterPack |=15820 TPL->containsUnexpandedParameterPack();15821 }15822 15823 TypeLocBuilder NewCallOpTLBuilder;15824 TypeLoc OldCallOpTypeLoc =15825 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();15826 QualType NewCallOpType =15827 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);15828 if (NewCallOpType.isNull())15829 return ExprError();15830 LSI->ContainsUnexpandedParameterPack |=15831 NewCallOpType->containsUnexpandedParameterPack();15832 TypeSourceInfo *NewCallOpTSI =15833 NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);15834 15835 // The type may be an AttributedType or some other kind of sugar;15836 // get the actual underlying FunctionProtoType.15837 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();15838 assert(FPTL && "Not a FunctionProtoType?");15839 15840 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();15841 if (!TRC.ArgPackSubstIndex)15842 TRC.ArgPackSubstIndex = SemaRef.ArgPackSubstIndex;15843 15844 getSema().CompleteLambdaCallOperator(15845 NewCallOperator, E->getCallOperator()->getLocation(),15846 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,15847 E->getCallOperator()->getConstexprKind(),15848 E->getCallOperator()->getStorageClass(), FPTL.getParams(),15849 E->hasExplicitResultType());15850 15851 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);15852 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});15853 15854 {15855 // Number the lambda for linkage purposes if necessary.15856 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());15857 15858 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;15859 if (getDerived().ReplacingOriginal()) {15860 Numbering = OldClass->getLambdaNumbering();15861 }15862 15863 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);15864 }15865 15866 // FIXME: Sema's lambda-building mechanism expects us to push an expression15867 // evaluation context even if we're not transforming the function body.15868 getSema().PushExpressionEvaluationContextForFunction(15869 Sema::ExpressionEvaluationContext::PotentiallyEvaluated,15870 E->getCallOperator());15871 15872 StmtResult Body;15873 {15874 Sema::NonSFINAEContext _(getSema());15875 Sema::CodeSynthesisContext C;15876 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;15877 C.PointOfInstantiation = E->getBody()->getBeginLoc();15878 getSema().pushCodeSynthesisContext(C);15879 15880 // Instantiate the body of the lambda expression.15881 Body = Invalid ? StmtError()15882 : getDerived().TransformLambdaBody(E, E->getBody());15883 15884 getSema().popCodeSynthesisContext();15885 }15886 15887 // ActOnLambda* will pop the function scope for us.15888 FuncScopeCleanup.disable();15889 15890 if (Body.isInvalid()) {15891 SavedContext.pop();15892 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,15893 /*IsInstantiation=*/true);15894 return ExprError();15895 }15896 15897 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),15898 /*IsInstantiation=*/true,15899 /*RetainFunctionScopeInfo=*/true);15900 SavedContext.pop();15901 15902 // Recompute the dependency of the lambda so that we can defer the lambda call15903 // construction until after we have all the necessary template arguments. For15904 // example, given15905 //15906 // template <class> struct S {15907 // template <class U>15908 // using Type = decltype([](U){}(42.0));15909 // };15910 // void foo() {15911 // using T = S<int>::Type<float>;15912 // ^~~~~~15913 // }15914 //15915 // We would end up here from instantiating S<int> when ensuring its15916 // completeness. That would transform the lambda call expression regardless of15917 // the absence of the corresponding argument for U.15918 //15919 // Going ahead with unsubstituted type U makes things worse: we would soon15920 // compare the argument type (which is float) against the parameter U15921 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus15922 // error suggesting unmatched types 'U' and 'float'!15923 //15924 // That said, everything will be fine if we defer that semantic checking.15925 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is15926 // dependent. Since the CallExpr's dependency boils down to the lambda's15927 // dependency in this case, we can harness that by recomputing the dependency15928 // from the instantiation arguments.15929 //15930 // FIXME: Creating the type of a lambda requires us to have a dependency15931 // value, which happens before its substitution. We update its dependency15932 // *after* the substitution in case we can't decide the dependency15933 // so early, e.g. because we want to see if any of the *substituted*15934 // parameters are dependent.15935 DependencyKind = getDerived().ComputeLambdaDependency(LSI);15936 Class->setLambdaDependencyKind(DependencyKind);15937 15938 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),15939 Body.get()->getEndLoc(), LSI);15940}15941 15942template<typename Derived>15943StmtResult15944TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {15945 return TransformStmt(S);15946}15947 15948template<typename Derived>15949StmtResult15950TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {15951 // Transform captures.15952 for (LambdaExpr::capture_iterator C = E->capture_begin(),15953 CEnd = E->capture_end();15954 C != CEnd; ++C) {15955 // When we hit the first implicit capture, tell Sema that we've finished15956 // the list of explicit captures.15957 if (!C->isImplicit())15958 continue;15959 15960 // Capturing 'this' is trivial.15961 if (C->capturesThis()) {15962 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),15963 /*BuildAndDiagnose*/ true, nullptr,15964 C->getCaptureKind() == LCK_StarThis);15965 continue;15966 }15967 // Captured expression will be recaptured during captured variables15968 // rebuilding.15969 if (C->capturesVLAType())15970 continue;15971 15972 assert(C->capturesVariable() && "unexpected kind of lambda capture");15973 assert(!E->isInitCapture(C) && "implicit init-capture?");15974 15975 // Transform the captured variable.15976 VarDecl *CapturedVar = cast_or_null<VarDecl>(15977 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));15978 if (!CapturedVar || CapturedVar->isInvalidDecl())15979 return StmtError();15980 15981 // Capture the transformed variable.15982 getSema().tryCaptureVariable(CapturedVar, C->getLocation());15983 }15984 15985 return S;15986}15987 15988template<typename Derived>15989ExprResult15990TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(15991 CXXUnresolvedConstructExpr *E) {15992 TypeSourceInfo *T =15993 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());15994 if (!T)15995 return ExprError();15996 15997 bool ArgumentChanged = false;15998 SmallVector<Expr*, 8> Args;15999 Args.reserve(E->getNumArgs());16000 {16001 EnterExpressionEvaluationContext Context(16002 getSema(), EnterExpressionEvaluationContext::InitList,16003 E->isListInitialization());16004 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,16005 &ArgumentChanged))16006 return ExprError();16007 }16008 16009 if (!getDerived().AlwaysRebuild() &&16010 T == E->getTypeSourceInfo() &&16011 !ArgumentChanged)16012 return E;16013 16014 // FIXME: we're faking the locations of the commas16015 return getDerived().RebuildCXXUnresolvedConstructExpr(16016 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());16017}16018 16019template<typename Derived>16020ExprResult16021TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(16022 CXXDependentScopeMemberExpr *E) {16023 // Transform the base of the expression.16024 ExprResult Base((Expr*) nullptr);16025 Expr *OldBase;16026 QualType BaseType;16027 QualType ObjectType;16028 if (!E->isImplicitAccess()) {16029 OldBase = E->getBase();16030 Base = getDerived().TransformExpr(OldBase);16031 if (Base.isInvalid())16032 return ExprError();16033 16034 // Start the member reference and compute the object's type.16035 ParsedType ObjectTy;16036 bool MayBePseudoDestructor = false;16037 Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(),16038 E->getOperatorLoc(),16039 E->isArrow()? tok::arrow : tok::period,16040 ObjectTy,16041 MayBePseudoDestructor);16042 if (Base.isInvalid())16043 return ExprError();16044 16045 ObjectType = ObjectTy.get();16046 BaseType = ((Expr*) Base.get())->getType();16047 } else {16048 OldBase = nullptr;16049 BaseType = getDerived().TransformType(E->getBaseType());16050 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();16051 }16052 16053 // Transform the first part of the nested-name-specifier that qualifies16054 // the member name.16055 NamedDecl *FirstQualifierInScope16056 = getDerived().TransformFirstQualifierInScope(16057 E->getFirstQualifierFoundInScope(),16058 E->getQualifierLoc().getBeginLoc());16059 16060 NestedNameSpecifierLoc QualifierLoc;16061 if (E->getQualifier()) {16062 QualifierLoc16063 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),16064 ObjectType,16065 FirstQualifierInScope);16066 if (!QualifierLoc)16067 return ExprError();16068 }16069 16070 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();16071 16072 // TODO: If this is a conversion-function-id, verify that the16073 // destination type name (if present) resolves the same way after16074 // instantiation as it did in the local scope.16075 16076 DeclarationNameInfo NameInfo16077 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());16078 if (!NameInfo.getName())16079 return ExprError();16080 16081 if (!E->hasExplicitTemplateArgs()) {16082 // This is a reference to a member without an explicitly-specified16083 // template argument list. Optimize for this common case.16084 if (!getDerived().AlwaysRebuild() &&16085 Base.get() == OldBase &&16086 BaseType == E->getBaseType() &&16087 QualifierLoc == E->getQualifierLoc() &&16088 NameInfo.getName() == E->getMember() &&16089 FirstQualifierInScope == E->getFirstQualifierFoundInScope())16090 return E;16091 16092 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),16093 BaseType,16094 E->isArrow(),16095 E->getOperatorLoc(),16096 QualifierLoc,16097 TemplateKWLoc,16098 FirstQualifierInScope,16099 NameInfo,16100 /*TemplateArgs*/nullptr);16101 }16102 16103 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());16104 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),16105 E->getNumTemplateArgs(),16106 TransArgs))16107 return ExprError();16108 16109 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),16110 BaseType,16111 E->isArrow(),16112 E->getOperatorLoc(),16113 QualifierLoc,16114 TemplateKWLoc,16115 FirstQualifierInScope,16116 NameInfo,16117 &TransArgs);16118}16119 16120template <typename Derived>16121ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(16122 UnresolvedMemberExpr *Old) {16123 // Transform the base of the expression.16124 ExprResult Base((Expr *)nullptr);16125 QualType BaseType;16126 if (!Old->isImplicitAccess()) {16127 Base = getDerived().TransformExpr(Old->getBase());16128 if (Base.isInvalid())16129 return ExprError();16130 Base =16131 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());16132 if (Base.isInvalid())16133 return ExprError();16134 BaseType = Base.get()->getType();16135 } else {16136 BaseType = getDerived().TransformType(Old->getBaseType());16137 }16138 16139 NestedNameSpecifierLoc QualifierLoc;16140 if (Old->getQualifierLoc()) {16141 QualifierLoc =16142 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());16143 if (!QualifierLoc)16144 return ExprError();16145 }16146 16147 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();16148 16149 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);16150 16151 // Transform the declaration set.16152 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ false, R))16153 return ExprError();16154 16155 // Determine the naming class.16156 if (Old->getNamingClass()) {16157 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(16158 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));16159 if (!NamingClass)16160 return ExprError();16161 16162 R.setNamingClass(NamingClass);16163 }16164 16165 TemplateArgumentListInfo TransArgs;16166 if (Old->hasExplicitTemplateArgs()) {16167 TransArgs.setLAngleLoc(Old->getLAngleLoc());16168 TransArgs.setRAngleLoc(Old->getRAngleLoc());16169 if (getDerived().TransformTemplateArguments(16170 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))16171 return ExprError();16172 }16173 16174 // FIXME: to do this check properly, we will need to preserve the16175 // first-qualifier-in-scope here, just in case we had a dependent16176 // base (and therefore couldn't do the check) and a16177 // nested-name-qualifier (and therefore could do the lookup).16178 NamedDecl *FirstQualifierInScope = nullptr;16179 16180 return getDerived().RebuildUnresolvedMemberExpr(16181 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,16182 TemplateKWLoc, FirstQualifierInScope, R,16183 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));16184}16185 16186template<typename Derived>16187ExprResult16188TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {16189 EnterExpressionEvaluationContext Unevaluated(16190 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);16191 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());16192 if (SubExpr.isInvalid())16193 return ExprError();16194 16195 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())16196 return E;16197 16198 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());16199}16200 16201template<typename Derived>16202ExprResult16203TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {16204 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());16205 if (Pattern.isInvalid())16206 return ExprError();16207 16208 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())16209 return E;16210 16211 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),16212 E->getNumExpansions());16213}16214 16215template <typename Derived>16216UnsignedOrNone TreeTransform<Derived>::ComputeSizeOfPackExprWithoutSubstitution(16217 ArrayRef<TemplateArgument> PackArgs) {16218 UnsignedOrNone Result = 0u;16219 for (const TemplateArgument &Arg : PackArgs) {16220 if (!Arg.isPackExpansion()) {16221 Result = *Result + 1;16222 continue;16223 }16224 16225 TemplateArgumentLoc ArgLoc;16226 InventTemplateArgumentLoc(Arg, ArgLoc);16227 16228 // Find the pattern of the pack expansion.16229 SourceLocation Ellipsis;16230 UnsignedOrNone OrigNumExpansions = std::nullopt;16231 TemplateArgumentLoc Pattern =16232 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,16233 OrigNumExpansions);16234 16235 // Substitute under the pack expansion. Do not expand the pack (yet).16236 TemplateArgumentLoc OutPattern;16237 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);16238 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,16239 /*Uneval*/ true))16240 return 1u;16241 16242 // See if we can determine the number of arguments from the result.16243 UnsignedOrNone NumExpansions =16244 getSema().getFullyPackExpandedSize(OutPattern.getArgument());16245 if (!NumExpansions) {16246 // No: we must be in an alias template expansion, and we're going to16247 // need to actually expand the packs.16248 Result = std::nullopt;16249 break;16250 }16251 16252 Result = *Result + *NumExpansions;16253 }16254 return Result;16255}16256 16257template<typename Derived>16258ExprResult16259TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {16260 // If E is not value-dependent, then nothing will change when we transform it.16261 // Note: This is an instantiation-centric view.16262 if (!E->isValueDependent())16263 return E;16264 16265 EnterExpressionEvaluationContext Unevaluated(16266 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);16267 16268 ArrayRef<TemplateArgument> PackArgs;16269 TemplateArgument ArgStorage;16270 16271 // Find the argument list to transform.16272 if (E->isPartiallySubstituted()) {16273 PackArgs = E->getPartialArguments();16274 } else if (E->isValueDependent()) {16275 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());16276 bool ShouldExpand = false;16277 bool RetainExpansion = false;16278 UnsignedOrNone NumExpansions = std::nullopt;16279 if (getDerived().TryExpandParameterPacks(16280 E->getOperatorLoc(), E->getPackLoc(), Unexpanded,16281 /*FailOnPackProducingTemplates=*/true, ShouldExpand,16282 RetainExpansion, NumExpansions))16283 return ExprError();16284 16285 // If we need to expand the pack, build a template argument from it and16286 // expand that.16287 if (ShouldExpand) {16288 auto *Pack = E->getPack();16289 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) {16290 ArgStorage = getSema().Context.getPackExpansionType(16291 getSema().Context.getTypeDeclType(TTPD), std::nullopt);16292 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {16293 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);16294 } else {16295 auto *VD = cast<ValueDecl>(Pack);16296 ExprResult DRE = getSema().BuildDeclRefExpr(16297 VD, VD->getType().getNonLValueExprType(getSema().Context),16298 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,16299 E->getPackLoc());16300 if (DRE.isInvalid())16301 return ExprError();16302 ArgStorage = TemplateArgument(16303 new (getSema().Context)16304 PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt),16305 /*IsCanonical=*/false);16306 }16307 PackArgs = ArgStorage;16308 }16309 }16310 16311 // If we're not expanding the pack, just transform the decl.16312 if (!PackArgs.size()) {16313 auto *Pack = cast_or_null<NamedDecl>(16314 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));16315 if (!Pack)16316 return ExprError();16317 return getDerived().RebuildSizeOfPackExpr(16318 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),16319 std::nullopt, {});16320 }16321 16322 // Try to compute the result without performing a partial substitution.16323 UnsignedOrNone Result =16324 getDerived().ComputeSizeOfPackExprWithoutSubstitution(PackArgs);16325 16326 // Common case: we could determine the number of expansions without16327 // substituting.16328 if (Result)16329 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),16330 E->getPackLoc(),16331 E->getRParenLoc(), *Result, {});16332 16333 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),16334 E->getPackLoc());16335 {16336 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());16337 typedef TemplateArgumentLocInventIterator<16338 Derived, const TemplateArgument*> PackLocIterator;16339 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),16340 PackLocIterator(*this, PackArgs.end()),16341 TransformedPackArgs, /*Uneval*/true))16342 return ExprError();16343 }16344 16345 // Check whether we managed to fully-expand the pack.16346 // FIXME: Is it possible for us to do so and not hit the early exit path?16347 SmallVector<TemplateArgument, 8> Args;16348 bool PartialSubstitution = false;16349 for (auto &Loc : TransformedPackArgs.arguments()) {16350 Args.push_back(Loc.getArgument());16351 if (Loc.getArgument().isPackExpansion())16352 PartialSubstitution = true;16353 }16354 16355 if (PartialSubstitution)16356 return getDerived().RebuildSizeOfPackExpr(16357 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),16358 std::nullopt, Args);16359 16360 return getDerived().RebuildSizeOfPackExpr(16361 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),16362 /*Length=*/static_cast<unsigned>(Args.size()),16363 /*PartialArgs=*/{});16364}16365 16366template <typename Derived>16367ExprResult16368TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {16369 if (!E->isValueDependent())16370 return E;16371 16372 // Transform the index16373 ExprResult IndexExpr;16374 {16375 EnterExpressionEvaluationContext ConstantContext(16376 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);16377 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());16378 if (IndexExpr.isInvalid())16379 return ExprError();16380 }16381 16382 SmallVector<Expr *, 5> ExpandedExprs;16383 bool FullySubstituted = true;16384 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {16385 Expr *Pattern = E->getPackIdExpression();16386 SmallVector<UnexpandedParameterPack, 2> Unexpanded;16387 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),16388 Unexpanded);16389 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");16390 16391 // Determine whether the set of unexpanded parameter packs can and should16392 // be expanded.16393 bool ShouldExpand = true;16394 bool RetainExpansion = false;16395 UnsignedOrNone OrigNumExpansions = std::nullopt,16396 NumExpansions = std::nullopt;16397 if (getDerived().TryExpandParameterPacks(16398 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,16399 /*FailOnPackProducingTemplates=*/true, ShouldExpand,16400 RetainExpansion, NumExpansions))16401 return true;16402 if (!ShouldExpand) {16403 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);16404 ExprResult Pack = getDerived().TransformExpr(Pattern);16405 if (Pack.isInvalid())16406 return ExprError();16407 return getDerived().RebuildPackIndexingExpr(16408 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),16409 {}, /*FullySubstituted=*/false);16410 }16411 for (unsigned I = 0; I != *NumExpansions; ++I) {16412 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);16413 ExprResult Out = getDerived().TransformExpr(Pattern);16414 if (Out.isInvalid())16415 return true;16416 if (Out.get()->containsUnexpandedParameterPack()) {16417 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),16418 OrigNumExpansions);16419 if (Out.isInvalid())16420 return true;16421 FullySubstituted = false;16422 }16423 ExpandedExprs.push_back(Out.get());16424 }16425 // If we're supposed to retain a pack expansion, do so by temporarily16426 // forgetting the partially-substituted parameter pack.16427 if (RetainExpansion) {16428 ForgetPartiallySubstitutedPackRAII Forget(getDerived());16429 16430 ExprResult Out = getDerived().TransformExpr(Pattern);16431 if (Out.isInvalid())16432 return true;16433 16434 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),16435 OrigNumExpansions);16436 if (Out.isInvalid())16437 return true;16438 FullySubstituted = false;16439 ExpandedExprs.push_back(Out.get());16440 }16441 } else if (!E->expandsToEmptyPack()) {16442 if (getDerived().TransformExprs(E->getExpressions().data(),16443 E->getExpressions().size(), false,16444 ExpandedExprs))16445 return ExprError();16446 }16447 16448 return getDerived().RebuildPackIndexingExpr(16449 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),16450 IndexExpr.get(), ExpandedExprs, FullySubstituted);16451}16452 16453template <typename Derived>16454ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(16455 SubstNonTypeTemplateParmPackExpr *E) {16456 if (!getSema().ArgPackSubstIndex)16457 // We aren't expanding the parameter pack, so just return ourselves.16458 return E;16459 16460 TemplateArgument Pack = E->getArgumentPack();16461 TemplateArgument Arg = SemaRef.getPackSubstitutedTemplateArgument(Pack);16462 return SemaRef.BuildSubstNonTypeTemplateParmExpr(16463 E->getAssociatedDecl(), E->getParameterPack(),16464 E->getParameterPackLocation(), Arg, SemaRef.getPackIndex(Pack),16465 E->getFinal());16466}16467 16468template <typename Derived>16469ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(16470 SubstNonTypeTemplateParmExpr *E) {16471 Expr *OrigReplacement = E->getReplacement()->IgnoreImplicitAsWritten();16472 ExprResult Replacement = getDerived().TransformExpr(OrigReplacement);16473 if (Replacement.isInvalid())16474 return true;16475 16476 Decl *AssociatedDecl =16477 getDerived().TransformDecl(E->getNameLoc(), E->getAssociatedDecl());16478 if (!AssociatedDecl)16479 return true;16480 16481 if (Replacement.get() == OrigReplacement &&16482 AssociatedDecl == E->getAssociatedDecl())16483 return E;16484 16485 auto getParamAndType = [E](Decl *AssociatedDecl)16486 -> std::tuple<NonTypeTemplateParmDecl *, QualType> {16487 auto [PDecl, Arg] =16488 getReplacedTemplateParameter(AssociatedDecl, E->getIndex());16489 auto *Param = cast<NonTypeTemplateParmDecl>(PDecl);16490 if (Arg.isNull())16491 return {Param, Param->getType()};16492 if (UnsignedOrNone PackIndex = E->getPackIndex())16493 Arg = Arg.getPackAsArray()[*PackIndex];16494 return {Param, Arg.getNonTypeTemplateArgumentType()};16495 };16496 16497 // If the replacement expression did not change, and the parameter type16498 // did not change, we can skip the semantic action because it would16499 // produce the same result anyway.16500 if (auto [Param, ParamType] = getParamAndType(AssociatedDecl);16501 !SemaRef.Context.hasSameType(16502 ParamType, std::get<1>(getParamAndType(E->getAssociatedDecl()))) ||16503 Replacement.get() != OrigReplacement) {16504 // When transforming the replacement expression previously, all Sema16505 // specific annotations, such as implicit casts, are discarded. Calling the16506 // corresponding sema action is necessary to recover those. Otherwise,16507 // equivalency of the result would be lost.16508 TemplateArgument SugaredConverted, CanonicalConverted;16509 Replacement = SemaRef.CheckTemplateArgument(16510 Param, ParamType, Replacement.get(), SugaredConverted,16511 CanonicalConverted,16512 /*StrictCheck=*/false, Sema::CTAK_Specified);16513 if (Replacement.isInvalid())16514 return true;16515 } else {16516 // Otherwise, the same expression would have been produced.16517 Replacement = E->getReplacement();16518 }16519 16520 return new (SemaRef.Context) SubstNonTypeTemplateParmExpr(16521 Replacement.get()->getType(), Replacement.get()->getValueKind(),16522 E->getNameLoc(), Replacement.get(), AssociatedDecl, E->getIndex(),16523 E->getPackIndex(), E->isReferenceParameter(), E->getFinal());16524}16525 16526template<typename Derived>16527ExprResult16528TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {16529 // Default behavior is to do nothing with this transformation.16530 return E;16531}16532 16533template<typename Derived>16534ExprResult16535TreeTransform<Derived>::TransformMaterializeTemporaryExpr(16536 MaterializeTemporaryExpr *E) {16537 return getDerived().TransformExpr(E->getSubExpr());16538}16539 16540template<typename Derived>16541ExprResult16542TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {16543 UnresolvedLookupExpr *Callee = nullptr;16544 if (Expr *OldCallee = E->getCallee()) {16545 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);16546 if (CalleeResult.isInvalid())16547 return ExprError();16548 Callee = cast<UnresolvedLookupExpr>(CalleeResult.get());16549 }16550 16551 Expr *Pattern = E->getPattern();16552 16553 SmallVector<UnexpandedParameterPack, 2> Unexpanded;16554 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);16555 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");16556 16557 // Determine whether the set of unexpanded parameter packs can and should16558 // be expanded.16559 bool Expand = true;16560 bool RetainExpansion = false;16561 UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),16562 NumExpansions = OrigNumExpansions;16563 if (getDerived().TryExpandParameterPacks(16564 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,16565 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,16566 NumExpansions))16567 return true;16568 16569 if (!Expand) {16570 // Do not expand any packs here, just transform and rebuild a fold16571 // expression.16572 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);16573 16574 ExprResult LHS =16575 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();16576 if (LHS.isInvalid())16577 return true;16578 16579 ExprResult RHS =16580 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();16581 if (RHS.isInvalid())16582 return true;16583 16584 if (!getDerived().AlwaysRebuild() &&16585 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())16586 return E;16587 16588 return getDerived().RebuildCXXFoldExpr(16589 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),16590 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);16591 }16592 16593 // Formally a fold expression expands to nested parenthesized expressions.16594 // Enforce this limit to avoid creating trees so deep we can't safely traverse16595 // them.16596 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < *NumExpansions) {16597 SemaRef.Diag(E->getEllipsisLoc(),16598 clang::diag::err_fold_expression_limit_exceeded)16599 << *NumExpansions << SemaRef.getLangOpts().BracketDepth16600 << E->getSourceRange();16601 SemaRef.Diag(E->getEllipsisLoc(), diag::note_bracket_depth);16602 return ExprError();16603 }16604 16605 // The transform has determined that we should perform an elementwise16606 // expansion of the pattern. Do so.16607 ExprResult Result = getDerived().TransformExpr(E->getInit());16608 if (Result.isInvalid())16609 return true;16610 bool LeftFold = E->isLeftFold();16611 16612 // If we're retaining an expansion for a right fold, it is the innermost16613 // component and takes the init (if any).16614 if (!LeftFold && RetainExpansion) {16615 ForgetPartiallySubstitutedPackRAII Forget(getDerived());16616 16617 ExprResult Out = getDerived().TransformExpr(Pattern);16618 if (Out.isInvalid())16619 return true;16620 16621 Result = getDerived().RebuildCXXFoldExpr(16622 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),16623 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);16624 if (Result.isInvalid())16625 return true;16626 }16627 16628 bool WarnedOnComparison = false;16629 for (unsigned I = 0; I != *NumExpansions; ++I) {16630 Sema::ArgPackSubstIndexRAII SubstIndex(16631 getSema(), LeftFold ? I : *NumExpansions - I - 1);16632 ExprResult Out = getDerived().TransformExpr(Pattern);16633 if (Out.isInvalid())16634 return true;16635 16636 if (Out.get()->containsUnexpandedParameterPack()) {16637 // We still have a pack; retain a pack expansion for this slice.16638 Result = getDerived().RebuildCXXFoldExpr(16639 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),16640 E->getOperator(), E->getEllipsisLoc(),16641 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),16642 OrigNumExpansions);16643 } else if (Result.isUsable()) {16644 // We've got down to a single element; build a binary operator.16645 Expr *LHS = LeftFold ? Result.get() : Out.get();16646 Expr *RHS = LeftFold ? Out.get() : Result.get();16647 if (Callee) {16648 UnresolvedSet<16> Functions;16649 Functions.append(Callee->decls_begin(), Callee->decls_end());16650 Result = getDerived().RebuildCXXOperatorCallExpr(16651 BinaryOperator::getOverloadedOperator(E->getOperator()),16652 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),16653 Functions, LHS, RHS);16654 } else {16655 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),16656 E->getOperator(), LHS, RHS,16657 /*ForFoldExpresion=*/true);16658 if (!WarnedOnComparison && Result.isUsable()) {16659 if (auto *BO = dyn_cast<BinaryOperator>(Result.get());16660 BO && BO->isComparisonOp()) {16661 WarnedOnComparison = true;16662 SemaRef.Diag(BO->getBeginLoc(),16663 diag::warn_comparison_in_fold_expression)16664 << BO->getOpcodeStr();16665 }16666 }16667 }16668 } else16669 Result = Out;16670 16671 if (Result.isInvalid())16672 return true;16673 }16674 16675 // If we're retaining an expansion for a left fold, it is the outermost16676 // component and takes the complete expansion so far as its init (if any).16677 if (LeftFold && RetainExpansion) {16678 ForgetPartiallySubstitutedPackRAII Forget(getDerived());16679 16680 ExprResult Out = getDerived().TransformExpr(Pattern);16681 if (Out.isInvalid())16682 return true;16683 16684 Result = getDerived().RebuildCXXFoldExpr(16685 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),16686 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);16687 if (Result.isInvalid())16688 return true;16689 }16690 16691 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Result.get()))16692 PE->setIsProducedByFoldExpansion();16693 16694 // If we had no init and an empty pack, and we're not retaining an expansion,16695 // then produce a fallback value or error.16696 if (Result.isUnset())16697 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),16698 E->getOperator());16699 return Result;16700}16701 16702template <typename Derived>16703ExprResult16704TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {16705 SmallVector<Expr *, 4> TransformedInits;16706 ArrayRef<Expr *> InitExprs = E->getInitExprs();16707 16708 QualType T = getDerived().TransformType(E->getType());16709 16710 bool ArgChanged = false;16711 16712 if (getDerived().TransformExprs(InitExprs.data(), InitExprs.size(), true,16713 TransformedInits, &ArgChanged))16714 return ExprError();16715 16716 if (!getDerived().AlwaysRebuild() && !ArgChanged && T == E->getType())16717 return E;16718 16719 return getDerived().RebuildCXXParenListInitExpr(16720 TransformedInits, T, E->getUserSpecifiedInitExprs().size(),16721 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());16722}16723 16724template<typename Derived>16725ExprResult16726TreeTransform<Derived>::TransformCXXStdInitializerListExpr(16727 CXXStdInitializerListExpr *E) {16728 return getDerived().TransformExpr(E->getSubExpr());16729}16730 16731template<typename Derived>16732ExprResult16733TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {16734 return SemaRef.MaybeBindToTemporary(E);16735}16736 16737template<typename Derived>16738ExprResult16739TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {16740 return E;16741}16742 16743template<typename Derived>16744ExprResult16745TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {16746 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());16747 if (SubExpr.isInvalid())16748 return ExprError();16749 16750 if (!getDerived().AlwaysRebuild() &&16751 SubExpr.get() == E->getSubExpr())16752 return E;16753 16754 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());16755}16756 16757template<typename Derived>16758ExprResult16759TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {16760 // Transform each of the elements.16761 SmallVector<Expr *, 8> Elements;16762 bool ArgChanged = false;16763 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),16764 /*IsCall=*/false, Elements, &ArgChanged))16765 return ExprError();16766 16767 if (!getDerived().AlwaysRebuild() && !ArgChanged)16768 return SemaRef.MaybeBindToTemporary(E);16769 16770 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),16771 Elements.data(),16772 Elements.size());16773}16774 16775template<typename Derived>16776ExprResult16777TreeTransform<Derived>::TransformObjCDictionaryLiteral(16778 ObjCDictionaryLiteral *E) {16779 // Transform each of the elements.16780 SmallVector<ObjCDictionaryElement, 8> Elements;16781 bool ArgChanged = false;16782 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {16783 ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);16784 16785 if (OrigElement.isPackExpansion()) {16786 // This key/value element is a pack expansion.16787 SmallVector<UnexpandedParameterPack, 2> Unexpanded;16788 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);16789 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);16790 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");16791 16792 // Determine whether the set of unexpanded parameter packs can16793 // and should be expanded.16794 bool Expand = true;16795 bool RetainExpansion = false;16796 UnsignedOrNone OrigNumExpansions = OrigElement.NumExpansions;16797 UnsignedOrNone NumExpansions = OrigNumExpansions;16798 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),16799 OrigElement.Value->getEndLoc());16800 if (getDerived().TryExpandParameterPacks(16801 OrigElement.EllipsisLoc, PatternRange, Unexpanded,16802 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,16803 NumExpansions))16804 return ExprError();16805 16806 if (!Expand) {16807 // The transform has determined that we should perform a simple16808 // transformation on the pack expansion, producing another pack16809 // expansion.16810 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);16811 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);16812 if (Key.isInvalid())16813 return ExprError();16814 16815 if (Key.get() != OrigElement.Key)16816 ArgChanged = true;16817 16818 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);16819 if (Value.isInvalid())16820 return ExprError();16821 16822 if (Value.get() != OrigElement.Value)16823 ArgChanged = true;16824 16825 ObjCDictionaryElement Expansion = {16826 Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions16827 };16828 Elements.push_back(Expansion);16829 continue;16830 }16831 16832 // Record right away that the argument was changed. This needs16833 // to happen even if the array expands to nothing.16834 ArgChanged = true;16835 16836 // The transform has determined that we should perform an elementwise16837 // expansion of the pattern. Do so.16838 for (unsigned I = 0; I != *NumExpansions; ++I) {16839 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);16840 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);16841 if (Key.isInvalid())16842 return ExprError();16843 16844 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);16845 if (Value.isInvalid())16846 return ExprError();16847 16848 ObjCDictionaryElement Element = {16849 Key.get(), Value.get(), SourceLocation(), NumExpansions16850 };16851 16852 // If any unexpanded parameter packs remain, we still have a16853 // pack expansion.16854 // FIXME: Can this really happen?16855 if (Key.get()->containsUnexpandedParameterPack() ||16856 Value.get()->containsUnexpandedParameterPack())16857 Element.EllipsisLoc = OrigElement.EllipsisLoc;16858 16859 Elements.push_back(Element);16860 }16861 16862 // FIXME: Retain a pack expansion if RetainExpansion is true.16863 16864 // We've finished with this pack expansion.16865 continue;16866 }16867 16868 // Transform and check key.16869 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);16870 if (Key.isInvalid())16871 return ExprError();16872 16873 if (Key.get() != OrigElement.Key)16874 ArgChanged = true;16875 16876 // Transform and check value.16877 ExprResult Value16878 = getDerived().TransformExpr(OrigElement.Value);16879 if (Value.isInvalid())16880 return ExprError();16881 16882 if (Value.get() != OrigElement.Value)16883 ArgChanged = true;16884 16885 ObjCDictionaryElement Element = {Key.get(), Value.get(), SourceLocation(),16886 std::nullopt};16887 Elements.push_back(Element);16888 }16889 16890 if (!getDerived().AlwaysRebuild() && !ArgChanged)16891 return SemaRef.MaybeBindToTemporary(E);16892 16893 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),16894 Elements);16895}16896 16897template<typename Derived>16898ExprResult16899TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {16900 TypeSourceInfo *EncodedTypeInfo16901 = getDerived().TransformType(E->getEncodedTypeSourceInfo());16902 if (!EncodedTypeInfo)16903 return ExprError();16904 16905 if (!getDerived().AlwaysRebuild() &&16906 EncodedTypeInfo == E->getEncodedTypeSourceInfo())16907 return E;16908 16909 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),16910 EncodedTypeInfo,16911 E->getRParenLoc());16912}16913 16914template<typename Derived>16915ExprResult TreeTransform<Derived>::16916TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {16917 // This is a kind of implicit conversion, and it needs to get dropped16918 // and recomputed for the same general reasons that ImplicitCastExprs16919 // do, as well a more specific one: this expression is only valid when16920 // it appears *immediately* as an argument expression.16921 return getDerived().TransformExpr(E->getSubExpr());16922}16923 16924template<typename Derived>16925ExprResult TreeTransform<Derived>::16926TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {16927 TypeSourceInfo *TSInfo16928 = getDerived().TransformType(E->getTypeInfoAsWritten());16929 if (!TSInfo)16930 return ExprError();16931 16932 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());16933 if (Result.isInvalid())16934 return ExprError();16935 16936 if (!getDerived().AlwaysRebuild() &&16937 TSInfo == E->getTypeInfoAsWritten() &&16938 Result.get() == E->getSubExpr())16939 return E;16940 16941 return SemaRef.ObjC().BuildObjCBridgedCast(16942 E->getLParenLoc(), E->getBridgeKind(), E->getBridgeKeywordLoc(), TSInfo,16943 Result.get());16944}16945 16946template <typename Derived>16947ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(16948 ObjCAvailabilityCheckExpr *E) {16949 return E;16950}16951 16952template<typename Derived>16953ExprResult16954TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {16955 // Transform arguments.16956 bool ArgChanged = false;16957 SmallVector<Expr*, 8> Args;16958 Args.reserve(E->getNumArgs());16959 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,16960 &ArgChanged))16961 return ExprError();16962 16963 if (E->getReceiverKind() == ObjCMessageExpr::Class) {16964 // Class message: transform the receiver type.16965 TypeSourceInfo *ReceiverTypeInfo16966 = getDerived().TransformType(E->getClassReceiverTypeInfo());16967 if (!ReceiverTypeInfo)16968 return ExprError();16969 16970 // If nothing changed, just retain the existing message send.16971 if (!getDerived().AlwaysRebuild() &&16972 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)16973 return SemaRef.MaybeBindToTemporary(E);16974 16975 // Build a new class message send.16976 SmallVector<SourceLocation, 16> SelLocs;16977 E->getSelectorLocs(SelLocs);16978 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,16979 E->getSelector(),16980 SelLocs,16981 E->getMethodDecl(),16982 E->getLeftLoc(),16983 Args,16984 E->getRightLoc());16985 }16986 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||16987 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {16988 if (!E->getMethodDecl())16989 return ExprError();16990 16991 // Build a new class message send to 'super'.16992 SmallVector<SourceLocation, 16> SelLocs;16993 E->getSelectorLocs(SelLocs);16994 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),16995 E->getSelector(),16996 SelLocs,16997 E->getReceiverType(),16998 E->getMethodDecl(),16999 E->getLeftLoc(),17000 Args,17001 E->getRightLoc());17002 }17003 17004 // Instance message: transform the receiver17005 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&17006 "Only class and instance messages may be instantiated");17007 ExprResult Receiver17008 = getDerived().TransformExpr(E->getInstanceReceiver());17009 if (Receiver.isInvalid())17010 return ExprError();17011 17012 // If nothing changed, just retain the existing message send.17013 if (!getDerived().AlwaysRebuild() &&17014 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)17015 return SemaRef.MaybeBindToTemporary(E);17016 17017 // Build a new instance message send.17018 SmallVector<SourceLocation, 16> SelLocs;17019 E->getSelectorLocs(SelLocs);17020 return getDerived().RebuildObjCMessageExpr(Receiver.get(),17021 E->getSelector(),17022 SelLocs,17023 E->getMethodDecl(),17024 E->getLeftLoc(),17025 Args,17026 E->getRightLoc());17027}17028 17029template<typename Derived>17030ExprResult17031TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {17032 return E;17033}17034 17035template<typename Derived>17036ExprResult17037TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {17038 return E;17039}17040 17041template<typename Derived>17042ExprResult17043TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {17044 // Transform the base expression.17045 ExprResult Base = getDerived().TransformExpr(E->getBase());17046 if (Base.isInvalid())17047 return ExprError();17048 17049 // We don't need to transform the ivar; it will never change.17050 17051 // If nothing changed, just retain the existing expression.17052 if (!getDerived().AlwaysRebuild() &&17053 Base.get() == E->getBase())17054 return E;17055 17056 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),17057 E->getLocation(),17058 E->isArrow(), E->isFreeIvar());17059}17060 17061template<typename Derived>17062ExprResult17063TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {17064 // 'super' and types never change. Property never changes. Just17065 // retain the existing expression.17066 if (!E->isObjectReceiver())17067 return E;17068 17069 // Transform the base expression.17070 ExprResult Base = getDerived().TransformExpr(E->getBase());17071 if (Base.isInvalid())17072 return ExprError();17073 17074 // We don't need to transform the property; it will never change.17075 17076 // If nothing changed, just retain the existing expression.17077 if (!getDerived().AlwaysRebuild() &&17078 Base.get() == E->getBase())17079 return E;17080 17081 if (E->isExplicitProperty())17082 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),17083 E->getExplicitProperty(),17084 E->getLocation());17085 17086 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),17087 SemaRef.Context.PseudoObjectTy,17088 E->getImplicitPropertyGetter(),17089 E->getImplicitPropertySetter(),17090 E->getLocation());17091}17092 17093template<typename Derived>17094ExprResult17095TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {17096 // Transform the base expression.17097 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());17098 if (Base.isInvalid())17099 return ExprError();17100 17101 // Transform the key expression.17102 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());17103 if (Key.isInvalid())17104 return ExprError();17105 17106 // If nothing changed, just retain the existing expression.17107 if (!getDerived().AlwaysRebuild() &&17108 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())17109 return E;17110 17111 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),17112 Base.get(), Key.get(),17113 E->getAtIndexMethodDecl(),17114 E->setAtIndexMethodDecl());17115}17116 17117template<typename Derived>17118ExprResult17119TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {17120 // Transform the base expression.17121 ExprResult Base = getDerived().TransformExpr(E->getBase());17122 if (Base.isInvalid())17123 return ExprError();17124 17125 // If nothing changed, just retain the existing expression.17126 if (!getDerived().AlwaysRebuild() &&17127 Base.get() == E->getBase())17128 return E;17129 17130 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),17131 E->getOpLoc(),17132 E->isArrow());17133}17134 17135template<typename Derived>17136ExprResult17137TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {17138 bool ArgumentChanged = false;17139 SmallVector<Expr*, 8> SubExprs;17140 SubExprs.reserve(E->getNumSubExprs());17141 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,17142 SubExprs, &ArgumentChanged))17143 return ExprError();17144 17145 if (!getDerived().AlwaysRebuild() &&17146 !ArgumentChanged)17147 return E;17148 17149 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),17150 SubExprs,17151 E->getRParenLoc());17152}17153 17154template<typename Derived>17155ExprResult17156TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {17157 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());17158 if (SrcExpr.isInvalid())17159 return ExprError();17160 17161 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());17162 if (!Type)17163 return ExprError();17164 17165 if (!getDerived().AlwaysRebuild() &&17166 Type == E->getTypeSourceInfo() &&17167 SrcExpr.get() == E->getSrcExpr())17168 return E;17169 17170 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),17171 SrcExpr.get(), Type,17172 E->getRParenLoc());17173}17174 17175template<typename Derived>17176ExprResult17177TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {17178 BlockDecl *oldBlock = E->getBlockDecl();17179 17180 SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr);17181 BlockScopeInfo *blockScope = SemaRef.getCurBlock();17182 17183 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());17184 blockScope->TheDecl->setBlockMissingReturnType(17185 oldBlock->blockMissingReturnType());17186 17187 SmallVector<ParmVarDecl*, 4> params;17188 SmallVector<QualType, 4> paramTypes;17189 17190 const FunctionProtoType *exprFunctionType = E->getFunctionType();17191 17192 // Parameter substitution.17193 Sema::ExtParameterInfoBuilder extParamInfos;17194 if (getDerived().TransformFunctionTypeParams(17195 E->getCaretLocation(), oldBlock->parameters(), nullptr,17196 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, ¶ms,17197 extParamInfos)) {17198 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);17199 return ExprError();17200 }17201 17202 QualType exprResultType =17203 getDerived().TransformType(exprFunctionType->getReturnType());17204 17205 auto epi = exprFunctionType->getExtProtoInfo();17206 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size());17207 17208 QualType functionType =17209 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);17210 blockScope->FunctionType = functionType;17211 17212 // Set the parameters on the block decl.17213 if (!params.empty())17214 blockScope->TheDecl->setParams(params);17215 17216 if (!oldBlock->blockMissingReturnType()) {17217 blockScope->HasImplicitReturnType = false;17218 blockScope->ReturnType = exprResultType;17219 }17220 17221 // Transform the body17222 StmtResult body = getDerived().TransformStmt(E->getBody());17223 if (body.isInvalid()) {17224 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);17225 return ExprError();17226 }17227 17228#ifndef NDEBUG17229 // In builds with assertions, make sure that we captured everything we17230 // captured before.17231 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {17232 for (const auto &I : oldBlock->captures()) {17233 VarDecl *oldCapture = I.getVariable();17234 17235 // Ignore parameter packs.17236 if (oldCapture->isParameterPack())17237 continue;17238 17239 VarDecl *newCapture =17240 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),17241 oldCapture));17242 assert(blockScope->CaptureMap.count(newCapture));17243 }17244 17245 // The this pointer may not be captured by the instantiated block, even when17246 // it's captured by the original block, if the expression causing the17247 // capture is in the discarded branch of a constexpr if statement.17248 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&17249 "this pointer isn't captured in the old block");17250 }17251#endif17252 17253 return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(),17254 /*Scope=*/nullptr);17255}17256 17257template<typename Derived>17258ExprResult17259TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {17260 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());17261 if (SrcExpr.isInvalid())17262 return ExprError();17263 17264 QualType Type = getDerived().TransformType(E->getType());17265 17266 return SemaRef.BuildAsTypeExpr(SrcExpr.get(), Type, E->getBuiltinLoc(),17267 E->getRParenLoc());17268}17269 17270template<typename Derived>17271ExprResult17272TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {17273 bool ArgumentChanged = false;17274 SmallVector<Expr*, 8> SubExprs;17275 SubExprs.reserve(E->getNumSubExprs());17276 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,17277 SubExprs, &ArgumentChanged))17278 return ExprError();17279 17280 if (!getDerived().AlwaysRebuild() &&17281 !ArgumentChanged)17282 return E;17283 17284 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,17285 E->getOp(), E->getRParenLoc());17286}17287 17288//===----------------------------------------------------------------------===//17289// Type reconstruction17290//===----------------------------------------------------------------------===//17291 17292template<typename Derived>17293QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,17294 SourceLocation Star) {17295 return SemaRef.BuildPointerType(PointeeType, Star,17296 getDerived().getBaseEntity());17297}17298 17299template<typename Derived>17300QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,17301 SourceLocation Star) {17302 return SemaRef.BuildBlockPointerType(PointeeType, Star,17303 getDerived().getBaseEntity());17304}17305 17306template<typename Derived>17307QualType17308TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,17309 bool WrittenAsLValue,17310 SourceLocation Sigil) {17311 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue,17312 Sigil, getDerived().getBaseEntity());17313}17314 17315template <typename Derived>17316QualType TreeTransform<Derived>::RebuildMemberPointerType(17317 QualType PointeeType, const CXXScopeSpec &SS, CXXRecordDecl *Cls,17318 SourceLocation Sigil) {17319 return SemaRef.BuildMemberPointerType(PointeeType, SS, Cls, Sigil,17320 getDerived().getBaseEntity());17321}17322 17323template<typename Derived>17324QualType TreeTransform<Derived>::RebuildObjCTypeParamType(17325 const ObjCTypeParamDecl *Decl,17326 SourceLocation ProtocolLAngleLoc,17327 ArrayRef<ObjCProtocolDecl *> Protocols,17328 ArrayRef<SourceLocation> ProtocolLocs,17329 SourceLocation ProtocolRAngleLoc) {17330 return SemaRef.ObjC().BuildObjCTypeParamType(17331 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,17332 /*FailOnError=*/true);17333}17334 17335template<typename Derived>17336QualType TreeTransform<Derived>::RebuildObjCObjectType(17337 QualType BaseType,17338 SourceLocation Loc,17339 SourceLocation TypeArgsLAngleLoc,17340 ArrayRef<TypeSourceInfo *> TypeArgs,17341 SourceLocation TypeArgsRAngleLoc,17342 SourceLocation ProtocolLAngleLoc,17343 ArrayRef<ObjCProtocolDecl *> Protocols,17344 ArrayRef<SourceLocation> ProtocolLocs,17345 SourceLocation ProtocolRAngleLoc) {17346 return SemaRef.ObjC().BuildObjCObjectType(17347 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,17348 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,17349 /*FailOnError=*/true,17350 /*Rebuilding=*/true);17351}17352 17353template<typename Derived>17354QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(17355 QualType PointeeType,17356 SourceLocation Star) {17357 return SemaRef.Context.getObjCObjectPointerType(PointeeType);17358}17359 17360template <typename Derived>17361QualType TreeTransform<Derived>::RebuildArrayType(17362 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,17363 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {17364 if (SizeExpr || !Size)17365 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,17366 IndexTypeQuals, BracketsRange,17367 getDerived().getBaseEntity());17368 17369 QualType Types[] = {17370 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,17371 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,17372 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty17373 };17374 QualType SizeType;17375 for (const auto &T : Types)17376 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {17377 SizeType = T;17378 break;17379 }17380 17381 // Note that we can return a VariableArrayType here in the case where17382 // the element type was a dependent VariableArrayType.17383 IntegerLiteral *ArraySize17384 = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType,17385 /*FIXME*/BracketsRange.getBegin());17386 return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize,17387 IndexTypeQuals, BracketsRange,17388 getDerived().getBaseEntity());17389}17390 17391template <typename Derived>17392QualType TreeTransform<Derived>::RebuildConstantArrayType(17393 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,17394 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {17395 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,17396 IndexTypeQuals, BracketsRange);17397}17398 17399template <typename Derived>17400QualType TreeTransform<Derived>::RebuildIncompleteArrayType(17401 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,17402 SourceRange BracketsRange) {17403 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,17404 IndexTypeQuals, BracketsRange);17405}17406 17407template <typename Derived>17408QualType TreeTransform<Derived>::RebuildVariableArrayType(17409 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,17410 unsigned IndexTypeQuals, SourceRange BracketsRange) {17411 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,17412 SizeExpr,17413 IndexTypeQuals, BracketsRange);17414}17415 17416template <typename Derived>17417QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(17418 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,17419 unsigned IndexTypeQuals, SourceRange BracketsRange) {17420 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,17421 SizeExpr,17422 IndexTypeQuals, BracketsRange);17423}17424 17425template <typename Derived>17426QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(17427 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {17428 return SemaRef.BuildAddressSpaceAttr(PointeeType, AddrSpaceExpr,17429 AttributeLoc);17430}17431 17432template <typename Derived>17433QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,17434 unsigned NumElements,17435 VectorKind VecKind) {17436 // FIXME: semantic checking!17437 return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);17438}17439 17440template <typename Derived>17441QualType TreeTransform<Derived>::RebuildDependentVectorType(17442 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,17443 VectorKind VecKind) {17444 return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc);17445}17446 17447template<typename Derived>17448QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,17449 unsigned NumElements,17450 SourceLocation AttributeLoc) {17451 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),17452 NumElements, true);17453 IntegerLiteral *VectorSize17454 = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,17455 AttributeLoc);17456 return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);17457}17458 17459template<typename Derived>17460QualType17461TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,17462 Expr *SizeExpr,17463 SourceLocation AttributeLoc) {17464 return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);17465}17466 17467template <typename Derived>17468QualType TreeTransform<Derived>::RebuildConstantMatrixType(17469 QualType ElementType, unsigned NumRows, unsigned NumColumns) {17470 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,17471 NumColumns);17472}17473 17474template <typename Derived>17475QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(17476 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,17477 SourceLocation AttributeLoc) {17478 return SemaRef.BuildMatrixType(ElementType, RowExpr, ColumnExpr,17479 AttributeLoc);17480}17481 17482template <typename Derived>17483QualType TreeTransform<Derived>::RebuildFunctionProtoType(17484 QualType T, MutableArrayRef<QualType> ParamTypes,17485 const FunctionProtoType::ExtProtoInfo &EPI) {17486 return SemaRef.BuildFunctionType(T, ParamTypes,17487 getDerived().getBaseLocation(),17488 getDerived().getBaseEntity(),17489 EPI);17490}17491 17492template<typename Derived>17493QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {17494 return SemaRef.Context.getFunctionNoProtoType(T);17495}17496 17497template <typename Derived>17498QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(17499 ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,17500 SourceLocation NameLoc, Decl *D) {17501 assert(D && "no decl found");17502 if (D->isInvalidDecl()) return QualType();17503 17504 // FIXME: Doesn't account for ObjCInterfaceDecl!17505 if (auto *UPD = dyn_cast<UsingPackDecl>(D)) {17506 // A valid resolved using typename pack expansion decl can have multiple17507 // UsingDecls, but they must each have exactly one type, and it must be17508 // the same type in every case. But we must have at least one expansion!17509 if (UPD->expansions().empty()) {17510 getSema().Diag(NameLoc, diag::err_using_pack_expansion_empty)17511 << UPD->isCXXClassMember() << UPD;17512 return QualType();17513 }17514 17515 // We might still have some unresolved types. Try to pick a resolved type17516 // if we can. The final instantiation will check that the remaining17517 // unresolved types instantiate to the type we pick.17518 QualType FallbackT;17519 QualType T;17520 for (auto *E : UPD->expansions()) {17521 QualType ThisT =17522 RebuildUnresolvedUsingType(Keyword, Qualifier, NameLoc, E);17523 if (ThisT.isNull())17524 continue;17525 if (ThisT->getAs<UnresolvedUsingType>())17526 FallbackT = ThisT;17527 else if (T.isNull())17528 T = ThisT;17529 else17530 assert(getSema().Context.hasSameType(ThisT, T) &&17531 "mismatched resolved types in using pack expansion");17532 }17533 return T.isNull() ? FallbackT : T;17534 }17535 if (auto *Using = dyn_cast<UsingDecl>(D)) {17536 assert(Using->hasTypename() &&17537 "UnresolvedUsingTypenameDecl transformed to non-typename using");17538 17539 // A valid resolved using typename decl points to exactly one type decl.17540 assert(++Using->shadow_begin() == Using->shadow_end());17541 17542 UsingShadowDecl *Shadow = *Using->shadow_begin();17543 if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), NameLoc))17544 return QualType();17545 return SemaRef.Context.getUsingType(Keyword, Qualifier, Shadow);17546 }17547 assert(isa<UnresolvedUsingTypenameDecl>(D) &&17548 "UnresolvedUsingTypenameDecl transformed to non-using decl");17549 return SemaRef.Context.getUnresolvedUsingType(17550 Keyword, Qualifier, cast<UnresolvedUsingTypenameDecl>(D));17551}17552 17553template <typename Derived>17554QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,17555 TypeOfKind Kind) {17556 return SemaRef.BuildTypeofExprType(E, Kind);17557}17558 17559template<typename Derived>17560QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,17561 TypeOfKind Kind) {17562 return SemaRef.Context.getTypeOfType(Underlying, Kind);17563}17564 17565template <typename Derived>17566QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {17567 return SemaRef.BuildDecltypeType(E);17568}17569 17570template <typename Derived>17571QualType TreeTransform<Derived>::RebuildPackIndexingType(17572 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,17573 SourceLocation EllipsisLoc, bool FullySubstituted,17574 ArrayRef<QualType> Expansions) {17575 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,17576 FullySubstituted, Expansions);17577}17578 17579template<typename Derived>17580QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,17581 UnaryTransformType::UTTKind UKind,17582 SourceLocation Loc) {17583 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);17584}17585 17586template <typename Derived>17587QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(17588 ElaboratedTypeKeyword Keyword, TemplateName Template,17589 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {17590 return SemaRef.CheckTemplateIdType(17591 Keyword, Template, TemplateNameLoc, TemplateArgs,17592 /*Scope=*/nullptr, /*ForNestedNameSpecifier=*/false);17593}17594 17595template<typename Derived>17596QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,17597 SourceLocation KWLoc) {17598 return SemaRef.BuildAtomicType(ValueType, KWLoc);17599}17600 17601template<typename Derived>17602QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,17603 SourceLocation KWLoc,17604 bool isReadPipe) {17605 return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc)17606 : SemaRef.BuildWritePipeType(ValueType, KWLoc);17607}17608 17609template <typename Derived>17610QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,17611 unsigned NumBits,17612 SourceLocation Loc) {17613 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),17614 NumBits, true);17615 IntegerLiteral *Bits = IntegerLiteral::Create(SemaRef.Context, NumBitsAP,17616 SemaRef.Context.IntTy, Loc);17617 return SemaRef.BuildBitIntType(IsUnsigned, Bits, Loc);17618}17619 17620template <typename Derived>17621QualType TreeTransform<Derived>::RebuildDependentBitIntType(17622 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {17623 return SemaRef.BuildBitIntType(IsUnsigned, NumBitsExpr, Loc);17624}17625 17626template <typename Derived>17627TemplateName TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,17628 bool TemplateKW,17629 TemplateName Name) {17630 return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW,17631 Name);17632}17633 17634template <typename Derived>17635TemplateName TreeTransform<Derived>::RebuildTemplateName(17636 CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name,17637 SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName) {17638 UnqualifiedId TemplateName;17639 TemplateName.setIdentifier(&Name, NameLoc);17640 Sema::TemplateTy Template;17641 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,17642 TemplateName, ParsedType::make(ObjectType),17643 /*EnteringContext=*/false, Template,17644 AllowInjectedClassName);17645 return Template.get();17646}17647 17648template<typename Derived>17649TemplateName17650TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,17651 SourceLocation TemplateKWLoc,17652 OverloadedOperatorKind Operator,17653 SourceLocation NameLoc,17654 QualType ObjectType,17655 bool AllowInjectedClassName) {17656 UnqualifiedId Name;17657 // FIXME: Bogus location information.17658 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };17659 Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);17660 Sema::TemplateTy Template;17661 getSema().ActOnTemplateName(17662 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(ObjectType),17663 /*EnteringContext=*/false, Template, AllowInjectedClassName);17664 return Template.get();17665}17666 17667template <typename Derived>17668ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(17669 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,17670 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,17671 Expr *Second) {17672 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);17673 17674 if (First->getObjectKind() == OK_ObjCProperty) {17675 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);17676 if (BinaryOperator::isAssignmentOp(Opc))17677 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/nullptr, OpLoc,17678 Opc, First, Second);17679 ExprResult Result = SemaRef.CheckPlaceholderExpr(First);17680 if (Result.isInvalid())17681 return ExprError();17682 First = Result.get();17683 }17684 17685 if (Second && Second->getObjectKind() == OK_ObjCProperty) {17686 ExprResult Result = SemaRef.CheckPlaceholderExpr(Second);17687 if (Result.isInvalid())17688 return ExprError();17689 Second = Result.get();17690 }17691 17692 // Determine whether this should be a builtin operation.17693 if (Op == OO_Subscript) {17694 if (!First->getType()->isOverloadableType() &&17695 !Second->getType()->isOverloadableType())17696 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,17697 OpLoc);17698 } else if (Op == OO_Arrow) {17699 // It is possible that the type refers to a RecoveryExpr created earlier17700 // in the tree transformation.17701 if (First->getType()->isDependentType())17702 return ExprError();17703 // -> is never a builtin operation.17704 return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);17705 } else if (Second == nullptr || isPostIncDec) {17706 if (!First->getType()->isOverloadableType() ||17707 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {17708 // The argument is not of overloadable type, or this is an expression17709 // of the form &Class::member, so try to create a built-in unary17710 // operation.17711 UnaryOperatorKind Opc17712 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);17713 17714 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);17715 }17716 } else {17717 if (!First->isTypeDependent() && !Second->isTypeDependent() &&17718 !First->getType()->isOverloadableType() &&17719 !Second->getType()->isOverloadableType()) {17720 // Neither of the arguments is type-dependent or has an overloadable17721 // type, so try to create a built-in binary operation.17722 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);17723 ExprResult Result17724 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);17725 if (Result.isInvalid())17726 return ExprError();17727 17728 return Result;17729 }17730 }17731 17732 // Create the overloaded operator invocation for unary operators.17733 if (!Second || isPostIncDec) {17734 UnaryOperatorKind Opc17735 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);17736 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First,17737 RequiresADL);17738 }17739 17740 // Create the overloaded operator invocation for binary operators.17741 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);17742 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions,17743 First, Second, RequiresADL);17744 if (Result.isInvalid())17745 return ExprError();17746 17747 return Result;17748}17749 17750template<typename Derived>17751ExprResult17752TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,17753 SourceLocation OperatorLoc,17754 bool isArrow,17755 CXXScopeSpec &SS,17756 TypeSourceInfo *ScopeType,17757 SourceLocation CCLoc,17758 SourceLocation TildeLoc,17759 PseudoDestructorTypeStorage Destroyed) {17760 QualType CanonicalBaseType = Base->getType().getCanonicalType();17761 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||17762 (!isArrow && !isa<RecordType>(CanonicalBaseType)) ||17763 (isArrow && isa<PointerType>(CanonicalBaseType) &&17764 !cast<PointerType>(CanonicalBaseType)17765 ->getPointeeType()17766 ->getAsCanonical<RecordType>())) {17767 // This pseudo-destructor expression is still a pseudo-destructor.17768 return SemaRef.BuildPseudoDestructorExpr(17769 Base, OperatorLoc, isArrow ? tok::arrow : tok::period, SS, ScopeType,17770 CCLoc, TildeLoc, Destroyed);17771 }17772 17773 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();17774 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(17775 SemaRef.Context.getCanonicalType(DestroyedType->getType())));17776 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());17777 NameInfo.setNamedTypeInfo(DestroyedType);17778 17779 // The scope type is now known to be a valid nested name specifier17780 // component. Tack it on to the nested name specifier.17781 if (ScopeType) {17782 if (!isa<TagType>(ScopeType->getType().getCanonicalType())) {17783 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),17784 diag::err_expected_class_or_namespace)17785 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;17786 return ExprError();17787 }17788 SS.clear();17789 SS.Make(SemaRef.Context, ScopeType->getTypeLoc(), CCLoc);17790 }17791 17792 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.17793 return getSema().BuildMemberReferenceExpr(17794 Base, Base->getType(), OperatorLoc, isArrow, SS, TemplateKWLoc,17795 /*FIXME: FirstQualifier*/ nullptr, NameInfo,17796 /*TemplateArgs*/ nullptr,17797 /*S*/ nullptr);17798}17799 17800template<typename Derived>17801StmtResult17802TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {17803 SourceLocation Loc = S->getBeginLoc();17804 CapturedDecl *CD = S->getCapturedDecl();17805 unsigned NumParams = CD->getNumParams();17806 unsigned ContextParamPos = CD->getContextParamPosition();17807 SmallVector<Sema::CapturedParamNameType, 4> Params;17808 for (unsigned I = 0; I < NumParams; ++I) {17809 if (I != ContextParamPos) {17810 Params.push_back(17811 std::make_pair(17812 CD->getParam(I)->getName(),17813 getDerived().TransformType(CD->getParam(I)->getType())));17814 } else {17815 Params.push_back(std::make_pair(StringRef(), QualType()));17816 }17817 }17818 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,17819 S->getCapturedRegionKind(), Params);17820 StmtResult Body;17821 {17822 Sema::CompoundScopeRAII CompoundScope(getSema());17823 Body = getDerived().TransformStmt(S->getCapturedStmt());17824 }17825 17826 if (Body.isInvalid()) {17827 getSema().ActOnCapturedRegionError();17828 return StmtError();17829 }17830 17831 return getSema().ActOnCapturedRegionEnd(Body.get());17832}17833 17834template <typename Derived>17835StmtResult17836TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {17837 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)17838 // function definition or instantiation of a function template specialization17839 // and will therefore never appear in a dependent context.17840 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "17841 "context");17842}17843 17844template <typename Derived>17845ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {17846 // We can transform the base expression and allow argument resolution to fill17847 // in the rest.17848 return getDerived().TransformExpr(E->getArgLValue());17849}17850 17851} // end namespace clang17852 17853#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H17854