diff options
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Sema/TreeTransform.h')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Sema/TreeTransform.h | 12893 |
1 files changed, 0 insertions, 12893 deletions
diff --git a/gnu/llvm/tools/clang/lib/Sema/TreeTransform.h b/gnu/llvm/tools/clang/lib/Sema/TreeTransform.h deleted file mode 100644 index 9de4e8d654f..00000000000 --- a/gnu/llvm/tools/clang/lib/Sema/TreeTransform.h +++ /dev/null @@ -1,12893 +0,0 @@ -//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -//===----------------------------------------------------------------------===// -// -// This file implements a semantic tree transformation that takes a given -// AST and rebuilds it, possibly transforming some nodes in the process. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H -#define LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H - -#include "CoroutineStmtBuilder.h" -#include "TypeLocBuilder.h" -#include "clang/AST/Decl.h" -#include "clang/AST/DeclObjC.h" -#include "clang/AST/DeclTemplate.h" -#include "clang/AST/Expr.h" -#include "clang/AST/ExprCXX.h" -#include "clang/AST/ExprObjC.h" -#include "clang/AST/ExprOpenMP.h" -#include "clang/AST/Stmt.h" -#include "clang/AST/StmtCXX.h" -#include "clang/AST/StmtObjC.h" -#include "clang/AST/StmtOpenMP.h" -#include "clang/Sema/Designator.h" -#include "clang/Sema/Lookup.h" -#include "clang/Sema/Ownership.h" -#include "clang/Sema/ParsedTemplate.h" -#include "clang/Sema/ScopeInfo.h" -#include "clang/Sema/SemaDiagnostic.h" -#include "clang/Sema/SemaInternal.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/Support/ErrorHandling.h" -#include <algorithm> - -namespace clang { -using namespace sema; - -/// A semantic tree transformation that allows one to transform one -/// abstract syntax tree into another. -/// -/// A new tree transformation is defined by creating a new subclass \c X of -/// \c TreeTransform<X> and then overriding certain operations to provide -/// behavior specific to that transformation. For example, template -/// instantiation is implemented as a tree transformation where the -/// transformation of TemplateTypeParmType nodes involves substituting the -/// template arguments for their corresponding template parameters; a similar -/// transformation is performed for non-type template parameters and -/// template template parameters. -/// -/// This tree-transformation template uses static polymorphism to allow -/// subclasses to customize any of its operations. Thus, a subclass can -/// override any of the transformation or rebuild operators by providing an -/// operation with the same signature as the default implementation. The -/// overriding function should not be virtual. -/// -/// Semantic tree transformations are split into two stages, either of which -/// can be replaced by a subclass. The "transform" step transforms an AST node -/// or the parts of an AST node using the various transformation functions, -/// then passes the pieces on to the "rebuild" step, which constructs a new AST -/// node of the appropriate kind from the pieces. The default transformation -/// routines recursively transform the operands to composite AST nodes (e.g., -/// the pointee type of a PointerType node) and, if any of those operand nodes -/// were changed by the transformation, invokes the rebuild operation to create -/// a new AST node. -/// -/// Subclasses can customize the transformation at various levels. The -/// most coarse-grained transformations involve replacing TransformType(), -/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(), -/// TransformTemplateName(), or TransformTemplateArgument() with entirely -/// new implementations. -/// -/// For more fine-grained transformations, subclasses can replace any of the -/// \c TransformXXX functions (where XXX is the name of an AST node, e.g., -/// PointerType, StmtExpr) to alter the transformation. As mentioned previously, -/// replacing TransformTemplateTypeParmType() allows template instantiation -/// to substitute template arguments for their corresponding template -/// parameters. Additionally, subclasses can override the \c RebuildXXX -/// functions to control how AST nodes are rebuilt when their operands change. -/// By default, \c TreeTransform will invoke semantic analysis to rebuild -/// AST nodes. However, certain other tree transformations (e.g, cloning) may -/// be able to use more efficient rebuild steps. -/// -/// There are a handful of other functions that can be overridden, allowing one -/// to avoid traversing nodes that don't need any transformation -/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their -/// operands have not changed (\c AlwaysRebuild()), and customize the -/// default locations and entity names used for type-checking -/// (\c getBaseLocation(), \c getBaseEntity()). -template<typename Derived> -class TreeTransform { - /// Private RAII object that helps us forget and then re-remember - /// the template argument corresponding to a partially-substituted parameter - /// pack. - class ForgetPartiallySubstitutedPackRAII { - Derived &Self; - TemplateArgument Old; - - public: - ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) { - Old = Self.ForgetPartiallySubstitutedPack(); - } - - ~ForgetPartiallySubstitutedPackRAII() { - Self.RememberPartiallySubstitutedPack(Old); - } - }; - -protected: - Sema &SemaRef; - - /// The set of local declarations that have been transformed, for - /// cases where we are forced to build new declarations within the transformer - /// rather than in the subclass (e.g., lambda closure types). - llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls; - -public: - /// Initializes a new tree transformer. - TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { } - - /// Retrieves a reference to the derived class. - Derived &getDerived() { return static_cast<Derived&>(*this); } - - /// Retrieves a reference to the derived class. - const Derived &getDerived() const { - return static_cast<const Derived&>(*this); - } - - static inline ExprResult Owned(Expr *E) { return E; } - static inline StmtResult Owned(Stmt *S) { return S; } - - /// Retrieves a reference to the semantic analysis object used for - /// this tree transform. - Sema &getSema() const { return SemaRef; } - - /// Whether the transformation should always rebuild AST nodes, even - /// if none of the children have changed. - /// - /// Subclasses may override this function to specify when the transformation - /// should rebuild all AST nodes. - /// - /// We must always rebuild all AST nodes when performing variadic template - /// pack expansion, in order to avoid violating the AST invariant that each - /// statement node appears at most once in its containing declaration. - bool AlwaysRebuild() { return SemaRef.ArgumentPackSubstitutionIndex != -1; } - - /// Returns the location of the entity being transformed, if that - /// information was not available elsewhere in the AST. - /// - /// By default, returns no source-location information. Subclasses can - /// provide an alternative implementation that provides better location - /// information. - SourceLocation getBaseLocation() { return SourceLocation(); } - - /// Returns the name of the entity being transformed, if that - /// information was not available elsewhere in the AST. - /// - /// By default, returns an empty name. Subclasses can provide an alternative - /// implementation with a more precise name. - DeclarationName getBaseEntity() { return DeclarationName(); } - - /// Sets the "base" location and entity when that - /// information is known based on another transformation. - /// - /// By default, the source location and entity are ignored. Subclasses can - /// override this function to provide a customized implementation. - void setBase(SourceLocation Loc, DeclarationName Entity) { } - - /// RAII object that temporarily sets the base location and entity - /// used for reporting diagnostics in types. - class TemporaryBase { - TreeTransform &Self; - SourceLocation OldLocation; - DeclarationName OldEntity; - - public: - TemporaryBase(TreeTransform &Self, SourceLocation Location, - DeclarationName Entity) : Self(Self) { - OldLocation = Self.getDerived().getBaseLocation(); - OldEntity = Self.getDerived().getBaseEntity(); - - if (Location.isValid()) - Self.getDerived().setBase(Location, Entity); - } - - ~TemporaryBase() { - Self.getDerived().setBase(OldLocation, OldEntity); - } - }; - - /// Determine whether the given type \p T has already been - /// transformed. - /// - /// Subclasses can provide an alternative implementation of this routine - /// to short-circuit evaluation when it is known that a given type will - /// not change. For example, template instantiation need not traverse - /// non-dependent types. - bool AlreadyTransformed(QualType T) { - return T.isNull(); - } - - /// Determine whether the given call argument should be dropped, e.g., - /// because it is a default argument. - /// - /// Subclasses can provide an alternative implementation of this routine to - /// determine which kinds of call arguments get dropped. By default, - /// CXXDefaultArgument nodes are dropped (prior to transformation). - bool DropCallArgument(Expr *E) { - return E->isDefaultArgument(); - } - - /// Determine whether we should expand a pack expansion with the - /// given set of parameter packs into separate arguments by repeatedly - /// transforming the pattern. - /// - /// By default, the transformer never tries to expand pack expansions. - /// Subclasses can override this routine to provide different behavior. - /// - /// \param EllipsisLoc The location of the ellipsis that identifies the - /// pack expansion. - /// - /// \param PatternRange The source range that covers the entire pattern of - /// the pack expansion. - /// - /// \param Unexpanded The set of unexpanded parameter packs within the - /// pattern. - /// - /// \param ShouldExpand Will be set to \c true if the transformer should - /// expand the corresponding pack expansions into separate arguments. When - /// set, \c NumExpansions must also be set. - /// - /// \param RetainExpansion Whether the caller should add an unexpanded - /// pack expansion after all of the expanded arguments. This is used - /// when extending explicitly-specified template argument packs per - /// C++0x [temp.arg.explicit]p9. - /// - /// \param NumExpansions The number of separate arguments that will be in - /// the expanded form of the corresponding pack expansion. This is both an - /// input and an output parameter, which can be set by the caller if the - /// number of expansions is known a priori (e.g., due to a prior substitution) - /// and will be set by the callee when the number of expansions is known. - /// The callee must set this value when \c ShouldExpand is \c true; it may - /// set this value in other cases. - /// - /// \returns true if an error occurred (e.g., because the parameter packs - /// are to be instantiated with arguments of different lengths), false - /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions) - /// must be set. - bool TryExpandParameterPacks(SourceLocation EllipsisLoc, - SourceRange PatternRange, - ArrayRef<UnexpandedParameterPack> Unexpanded, - bool &ShouldExpand, - bool &RetainExpansion, - Optional<unsigned> &NumExpansions) { - ShouldExpand = false; - return false; - } - - /// "Forget" about the partially-substituted pack template argument, - /// when performing an instantiation that must preserve the parameter pack - /// use. - /// - /// This routine is meant to be overridden by the template instantiator. - TemplateArgument ForgetPartiallySubstitutedPack() { - return TemplateArgument(); - } - - /// "Remember" the partially-substituted pack template argument - /// after performing an instantiation that must preserve the parameter pack - /// use. - /// - /// This routine is meant to be overridden by the template instantiator. - void RememberPartiallySubstitutedPack(TemplateArgument Arg) { } - - /// Note to the derived class when a function parameter pack is - /// being expanded. - void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { } - - /// Transforms the given type into another type. - /// - /// By default, this routine transforms a type by creating a - /// TypeSourceInfo for it and delegating to the appropriate - /// function. This is expensive, but we don't mind, because - /// this method is deprecated anyway; all users should be - /// switched to storing TypeSourceInfos. - /// - /// \returns the transformed type. - QualType TransformType(QualType T); - - /// Transforms the given type-with-location into a new - /// type-with-location. - /// - /// By default, this routine transforms a type by delegating to the - /// appropriate TransformXXXType to build a new type. Subclasses - /// may override this function (to take over all type - /// transformations) or some set of the TransformXXXType functions - /// to alter the transformation. - TypeSourceInfo *TransformType(TypeSourceInfo *DI); - - /// Transform the given type-with-location into a new - /// type, collecting location information in the given builder - /// as necessary. - /// - QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL); - - /// Transform a type that is permitted to produce a - /// DeducedTemplateSpecializationType. - /// - /// This is used in the (relatively rare) contexts where it is acceptable - /// for transformation to produce a class template type with deduced - /// template arguments. - /// @{ - QualType TransformTypeWithDeducedTST(QualType T); - TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *DI); - /// @} - - /// Transform the given statement. - /// - /// By default, this routine transforms a statement by delegating to the - /// appropriate TransformXXXStmt function to transform a specific kind of - /// statement or the TransformExpr() function to transform an expression. - /// Subclasses may override this function to transform statements using some - /// other mechanism. - /// - /// \returns the transformed statement. - StmtResult TransformStmt(Stmt *S); - - /// Transform the given statement. - /// - /// By default, this routine transforms a statement by delegating to the - /// appropriate TransformOMPXXXClause function to transform a specific kind - /// of clause. Subclasses may override this function to transform statements - /// using some other mechanism. - /// - /// \returns the transformed OpenMP clause. - OMPClause *TransformOMPClause(OMPClause *S); - - /// Transform the given attribute. - /// - /// By default, this routine transforms a statement by delegating to the - /// appropriate TransformXXXAttr function to transform a specific kind - /// of attribute. Subclasses may override this function to transform - /// attributed statements using some other mechanism. - /// - /// \returns the transformed attribute - const Attr *TransformAttr(const Attr *S); - -/// Transform the specified attribute. -/// -/// Subclasses should override the transformation of attributes with a pragma -/// spelling to transform expressions stored within the attribute. -/// -/// \returns the transformed attribute. -#define ATTR(X) -#define PRAGMA_SPELLING_ATTR(X) \ - const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; } -#include "clang/Basic/AttrList.inc" - - /// Transform the given expression. - /// - /// By default, this routine transforms an expression by delegating to the - /// appropriate TransformXXXExpr function to build a new expression. - /// Subclasses may override this function to transform expressions using some - /// other mechanism. - /// - /// \returns the transformed expression. - ExprResult TransformExpr(Expr *E); - - /// Transform the given initializer. - /// - /// By default, this routine transforms an initializer by stripping off the - /// semantic nodes added by initialization, then passing the result to - /// TransformExpr or TransformExprs. - /// - /// \returns the transformed initializer. - ExprResult TransformInitializer(Expr *Init, bool NotCopyInit); - - /// Transform the given list of expressions. - /// - /// This routine transforms a list of expressions by invoking - /// \c TransformExpr() for each subexpression. However, it also provides - /// support for variadic templates by expanding any pack expansions (if the - /// derived class permits such expansion) along the way. When pack expansions - /// are present, the number of outputs may not equal the number of inputs. - /// - /// \param Inputs The set of expressions to be transformed. - /// - /// \param NumInputs The number of expressions in \c Inputs. - /// - /// \param IsCall If \c true, then this transform is being performed on - /// function-call arguments, and any arguments that should be dropped, will - /// be. - /// - /// \param Outputs The transformed input expressions will be added to this - /// vector. - /// - /// \param ArgChanged If non-NULL, will be set \c true if any argument changed - /// due to transformation. - /// - /// \returns true if an error occurred, false otherwise. - bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall, - SmallVectorImpl<Expr *> &Outputs, - bool *ArgChanged = nullptr); - - /// Transform the given declaration, which is referenced from a type - /// or expression. - /// - /// By default, acts as the identity function on declarations, unless the - /// transformer has had to transform the declaration itself. Subclasses - /// may override this function to provide alternate behavior. - Decl *TransformDecl(SourceLocation Loc, Decl *D) { - llvm::DenseMap<Decl *, Decl *>::iterator Known - = TransformedLocalDecls.find(D); - if (Known != TransformedLocalDecls.end()) - return Known->second; - - return D; - } - - /// Transform the specified condition. - /// - /// By default, this transforms the variable and expression and rebuilds - /// the condition. - Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var, - Expr *Expr, - Sema::ConditionKind Kind); - - /// Transform the attributes associated with the given declaration and - /// place them on the new declaration. - /// - /// By default, this operation does nothing. Subclasses may override this - /// behavior to transform attributes. - void transformAttrs(Decl *Old, Decl *New) { } - - /// Note that a local declaration has been transformed by this - /// transformer. - /// - /// Local declarations are typically transformed via a call to - /// TransformDefinition. However, in some cases (e.g., lambda expressions), - /// the transformer itself has to transform the declarations. This routine - /// can be overridden by a subclass that keeps track of such mappings. - void transformedLocalDecl(Decl *Old, Decl *New) { - TransformedLocalDecls[Old] = New; - } - - /// Transform the definition of the given declaration. - /// - /// By default, invokes TransformDecl() to transform the declaration. - /// Subclasses may override this function to provide alternate behavior. - Decl *TransformDefinition(SourceLocation Loc, Decl *D) { - return getDerived().TransformDecl(Loc, D); - } - - /// Transform the given declaration, which was the first part of a - /// nested-name-specifier in a member access expression. - /// - /// This specific declaration transformation only applies to the first - /// identifier in a nested-name-specifier of a member access expression, e.g., - /// the \c T in \c x->T::member - /// - /// By default, invokes TransformDecl() to transform the declaration. - /// Subclasses may override this function to provide alternate behavior. - NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) { - return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D)); - } - - /// Transform the set of declarations in an OverloadExpr. - bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL, - LookupResult &R); - - /// Transform the given nested-name-specifier with source-location - /// information. - /// - /// By default, transforms all of the types and declarations within the - /// nested-name-specifier. Subclasses may override this function to provide - /// alternate behavior. - NestedNameSpecifierLoc - TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS, - QualType ObjectType = QualType(), - NamedDecl *FirstQualifierInScope = nullptr); - - /// Transform the given declaration name. - /// - /// By default, transforms the types of conversion function, constructor, - /// and destructor names and then (if needed) rebuilds the declaration name. - /// Identifiers and selectors are returned unmodified. Sublcasses may - /// override this function to provide alternate behavior. - DeclarationNameInfo - TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo); - - /// Transform the given template name. - /// - /// \param SS The nested-name-specifier that qualifies the template - /// name. This nested-name-specifier must already have been transformed. - /// - /// \param Name The template name to transform. - /// - /// \param NameLoc The source location of the template name. - /// - /// \param ObjectType If we're translating a template name within a member - /// access expression, this is the type of the object whose member template - /// is being referenced. - /// - /// \param FirstQualifierInScope If the first part of a nested-name-specifier - /// also refers to a name within the current (lexical) scope, this is the - /// declaration it refers to. - /// - /// By default, transforms the template name by transforming the declarations - /// and nested-name-specifiers that occur within the template name. - /// Subclasses may override this function to provide alternate behavior. - TemplateName - TransformTemplateName(CXXScopeSpec &SS, TemplateName Name, - SourceLocation NameLoc, - QualType ObjectType = QualType(), - NamedDecl *FirstQualifierInScope = nullptr, - bool AllowInjectedClassName = false); - - /// Transform the given template argument. - /// - /// By default, this operation transforms the type, expression, or - /// declaration stored within the template argument and constructs a - /// new template argument from the transformed result. Subclasses may - /// override this function to provide alternate behavior. - /// - /// Returns true if there was an error. - bool TransformTemplateArgument(const TemplateArgumentLoc &Input, - TemplateArgumentLoc &Output, - bool Uneval = false); - - /// Transform the given set of template arguments. - /// - /// By default, this operation transforms all of the template arguments - /// in the input set using \c TransformTemplateArgument(), and appends - /// the transformed arguments to the output list. - /// - /// Note that this overload of \c TransformTemplateArguments() is merely - /// a convenience function. Subclasses that wish to override this behavior - /// should override the iterator-based member template version. - /// - /// \param Inputs The set of template arguments to be transformed. - /// - /// \param NumInputs The number of template arguments in \p Inputs. - /// - /// \param Outputs The set of transformed template arguments output by this - /// routine. - /// - /// Returns true if an error occurred. - bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs, - unsigned NumInputs, - TemplateArgumentListInfo &Outputs, - bool Uneval = false) { - return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs, - Uneval); - } - - /// Transform the given set of template arguments. - /// - /// By default, this operation transforms all of the template arguments - /// in the input set using \c TransformTemplateArgument(), and appends - /// the transformed arguments to the output list. - /// - /// \param First An iterator to the first template argument. - /// - /// \param Last An iterator one step past the last template argument. - /// - /// \param Outputs The set of transformed template arguments output by this - /// routine. - /// - /// Returns true if an error occurred. - template<typename InputIterator> - bool TransformTemplateArguments(InputIterator First, - InputIterator Last, - TemplateArgumentListInfo &Outputs, - bool Uneval = false); - - /// Fakes up a TemplateArgumentLoc for a given TemplateArgument. - void InventTemplateArgumentLoc(const TemplateArgument &Arg, - TemplateArgumentLoc &ArgLoc); - - /// Fakes up a TypeSourceInfo for a type. - TypeSourceInfo *InventTypeSourceInfo(QualType T) { - return SemaRef.Context.getTrivialTypeSourceInfo(T, - getDerived().getBaseLocation()); - } - -#define ABSTRACT_TYPELOC(CLASS, PARENT) -#define TYPELOC(CLASS, PARENT) \ - QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T); -#include "clang/AST/TypeLocNodes.def" - - template<typename Fn> - QualType TransformFunctionProtoType(TypeLocBuilder &TLB, - FunctionProtoTypeLoc TL, - CXXRecordDecl *ThisContext, - Qualifiers ThisTypeQuals, - Fn TransformExceptionSpec); - - bool TransformExceptionSpec(SourceLocation Loc, - FunctionProtoType::ExceptionSpecInfo &ESI, - SmallVectorImpl<QualType> &Exceptions, - bool &Changed); - - StmtResult TransformSEHHandler(Stmt *Handler); - - QualType - TransformTemplateSpecializationType(TypeLocBuilder &TLB, - TemplateSpecializationTypeLoc TL, - TemplateName Template); - - QualType - TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, - DependentTemplateSpecializationTypeLoc TL, - TemplateName Template, - CXXScopeSpec &SS); - - QualType TransformDependentTemplateSpecializationType( - TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL, - NestedNameSpecifierLoc QualifierLoc); - - /// Transforms the parameters of a function type into the - /// given vectors. - /// - /// The result vectors should be kept in sync; null entries in the - /// variables vector are acceptable. - /// - /// Return true on error. - bool TransformFunctionTypeParams( - SourceLocation Loc, ArrayRef<ParmVarDecl *> Params, - const QualType *ParamTypes, - const FunctionProtoType::ExtParameterInfo *ParamInfos, - SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars, - Sema::ExtParameterInfoBuilder &PInfos); - - /// Transforms a single function-type parameter. Return null - /// on error. - /// - /// \param indexAdjustment - A number to add to the parameter's - /// scope index; can be negative - ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm, - int indexAdjustment, - Optional<unsigned> NumExpansions, - bool ExpectParameterPack); - - QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL); - - StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr); - ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E); - - TemplateParameterList *TransformTemplateParameterList( - TemplateParameterList *TPL) { - return TPL; - } - - ExprResult TransformAddressOfOperand(Expr *E); - - ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E, - bool IsAddressOfOperand, - TypeSourceInfo **RecoveryTSI); - - ExprResult TransformParenDependentScopeDeclRefExpr( - ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand, - TypeSourceInfo **RecoveryTSI); - - StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S); - -// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous -// amount of stack usage with clang. -#define STMT(Node, Parent) \ - LLVM_ATTRIBUTE_NOINLINE \ - StmtResult Transform##Node(Node *S); -#define EXPR(Node, Parent) \ - LLVM_ATTRIBUTE_NOINLINE \ - ExprResult Transform##Node(Node *E); -#define ABSTRACT_STMT(Stmt) -#include "clang/AST/StmtNodes.inc" - -#define OPENMP_CLAUSE(Name, Class) \ - LLVM_ATTRIBUTE_NOINLINE \ - OMPClause *Transform ## Class(Class *S); -#include "clang/Basic/OpenMPKinds.def" - - /// Build a new qualified type given its unqualified type and type location. - /// - /// By default, this routine adds type qualifiers only to types that can - /// have qualifiers, and silently suppresses those qualifiers that are not - /// permitted. Subclasses may override this routine to provide different - /// behavior. - QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL); - - /// Build a new pointer type given its pointee type. - /// - /// By default, performs semantic analysis when building the pointer type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil); - - /// Build a new block pointer type given its pointee type. - /// - /// By default, performs semantic analysis when building the block pointer - /// type. Subclasses may override this routine to provide different behavior. - QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil); - - /// Build a new reference type given the type it references. - /// - /// By default, performs semantic analysis when building the - /// reference type. Subclasses may override this routine to provide - /// different behavior. - /// - /// \param LValue whether the type was written with an lvalue sigil - /// or an rvalue sigil. - QualType RebuildReferenceType(QualType ReferentType, - bool LValue, - SourceLocation Sigil); - - /// Build a new member pointer type given the pointee type and the - /// class type it refers into. - /// - /// By default, performs semantic analysis when building the member pointer - /// type. Subclasses may override this routine to provide different behavior. - QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType, - SourceLocation Sigil); - - QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl, - SourceLocation ProtocolLAngleLoc, - ArrayRef<ObjCProtocolDecl *> Protocols, - ArrayRef<SourceLocation> ProtocolLocs, - SourceLocation ProtocolRAngleLoc); - - /// Build an Objective-C object type. - /// - /// By default, performs semantic analysis when building the object type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildObjCObjectType(QualType BaseType, - SourceLocation Loc, - SourceLocation TypeArgsLAngleLoc, - ArrayRef<TypeSourceInfo *> TypeArgs, - SourceLocation TypeArgsRAngleLoc, - SourceLocation ProtocolLAngleLoc, - ArrayRef<ObjCProtocolDecl *> Protocols, - ArrayRef<SourceLocation> ProtocolLocs, - SourceLocation ProtocolRAngleLoc); - - /// Build a new Objective-C object pointer type given the pointee type. - /// - /// By default, directly builds the pointer type, with no additional semantic - /// analysis. - QualType RebuildObjCObjectPointerType(QualType PointeeType, - SourceLocation Star); - - /// Build a new array type given the element type, size - /// modifier, size of the array (if known), size expression, and index type - /// qualifiers. - /// - /// By default, performs semantic analysis when building the array type. - /// Subclasses may override this routine to provide different behavior. - /// Also by default, all of the other Rebuild*Array - QualType RebuildArrayType(QualType ElementType, - ArrayType::ArraySizeModifier SizeMod, - const llvm::APInt *Size, - Expr *SizeExpr, - unsigned IndexTypeQuals, - SourceRange BracketsRange); - - /// Build a new constant array type given the element type, size - /// modifier, (known) size of the array, and index type qualifiers. - /// - /// By default, performs semantic analysis when building the array type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildConstantArrayType(QualType ElementType, - ArrayType::ArraySizeModifier SizeMod, - const llvm::APInt &Size, - unsigned IndexTypeQuals, - SourceRange BracketsRange); - - /// Build a new incomplete array type given the element type, size - /// modifier, and index type qualifiers. - /// - /// By default, performs semantic analysis when building the array type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildIncompleteArrayType(QualType ElementType, - ArrayType::ArraySizeModifier SizeMod, - unsigned IndexTypeQuals, - SourceRange BracketsRange); - - /// Build a new variable-length array type given the element type, - /// size modifier, size expression, and index type qualifiers. - /// - /// By default, performs semantic analysis when building the array type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildVariableArrayType(QualType ElementType, - ArrayType::ArraySizeModifier SizeMod, - Expr *SizeExpr, - unsigned IndexTypeQuals, - SourceRange BracketsRange); - - /// Build a new dependent-sized array type given the element type, - /// size modifier, size expression, and index type qualifiers. - /// - /// By default, performs semantic analysis when building the array type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildDependentSizedArrayType(QualType ElementType, - ArrayType::ArraySizeModifier SizeMod, - Expr *SizeExpr, - unsigned IndexTypeQuals, - SourceRange BracketsRange); - - /// Build a new vector type given the element type and - /// number of elements. - /// - /// By default, performs semantic analysis when building the vector type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildVectorType(QualType ElementType, unsigned NumElements, - VectorType::VectorKind VecKind); - - /// Build a new potentially dependently-sized extended vector type - /// given the element type and number of elements. - /// - /// By default, performs semantic analysis when building the vector type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr, - SourceLocation AttributeLoc, - VectorType::VectorKind); - - /// Build a new extended vector type given the element type and - /// number of elements. - /// - /// By default, performs semantic analysis when building the vector type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements, - SourceLocation AttributeLoc); - - /// Build a new potentially dependently-sized extended vector type - /// given the element type and number of elements. - /// - /// By default, performs semantic analysis when building the vector type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildDependentSizedExtVectorType(QualType ElementType, - Expr *SizeExpr, - SourceLocation AttributeLoc); - - /// Build a new DependentAddressSpaceType or return the pointee - /// type variable with the correct address space (retrieved from - /// AddrSpaceExpr) applied to it. The former will be returned in cases - /// where the address space remains dependent. - /// - /// By default, performs semantic analysis when building the type with address - /// space applied. Subclasses may override this routine to provide different - /// behavior. - QualType RebuildDependentAddressSpaceType(QualType PointeeType, - Expr *AddrSpaceExpr, - SourceLocation AttributeLoc); - - /// Build a new function type. - /// - /// By default, performs semantic analysis when building the function type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildFunctionProtoType(QualType T, - MutableArrayRef<QualType> ParamTypes, - const FunctionProtoType::ExtProtoInfo &EPI); - - /// Build a new unprototyped function type. - QualType RebuildFunctionNoProtoType(QualType ResultType); - - /// Rebuild an unresolved typename type, given the decl that - /// the UnresolvedUsingTypenameDecl was transformed to. - QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D); - - /// Build a new typedef type. - QualType RebuildTypedefType(TypedefNameDecl *Typedef) { - return SemaRef.Context.getTypeDeclType(Typedef); - } - - /// Build a new class/struct/union type. - QualType RebuildRecordType(RecordDecl *Record) { - return SemaRef.Context.getTypeDeclType(Record); - } - - /// Build a new Enum type. - QualType RebuildEnumType(EnumDecl *Enum) { - return SemaRef.Context.getTypeDeclType(Enum); - } - - /// Build a new typeof(expr) type. - /// - /// By default, performs semantic analysis when building the typeof type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc); - - /// Build a new typeof(type) type. - /// - /// By default, builds a new TypeOfType with the given underlying type. - QualType RebuildTypeOfType(QualType Underlying); - - /// Build a new unary transform type. - QualType RebuildUnaryTransformType(QualType BaseType, - UnaryTransformType::UTTKind UKind, - SourceLocation Loc); - - /// Build a new C++11 decltype type. - /// - /// By default, performs semantic analysis when building the decltype type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc); - - /// Build a new C++11 auto type. - /// - /// By default, builds a new AutoType with the given deduced type. - QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword) { - // Note, IsDependent is always false here: we implicitly convert an 'auto' - // which has been deduced to a dependent type into an undeduced 'auto', so - // that we'll retry deduction after the transformation. - return SemaRef.Context.getAutoType(Deduced, Keyword, - /*IsDependent*/ false); - } - - /// By default, builds a new DeducedTemplateSpecializationType with the given - /// deduced type. - QualType RebuildDeducedTemplateSpecializationType(TemplateName Template, - QualType Deduced) { - return SemaRef.Context.getDeducedTemplateSpecializationType( - Template, Deduced, /*IsDependent*/ false); - } - - /// Build a new template specialization type. - /// - /// By default, performs semantic analysis when building the template - /// specialization type. Subclasses may override this routine to provide - /// different behavior. - QualType RebuildTemplateSpecializationType(TemplateName Template, - SourceLocation TemplateLoc, - TemplateArgumentListInfo &Args); - - /// Build a new parenthesized type. - /// - /// By default, builds a new ParenType type from the inner type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildParenType(QualType InnerType) { - return SemaRef.BuildParenType(InnerType); - } - - /// Build a new qualified name type. - /// - /// By default, builds a new ElaboratedType type from the keyword, - /// the nested-name-specifier and the named type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildElaboratedType(SourceLocation KeywordLoc, - ElaboratedTypeKeyword Keyword, - NestedNameSpecifierLoc QualifierLoc, - QualType Named) { - return SemaRef.Context.getElaboratedType(Keyword, - QualifierLoc.getNestedNameSpecifier(), - Named); - } - - /// Build a new typename type that refers to a template-id. - /// - /// By default, builds a new DependentNameType type from the - /// nested-name-specifier and the given type. Subclasses may override - /// this routine to provide different behavior. - QualType RebuildDependentTemplateSpecializationType( - ElaboratedTypeKeyword Keyword, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - const IdentifierInfo *Name, - SourceLocation NameLoc, - TemplateArgumentListInfo &Args, - bool AllowInjectedClassName) { - // Rebuild the template name. - // TODO: avoid TemplateName abstraction - CXXScopeSpec SS; - SS.Adopt(QualifierLoc); - TemplateName InstName = getDerived().RebuildTemplateName( - SS, TemplateKWLoc, *Name, NameLoc, QualType(), nullptr, - AllowInjectedClassName); - - if (InstName.isNull()) - return QualType(); - - // If it's still dependent, make a dependent specialization. - if (InstName.getAsDependentTemplateName()) - return SemaRef.Context.getDependentTemplateSpecializationType(Keyword, - QualifierLoc.getNestedNameSpecifier(), - Name, - Args); - - // Otherwise, make an elaborated type wrapping a non-dependent - // specialization. - QualType T = - getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args); - if (T.isNull()) return QualType(); - - if (Keyword == ETK_None && QualifierLoc.getNestedNameSpecifier() == nullptr) - return T; - - return SemaRef.Context.getElaboratedType(Keyword, - QualifierLoc.getNestedNameSpecifier(), - T); - } - - /// Build a new typename type that refers to an identifier. - /// - /// By default, performs semantic analysis when building the typename type - /// (or elaborated type). Subclasses may override this routine to provide - /// different behavior. - QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword, - SourceLocation KeywordLoc, - NestedNameSpecifierLoc QualifierLoc, - const IdentifierInfo *Id, - SourceLocation IdLoc, - bool DeducedTSTContext) { - CXXScopeSpec SS; - SS.Adopt(QualifierLoc); - - if (QualifierLoc.getNestedNameSpecifier()->isDependent()) { - // If the name is still dependent, just build a new dependent name type. - if (!SemaRef.computeDeclContext(SS)) - return SemaRef.Context.getDependentNameType(Keyword, - QualifierLoc.getNestedNameSpecifier(), - Id); - } - - if (Keyword == ETK_None || Keyword == ETK_Typename) { - QualType T = SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc, - *Id, IdLoc); - // If a dependent name resolves to a deduced template specialization type, - // check that we're in one of the syntactic contexts permitting it. - if (!DeducedTSTContext) { - if (auto *Deduced = dyn_cast_or_null<DeducedTemplateSpecializationType>( - T.isNull() ? nullptr : T->getContainedDeducedType())) { - SemaRef.Diag(IdLoc, diag::err_dependent_deduced_tst) - << (int)SemaRef.getTemplateNameKindForDiagnostics( - Deduced->getTemplateName()) - << QualType(QualifierLoc.getNestedNameSpecifier()->getAsType(), 0); - if (auto *TD = Deduced->getTemplateName().getAsTemplateDecl()) - SemaRef.Diag(TD->getLocation(), diag::note_template_decl_here); - return QualType(); - } - } - return T; - } - - TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword); - - // We had a dependent elaborated-type-specifier that has been transformed - // into a non-dependent elaborated-type-specifier. Find the tag we're - // referring to. - LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName); - DeclContext *DC = SemaRef.computeDeclContext(SS, false); - if (!DC) - return QualType(); - - if (SemaRef.RequireCompleteDeclContext(SS, DC)) - return QualType(); - - TagDecl *Tag = nullptr; - SemaRef.LookupQualifiedName(Result, DC); - switch (Result.getResultKind()) { - case LookupResult::NotFound: - case LookupResult::NotFoundInCurrentInstantiation: - break; - - case LookupResult::Found: - Tag = Result.getAsSingle<TagDecl>(); - break; - - case LookupResult::FoundOverloaded: - case LookupResult::FoundUnresolvedValue: - llvm_unreachable("Tag lookup cannot find non-tags"); - - case LookupResult::Ambiguous: - // Let the LookupResult structure handle ambiguities. - return QualType(); - } - - if (!Tag) { - // Check where the name exists but isn't a tag type and use that to emit - // better diagnostics. - LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName); - SemaRef.LookupQualifiedName(Result, DC); - switch (Result.getResultKind()) { - case LookupResult::Found: - case LookupResult::FoundOverloaded: - case LookupResult::FoundUnresolvedValue: { - NamedDecl *SomeDecl = Result.getRepresentativeDecl(); - Sema::NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(SomeDecl, Kind); - SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag) << SomeDecl - << NTK << Kind; - SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at); - break; - } - default: - SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope) - << Kind << Id << DC << QualifierLoc.getSourceRange(); - break; - } - return QualType(); - } - - if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false, - IdLoc, Id)) { - SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id; - SemaRef.Diag(Tag->getLocation(), diag::note_previous_use); - return QualType(); - } - - // Build the elaborated-type-specifier type. - QualType T = SemaRef.Context.getTypeDeclType(Tag); - return SemaRef.Context.getElaboratedType(Keyword, - QualifierLoc.getNestedNameSpecifier(), - T); - } - - /// Build a new pack expansion type. - /// - /// By default, builds a new PackExpansionType type from the given pattern. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildPackExpansionType(QualType Pattern, - SourceRange PatternRange, - SourceLocation EllipsisLoc, - Optional<unsigned> NumExpansions) { - return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc, - NumExpansions); - } - - /// Build a new atomic type given its value type. - /// - /// By default, performs semantic analysis when building the atomic type. - /// Subclasses may override this routine to provide different behavior. - QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc); - - /// Build a new pipe type given its value type. - QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc, - bool isReadPipe); - - /// Build a new template name given a nested name specifier, a flag - /// indicating whether the "template" keyword was provided, and the template - /// that the template name refers to. - /// - /// By default, builds the new template name directly. Subclasses may override - /// this routine to provide different behavior. - TemplateName RebuildTemplateName(CXXScopeSpec &SS, - bool TemplateKW, - TemplateDecl *Template); - - /// Build a new template name given a nested name specifier and the - /// name that is referred to as a template. - /// - /// By default, performs semantic analysis to determine whether the name can - /// be resolved to a specific template, then builds the appropriate kind of - /// template name. Subclasses may override this routine to provide different - /// behavior. - TemplateName RebuildTemplateName(CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - const IdentifierInfo &Name, - SourceLocation NameLoc, QualType ObjectType, - NamedDecl *FirstQualifierInScope, - bool AllowInjectedClassName); - - /// Build a new template name given a nested name specifier and the - /// overloaded operator name that is referred to as a template. - /// - /// By default, performs semantic analysis to determine whether the name can - /// be resolved to a specific template, then builds the appropriate kind of - /// template name. Subclasses may override this routine to provide different - /// behavior. - TemplateName RebuildTemplateName(CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - OverloadedOperatorKind Operator, - SourceLocation NameLoc, QualType ObjectType, - bool AllowInjectedClassName); - - /// Build a new template name given a template template parameter pack - /// and the - /// - /// By default, performs semantic analysis to determine whether the name can - /// be resolved to a specific template, then builds the appropriate kind of - /// template name. Subclasses may override this routine to provide different - /// behavior. - TemplateName RebuildTemplateName(TemplateTemplateParmDecl *Param, - const TemplateArgument &ArgPack) { - return getSema().Context.getSubstTemplateTemplateParmPack(Param, ArgPack); - } - - /// Build a new compound statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc, - MultiStmtArg Statements, - SourceLocation RBraceLoc, - bool IsStmtExpr) { - return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements, - IsStmtExpr); - } - - /// Build a new case statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildCaseStmt(SourceLocation CaseLoc, - Expr *LHS, - SourceLocation EllipsisLoc, - Expr *RHS, - SourceLocation ColonLoc) { - return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS, - ColonLoc); - } - - /// Attach the body to a new case statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) { - getSema().ActOnCaseStmtBody(S, Body); - return S; - } - - /// Build a new default statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc, - SourceLocation ColonLoc, - Stmt *SubStmt) { - return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt, - /*CurScope=*/nullptr); - } - - /// Build a new label statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L, - SourceLocation ColonLoc, Stmt *SubStmt) { - return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt); - } - - /// Build a new label statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildAttributedStmt(SourceLocation AttrLoc, - ArrayRef<const Attr*> Attrs, - Stmt *SubStmt) { - return SemaRef.ActOnAttributedStmt(AttrLoc, Attrs, SubStmt); - } - - /// Build a new "if" statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildIfStmt(SourceLocation IfLoc, bool IsConstexpr, - Sema::ConditionResult Cond, Stmt *Init, Stmt *Then, - SourceLocation ElseLoc, Stmt *Else) { - return getSema().ActOnIfStmt(IfLoc, IsConstexpr, Init, Cond, Then, - ElseLoc, Else); - } - - /// Start building a new switch statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc, Stmt *Init, - Sema::ConditionResult Cond) { - return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Init, Cond); - } - - /// Attach the body to the switch statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc, - Stmt *Switch, Stmt *Body) { - return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body); - } - - /// Build a new while statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildWhileStmt(SourceLocation WhileLoc, - Sema::ConditionResult Cond, Stmt *Body) { - return getSema().ActOnWhileStmt(WhileLoc, Cond, Body); - } - - /// Build a new do-while statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body, - SourceLocation WhileLoc, SourceLocation LParenLoc, - Expr *Cond, SourceLocation RParenLoc) { - return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc, - Cond, RParenLoc); - } - - /// Build a new for statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, - Stmt *Init, Sema::ConditionResult Cond, - Sema::FullExprArg Inc, SourceLocation RParenLoc, - Stmt *Body) { - return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond, - Inc, RParenLoc, Body); - } - - /// Build a new goto statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, - LabelDecl *Label) { - return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label); - } - - /// Build a new indirect goto statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc, - SourceLocation StarLoc, - Expr *Target) { - return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target); - } - - /// Build a new return statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) { - return getSema().BuildReturnStmt(ReturnLoc, Result); - } - - /// Build a new declaration statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls, - SourceLocation StartLoc, SourceLocation EndLoc) { - Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls); - return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc); - } - - /// Build a new inline asm statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, - bool IsVolatile, unsigned NumOutputs, - unsigned NumInputs, IdentifierInfo **Names, - MultiExprArg Constraints, MultiExprArg Exprs, - Expr *AsmString, MultiExprArg Clobbers, - SourceLocation RParenLoc) { - return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs, - NumInputs, Names, Constraints, Exprs, - AsmString, Clobbers, RParenLoc); - } - - /// Build a new MS style inline asm statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, - ArrayRef<Token> AsmToks, - StringRef AsmString, - unsigned NumOutputs, unsigned NumInputs, - ArrayRef<StringRef> Constraints, - ArrayRef<StringRef> Clobbers, - ArrayRef<Expr*> Exprs, - SourceLocation EndLoc) { - return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString, - NumOutputs, NumInputs, - Constraints, Clobbers, Exprs, EndLoc); - } - - /// Build a new co_return statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result, - bool IsImplicit) { - return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit); - } - - /// Build a new co_await expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Result, - bool IsImplicit) { - return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Result, IsImplicit); - } - - /// Build a new co_await expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc, - Expr *Result, - UnresolvedLookupExpr *Lookup) { - return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup); - } - - /// Build a new co_yield expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) { - return getSema().BuildCoyieldExpr(CoyieldLoc, Result); - } - - StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) { - return getSema().BuildCoroutineBodyStmt(Args); - } - - /// Build a new Objective-C \@try statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc, - Stmt *TryBody, - MultiStmtArg CatchStmts, - Stmt *Finally) { - return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts, - Finally); - } - - /// Rebuild an Objective-C exception declaration. - /// - /// By default, performs semantic analysis to build the new declaration. - /// Subclasses may override this routine to provide different behavior. - VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl, - TypeSourceInfo *TInfo, QualType T) { - return getSema().BuildObjCExceptionDecl(TInfo, T, - ExceptionDecl->getInnerLocStart(), - ExceptionDecl->getLocation(), - ExceptionDecl->getIdentifier()); - } - - /// Build a new Objective-C \@catch statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc, - SourceLocation RParenLoc, - VarDecl *Var, - Stmt *Body) { - return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, - Var, Body); - } - - /// Build a new Objective-C \@finally statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc, - Stmt *Body) { - return getSema().ActOnObjCAtFinallyStmt(AtLoc, Body); - } - - /// Build a new Objective-C \@throw statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc, - Expr *Operand) { - return getSema().BuildObjCAtThrowStmt(AtLoc, Operand); - } - - /// Build a new OpenMP executable directive. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind, - DeclarationNameInfo DirName, - OpenMPDirectiveKind CancelRegion, - ArrayRef<OMPClause *> Clauses, - Stmt *AStmt, SourceLocation StartLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPExecutableDirective( - Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc); - } - - /// Build a new OpenMP 'if' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier, - Expr *Condition, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation NameModifierLoc, - SourceLocation ColonLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPIfClause(NameModifier, Condition, StartLoc, - LParenLoc, NameModifierLoc, ColonLoc, - EndLoc); - } - - /// Build a new OpenMP 'final' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPFinalClause(Condition, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'num_threads' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPNumThreadsClause(Expr *NumThreads, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc, - LParenLoc, EndLoc); - } - - /// Build a new OpenMP 'safelen' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc, EndLoc); - } - - /// Build a new OpenMP 'simdlen' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc, EndLoc); - } - - /// Build a new OpenMP 'collapse' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPCollapseClause(Num, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'default' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPDefaultClause(OpenMPDefaultClauseKind Kind, - SourceLocation KindKwLoc, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPDefaultClause(Kind, KindKwLoc, - StartLoc, LParenLoc, EndLoc); - } - - /// Build a new OpenMP 'proc_bind' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPProcBindClause(OpenMPProcBindClauseKind Kind, - SourceLocation KindKwLoc, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPProcBindClause(Kind, KindKwLoc, - StartLoc, LParenLoc, EndLoc); - } - - /// Build a new OpenMP 'schedule' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPScheduleClause( - OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, - OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, - SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { - return getSema().ActOnOpenMPScheduleClause( - M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc, - CommaLoc, EndLoc); - } - - /// Build a new OpenMP 'ordered' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc, - SourceLocation EndLoc, - SourceLocation LParenLoc, Expr *Num) { - return getSema().ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Num); - } - - /// Build a new OpenMP 'private' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'firstprivate' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'lastprivate' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'shared' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'reduction' clause. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPReductionClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation ColonLoc, - SourceLocation EndLoc, - CXXScopeSpec &ReductionIdScopeSpec, - const DeclarationNameInfo &ReductionId, - ArrayRef<Expr *> UnresolvedReductions) { - return getSema().ActOnOpenMPReductionClause( - VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, - ReductionId, UnresolvedReductions); - } - - /// Build a new OpenMP 'task_reduction' clause. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPTaskReductionClause( - ArrayRef<Expr *> VarList, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, - CXXScopeSpec &ReductionIdScopeSpec, - const DeclarationNameInfo &ReductionId, - ArrayRef<Expr *> UnresolvedReductions) { - return getSema().ActOnOpenMPTaskReductionClause( - VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, - ReductionId, UnresolvedReductions); - } - - /// Build a new OpenMP 'in_reduction' clause. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - OMPClause * - RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation ColonLoc, - SourceLocation EndLoc, - CXXScopeSpec &ReductionIdScopeSpec, - const DeclarationNameInfo &ReductionId, - ArrayRef<Expr *> UnresolvedReductions) { - return getSema().ActOnOpenMPInReductionClause( - VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, - ReductionId, UnresolvedReductions); - } - - /// Build a new OpenMP 'linear' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, - SourceLocation StartLoc, - SourceLocation LParenLoc, - OpenMPLinearClauseKind Modifier, - SourceLocation ModifierLoc, - SourceLocation ColonLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPLinearClause(VarList, Step, StartLoc, LParenLoc, - Modifier, ModifierLoc, ColonLoc, - EndLoc); - } - - /// Build a new OpenMP 'aligned' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation ColonLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPAlignedClause(VarList, Alignment, StartLoc, - LParenLoc, ColonLoc, EndLoc); - } - - /// Build a new OpenMP 'copyin' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'copyprivate' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'flush' pseudo clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'depend' pseudo clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause * - RebuildOMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, - SourceLocation ColonLoc, ArrayRef<Expr *> VarList, - SourceLocation StartLoc, SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPDependClause(DepKind, DepLoc, ColonLoc, VarList, - StartLoc, LParenLoc, EndLoc); - } - - /// Build a new OpenMP 'device' clause. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPDeviceClause(Expr *Device, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPDeviceClause(Device, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'map' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause * - RebuildOMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, - ArrayRef<SourceLocation> MapTypeModifiersLoc, - OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, - SourceLocation MapLoc, SourceLocation ColonLoc, - ArrayRef<Expr *> VarList, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation EndLoc) { - return getSema().ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, - MapType, IsMapTypeImplicit, MapLoc, - ColonLoc, VarList, StartLoc, - LParenLoc, EndLoc); - } - - /// Build a new OpenMP 'num_teams' clause. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPNumTeamsClause(NumTeams, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'thread_limit' clause. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPThreadLimitClause(Expr *ThreadLimit, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPThreadLimitClause(ThreadLimit, StartLoc, - LParenLoc, EndLoc); - } - - /// Build a new OpenMP 'priority' clause. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPPriorityClause(Priority, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'grainsize' clause. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPGrainsizeClause(Expr *Grainsize, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPGrainsizeClause(Grainsize, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'num_tasks' clause. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPNumTasksClause(NumTasks, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'hint' clause. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc, EndLoc); - } - - /// Build a new OpenMP 'dist_schedule' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause * - RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, - Expr *ChunkSize, SourceLocation StartLoc, - SourceLocation LParenLoc, SourceLocation KindLoc, - SourceLocation CommaLoc, SourceLocation EndLoc) { - return getSema().ActOnOpenMPDistScheduleClause( - Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc); - } - - /// Build a new OpenMP 'to' clause. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPToClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); - } - - /// Build a new OpenMP 'from' clause. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPFromClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'use_device_ptr' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, - EndLoc); - } - - /// Build a new OpenMP 'is_device_ptr' clause. - /// - /// By default, performs semantic analysis to build the new OpenMP clause. - /// Subclasses may override this routine to provide different behavior. - OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList, - SourceLocation StartLoc, - SourceLocation LParenLoc, - SourceLocation EndLoc) { - return getSema().ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, - EndLoc); - } - - /// Rebuild the operand to an Objective-C \@synchronized statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc, - Expr *object) { - return getSema().ActOnObjCAtSynchronizedOperand(atLoc, object); - } - - /// Build a new Objective-C \@synchronized statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc, - Expr *Object, Stmt *Body) { - return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body); - } - - /// Build a new Objective-C \@autoreleasepool statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc, - Stmt *Body) { - return getSema().ActOnObjCAutoreleasePoolStmt(AtLoc, Body); - } - - /// Build a new Objective-C fast enumeration statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc, - Stmt *Element, - Expr *Collection, - SourceLocation RParenLoc, - Stmt *Body) { - StmtResult ForEachStmt = getSema().ActOnObjCForCollectionStmt(ForLoc, - Element, - Collection, - RParenLoc); - if (ForEachStmt.isInvalid()) - return StmtError(); - - return getSema().FinishObjCForCollectionStmt(ForEachStmt.get(), Body); - } - - /// Build a new C++ exception declaration. - /// - /// By default, performs semantic analysis to build the new decaration. - /// Subclasses may override this routine to provide different behavior. - VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, - TypeSourceInfo *Declarator, - SourceLocation StartLoc, - SourceLocation IdLoc, - IdentifierInfo *Id) { - VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator, - StartLoc, IdLoc, Id); - if (Var) - getSema().CurContext->addDecl(Var); - return Var; - } - - /// Build a new C++ catch statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc, - VarDecl *ExceptionDecl, - Stmt *Handler) { - return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl, - Handler)); - } - - /// Build a new C++ try statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock, - ArrayRef<Stmt *> Handlers) { - return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers); - } - - /// Build a new C++0x range-based for statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildCXXForRangeStmt(SourceLocation ForLoc, - SourceLocation CoawaitLoc, Stmt *Init, - SourceLocation ColonLoc, Stmt *Range, - Stmt *Begin, Stmt *End, Expr *Cond, - Expr *Inc, Stmt *LoopVar, - SourceLocation RParenLoc) { - // If we've just learned that the range is actually an Objective-C - // collection, treat this as an Objective-C fast enumeration loop. - if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) { - if (RangeStmt->isSingleDecl()) { - if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) { - if (RangeVar->isInvalidDecl()) - return StmtError(); - - Expr *RangeExpr = RangeVar->getInit(); - if (!RangeExpr->isTypeDependent() && - RangeExpr->getType()->isObjCObjectPointerType()) { - // FIXME: Support init-statements in Objective-C++20 ranged for - // statement. - if (Init) { - return SemaRef.Diag(Init->getBeginLoc(), - diag::err_objc_for_range_init_stmt) - << Init->getSourceRange(); - } - return getSema().ActOnObjCForCollectionStmt(ForLoc, LoopVar, - RangeExpr, RParenLoc); - } - } - } - } - - return getSema().BuildCXXForRangeStmt(ForLoc, CoawaitLoc, Init, ColonLoc, - Range, Begin, End, Cond, Inc, LoopVar, - RParenLoc, Sema::BFRK_Rebuild); - } - - /// Build a new C++0x range-based for statement. - /// - /// By default, performs semantic analysis to build the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc, - bool IsIfExists, - NestedNameSpecifierLoc QualifierLoc, - DeclarationNameInfo NameInfo, - Stmt *Nested) { - return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists, - QualifierLoc, NameInfo, Nested); - } - - /// Attach body to a C++0x range-based for statement. - /// - /// By default, performs semantic analysis to finish the new statement. - /// Subclasses may override this routine to provide different behavior. - StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) { - return getSema().FinishCXXForRangeStmt(ForRange, Body); - } - - StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, - Stmt *TryBlock, Stmt *Handler) { - return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler); - } - - StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, - Stmt *Block) { - return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block); - } - - StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) { - return SEHFinallyStmt::Create(getSema().getASTContext(), Loc, Block); - } - - /// Build a new predefined expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildPredefinedExpr(SourceLocation Loc, - PredefinedExpr::IdentKind IK) { - return getSema().BuildPredefinedExpr(Loc, IK); - } - - /// Build a new expression that references a declaration. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS, - LookupResult &R, - bool RequiresADL) { - return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL); - } - - - /// Build a new expression that references a declaration. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc, - ValueDecl *VD, - const DeclarationNameInfo &NameInfo, - TemplateArgumentListInfo *TemplateArgs) { - CXXScopeSpec SS; - SS.Adopt(QualifierLoc); - - // FIXME: loses template args. - - return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD); - } - - /// Build a new expression in parentheses. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen, - SourceLocation RParen) { - return getSema().ActOnParenExpr(LParen, RParen, SubExpr); - } - - /// Build a new pseudo-destructor expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base, - SourceLocation OperatorLoc, - bool isArrow, - CXXScopeSpec &SS, - TypeSourceInfo *ScopeType, - SourceLocation CCLoc, - SourceLocation TildeLoc, - PseudoDestructorTypeStorage Destroyed); - - /// Build a new unary operator expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildUnaryOperator(SourceLocation OpLoc, - UnaryOperatorKind Opc, - Expr *SubExpr) { - return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr); - } - - /// Build a new builtin offsetof expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc, - TypeSourceInfo *Type, - ArrayRef<Sema::OffsetOfComponent> Components, - SourceLocation RParenLoc) { - return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components, - RParenLoc); - } - - /// Build a new sizeof, alignof or vec_step expression with a - /// type argument. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo, - SourceLocation OpLoc, - UnaryExprOrTypeTrait ExprKind, - SourceRange R) { - return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R); - } - - /// Build a new sizeof, alignof or vec step expression with an - /// expression argument. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc, - UnaryExprOrTypeTrait ExprKind, - SourceRange R) { - ExprResult Result - = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind); - if (Result.isInvalid()) - return ExprError(); - - return Result; - } - - /// Build a new array subscript expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildArraySubscriptExpr(Expr *LHS, - SourceLocation LBracketLoc, - Expr *RHS, - SourceLocation RBracketLoc) { - return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS, - LBracketLoc, RHS, - RBracketLoc); - } - - /// Build a new array section expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildOMPArraySectionExpr(Expr *Base, SourceLocation LBracketLoc, - Expr *LowerBound, - SourceLocation ColonLoc, Expr *Length, - SourceLocation RBracketLoc) { - return getSema().ActOnOMPArraySectionExpr(Base, LBracketLoc, LowerBound, - ColonLoc, Length, RBracketLoc); - } - - /// Build a new call expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc, - MultiExprArg Args, - SourceLocation RParenLoc, - Expr *ExecConfig = nullptr) { - return getSema().ActOnCallExpr(/*Scope=*/nullptr, Callee, LParenLoc, - Args, RParenLoc, ExecConfig); - } - - /// Build a new member access expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc, - bool isArrow, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - const DeclarationNameInfo &MemberNameInfo, - ValueDecl *Member, - NamedDecl *FoundDecl, - const TemplateArgumentListInfo *ExplicitTemplateArgs, - NamedDecl *FirstQualifierInScope) { - ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base, - isArrow); - if (!Member->getDeclName()) { - // We have a reference to an unnamed field. This is always the - // base of an anonymous struct/union member access, i.e. the - // field is always of record type. - assert(Member->getType()->isRecordType() && - "unnamed member not of record type?"); - - BaseResult = - getSema().PerformObjectMemberConversion(BaseResult.get(), - QualifierLoc.getNestedNameSpecifier(), - FoundDecl, Member); - if (BaseResult.isInvalid()) - return ExprError(); - Base = BaseResult.get(); - - CXXScopeSpec EmptySS; - return getSema().BuildFieldReferenceExpr( - Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member), - DeclAccessPair::make(FoundDecl, FoundDecl->getAccess()), MemberNameInfo); - } - - CXXScopeSpec SS; - SS.Adopt(QualifierLoc); - - Base = BaseResult.get(); - QualType BaseType = Base->getType(); - - if (isArrow && !BaseType->isPointerType()) - return ExprError(); - - // FIXME: this involves duplicating earlier analysis in a lot of - // cases; we should avoid this when possible. - LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName); - R.addDecl(FoundDecl); - R.resolveKind(); - - return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow, - SS, TemplateKWLoc, - FirstQualifierInScope, - R, ExplicitTemplateArgs, - /*S*/nullptr); - } - - /// Build a new binary operator expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildBinaryOperator(SourceLocation OpLoc, - BinaryOperatorKind Opc, - Expr *LHS, Expr *RHS) { - return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS); - } - - /// Build a new conditional operator expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildConditionalOperator(Expr *Cond, - SourceLocation QuestionLoc, - Expr *LHS, - SourceLocation ColonLoc, - Expr *RHS) { - return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond, - LHS, RHS); - } - - /// Build a new C-style cast expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc, - TypeSourceInfo *TInfo, - SourceLocation RParenLoc, - Expr *SubExpr) { - return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, - SubExpr); - } - - /// Build a new compound literal expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc, - TypeSourceInfo *TInfo, - SourceLocation RParenLoc, - Expr *Init) { - return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, - Init); - } - - /// Build a new extended vector element access expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildExtVectorElementExpr(Expr *Base, - SourceLocation OpLoc, - SourceLocation AccessorLoc, - IdentifierInfo &Accessor) { - - CXXScopeSpec SS; - DeclarationNameInfo NameInfo(&Accessor, AccessorLoc); - return getSema().BuildMemberReferenceExpr(Base, Base->getType(), - OpLoc, /*IsArrow*/ false, - SS, SourceLocation(), - /*FirstQualifierInScope*/ nullptr, - NameInfo, - /* TemplateArgs */ nullptr, - /*S*/ nullptr); - } - - /// Build a new initializer list expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildInitList(SourceLocation LBraceLoc, - MultiExprArg Inits, - SourceLocation RBraceLoc) { - return SemaRef.ActOnInitList(LBraceLoc, Inits, RBraceLoc); - } - - /// Build a new designated initializer expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildDesignatedInitExpr(Designation &Desig, - MultiExprArg ArrayExprs, - SourceLocation EqualOrColonLoc, - bool GNUSyntax, - Expr *Init) { - ExprResult Result - = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax, - Init); - if (Result.isInvalid()) - return ExprError(); - - return Result; - } - - /// Build a new value-initialized expression. - /// - /// By default, builds the implicit value initialization without performing - /// any semantic analysis. Subclasses may override this routine to provide - /// different behavior. - ExprResult RebuildImplicitValueInitExpr(QualType T) { - return new (SemaRef.Context) ImplicitValueInitExpr(T); - } - - /// Build a new \c va_arg expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, - Expr *SubExpr, TypeSourceInfo *TInfo, - SourceLocation RParenLoc) { - return getSema().BuildVAArgExpr(BuiltinLoc, - SubExpr, TInfo, - RParenLoc); - } - - /// Build a new expression list in parentheses. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildParenListExpr(SourceLocation LParenLoc, - MultiExprArg SubExprs, - SourceLocation RParenLoc) { - return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs); - } - - /// Build a new address-of-label expression. - /// - /// By default, performs semantic analysis, using the name of the label - /// rather than attempting to map the label statement itself. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc, - SourceLocation LabelLoc, LabelDecl *Label) { - return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label); - } - - /// Build a new GNU statement expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildStmtExpr(SourceLocation LParenLoc, - Stmt *SubStmt, - SourceLocation RParenLoc) { - return getSema().ActOnStmtExpr(LParenLoc, SubStmt, RParenLoc); - } - - /// Build a new __builtin_choose_expr expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc, - Expr *Cond, Expr *LHS, Expr *RHS, - SourceLocation RParenLoc) { - return SemaRef.ActOnChooseExpr(BuiltinLoc, - Cond, LHS, RHS, - RParenLoc); - } - - /// Build a new generic selection expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc, - SourceLocation DefaultLoc, - SourceLocation RParenLoc, - Expr *ControllingExpr, - ArrayRef<TypeSourceInfo *> Types, - ArrayRef<Expr *> Exprs) { - return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc, - ControllingExpr, Types, Exprs); - } - - /// Build a new overloaded operator call expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// The semantic analysis provides the behavior of template instantiation, - /// copying with transformations that turn what looks like an overloaded - /// operator call into a use of a builtin operator, performing - /// argument-dependent lookup, etc. Subclasses may override this routine to - /// provide different behavior. - ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op, - SourceLocation OpLoc, - Expr *Callee, - Expr *First, - Expr *Second); - - /// Build a new C++ "named" cast expression, such as static_cast or - /// reinterpret_cast. - /// - /// By default, this routine dispatches to one of the more-specific routines - /// for a particular named case, e.g., RebuildCXXStaticCastExpr(). - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc, - Stmt::StmtClass Class, - SourceLocation LAngleLoc, - TypeSourceInfo *TInfo, - SourceLocation RAngleLoc, - SourceLocation LParenLoc, - Expr *SubExpr, - SourceLocation RParenLoc) { - switch (Class) { - case Stmt::CXXStaticCastExprClass: - return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo, - RAngleLoc, LParenLoc, - SubExpr, RParenLoc); - - case Stmt::CXXDynamicCastExprClass: - return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo, - RAngleLoc, LParenLoc, - SubExpr, RParenLoc); - - case Stmt::CXXReinterpretCastExprClass: - return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo, - RAngleLoc, LParenLoc, - SubExpr, - RParenLoc); - - case Stmt::CXXConstCastExprClass: - return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo, - RAngleLoc, LParenLoc, - SubExpr, RParenLoc); - - default: - llvm_unreachable("Invalid C++ named cast"); - } - } - - /// Build a new C++ static_cast expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc, - SourceLocation LAngleLoc, - TypeSourceInfo *TInfo, - SourceLocation RAngleLoc, - SourceLocation LParenLoc, - Expr *SubExpr, - SourceLocation RParenLoc) { - return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast, - TInfo, SubExpr, - SourceRange(LAngleLoc, RAngleLoc), - SourceRange(LParenLoc, RParenLoc)); - } - - /// Build a new C++ dynamic_cast expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc, - SourceLocation LAngleLoc, - TypeSourceInfo *TInfo, - SourceLocation RAngleLoc, - SourceLocation LParenLoc, - Expr *SubExpr, - SourceLocation RParenLoc) { - return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast, - TInfo, SubExpr, - SourceRange(LAngleLoc, RAngleLoc), - SourceRange(LParenLoc, RParenLoc)); - } - - /// Build a new C++ reinterpret_cast expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc, - SourceLocation LAngleLoc, - TypeSourceInfo *TInfo, - SourceLocation RAngleLoc, - SourceLocation LParenLoc, - Expr *SubExpr, - SourceLocation RParenLoc) { - return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast, - TInfo, SubExpr, - SourceRange(LAngleLoc, RAngleLoc), - SourceRange(LParenLoc, RParenLoc)); - } - - /// Build a new C++ const_cast expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc, - SourceLocation LAngleLoc, - TypeSourceInfo *TInfo, - SourceLocation RAngleLoc, - SourceLocation LParenLoc, - Expr *SubExpr, - SourceLocation RParenLoc) { - return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast, - TInfo, SubExpr, - SourceRange(LAngleLoc, RAngleLoc), - SourceRange(LParenLoc, RParenLoc)); - } - - /// Build a new C++ functional-style cast expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, - SourceLocation LParenLoc, - Expr *Sub, - SourceLocation RParenLoc, - bool ListInitialization) { - return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc, - MultiExprArg(&Sub, 1), RParenLoc, - ListInitialization); - } - - /// Build a new C++ typeid(type) expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType, - SourceLocation TypeidLoc, - TypeSourceInfo *Operand, - SourceLocation RParenLoc) { - return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand, - RParenLoc); - } - - - /// Build a new C++ typeid(expr) expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType, - SourceLocation TypeidLoc, - Expr *Operand, - SourceLocation RParenLoc) { - return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand, - RParenLoc); - } - - /// Build a new C++ __uuidof(type) expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXUuidofExpr(QualType TypeInfoType, - SourceLocation TypeidLoc, - TypeSourceInfo *Operand, - SourceLocation RParenLoc) { - return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand, - RParenLoc); - } - - /// Build a new C++ __uuidof(expr) expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXUuidofExpr(QualType TypeInfoType, - SourceLocation TypeidLoc, - Expr *Operand, - SourceLocation RParenLoc) { - return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand, - RParenLoc); - } - - /// Build a new C++ "this" expression. - /// - /// By default, builds a new "this" expression without performing any - /// semantic analysis. Subclasses may override this routine to provide - /// different behavior. - ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc, - QualType ThisType, - bool isImplicit) { - getSema().CheckCXXThisCapture(ThisLoc); - return new (getSema().Context) CXXThisExpr(ThisLoc, ThisType, isImplicit); - } - - /// Build a new C++ throw expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub, - bool IsThrownVariableInScope) { - return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope); - } - - /// Build a new C++ default-argument expression. - /// - /// By default, builds a new default-argument expression, which does not - /// require any semantic analysis. Subclasses may override this routine to - /// provide different behavior. - ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, - ParmVarDecl *Param) { - return CXXDefaultArgExpr::Create(getSema().Context, Loc, Param); - } - - /// Build a new C++11 default-initialization expression. - /// - /// By default, builds a new default field initialization expression, which - /// does not require any semantic analysis. Subclasses may override this - /// routine to provide different behavior. - ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc, - FieldDecl *Field) { - return CXXDefaultInitExpr::Create(getSema().Context, Loc, Field); - } - - /// Build a new C++ zero-initialization expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo, - SourceLocation LParenLoc, - SourceLocation RParenLoc) { - return getSema().BuildCXXTypeConstructExpr( - TSInfo, LParenLoc, None, RParenLoc, /*ListInitialization=*/false); - } - - /// Build a new C++ "new" expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, - bool UseGlobal, - SourceLocation PlacementLParen, - MultiExprArg PlacementArgs, - SourceLocation PlacementRParen, - SourceRange TypeIdParens, - QualType AllocatedType, - TypeSourceInfo *AllocatedTypeInfo, - Expr *ArraySize, - SourceRange DirectInitRange, - Expr *Initializer) { - return getSema().BuildCXXNew(StartLoc, UseGlobal, - PlacementLParen, - PlacementArgs, - PlacementRParen, - TypeIdParens, - AllocatedType, - AllocatedTypeInfo, - ArraySize, - DirectInitRange, - Initializer); - } - - /// Build a new C++ "delete" expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc, - bool IsGlobalDelete, - bool IsArrayForm, - Expr *Operand) { - return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm, - Operand); - } - - /// Build a new type trait expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildTypeTrait(TypeTrait Trait, - SourceLocation StartLoc, - ArrayRef<TypeSourceInfo *> Args, - SourceLocation RParenLoc) { - return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc); - } - - /// Build a new array type trait expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait, - SourceLocation StartLoc, - TypeSourceInfo *TSInfo, - Expr *DimExpr, - SourceLocation RParenLoc) { - return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc); - } - - /// Build a new expression trait expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildExpressionTrait(ExpressionTrait Trait, - SourceLocation StartLoc, - Expr *Queried, - SourceLocation RParenLoc) { - return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc); - } - - /// Build a new (previously unresolved) declaration reference - /// expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildDependentScopeDeclRefExpr( - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - const DeclarationNameInfo &NameInfo, - const TemplateArgumentListInfo *TemplateArgs, - bool IsAddressOfOperand, - TypeSourceInfo **RecoveryTSI) { - CXXScopeSpec SS; - SS.Adopt(QualifierLoc); - - if (TemplateArgs || TemplateKWLoc.isValid()) - return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, NameInfo, - TemplateArgs); - - return getSema().BuildQualifiedDeclarationNameExpr( - SS, NameInfo, IsAddressOfOperand, /*S*/nullptr, RecoveryTSI); - } - - /// Build a new template-id expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - LookupResult &R, - bool RequiresADL, - const TemplateArgumentListInfo *TemplateArgs) { - return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL, - TemplateArgs); - } - - /// Build a new object-construction expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXConstructExpr(QualType T, - SourceLocation Loc, - CXXConstructorDecl *Constructor, - bool IsElidable, - MultiExprArg Args, - bool HadMultipleCandidates, - bool ListInitialization, - bool StdInitListInitialization, - bool RequiresZeroInit, - CXXConstructExpr::ConstructionKind ConstructKind, - SourceRange ParenRange) { - SmallVector<Expr*, 8> ConvertedArgs; - if (getSema().CompleteConstructorCall(Constructor, Args, Loc, - ConvertedArgs)) - return ExprError(); - - return getSema().BuildCXXConstructExpr(Loc, T, Constructor, - IsElidable, - ConvertedArgs, - HadMultipleCandidates, - ListInitialization, - StdInitListInitialization, - RequiresZeroInit, ConstructKind, - ParenRange); - } - - /// Build a new implicit construction via inherited constructor - /// expression. - ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc, - CXXConstructorDecl *Constructor, - bool ConstructsVBase, - bool InheritedFromVBase) { - return new (getSema().Context) CXXInheritedCtorInitExpr( - Loc, T, Constructor, ConstructsVBase, InheritedFromVBase); - } - - /// Build a new object-construction expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo, - SourceLocation LParenOrBraceLoc, - MultiExprArg Args, - SourceLocation RParenOrBraceLoc, - bool ListInitialization) { - return getSema().BuildCXXTypeConstructExpr( - TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization); - } - - /// Build a new object-construction expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo, - SourceLocation LParenLoc, - MultiExprArg Args, - SourceLocation RParenLoc, - bool ListInitialization) { - return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args, - RParenLoc, ListInitialization); - } - - /// Build a new member reference expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE, - QualType BaseType, - bool IsArrow, - SourceLocation OperatorLoc, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - NamedDecl *FirstQualifierInScope, - const DeclarationNameInfo &MemberNameInfo, - const TemplateArgumentListInfo *TemplateArgs) { - CXXScopeSpec SS; - SS.Adopt(QualifierLoc); - - return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType, - OperatorLoc, IsArrow, - SS, TemplateKWLoc, - FirstQualifierInScope, - MemberNameInfo, - TemplateArgs, /*S*/nullptr); - } - - /// Build a new member reference expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType, - SourceLocation OperatorLoc, - bool IsArrow, - NestedNameSpecifierLoc QualifierLoc, - SourceLocation TemplateKWLoc, - NamedDecl *FirstQualifierInScope, - LookupResult &R, - const TemplateArgumentListInfo *TemplateArgs) { - CXXScopeSpec SS; - SS.Adopt(QualifierLoc); - - return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType, - OperatorLoc, IsArrow, - SS, TemplateKWLoc, - FirstQualifierInScope, - R, TemplateArgs, /*S*/nullptr); - } - - /// Build a new noexcept expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) { - return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd()); - } - - /// Build a new expression to compute the length of a parameter pack. - ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, - NamedDecl *Pack, - SourceLocation PackLoc, - SourceLocation RParenLoc, - Optional<unsigned> Length, - ArrayRef<TemplateArgument> PartialArgs) { - return SizeOfPackExpr::Create(SemaRef.Context, OperatorLoc, Pack, PackLoc, - RParenLoc, Length, PartialArgs); - } - - /// Build a new Objective-C boxed expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { - return getSema().BuildObjCBoxedExpr(SR, ValueExpr); - } - - /// Build a new Objective-C array literal. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildObjCArrayLiteral(SourceRange Range, - Expr **Elements, unsigned NumElements) { - return getSema().BuildObjCArrayLiteral(Range, - MultiExprArg(Elements, NumElements)); - } - - ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB, - Expr *Base, Expr *Key, - ObjCMethodDecl *getterMethod, - ObjCMethodDecl *setterMethod) { - return getSema().BuildObjCSubscriptExpression(RB, Base, Key, - getterMethod, setterMethod); - } - - /// Build a new Objective-C dictionary literal. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildObjCDictionaryLiteral(SourceRange Range, - MutableArrayRef<ObjCDictionaryElement> Elements) { - return getSema().BuildObjCDictionaryLiteral(Range, Elements); - } - - /// Build a new Objective-C \@encode expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc, - TypeSourceInfo *EncodeTypeInfo, - SourceLocation RParenLoc) { - return SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, RParenLoc); - } - - /// Build a new Objective-C class message. - ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo, - Selector Sel, - ArrayRef<SourceLocation> SelectorLocs, - ObjCMethodDecl *Method, - SourceLocation LBracLoc, - MultiExprArg Args, - SourceLocation RBracLoc) { - return SemaRef.BuildClassMessage(ReceiverTypeInfo, - ReceiverTypeInfo->getType(), - /*SuperLoc=*/SourceLocation(), - Sel, Method, LBracLoc, SelectorLocs, - RBracLoc, Args); - } - - /// Build a new Objective-C instance message. - ExprResult RebuildObjCMessageExpr(Expr *Receiver, - Selector Sel, - ArrayRef<SourceLocation> SelectorLocs, - ObjCMethodDecl *Method, - SourceLocation LBracLoc, - MultiExprArg Args, - SourceLocation RBracLoc) { - return SemaRef.BuildInstanceMessage(Receiver, - Receiver->getType(), - /*SuperLoc=*/SourceLocation(), - Sel, Method, LBracLoc, SelectorLocs, - RBracLoc, Args); - } - - /// Build a new Objective-C instance/class message to 'super'. - ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc, - Selector Sel, - ArrayRef<SourceLocation> SelectorLocs, - QualType SuperType, - ObjCMethodDecl *Method, - SourceLocation LBracLoc, - MultiExprArg Args, - SourceLocation RBracLoc) { - return Method->isInstanceMethod() ? SemaRef.BuildInstanceMessage(nullptr, - SuperType, - SuperLoc, - Sel, Method, LBracLoc, SelectorLocs, - RBracLoc, Args) - : SemaRef.BuildClassMessage(nullptr, - SuperType, - SuperLoc, - Sel, Method, LBracLoc, SelectorLocs, - RBracLoc, Args); - - - } - - /// Build a new Objective-C ivar reference expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar, - SourceLocation IvarLoc, - bool IsArrow, bool IsFreeIvar) { - CXXScopeSpec SS; - DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc); - ExprResult Result = getSema().BuildMemberReferenceExpr( - BaseArg, BaseArg->getType(), - /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(), - /*FirstQualifierInScope=*/nullptr, NameInfo, - /*TemplateArgs=*/nullptr, - /*S=*/nullptr); - if (IsFreeIvar && Result.isUsable()) - cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar); - return Result; - } - - /// Build a new Objective-C property reference expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg, - ObjCPropertyDecl *Property, - SourceLocation PropertyLoc) { - CXXScopeSpec SS; - DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc); - return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(), - /*FIXME:*/PropertyLoc, - /*IsArrow=*/false, - SS, SourceLocation(), - /*FirstQualifierInScope=*/nullptr, - NameInfo, - /*TemplateArgs=*/nullptr, - /*S=*/nullptr); - } - - /// Build a new Objective-C property reference expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T, - ObjCMethodDecl *Getter, - ObjCMethodDecl *Setter, - SourceLocation PropertyLoc) { - // Since these expressions can only be value-dependent, we do not - // need to perform semantic analysis again. - return Owned( - new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T, - VK_LValue, OK_ObjCProperty, - PropertyLoc, Base)); - } - - /// Build a new Objective-C "isa" expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc, - SourceLocation OpLoc, bool IsArrow) { - CXXScopeSpec SS; - DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc); - return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(), - OpLoc, IsArrow, - SS, SourceLocation(), - /*FirstQualifierInScope=*/nullptr, - NameInfo, - /*TemplateArgs=*/nullptr, - /*S=*/nullptr); - } - - /// Build a new shuffle vector expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc, - MultiExprArg SubExprs, - SourceLocation RParenLoc) { - // Find the declaration for __builtin_shufflevector - const IdentifierInfo &Name - = SemaRef.Context.Idents.get("__builtin_shufflevector"); - TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl(); - DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name)); - assert(!Lookup.empty() && "No __builtin_shufflevector?"); - - // Build a reference to the __builtin_shufflevector builtin - FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front()); - Expr *Callee = new (SemaRef.Context) - DeclRefExpr(SemaRef.Context, Builtin, false, - SemaRef.Context.BuiltinFnTy, VK_RValue, BuiltinLoc); - QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType()); - Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy, - CK_BuiltinFnToFnPtr).get(); - - // Build the CallExpr - ExprResult TheCall = CallExpr::Create( - SemaRef.Context, Callee, SubExprs, Builtin->getCallResultType(), - Expr::getValueKindForType(Builtin->getReturnType()), RParenLoc); - - // Type-check the __builtin_shufflevector expression. - return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.get())); - } - - /// Build a new convert vector expression. - ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc, - Expr *SrcExpr, TypeSourceInfo *DstTInfo, - SourceLocation RParenLoc) { - return SemaRef.SemaConvertVectorExpr(SrcExpr, DstTInfo, - BuiltinLoc, RParenLoc); - } - - /// Build a new template argument pack expansion. - /// - /// By default, performs semantic analysis to build a new pack expansion - /// for a template argument. Subclasses may override this routine to provide - /// different behavior. - TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern, - SourceLocation EllipsisLoc, - Optional<unsigned> NumExpansions) { - switch (Pattern.getArgument().getKind()) { - case TemplateArgument::Expression: { - ExprResult Result - = getSema().CheckPackExpansion(Pattern.getSourceExpression(), - EllipsisLoc, NumExpansions); - if (Result.isInvalid()) - return TemplateArgumentLoc(); - - return TemplateArgumentLoc(Result.get(), Result.get()); - } - - case TemplateArgument::Template: - return TemplateArgumentLoc(TemplateArgument( - Pattern.getArgument().getAsTemplate(), - NumExpansions), - Pattern.getTemplateQualifierLoc(), - Pattern.getTemplateNameLoc(), - EllipsisLoc); - - case TemplateArgument::Null: - case TemplateArgument::Integral: - case TemplateArgument::Declaration: - case TemplateArgument::Pack: - case TemplateArgument::TemplateExpansion: - case TemplateArgument::NullPtr: - llvm_unreachable("Pack expansion pattern has no parameter packs"); - - case TemplateArgument::Type: - if (TypeSourceInfo *Expansion - = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(), - EllipsisLoc, - NumExpansions)) - return TemplateArgumentLoc(TemplateArgument(Expansion->getType()), - Expansion); - break; - } - - return TemplateArgumentLoc(); - } - - /// Build a new expression pack expansion. - /// - /// By default, performs semantic analysis to build a new pack expansion - /// for an expression. Subclasses may override this routine to provide - /// different behavior. - ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, - Optional<unsigned> NumExpansions) { - return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions); - } - - /// Build a new C++1z fold-expression. - /// - /// By default, performs semantic analysis in order to build a new fold - /// expression. - ExprResult RebuildCXXFoldExpr(SourceLocation LParenLoc, Expr *LHS, - BinaryOperatorKind Operator, - SourceLocation EllipsisLoc, Expr *RHS, - SourceLocation RParenLoc) { - return getSema().BuildCXXFoldExpr(LParenLoc, LHS, Operator, EllipsisLoc, - RHS, RParenLoc); - } - - /// Build an empty C++1z fold-expression with the given operator. - /// - /// By default, produces the fallback value for the fold-expression, or - /// produce an error if there is no fallback value. - ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc, - BinaryOperatorKind Operator) { - return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator); - } - - /// Build a new atomic operation expression. - /// - /// By default, performs semantic analysis to build the new expression. - /// Subclasses may override this routine to provide different behavior. - ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, - MultiExprArg SubExprs, - QualType RetTy, - AtomicExpr::AtomicOp Op, - SourceLocation RParenLoc) { - // Just create the expression; there is not any interesting semantic - // analysis here because we can't actually build an AtomicExpr until - // we are sure it is semantically sound. - return new (SemaRef.Context) AtomicExpr(BuiltinLoc, SubExprs, RetTy, Op, - RParenLoc); - } - -private: - TypeLoc TransformTypeInObjectScope(TypeLoc TL, - QualType ObjectType, - NamedDecl *FirstQualifierInScope, - CXXScopeSpec &SS); - - TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo, - QualType ObjectType, - NamedDecl *FirstQualifierInScope, - CXXScopeSpec &SS); - - TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType, - NamedDecl *FirstQualifierInScope, - CXXScopeSpec &SS); - - QualType TransformDependentNameType(TypeLocBuilder &TLB, - DependentNameTypeLoc TL, - bool DeducibleTSTContext); -}; - -template<typename Derived> -StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) { - if (!S) - return S; - - switch (S->getStmtClass()) { - case Stmt::NoStmtClass: break; - - // Transform individual statement nodes -#define STMT(Node, Parent) \ - case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S)); -#define ABSTRACT_STMT(Node) -#define EXPR(Node, Parent) -#include "clang/AST/StmtNodes.inc" - - // Transform expressions by calling TransformExpr. -#define STMT(Node, Parent) -#define ABSTRACT_STMT(Stmt) -#define EXPR(Node, Parent) case Stmt::Node##Class: -#include "clang/AST/StmtNodes.inc" - { - ExprResult E = getDerived().TransformExpr(cast<Expr>(S)); - if (E.isInvalid()) - return StmtError(); - - return getSema().ActOnExprStmt(E); - } - } - - return S; -} - -template<typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) { - if (!S) - return S; - - switch (S->getClauseKind()) { - default: break; - // Transform individual clause nodes -#define OPENMP_CLAUSE(Name, Class) \ - case OMPC_ ## Name : \ - return getDerived().Transform ## Class(cast<Class>(S)); -#include "clang/Basic/OpenMPKinds.def" - } - - return S; -} - - -template<typename Derived> -ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) { - if (!E) - return E; - - switch (E->getStmtClass()) { - case Stmt::NoStmtClass: break; -#define STMT(Node, Parent) case Stmt::Node##Class: break; -#define ABSTRACT_STMT(Stmt) -#define EXPR(Node, Parent) \ - case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E)); -#include "clang/AST/StmtNodes.inc" - } - - return E; -} - -template<typename Derived> -ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init, - bool NotCopyInit) { - // Initializers are instantiated like expressions, except that various outer - // layers are stripped. - if (!Init) - return Init; - - if (auto *FE = dyn_cast<FullExpr>(Init)) - Init = FE->getSubExpr(); - - if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) - Init = AIL->getCommonExpr(); - - if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init)) - Init = MTE->GetTemporaryExpr(); - - while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init)) - Init = Binder->getSubExpr(); - - if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init)) - Init = ICE->getSubExprAsWritten(); - - if (CXXStdInitializerListExpr *ILE = - dyn_cast<CXXStdInitializerListExpr>(Init)) - return TransformInitializer(ILE->getSubExpr(), NotCopyInit); - - // If this is copy-initialization, we only need to reconstruct - // InitListExprs. Other forms of copy-initialization will be a no-op if - // the initializer is already the right type. - CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init); - if (!NotCopyInit && !(Construct && Construct->isListInitialization())) - return getDerived().TransformExpr(Init); - - // Revert value-initialization back to empty parens. - if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) { - SourceRange Parens = VIE->getSourceRange(); - return getDerived().RebuildParenListExpr(Parens.getBegin(), None, - Parens.getEnd()); - } - - // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization. - if (isa<ImplicitValueInitExpr>(Init)) - return getDerived().RebuildParenListExpr(SourceLocation(), None, - SourceLocation()); - - // Revert initialization by constructor back to a parenthesized or braced list - // of expressions. Any other form of initializer can just be reused directly. - if (!Construct || isa<CXXTemporaryObjectExpr>(Construct)) - return getDerived().TransformExpr(Init); - - // If the initialization implicitly converted an initializer list to a - // std::initializer_list object, unwrap the std::initializer_list too. - if (Construct && Construct->isStdInitListInitialization()) - return TransformInitializer(Construct->getArg(0), NotCopyInit); - - // Enter a list-init context if this was list initialization. - EnterExpressionEvaluationContext Context( - getSema(), EnterExpressionEvaluationContext::InitList, - Construct->isListInitialization()); - - SmallVector<Expr*, 8> NewArgs; - bool ArgChanged = false; - if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(), - /*IsCall*/true, NewArgs, &ArgChanged)) - return ExprError(); - - // If this was list initialization, revert to syntactic list form. - if (Construct->isListInitialization()) - return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs, - Construct->getEndLoc()); - - // Build a ParenListExpr to represent anything else. - SourceRange Parens = Construct->getParenOrBraceRange(); - if (Parens.isInvalid()) { - // This was a variable declaration's initialization for which no initializer - // was specified. - assert(NewArgs.empty() && - "no parens or braces but have direct init with arguments?"); - return ExprEmpty(); - } - return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs, - Parens.getEnd()); -} - -template<typename Derived> -bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs, - unsigned NumInputs, - bool IsCall, - SmallVectorImpl<Expr *> &Outputs, - bool *ArgChanged) { - for (unsigned I = 0; I != NumInputs; ++I) { - // If requested, drop call arguments that need to be dropped. - if (IsCall && getDerived().DropCallArgument(Inputs[I])) { - if (ArgChanged) - *ArgChanged = true; - - break; - } - - if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) { - Expr *Pattern = Expansion->getPattern(); - - SmallVector<UnexpandedParameterPack, 2> Unexpanded; - getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); - assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); - - // Determine whether the set of unexpanded parameter packs can and should - // be expanded. - bool Expand = true; - bool RetainExpansion = false; - Optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions(); - Optional<unsigned> NumExpansions = OrigNumExpansions; - if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(), - Pattern->getSourceRange(), - Unexpanded, - Expand, RetainExpansion, - NumExpansions)) - return true; - - if (!Expand) { - // The transform has determined that we should perform a simple - // transformation on the pack expansion, producing another pack - // expansion. - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); - ExprResult OutPattern = getDerived().TransformExpr(Pattern); - if (OutPattern.isInvalid()) - return true; - - ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(), - Expansion->getEllipsisLoc(), - NumExpansions); - if (Out.isInvalid()) - return true; - - if (ArgChanged) - *ArgChanged = true; - Outputs.push_back(Out.get()); - continue; - } - - // Record right away that the argument was changed. This needs - // to happen even if the array expands to nothing. - if (ArgChanged) *ArgChanged = true; - - // The transform has determined that we should perform an elementwise - // expansion of the pattern. Do so. - for (unsigned I = 0; I != *NumExpansions; ++I) { - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); - ExprResult Out = getDerived().TransformExpr(Pattern); - if (Out.isInvalid()) - return true; - - if (Out.get()->containsUnexpandedParameterPack()) { - Out = getDerived().RebuildPackExpansion( - Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions); - if (Out.isInvalid()) - return true; - } - - Outputs.push_back(Out.get()); - } - - // If we're supposed to retain a pack expansion, do so by temporarily - // forgetting the partially-substituted parameter pack. - if (RetainExpansion) { - ForgetPartiallySubstitutedPackRAII Forget(getDerived()); - - ExprResult Out = getDerived().TransformExpr(Pattern); - if (Out.isInvalid()) - return true; - - Out = getDerived().RebuildPackExpansion( - Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions); - if (Out.isInvalid()) - return true; - - Outputs.push_back(Out.get()); - } - - continue; - } - - ExprResult Result = - IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false) - : getDerived().TransformExpr(Inputs[I]); - if (Result.isInvalid()) - return true; - - if (Result.get() != Inputs[I] && ArgChanged) - *ArgChanged = true; - - Outputs.push_back(Result.get()); - } - - return false; -} - -template <typename Derived> -Sema::ConditionResult TreeTransform<Derived>::TransformCondition( - SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) { - if (Var) { - VarDecl *ConditionVar = cast_or_null<VarDecl>( - getDerived().TransformDefinition(Var->getLocation(), Var)); - - if (!ConditionVar) - return Sema::ConditionError(); - - return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind); - } - - if (Expr) { - ExprResult CondExpr = getDerived().TransformExpr(Expr); - - if (CondExpr.isInvalid()) - return Sema::ConditionError(); - - return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind); - } - - return Sema::ConditionResult(); -} - -template<typename Derived> -NestedNameSpecifierLoc -TreeTransform<Derived>::TransformNestedNameSpecifierLoc( - NestedNameSpecifierLoc NNS, - QualType ObjectType, - NamedDecl *FirstQualifierInScope) { - SmallVector<NestedNameSpecifierLoc, 4> Qualifiers; - for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier; - Qualifier = Qualifier.getPrefix()) - Qualifiers.push_back(Qualifier); - - CXXScopeSpec SS; - while (!Qualifiers.empty()) { - NestedNameSpecifierLoc Q = Qualifiers.pop_back_val(); - NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier(); - - switch (QNNS->getKind()) { - case NestedNameSpecifier::Identifier: { - Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(), - Q.getLocalBeginLoc(), Q.getLocalEndLoc(), ObjectType); - if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false, - SS, FirstQualifierInScope, false)) - return NestedNameSpecifierLoc(); - } - break; - - case NestedNameSpecifier::Namespace: { - NamespaceDecl *NS - = cast_or_null<NamespaceDecl>( - getDerived().TransformDecl( - Q.getLocalBeginLoc(), - QNNS->getAsNamespace())); - SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc()); - break; - } - - case NestedNameSpecifier::NamespaceAlias: { - NamespaceAliasDecl *Alias - = cast_or_null<NamespaceAliasDecl>( - getDerived().TransformDecl(Q.getLocalBeginLoc(), - QNNS->getAsNamespaceAlias())); - SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(), - Q.getLocalEndLoc()); - break; - } - - case NestedNameSpecifier::Global: - // There is no meaningful transformation that one could perform on the - // global scope. - SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc()); - break; - - case NestedNameSpecifier::Super: { - CXXRecordDecl *RD = - cast_or_null<CXXRecordDecl>(getDerived().TransformDecl( - SourceLocation(), QNNS->getAsRecordDecl())); - SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc()); - break; - } - - case NestedNameSpecifier::TypeSpecWithTemplate: - case NestedNameSpecifier::TypeSpec: { - TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType, - FirstQualifierInScope, SS); - - if (!TL) - return NestedNameSpecifierLoc(); - - if (TL.getType()->isDependentType() || TL.getType()->isRecordType() || - (SemaRef.getLangOpts().CPlusPlus11 && - TL.getType()->isEnumeralType())) { - assert(!TL.getType().hasLocalQualifiers() && - "Can't get cv-qualifiers here"); - if (TL.getType()->isEnumeralType()) - SemaRef.Diag(TL.getBeginLoc(), - diag::warn_cxx98_compat_enum_nested_name_spec); - SS.Extend(SemaRef.Context, /*FIXME:*/SourceLocation(), TL, - Q.getLocalEndLoc()); - break; - } - // If the nested-name-specifier is an invalid type def, don't emit an - // error because a previous error should have already been emitted. - TypedefTypeLoc TTL = TL.getAs<TypedefTypeLoc>(); - if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) { - SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag) - << TL.getType() << SS.getRange(); - } - return NestedNameSpecifierLoc(); - } - } - - // The qualifier-in-scope and object type only apply to the leftmost entity. - FirstQualifierInScope = nullptr; - ObjectType = QualType(); - } - - // Don't rebuild the nested-name-specifier if we don't have to. - if (SS.getScopeRep() == NNS.getNestedNameSpecifier() && - !getDerived().AlwaysRebuild()) - return NNS; - - // If we can re-use the source-location data from the original - // nested-name-specifier, do so. - if (SS.location_size() == NNS.getDataLength() && - memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0) - return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData()); - - // Allocate new nested-name-specifier location information. - return SS.getWithLocInContext(SemaRef.Context); -} - -template<typename Derived> -DeclarationNameInfo -TreeTransform<Derived> -::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) { - DeclarationName Name = NameInfo.getName(); - if (!Name) - return DeclarationNameInfo(); - - switch (Name.getNameKind()) { - case DeclarationName::Identifier: - case DeclarationName::ObjCZeroArgSelector: - case DeclarationName::ObjCOneArgSelector: - case DeclarationName::ObjCMultiArgSelector: - case DeclarationName::CXXOperatorName: - case DeclarationName::CXXLiteralOperatorName: - case DeclarationName::CXXUsingDirective: - return NameInfo; - - case DeclarationName::CXXDeductionGuideName: { - TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate(); - TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>( - getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate)); - if (!NewTemplate) - return DeclarationNameInfo(); - - DeclarationNameInfo NewNameInfo(NameInfo); - NewNameInfo.setName( - SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(NewTemplate)); - return NewNameInfo; - } - - case DeclarationName::CXXConstructorName: - case DeclarationName::CXXDestructorName: - case DeclarationName::CXXConversionFunctionName: { - TypeSourceInfo *NewTInfo; - CanQualType NewCanTy; - if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) { - NewTInfo = getDerived().TransformType(OldTInfo); - if (!NewTInfo) - return DeclarationNameInfo(); - NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType()); - } - else { - NewTInfo = nullptr; - TemporaryBase Rebase(*this, NameInfo.getLoc(), Name); - QualType NewT = getDerived().TransformType(Name.getCXXNameType()); - if (NewT.isNull()) - return DeclarationNameInfo(); - NewCanTy = SemaRef.Context.getCanonicalType(NewT); - } - - DeclarationName NewName - = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(), - NewCanTy); - DeclarationNameInfo NewNameInfo(NameInfo); - NewNameInfo.setName(NewName); - NewNameInfo.setNamedTypeInfo(NewTInfo); - return NewNameInfo; - } - } - - llvm_unreachable("Unknown name kind."); -} - -template<typename Derived> -TemplateName -TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS, - TemplateName Name, - SourceLocation NameLoc, - QualType ObjectType, - NamedDecl *FirstQualifierInScope, - bool AllowInjectedClassName) { - if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) { - TemplateDecl *Template = QTN->getTemplateDecl(); - assert(Template && "qualified template name must refer to a template"); - - TemplateDecl *TransTemplate - = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc, - Template)); - if (!TransTemplate) - return TemplateName(); - - if (!getDerived().AlwaysRebuild() && - SS.getScopeRep() == QTN->getQualifier() && - TransTemplate == Template) - return Name; - - return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(), - TransTemplate); - } - - if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) { - if (SS.getScopeRep()) { - // These apply to the scope specifier, not the template. - ObjectType = QualType(); - FirstQualifierInScope = nullptr; - } - - if (!getDerived().AlwaysRebuild() && - SS.getScopeRep() == DTN->getQualifier() && - ObjectType.isNull()) - return Name; - - // FIXME: Preserve the location of the "template" keyword. - SourceLocation TemplateKWLoc = NameLoc; - - if (DTN->isIdentifier()) { - return getDerived().RebuildTemplateName(SS, - TemplateKWLoc, - *DTN->getIdentifier(), - NameLoc, - ObjectType, - FirstQualifierInScope, - AllowInjectedClassName); - } - - return getDerived().RebuildTemplateName(SS, TemplateKWLoc, - DTN->getOperator(), NameLoc, - ObjectType, AllowInjectedClassName); - } - - if (TemplateDecl *Template = Name.getAsTemplateDecl()) { - TemplateDecl *TransTemplate - = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc, - Template)); - if (!TransTemplate) - return TemplateName(); - - if (!getDerived().AlwaysRebuild() && - TransTemplate == Template) - return Name; - - return TemplateName(TransTemplate); - } - - if (SubstTemplateTemplateParmPackStorage *SubstPack - = Name.getAsSubstTemplateTemplateParmPack()) { - TemplateTemplateParmDecl *TransParam - = cast_or_null<TemplateTemplateParmDecl>( - getDerived().TransformDecl(NameLoc, SubstPack->getParameterPack())); - if (!TransParam) - return TemplateName(); - - if (!getDerived().AlwaysRebuild() && - TransParam == SubstPack->getParameterPack()) - return Name; - - return getDerived().RebuildTemplateName(TransParam, - SubstPack->getArgumentPack()); - } - - // These should be getting filtered out before they reach the AST. - llvm_unreachable("overloaded function decl survived to here"); -} - -template<typename Derived> -void TreeTransform<Derived>::InventTemplateArgumentLoc( - const TemplateArgument &Arg, - TemplateArgumentLoc &Output) { - SourceLocation Loc = getDerived().getBaseLocation(); - switch (Arg.getKind()) { - case TemplateArgument::Null: - llvm_unreachable("null template argument in TreeTransform"); - break; - - case TemplateArgument::Type: - Output = TemplateArgumentLoc(Arg, - SemaRef.Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc)); - - break; - - case TemplateArgument::Template: - case TemplateArgument::TemplateExpansion: { - NestedNameSpecifierLocBuilder Builder; - TemplateName Template = Arg.getAsTemplateOrTemplatePattern(); - if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) - Builder.MakeTrivial(SemaRef.Context, DTN->getQualifier(), Loc); - else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) - Builder.MakeTrivial(SemaRef.Context, QTN->getQualifier(), Loc); - - if (Arg.getKind() == TemplateArgument::Template) - Output = TemplateArgumentLoc(Arg, - Builder.getWithLocInContext(SemaRef.Context), - Loc); - else - Output = TemplateArgumentLoc(Arg, - Builder.getWithLocInContext(SemaRef.Context), - Loc, Loc); - - break; - } - - case TemplateArgument::Expression: - Output = TemplateArgumentLoc(Arg, Arg.getAsExpr()); - break; - - case TemplateArgument::Declaration: - case TemplateArgument::Integral: - case TemplateArgument::Pack: - case TemplateArgument::NullPtr: - Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo()); - break; - } -} - -template<typename Derived> -bool TreeTransform<Derived>::TransformTemplateArgument( - const TemplateArgumentLoc &Input, - TemplateArgumentLoc &Output, bool Uneval) { - EnterExpressionEvaluationContext EEEC( - SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated, - /*LambdaContextDecl=*/nullptr, /*ExprContext=*/ - Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument); - const TemplateArgument &Arg = Input.getArgument(); - switch (Arg.getKind()) { - case TemplateArgument::Null: - case TemplateArgument::Integral: - case TemplateArgument::Pack: - case TemplateArgument::Declaration: - case TemplateArgument::NullPtr: - llvm_unreachable("Unexpected TemplateArgument"); - - case TemplateArgument::Type: { - TypeSourceInfo *DI = Input.getTypeSourceInfo(); - if (!DI) - DI = InventTypeSourceInfo(Input.getArgument().getAsType()); - - DI = getDerived().TransformType(DI); - if (!DI) return true; - - Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI); - return false; - } - - case TemplateArgument::Template: { - NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc(); - if (QualifierLoc) { - QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc); - if (!QualifierLoc) - return true; - } - - CXXScopeSpec SS; - SS.Adopt(QualifierLoc); - TemplateName Template - = getDerived().TransformTemplateName(SS, Arg.getAsTemplate(), - Input.getTemplateNameLoc()); - if (Template.isNull()) - return true; - - Output = TemplateArgumentLoc(TemplateArgument(Template), QualifierLoc, - Input.getTemplateNameLoc()); - return false; - } - - case TemplateArgument::TemplateExpansion: - llvm_unreachable("Caller should expand pack expansions"); - - case TemplateArgument::Expression: { - // Template argument expressions are constant expressions. - EnterExpressionEvaluationContext Unevaluated( - getSema(), Uneval - ? Sema::ExpressionEvaluationContext::Unevaluated - : Sema::ExpressionEvaluationContext::ConstantEvaluated); - - Expr *InputExpr = Input.getSourceExpression(); - if (!InputExpr) InputExpr = Input.getArgument().getAsExpr(); - - ExprResult E = getDerived().TransformExpr(InputExpr); - E = SemaRef.ActOnConstantExpression(E); - if (E.isInvalid()) return true; - Output = TemplateArgumentLoc(TemplateArgument(E.get()), E.get()); - return false; - } - } - - // Work around bogus GCC warning - return true; -} - -/// Iterator adaptor that invents template argument location information -/// for each of the template arguments in its underlying iterator. -template<typename Derived, typename InputIterator> -class TemplateArgumentLocInventIterator { - TreeTransform<Derived> &Self; - InputIterator Iter; - -public: - typedef TemplateArgumentLoc value_type; - typedef TemplateArgumentLoc reference; - typedef typename std::iterator_traits<InputIterator>::difference_type - difference_type; - typedef std::input_iterator_tag iterator_category; - - class pointer { - TemplateArgumentLoc Arg; - - public: - explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { } - - const TemplateArgumentLoc *operator->() const { return &Arg; } - }; - - TemplateArgumentLocInventIterator() { } - - explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self, - InputIterator Iter) - : Self(Self), Iter(Iter) { } - - TemplateArgumentLocInventIterator &operator++() { - ++Iter; - return *this; - } - - TemplateArgumentLocInventIterator operator++(int) { - TemplateArgumentLocInventIterator Old(*this); - ++(*this); - return Old; - } - - reference operator*() const { - TemplateArgumentLoc Result; - Self.InventTemplateArgumentLoc(*Iter, Result); - return Result; - } - - pointer operator->() const { return pointer(**this); } - - friend bool operator==(const TemplateArgumentLocInventIterator &X, - const TemplateArgumentLocInventIterator &Y) { - return X.Iter == Y.Iter; - } - - friend bool operator!=(const TemplateArgumentLocInventIterator &X, - const TemplateArgumentLocInventIterator &Y) { - return X.Iter != Y.Iter; - } -}; - -template<typename Derived> -template<typename InputIterator> -bool TreeTransform<Derived>::TransformTemplateArguments( - InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs, - bool Uneval) { - for (; First != Last; ++First) { - TemplateArgumentLoc Out; - TemplateArgumentLoc In = *First; - - if (In.getArgument().getKind() == TemplateArgument::Pack) { - // Unpack argument packs, which we translate them into separate - // arguments. - // FIXME: We could do much better if we could guarantee that the - // TemplateArgumentLocInfo for the pack expansion would be usable for - // all of the template arguments in the argument pack. - typedef TemplateArgumentLocInventIterator<Derived, - TemplateArgument::pack_iterator> - PackLocIterator; - if (TransformTemplateArguments(PackLocIterator(*this, - In.getArgument().pack_begin()), - PackLocIterator(*this, - In.getArgument().pack_end()), - Outputs, Uneval)) - return true; - - continue; - } - - if (In.getArgument().isPackExpansion()) { - // We have a pack expansion, for which we will be substituting into - // the pattern. - SourceLocation Ellipsis; - Optional<unsigned> OrigNumExpansions; - TemplateArgumentLoc Pattern - = getSema().getTemplateArgumentPackExpansionPattern( - In, Ellipsis, OrigNumExpansions); - - SmallVector<UnexpandedParameterPack, 2> Unexpanded; - getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); - assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); - - // Determine whether the set of unexpanded parameter packs can and should - // be expanded. - bool Expand = true; - bool RetainExpansion = false; - Optional<unsigned> NumExpansions = OrigNumExpansions; - if (getDerived().TryExpandParameterPacks(Ellipsis, - Pattern.getSourceRange(), - Unexpanded, - Expand, - RetainExpansion, - NumExpansions)) - return true; - - if (!Expand) { - // The transform has determined that we should perform a simple - // transformation on the pack expansion, producing another pack - // expansion. - TemplateArgumentLoc OutPattern; - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); - if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval)) - return true; - - Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis, - NumExpansions); - if (Out.getArgument().isNull()) - return true; - - Outputs.addArgument(Out); - continue; - } - - // The transform has determined that we should perform an elementwise - // expansion of the pattern. Do so. - for (unsigned I = 0; I != *NumExpansions; ++I) { - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); - - if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval)) - return true; - - if (Out.getArgument().containsUnexpandedParameterPack()) { - Out = getDerived().RebuildPackExpansion(Out, Ellipsis, - OrigNumExpansions); - if (Out.getArgument().isNull()) - return true; - } - - Outputs.addArgument(Out); - } - - // If we're supposed to retain a pack expansion, do so by temporarily - // forgetting the partially-substituted parameter pack. - if (RetainExpansion) { - ForgetPartiallySubstitutedPackRAII Forget(getDerived()); - - if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval)) - return true; - - Out = getDerived().RebuildPackExpansion(Out, Ellipsis, - OrigNumExpansions); - if (Out.getArgument().isNull()) - return true; - - Outputs.addArgument(Out); - } - - continue; - } - - // The simple case: - if (getDerived().TransformTemplateArgument(In, Out, Uneval)) - return true; - - Outputs.addArgument(Out); - } - - return false; - -} - -//===----------------------------------------------------------------------===// -// Type transformation -//===----------------------------------------------------------------------===// - -template<typename Derived> -QualType TreeTransform<Derived>::TransformType(QualType T) { - if (getDerived().AlreadyTransformed(T)) - return T; - - // Temporary workaround. All of these transformations should - // eventually turn into transformations on TypeLocs. - TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T, - getDerived().getBaseLocation()); - - TypeSourceInfo *NewDI = getDerived().TransformType(DI); - - if (!NewDI) - return QualType(); - - return NewDI->getType(); -} - -template<typename Derived> -TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) { - // Refine the base location to the type's location. - TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(), - getDerived().getBaseEntity()); - if (getDerived().AlreadyTransformed(DI->getType())) - return DI; - - TypeLocBuilder TLB; - - TypeLoc TL = DI->getTypeLoc(); - TLB.reserve(TL.getFullDataSize()); - - QualType Result = getDerived().TransformType(TLB, TL); - if (Result.isNull()) - return nullptr; - - return TLB.getTypeSourceInfo(SemaRef.Context, Result); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) { - switch (T.getTypeLocClass()) { -#define ABSTRACT_TYPELOC(CLASS, PARENT) -#define TYPELOC(CLASS, PARENT) \ - case TypeLoc::CLASS: \ - return getDerived().Transform##CLASS##Type(TLB, \ - T.castAs<CLASS##TypeLoc>()); -#include "clang/AST/TypeLocNodes.def" - } - - llvm_unreachable("unhandled type loc!"); -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) { - if (!isa<DependentNameType>(T)) - return TransformType(T); - - if (getDerived().AlreadyTransformed(T)) - return T; - TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T, - getDerived().getBaseLocation()); - TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI); - return NewDI ? NewDI->getType() : QualType(); -} - -template<typename Derived> -TypeSourceInfo * -TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) { - if (!isa<DependentNameType>(DI->getType())) - return TransformType(DI); - - // Refine the base location to the type's location. - TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(), - getDerived().getBaseEntity()); - if (getDerived().AlreadyTransformed(DI->getType())) - return DI; - - TypeLocBuilder TLB; - - TypeLoc TL = DI->getTypeLoc(); - TLB.reserve(TL.getFullDataSize()); - - auto QTL = TL.getAs<QualifiedTypeLoc>(); - if (QTL) - TL = QTL.getUnqualifiedLoc(); - - auto DNTL = TL.castAs<DependentNameTypeLoc>(); - - QualType Result = getDerived().TransformDependentNameType( - TLB, DNTL, /*DeducedTSTContext*/true); - if (Result.isNull()) - return nullptr; - - if (QTL) { - Result = getDerived().RebuildQualifiedType(Result, QTL); - if (Result.isNull()) - return nullptr; - TLB.TypeWasModifiedSafely(Result); - } - - return TLB.getTypeSourceInfo(SemaRef.Context, Result); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB, - QualifiedTypeLoc T) { - QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc()); - if (Result.isNull()) - return QualType(); - - Result = getDerived().RebuildQualifiedType(Result, T); - - if (Result.isNull()) - return QualType(); - - // RebuildQualifiedType might have updated the type, but not in a way - // that invalidates the TypeLoc. (There's no location information for - // qualifiers.) - TLB.TypeWasModifiedSafely(Result); - - return Result; -} - -template <typename Derived> -QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T, - QualifiedTypeLoc TL) { - - SourceLocation Loc = TL.getBeginLoc(); - Qualifiers Quals = TL.getType().getLocalQualifiers(); - - if (((T.getAddressSpace() != LangAS::Default && - Quals.getAddressSpace() != LangAS::Default)) && - T.getAddressSpace() != Quals.getAddressSpace()) { - SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst) - << TL.getType() << T; - return QualType(); - } - - // C++ [dcl.fct]p7: - // [When] adding cv-qualifications on top of the function type [...] the - // cv-qualifiers are ignored. - if (T->isFunctionType()) { - T = SemaRef.getASTContext().getAddrSpaceQualType(T, - Quals.getAddressSpace()); - return T; - } - - // C++ [dcl.ref]p1: - // when the cv-qualifiers are introduced through the use of a typedef-name - // or decltype-specifier [...] the cv-qualifiers are ignored. - // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be - // applied to a reference type. - if (T->isReferenceType()) { - // The only qualifier that applies to a reference type is restrict. - if (!Quals.hasRestrict()) - return T; - Quals = Qualifiers::fromCVRMask(Qualifiers::Restrict); - } - - // Suppress Objective-C lifetime qualifiers if they don't make sense for the - // resulting type. - if (Quals.hasObjCLifetime()) { - if (!T->isObjCLifetimeType() && !T->isDependentType()) - Quals.removeObjCLifetime(); - else if (T.getObjCLifetime()) { - // Objective-C ARC: - // A lifetime qualifier applied to a substituted template parameter - // overrides the lifetime qualifier from the template argument. - const AutoType *AutoTy; - if (const SubstTemplateTypeParmType *SubstTypeParam - = dyn_cast<SubstTemplateTypeParmType>(T)) { - QualType Replacement = SubstTypeParam->getReplacementType(); - Qualifiers Qs = Replacement.getQualifiers(); - Qs.removeObjCLifetime(); - Replacement = SemaRef.Context.getQualifiedType( - Replacement.getUnqualifiedType(), Qs); - T = SemaRef.Context.getSubstTemplateTypeParmType( - SubstTypeParam->getReplacedParameter(), Replacement); - } else if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) { - // 'auto' types behave the same way as template parameters. - QualType Deduced = AutoTy->getDeducedType(); - Qualifiers Qs = Deduced.getQualifiers(); - Qs.removeObjCLifetime(); - Deduced = - SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), Qs); - T = SemaRef.Context.getAutoType(Deduced, AutoTy->getKeyword(), - AutoTy->isDependentType()); - } else { - // Otherwise, complain about the addition of a qualifier to an - // already-qualified type. - // FIXME: Why is this check not in Sema::BuildQualifiedType? - SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T; - Quals.removeObjCLifetime(); - } - } - } - - return SemaRef.BuildQualifiedType(T, Loc, Quals); -} - -template<typename Derived> -TypeLoc -TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL, - QualType ObjectType, - NamedDecl *UnqualLookup, - CXXScopeSpec &SS) { - if (getDerived().AlreadyTransformed(TL.getType())) - return TL; - - TypeSourceInfo *TSI = - TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS); - if (TSI) - return TSI->getTypeLoc(); - return TypeLoc(); -} - -template<typename Derived> -TypeSourceInfo * -TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo, - QualType ObjectType, - NamedDecl *UnqualLookup, - CXXScopeSpec &SS) { - if (getDerived().AlreadyTransformed(TSInfo->getType())) - return TSInfo; - - return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType, - UnqualLookup, SS); -} - -template <typename Derived> -TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope( - TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup, - CXXScopeSpec &SS) { - QualType T = TL.getType(); - assert(!getDerived().AlreadyTransformed(T)); - - TypeLocBuilder TLB; - QualType Result; - - if (isa<TemplateSpecializationType>(T)) { - TemplateSpecializationTypeLoc SpecTL = - TL.castAs<TemplateSpecializationTypeLoc>(); - - TemplateName Template = getDerived().TransformTemplateName( - SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(), - ObjectType, UnqualLookup, /*AllowInjectedClassName*/true); - if (Template.isNull()) - return nullptr; - - Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL, - Template); - } else if (isa<DependentTemplateSpecializationType>(T)) { - DependentTemplateSpecializationTypeLoc SpecTL = - TL.castAs<DependentTemplateSpecializationTypeLoc>(); - - TemplateName Template - = getDerived().RebuildTemplateName(SS, - SpecTL.getTemplateKeywordLoc(), - *SpecTL.getTypePtr()->getIdentifier(), - SpecTL.getTemplateNameLoc(), - ObjectType, UnqualLookup, - /*AllowInjectedClassName*/true); - if (Template.isNull()) - return nullptr; - - Result = getDerived().TransformDependentTemplateSpecializationType(TLB, - SpecTL, - Template, - SS); - } else { - // Nothing special needs to be done for these. - Result = getDerived().TransformType(TLB, TL); - } - - if (Result.isNull()) - return nullptr; - - return TLB.getTypeSourceInfo(SemaRef.Context, Result); -} - -template <class TyLoc> static inline -QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) { - TyLoc NewT = TLB.push<TyLoc>(T.getType()); - NewT.setNameLoc(T.getNameLoc()); - return T.getType(); -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB, - BuiltinTypeLoc T) { - BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType()); - NewT.setBuiltinLoc(T.getBuiltinLoc()); - if (T.needsExtraLocalData()) - NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs(); - return T.getType(); -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB, - ComplexTypeLoc T) { - // FIXME: recurse? - return TransformTypeSpecType(TLB, T); -} - -template <typename Derived> -QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB, - AdjustedTypeLoc TL) { - // Adjustments applied during transformation are handled elsewhere. - return getDerived().TransformType(TLB, TL.getOriginalLoc()); -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB, - DecayedTypeLoc TL) { - QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc()); - if (OriginalType.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - OriginalType != TL.getOriginalLoc().getType()) - Result = SemaRef.Context.getDecayedType(OriginalType); - TLB.push<DecayedTypeLoc>(Result); - // Nothing to set for DecayedTypeLoc. - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB, - PointerTypeLoc TL) { - QualType PointeeType - = getDerived().TransformType(TLB, TL.getPointeeLoc()); - if (PointeeType.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (PointeeType->getAs<ObjCObjectType>()) { - // A dependent pointer type 'T *' has is being transformed such - // that an Objective-C class type is being replaced for 'T'. The - // resulting pointer type is an ObjCObjectPointerType, not a - // PointerType. - Result = SemaRef.Context.getObjCObjectPointerType(PointeeType); - - ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result); - NewT.setStarLoc(TL.getStarLoc()); - return Result; - } - - if (getDerived().AlwaysRebuild() || - PointeeType != TL.getPointeeLoc().getType()) { - Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc()); - if (Result.isNull()) - return QualType(); - } - - // Objective-C ARC can add lifetime qualifiers to the type that we're - // pointing to. - TLB.TypeWasModifiedSafely(Result->getPointeeType()); - - PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result); - NewT.setSigilLoc(TL.getSigilLoc()); - return Result; -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB, - BlockPointerTypeLoc TL) { - QualType PointeeType - = getDerived().TransformType(TLB, TL.getPointeeLoc()); - if (PointeeType.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - PointeeType != TL.getPointeeLoc().getType()) { - Result = getDerived().RebuildBlockPointerType(PointeeType, - TL.getSigilLoc()); - if (Result.isNull()) - return QualType(); - } - - BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result); - NewT.setSigilLoc(TL.getSigilLoc()); - return Result; -} - -/// Transforms a reference type. Note that somewhat paradoxically we -/// don't care whether the type itself is an l-value type or an r-value -/// type; we only care if the type was *written* as an l-value type -/// or an r-value type. -template<typename Derived> -QualType -TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB, - ReferenceTypeLoc TL) { - const ReferenceType *T = TL.getTypePtr(); - - // Note that this works with the pointee-as-written. - QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc()); - if (PointeeType.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - PointeeType != T->getPointeeTypeAsWritten()) { - Result = getDerived().RebuildReferenceType(PointeeType, - T->isSpelledAsLValue(), - TL.getSigilLoc()); - if (Result.isNull()) - return QualType(); - } - - // Objective-C ARC can add lifetime qualifiers to the type that we're - // referring to. - TLB.TypeWasModifiedSafely( - Result->getAs<ReferenceType>()->getPointeeTypeAsWritten()); - - // r-value references can be rebuilt as l-value references. - ReferenceTypeLoc NewTL; - if (isa<LValueReferenceType>(Result)) - NewTL = TLB.push<LValueReferenceTypeLoc>(Result); - else - NewTL = TLB.push<RValueReferenceTypeLoc>(Result); - NewTL.setSigilLoc(TL.getSigilLoc()); - - return Result; -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB, - LValueReferenceTypeLoc TL) { - return TransformReferenceType(TLB, TL); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB, - RValueReferenceTypeLoc TL) { - return TransformReferenceType(TLB, TL); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB, - MemberPointerTypeLoc TL) { - QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc()); - if (PointeeType.isNull()) - return QualType(); - - TypeSourceInfo* OldClsTInfo = TL.getClassTInfo(); - TypeSourceInfo *NewClsTInfo = nullptr; - if (OldClsTInfo) { - NewClsTInfo = getDerived().TransformType(OldClsTInfo); - if (!NewClsTInfo) - return QualType(); - } - - const MemberPointerType *T = TL.getTypePtr(); - QualType OldClsType = QualType(T->getClass(), 0); - QualType NewClsType; - if (NewClsTInfo) - NewClsType = NewClsTInfo->getType(); - else { - NewClsType = getDerived().TransformType(OldClsType); - if (NewClsType.isNull()) - return QualType(); - } - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - PointeeType != T->getPointeeType() || - NewClsType != OldClsType) { - Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType, - TL.getStarLoc()); - if (Result.isNull()) - return QualType(); - } - - // If we had to adjust the pointee type when building a member pointer, make - // sure to push TypeLoc info for it. - const MemberPointerType *MPT = Result->getAs<MemberPointerType>(); - if (MPT && PointeeType != MPT->getPointeeType()) { - assert(isa<AdjustedType>(MPT->getPointeeType())); - TLB.push<AdjustedTypeLoc>(MPT->getPointeeType()); - } - - MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result); - NewTL.setSigilLoc(TL.getSigilLoc()); - NewTL.setClassTInfo(NewClsTInfo); - - return Result; -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB, - ConstantArrayTypeLoc TL) { - const ConstantArrayType *T = TL.getTypePtr(); - QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); - if (ElementType.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - ElementType != T->getElementType()) { - Result = getDerived().RebuildConstantArrayType(ElementType, - T->getSizeModifier(), - T->getSize(), - T->getIndexTypeCVRQualifiers(), - TL.getBracketsRange()); - if (Result.isNull()) - return QualType(); - } - - // We might have either a ConstantArrayType or a VariableArrayType now: - // a ConstantArrayType is allowed to have an element type which is a - // VariableArrayType if the type is dependent. Fortunately, all array - // types have the same location layout. - ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result); - NewTL.setLBracketLoc(TL.getLBracketLoc()); - NewTL.setRBracketLoc(TL.getRBracketLoc()); - - Expr *Size = TL.getSizeExpr(); - if (Size) { - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); - Size = getDerived().TransformExpr(Size).template getAs<Expr>(); - Size = SemaRef.ActOnConstantExpression(Size).get(); - } - NewTL.setSizeExpr(Size); - - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformIncompleteArrayType( - TypeLocBuilder &TLB, - IncompleteArrayTypeLoc TL) { - const IncompleteArrayType *T = TL.getTypePtr(); - QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); - if (ElementType.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - ElementType != T->getElementType()) { - Result = getDerived().RebuildIncompleteArrayType(ElementType, - T->getSizeModifier(), - T->getIndexTypeCVRQualifiers(), - TL.getBracketsRange()); - if (Result.isNull()) - return QualType(); - } - - IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result); - NewTL.setLBracketLoc(TL.getLBracketLoc()); - NewTL.setRBracketLoc(TL.getRBracketLoc()); - NewTL.setSizeExpr(nullptr); - - return Result; -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB, - VariableArrayTypeLoc TL) { - const VariableArrayType *T = TL.getTypePtr(); - QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); - if (ElementType.isNull()) - return QualType(); - - ExprResult SizeResult; - { - EnterExpressionEvaluationContext Context( - SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated); - SizeResult = getDerived().TransformExpr(T->getSizeExpr()); - } - if (SizeResult.isInvalid()) - return QualType(); - SizeResult = SemaRef.ActOnFinishFullExpr(SizeResult.get()); - if (SizeResult.isInvalid()) - return QualType(); - - Expr *Size = SizeResult.get(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - ElementType != T->getElementType() || - Size != T->getSizeExpr()) { - Result = getDerived().RebuildVariableArrayType(ElementType, - T->getSizeModifier(), - Size, - T->getIndexTypeCVRQualifiers(), - TL.getBracketsRange()); - if (Result.isNull()) - return QualType(); - } - - // We might have constant size array now, but fortunately it has the same - // location layout. - ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result); - NewTL.setLBracketLoc(TL.getLBracketLoc()); - NewTL.setRBracketLoc(TL.getRBracketLoc()); - NewTL.setSizeExpr(Size); - - return Result; -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB, - DependentSizedArrayTypeLoc TL) { - const DependentSizedArrayType *T = TL.getTypePtr(); - QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); - if (ElementType.isNull()) - return QualType(); - - // Array bounds are constant expressions. - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); - - // Prefer the expression from the TypeLoc; the other may have been uniqued. - Expr *origSize = TL.getSizeExpr(); - if (!origSize) origSize = T->getSizeExpr(); - - ExprResult sizeResult - = getDerived().TransformExpr(origSize); - sizeResult = SemaRef.ActOnConstantExpression(sizeResult); - if (sizeResult.isInvalid()) - return QualType(); - - Expr *size = sizeResult.get(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - ElementType != T->getElementType() || - size != origSize) { - Result = getDerived().RebuildDependentSizedArrayType(ElementType, - T->getSizeModifier(), - size, - T->getIndexTypeCVRQualifiers(), - TL.getBracketsRange()); - if (Result.isNull()) - return QualType(); - } - - // We might have any sort of array type now, but fortunately they - // all have the same location layout. - ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result); - NewTL.setLBracketLoc(TL.getLBracketLoc()); - NewTL.setRBracketLoc(TL.getRBracketLoc()); - NewTL.setSizeExpr(size); - - return Result; -} - -template <typename Derived> -QualType TreeTransform<Derived>::TransformDependentVectorType( - TypeLocBuilder &TLB, DependentVectorTypeLoc TL) { - const DependentVectorType *T = TL.getTypePtr(); - QualType ElementType = getDerived().TransformType(T->getElementType()); - if (ElementType.isNull()) - return QualType(); - - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); - - ExprResult Size = getDerived().TransformExpr(T->getSizeExpr()); - Size = SemaRef.ActOnConstantExpression(Size); - if (Size.isInvalid()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() || - Size.get() != T->getSizeExpr()) { - Result = getDerived().RebuildDependentVectorType( - ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind()); - if (Result.isNull()) - return QualType(); - } - - // Result might be dependent or not. - if (isa<DependentVectorType>(Result)) { - DependentVectorTypeLoc NewTL = - TLB.push<DependentVectorTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - } else { - VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - } - - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType( - TypeLocBuilder &TLB, - DependentSizedExtVectorTypeLoc TL) { - const DependentSizedExtVectorType *T = TL.getTypePtr(); - - // FIXME: ext vector locs should be nested - QualType ElementType = getDerived().TransformType(T->getElementType()); - if (ElementType.isNull()) - return QualType(); - - // Vector sizes are constant expressions. - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); - - ExprResult Size = getDerived().TransformExpr(T->getSizeExpr()); - Size = SemaRef.ActOnConstantExpression(Size); - if (Size.isInvalid()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - ElementType != T->getElementType() || - Size.get() != T->getSizeExpr()) { - Result = getDerived().RebuildDependentSizedExtVectorType(ElementType, - Size.get(), - T->getAttributeLoc()); - if (Result.isNull()) - return QualType(); - } - - // Result might be dependent or not. - if (isa<DependentSizedExtVectorType>(Result)) { - DependentSizedExtVectorTypeLoc NewTL - = TLB.push<DependentSizedExtVectorTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - } else { - ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - } - - return Result; -} - -template <typename Derived> -QualType TreeTransform<Derived>::TransformDependentAddressSpaceType( - TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) { - const DependentAddressSpaceType *T = TL.getTypePtr(); - - QualType pointeeType = getDerived().TransformType(T->getPointeeType()); - - if (pointeeType.isNull()) - return QualType(); - - // Address spaces are constant expressions. - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); - - ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr()); - AddrSpace = SemaRef.ActOnConstantExpression(AddrSpace); - if (AddrSpace.isInvalid()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() || - AddrSpace.get() != T->getAddrSpaceExpr()) { - Result = getDerived().RebuildDependentAddressSpaceType( - pointeeType, AddrSpace.get(), T->getAttributeLoc()); - if (Result.isNull()) - return QualType(); - } - - // Result might be dependent or not. - if (isa<DependentAddressSpaceType>(Result)) { - DependentAddressSpaceTypeLoc NewTL = - TLB.push<DependentAddressSpaceTypeLoc>(Result); - - NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange()); - NewTL.setAttrExprOperand(TL.getAttrExprOperand()); - NewTL.setAttrNameLoc(TL.getAttrNameLoc()); - - } else { - TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo( - Result, getDerived().getBaseLocation()); - TransformType(TLB, DI->getTypeLoc()); - } - - return Result; -} - -template <typename Derived> -QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB, - VectorTypeLoc TL) { - const VectorType *T = TL.getTypePtr(); - QualType ElementType = getDerived().TransformType(T->getElementType()); - if (ElementType.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - ElementType != T->getElementType()) { - Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(), - T->getVectorKind()); - if (Result.isNull()) - return QualType(); - } - - VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB, - ExtVectorTypeLoc TL) { - const VectorType *T = TL.getTypePtr(); - QualType ElementType = getDerived().TransformType(T->getElementType()); - if (ElementType.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - ElementType != T->getElementType()) { - Result = getDerived().RebuildExtVectorType(ElementType, - T->getNumElements(), - /*FIXME*/ SourceLocation()); - if (Result.isNull()) - return QualType(); - } - - ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - - return Result; -} - -template <typename Derived> -ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam( - ParmVarDecl *OldParm, int indexAdjustment, Optional<unsigned> NumExpansions, - bool ExpectParameterPack) { - TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo(); - TypeSourceInfo *NewDI = nullptr; - - if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) { - // If we're substituting into a pack expansion type and we know the - // length we want to expand to, just substitute for the pattern. - TypeLoc OldTL = OldDI->getTypeLoc(); - PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>(); - - TypeLocBuilder TLB; - TypeLoc NewTL = OldDI->getTypeLoc(); - TLB.reserve(NewTL.getFullDataSize()); - - QualType Result = getDerived().TransformType(TLB, - OldExpansionTL.getPatternLoc()); - if (Result.isNull()) - return nullptr; - - Result = RebuildPackExpansionType(Result, - OldExpansionTL.getPatternLoc().getSourceRange(), - OldExpansionTL.getEllipsisLoc(), - NumExpansions); - if (Result.isNull()) - return nullptr; - - PackExpansionTypeLoc NewExpansionTL - = TLB.push<PackExpansionTypeLoc>(Result); - NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc()); - NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result); - } else - NewDI = getDerived().TransformType(OldDI); - if (!NewDI) - return nullptr; - - if (NewDI == OldDI && indexAdjustment == 0) - return OldParm; - - ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context, - OldParm->getDeclContext(), - OldParm->getInnerLocStart(), - OldParm->getLocation(), - OldParm->getIdentifier(), - NewDI->getType(), - NewDI, - OldParm->getStorageClass(), - /* DefArg */ nullptr); - newParm->setScopeInfo(OldParm->getFunctionScopeDepth(), - OldParm->getFunctionScopeIndex() + indexAdjustment); - return newParm; -} - -template <typename Derived> -bool TreeTransform<Derived>::TransformFunctionTypeParams( - SourceLocation Loc, ArrayRef<ParmVarDecl *> Params, - const QualType *ParamTypes, - const FunctionProtoType::ExtParameterInfo *ParamInfos, - SmallVectorImpl<QualType> &OutParamTypes, - SmallVectorImpl<ParmVarDecl *> *PVars, - Sema::ExtParameterInfoBuilder &PInfos) { - int indexAdjustment = 0; - - unsigned NumParams = Params.size(); - for (unsigned i = 0; i != NumParams; ++i) { - if (ParmVarDecl *OldParm = Params[i]) { - assert(OldParm->getFunctionScopeIndex() == i); - - Optional<unsigned> NumExpansions; - ParmVarDecl *NewParm = nullptr; - if (OldParm->isParameterPack()) { - // We have a function parameter pack that may need to be expanded. - SmallVector<UnexpandedParameterPack, 2> Unexpanded; - - // Find the parameter packs that could be expanded. - TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc(); - PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>(); - TypeLoc Pattern = ExpansionTL.getPatternLoc(); - SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded); - assert(Unexpanded.size() > 0 && "Could not find parameter packs!"); - - // Determine whether we should expand the parameter packs. - bool ShouldExpand = false; - bool RetainExpansion = false; - Optional<unsigned> OrigNumExpansions = - ExpansionTL.getTypePtr()->getNumExpansions(); - NumExpansions = OrigNumExpansions; - if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(), - Pattern.getSourceRange(), - Unexpanded, - ShouldExpand, - RetainExpansion, - NumExpansions)) { - return true; - } - - if (ShouldExpand) { - // Expand the function parameter pack into multiple, separate - // parameters. - getDerived().ExpandingFunctionParameterPack(OldParm); - for (unsigned I = 0; I != *NumExpansions; ++I) { - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); - ParmVarDecl *NewParm - = getDerived().TransformFunctionTypeParam(OldParm, - indexAdjustment++, - OrigNumExpansions, - /*ExpectParameterPack=*/false); - if (!NewParm) - return true; - - if (ParamInfos) - PInfos.set(OutParamTypes.size(), ParamInfos[i]); - OutParamTypes.push_back(NewParm->getType()); - if (PVars) - PVars->push_back(NewParm); - } - - // If we're supposed to retain a pack expansion, do so by temporarily - // forgetting the partially-substituted parameter pack. - if (RetainExpansion) { - ForgetPartiallySubstitutedPackRAII Forget(getDerived()); - ParmVarDecl *NewParm - = getDerived().TransformFunctionTypeParam(OldParm, - indexAdjustment++, - OrigNumExpansions, - /*ExpectParameterPack=*/false); - if (!NewParm) - return true; - - if (ParamInfos) - PInfos.set(OutParamTypes.size(), ParamInfos[i]); - OutParamTypes.push_back(NewParm->getType()); - if (PVars) - PVars->push_back(NewParm); - } - - // The next parameter should have the same adjustment as the - // last thing we pushed, but we post-incremented indexAdjustment - // on every push. Also, if we push nothing, the adjustment should - // go down by one. - indexAdjustment--; - - // We're done with the pack expansion. - continue; - } - - // We'll substitute the parameter now without expanding the pack - // expansion. - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); - NewParm = getDerived().TransformFunctionTypeParam(OldParm, - indexAdjustment, - NumExpansions, - /*ExpectParameterPack=*/true); - } else { - NewParm = getDerived().TransformFunctionTypeParam( - OldParm, indexAdjustment, None, /*ExpectParameterPack=*/ false); - } - - if (!NewParm) - return true; - - if (ParamInfos) - PInfos.set(OutParamTypes.size(), ParamInfos[i]); - OutParamTypes.push_back(NewParm->getType()); - if (PVars) - PVars->push_back(NewParm); - continue; - } - - // Deal with the possibility that we don't have a parameter - // declaration for this parameter. - QualType OldType = ParamTypes[i]; - bool IsPackExpansion = false; - Optional<unsigned> NumExpansions; - QualType NewType; - if (const PackExpansionType *Expansion - = dyn_cast<PackExpansionType>(OldType)) { - // We have a function parameter pack that may need to be expanded. - QualType Pattern = Expansion->getPattern(); - SmallVector<UnexpandedParameterPack, 2> Unexpanded; - getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); - - // Determine whether we should expand the parameter packs. - bool ShouldExpand = false; - bool RetainExpansion = false; - if (getDerived().TryExpandParameterPacks(Loc, SourceRange(), - Unexpanded, - ShouldExpand, - RetainExpansion, - NumExpansions)) { - return true; - } - - if (ShouldExpand) { - // Expand the function parameter pack into multiple, separate - // parameters. - for (unsigned I = 0; I != *NumExpansions; ++I) { - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); - QualType NewType = getDerived().TransformType(Pattern); - if (NewType.isNull()) - return true; - - if (NewType->containsUnexpandedParameterPack()) { - NewType = - getSema().getASTContext().getPackExpansionType(NewType, None); - - if (NewType.isNull()) - return true; - } - - if (ParamInfos) - PInfos.set(OutParamTypes.size(), ParamInfos[i]); - OutParamTypes.push_back(NewType); - if (PVars) - PVars->push_back(nullptr); - } - - // We're done with the pack expansion. - continue; - } - - // If we're supposed to retain a pack expansion, do so by temporarily - // forgetting the partially-substituted parameter pack. - if (RetainExpansion) { - ForgetPartiallySubstitutedPackRAII Forget(getDerived()); - QualType NewType = getDerived().TransformType(Pattern); - if (NewType.isNull()) - return true; - - if (ParamInfos) - PInfos.set(OutParamTypes.size(), ParamInfos[i]); - OutParamTypes.push_back(NewType); - if (PVars) - PVars->push_back(nullptr); - } - - // We'll substitute the parameter now without expanding the pack - // expansion. - OldType = Expansion->getPattern(); - IsPackExpansion = true; - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); - NewType = getDerived().TransformType(OldType); - } else { - NewType = getDerived().TransformType(OldType); - } - - if (NewType.isNull()) - return true; - - if (IsPackExpansion) - NewType = getSema().Context.getPackExpansionType(NewType, - NumExpansions); - - if (ParamInfos) - PInfos.set(OutParamTypes.size(), ParamInfos[i]); - OutParamTypes.push_back(NewType); - if (PVars) - PVars->push_back(nullptr); - } - -#ifndef NDEBUG - if (PVars) { - for (unsigned i = 0, e = PVars->size(); i != e; ++i) - if (ParmVarDecl *parm = (*PVars)[i]) - assert(parm->getFunctionScopeIndex() == i); - } -#endif - - return false; -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, - FunctionProtoTypeLoc TL) { - SmallVector<QualType, 4> ExceptionStorage; - TreeTransform *This = this; // Work around gcc.gnu.org/PR56135. - return getDerived().TransformFunctionProtoType( - TLB, TL, nullptr, Qualifiers(), - [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) { - return This->TransformExceptionSpec(TL.getBeginLoc(), ESI, - ExceptionStorage, Changed); - }); -} - -template<typename Derived> template<typename Fn> -QualType TreeTransform<Derived>::TransformFunctionProtoType( - TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext, - Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) { - - // Transform the parameters and return type. - // - // We are required to instantiate the params and return type in source order. - // When the function has a trailing return type, we instantiate the - // parameters before the return type, since the return type can then refer - // to the parameters themselves (via decltype, sizeof, etc.). - // - SmallVector<QualType, 4> ParamTypes; - SmallVector<ParmVarDecl*, 4> ParamDecls; - Sema::ExtParameterInfoBuilder ExtParamInfos; - const FunctionProtoType *T = TL.getTypePtr(); - - QualType ResultType; - - if (T->hasTrailingReturn()) { - if (getDerived().TransformFunctionTypeParams( - TL.getBeginLoc(), TL.getParams(), - TL.getTypePtr()->param_type_begin(), - T->getExtParameterInfosOrNull(), - ParamTypes, &ParamDecls, ExtParamInfos)) - return QualType(); - - { - // C++11 [expr.prim.general]p3: - // If a declaration declares a member function or member function - // template of a class X, the expression this is a prvalue of type - // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq - // and the end of the function-definition, member-declarator, or - // declarator. - Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals); - - ResultType = getDerived().TransformType(TLB, TL.getReturnLoc()); - if (ResultType.isNull()) - return QualType(); - } - } - else { - ResultType = getDerived().TransformType(TLB, TL.getReturnLoc()); - if (ResultType.isNull()) - return QualType(); - - // Return type can not be qualified with an address space. - if (ResultType.getAddressSpace() != LangAS::Default) { - SemaRef.Diag(TL.getReturnLoc().getBeginLoc(), - diag::err_attribute_address_function_type); - return QualType(); - } - - if (getDerived().TransformFunctionTypeParams( - TL.getBeginLoc(), TL.getParams(), - TL.getTypePtr()->param_type_begin(), - T->getExtParameterInfosOrNull(), - ParamTypes, &ParamDecls, ExtParamInfos)) - return QualType(); - } - - FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo(); - - bool EPIChanged = false; - if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged)) - return QualType(); - - // Handle extended parameter information. - if (auto NewExtParamInfos = - ExtParamInfos.getPointerOrNull(ParamTypes.size())) { - if (!EPI.ExtParameterInfos || - llvm::makeArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) - != llvm::makeArrayRef(NewExtParamInfos, ParamTypes.size())) { - EPIChanged = true; - } - EPI.ExtParameterInfos = NewExtParamInfos; - } else if (EPI.ExtParameterInfos) { - EPIChanged = true; - EPI.ExtParameterInfos = nullptr; - } - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() || - T->getParamTypes() != llvm::makeArrayRef(ParamTypes) || EPIChanged) { - Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI); - if (Result.isNull()) - return QualType(); - } - - FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result); - NewTL.setLocalRangeBegin(TL.getLocalRangeBegin()); - NewTL.setLParenLoc(TL.getLParenLoc()); - NewTL.setRParenLoc(TL.getRParenLoc()); - NewTL.setExceptionSpecRange(TL.getExceptionSpecRange()); - NewTL.setLocalRangeEnd(TL.getLocalRangeEnd()); - for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i) - NewTL.setParam(i, ParamDecls[i]); - - return Result; -} - -template<typename Derived> -bool TreeTransform<Derived>::TransformExceptionSpec( - SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI, - SmallVectorImpl<QualType> &Exceptions, bool &Changed) { - assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated); - - // Instantiate a dynamic noexcept expression, if any. - if (isComputedNoexcept(ESI.Type)) { - EnterExpressionEvaluationContext Unevaluated( - getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated); - ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr); - if (NoexceptExpr.isInvalid()) - return true; - - ExceptionSpecificationType EST = ESI.Type; - NoexceptExpr = - getSema().ActOnNoexceptSpec(Loc, NoexceptExpr.get(), EST); - if (NoexceptExpr.isInvalid()) - return true; - - if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type) - Changed = true; - ESI.NoexceptExpr = NoexceptExpr.get(); - ESI.Type = EST; - } - - if (ESI.Type != EST_Dynamic) - return false; - - // Instantiate a dynamic exception specification's type. - for (QualType T : ESI.Exceptions) { - if (const PackExpansionType *PackExpansion = - T->getAs<PackExpansionType>()) { - Changed = true; - - // We have a pack expansion. Instantiate it. - SmallVector<UnexpandedParameterPack, 2> Unexpanded; - SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(), - Unexpanded); - assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); - - // Determine whether the set of unexpanded parameter packs can and - // should - // be expanded. - bool Expand = false; - bool RetainExpansion = false; - Optional<unsigned> NumExpansions = PackExpansion->getNumExpansions(); - // FIXME: Track the location of the ellipsis (and track source location - // information for the types in the exception specification in general). - if (getDerived().TryExpandParameterPacks( - Loc, SourceRange(), Unexpanded, Expand, - RetainExpansion, NumExpansions)) - return true; - - if (!Expand) { - // We can't expand this pack expansion into separate arguments yet; - // just substitute into the pattern and create a new pack expansion - // type. - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); - QualType U = getDerived().TransformType(PackExpansion->getPattern()); - if (U.isNull()) - return true; - - U = SemaRef.Context.getPackExpansionType(U, NumExpansions); - Exceptions.push_back(U); - continue; - } - - // Substitute into the pack expansion pattern for each slice of the - // pack. - for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) { - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx); - - QualType U = getDerived().TransformType(PackExpansion->getPattern()); - if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc)) - return true; - - Exceptions.push_back(U); - } - } else { - QualType U = getDerived().TransformType(T); - if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc)) - return true; - if (T != U) - Changed = true; - - Exceptions.push_back(U); - } - } - - ESI.Exceptions = Exceptions; - if (ESI.Exceptions.empty()) - ESI.Type = EST_DynamicNone; - return false; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformFunctionNoProtoType( - TypeLocBuilder &TLB, - FunctionNoProtoTypeLoc TL) { - const FunctionNoProtoType *T = TL.getTypePtr(); - QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc()); - if (ResultType.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType()) - Result = getDerived().RebuildFunctionNoProtoType(ResultType); - - FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result); - NewTL.setLocalRangeBegin(TL.getLocalRangeBegin()); - NewTL.setLParenLoc(TL.getLParenLoc()); - NewTL.setRParenLoc(TL.getRParenLoc()); - NewTL.setLocalRangeEnd(TL.getLocalRangeEnd()); - - return Result; -} - -template<typename Derived> QualType -TreeTransform<Derived>::TransformUnresolvedUsingType(TypeLocBuilder &TLB, - UnresolvedUsingTypeLoc TL) { - const UnresolvedUsingType *T = TL.getTypePtr(); - Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()); - if (!D) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || D != T->getDecl()) { - Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D); - if (Result.isNull()) - return QualType(); - } - - // We might get an arbitrary type spec type back. We should at - // least always get a type spec type, though. - TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result); - NewTL.setNameLoc(TL.getNameLoc()); - - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB, - TypedefTypeLoc TL) { - const TypedefType *T = TL.getTypePtr(); - TypedefNameDecl *Typedef - = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(), - T->getDecl())); - if (!Typedef) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - Typedef != T->getDecl()) { - Result = getDerived().RebuildTypedefType(Typedef); - if (Result.isNull()) - return QualType(); - } - - TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB, - TypeOfExprTypeLoc TL) { - // typeof expressions are not potentially evaluated contexts - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, - Sema::ReuseLambdaContextDecl); - - ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr()); - if (E.isInvalid()) - return QualType(); - - E = SemaRef.HandleExprEvaluationContextForTypeof(E.get()); - if (E.isInvalid()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - E.get() != TL.getUnderlyingExpr()) { - Result = getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc()); - if (Result.isNull()) - return QualType(); - } - else E.get(); - - TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result); - NewTL.setTypeofLoc(TL.getTypeofLoc()); - NewTL.setLParenLoc(TL.getLParenLoc()); - NewTL.setRParenLoc(TL.getRParenLoc()); - - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB, - TypeOfTypeLoc TL) { - TypeSourceInfo* Old_Under_TI = TL.getUnderlyingTInfo(); - TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI); - if (!New_Under_TI) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) { - Result = getDerived().RebuildTypeOfType(New_Under_TI->getType()); - if (Result.isNull()) - return QualType(); - } - - TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result); - NewTL.setTypeofLoc(TL.getTypeofLoc()); - NewTL.setLParenLoc(TL.getLParenLoc()); - NewTL.setRParenLoc(TL.getRParenLoc()); - NewTL.setUnderlyingTInfo(New_Under_TI); - - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB, - DecltypeTypeLoc TL) { - const DecltypeType *T = TL.getTypePtr(); - - // decltype expressions are not potentially evaluated contexts - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr, - Sema::ExpressionEvaluationContextRecord::EK_Decltype); - - ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr()); - if (E.isInvalid()) - return QualType(); - - E = getSema().ActOnDecltypeExpression(E.get()); - if (E.isInvalid()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - E.get() != T->getUnderlyingExpr()) { - Result = getDerived().RebuildDecltypeType(E.get(), TL.getNameLoc()); - if (Result.isNull()) - return QualType(); - } - else E.get(); - - DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformUnaryTransformType( - TypeLocBuilder &TLB, - UnaryTransformTypeLoc TL) { - QualType Result = TL.getType(); - if (Result->isDependentType()) { - const UnaryTransformType *T = TL.getTypePtr(); - QualType NewBase = - getDerived().TransformType(TL.getUnderlyingTInfo())->getType(); - Result = getDerived().RebuildUnaryTransformType(NewBase, - T->getUTTKind(), - TL.getKWLoc()); - if (Result.isNull()) - return QualType(); - } - - UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result); - NewTL.setKWLoc(TL.getKWLoc()); - NewTL.setParensRange(TL.getParensRange()); - NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo()); - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB, - AutoTypeLoc TL) { - const AutoType *T = TL.getTypePtr(); - QualType OldDeduced = T->getDeducedType(); - QualType NewDeduced; - if (!OldDeduced.isNull()) { - NewDeduced = getDerived().TransformType(OldDeduced); - if (NewDeduced.isNull()) - return QualType(); - } - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced || - T->isDependentType()) { - Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword()); - if (Result.isNull()) - return QualType(); - } - - AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType( - TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) { - const DeducedTemplateSpecializationType *T = TL.getTypePtr(); - - CXXScopeSpec SS; - TemplateName TemplateName = getDerived().TransformTemplateName( - SS, T->getTemplateName(), TL.getTemplateNameLoc()); - if (TemplateName.isNull()) - return QualType(); - - QualType OldDeduced = T->getDeducedType(); - QualType NewDeduced; - if (!OldDeduced.isNull()) { - NewDeduced = getDerived().TransformType(OldDeduced); - if (NewDeduced.isNull()) - return QualType(); - } - - QualType Result = getDerived().RebuildDeducedTemplateSpecializationType( - TemplateName, NewDeduced); - if (Result.isNull()) - return QualType(); - - DeducedTemplateSpecializationTypeLoc NewTL = - TLB.push<DeducedTemplateSpecializationTypeLoc>(Result); - NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); - - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB, - RecordTypeLoc TL) { - const RecordType *T = TL.getTypePtr(); - RecordDecl *Record - = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(), - T->getDecl())); - if (!Record) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - Record != T->getDecl()) { - Result = getDerived().RebuildRecordType(Record); - if (Result.isNull()) - return QualType(); - } - - RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB, - EnumTypeLoc TL) { - const EnumType *T = TL.getTypePtr(); - EnumDecl *Enum - = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(), - T->getDecl())); - if (!Enum) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - Enum != T->getDecl()) { - Result = getDerived().RebuildEnumType(Enum); - if (Result.isNull()) - return QualType(); - } - - EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformInjectedClassNameType( - TypeLocBuilder &TLB, - InjectedClassNameTypeLoc TL) { - Decl *D = getDerived().TransformDecl(TL.getNameLoc(), - TL.getTypePtr()->getDecl()); - if (!D) return QualType(); - - QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D)); - TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc()); - return T; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformTemplateTypeParmType( - TypeLocBuilder &TLB, - TemplateTypeParmTypeLoc TL) { - return TransformTypeSpecType(TLB, TL); -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType( - TypeLocBuilder &TLB, - SubstTemplateTypeParmTypeLoc TL) { - const SubstTemplateTypeParmType *T = TL.getTypePtr(); - - // Substitute into the replacement type, which itself might involve something - // that needs to be transformed. This only tends to occur with default - // template arguments of template template parameters. - TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName()); - QualType Replacement = getDerived().TransformType(T->getReplacementType()); - if (Replacement.isNull()) - return QualType(); - - // Always canonicalize the replacement type. - Replacement = SemaRef.Context.getCanonicalType(Replacement); - QualType Result - = SemaRef.Context.getSubstTemplateTypeParmType(T->getReplacedParameter(), - Replacement); - - // Propagate type-source information. - SubstTemplateTypeParmTypeLoc NewTL - = TLB.push<SubstTemplateTypeParmTypeLoc>(Result); - NewTL.setNameLoc(TL.getNameLoc()); - return Result; - -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType( - TypeLocBuilder &TLB, - SubstTemplateTypeParmPackTypeLoc TL) { - return TransformTypeSpecType(TLB, TL); -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformTemplateSpecializationType( - TypeLocBuilder &TLB, - TemplateSpecializationTypeLoc TL) { - const TemplateSpecializationType *T = TL.getTypePtr(); - - // The nested-name-specifier never matters in a TemplateSpecializationType, - // because we can't have a dependent nested-name-specifier anyway. - CXXScopeSpec SS; - TemplateName Template - = getDerived().TransformTemplateName(SS, T->getTemplateName(), - TL.getTemplateNameLoc()); - if (Template.isNull()) - return QualType(); - - return getDerived().TransformTemplateSpecializationType(TLB, TL, Template); -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB, - AtomicTypeLoc TL) { - QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc()); - if (ValueType.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - ValueType != TL.getValueLoc().getType()) { - Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc()); - if (Result.isNull()) - return QualType(); - } - - AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result); - NewTL.setKWLoc(TL.getKWLoc()); - NewTL.setLParenLoc(TL.getLParenLoc()); - NewTL.setRParenLoc(TL.getRParenLoc()); - - return Result; -} - -template <typename Derived> -QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB, - PipeTypeLoc TL) { - QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc()); - if (ValueType.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) { - const PipeType *PT = Result->getAs<PipeType>(); - bool isReadPipe = PT->isReadOnly(); - Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe); - if (Result.isNull()) - return QualType(); - } - - PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result); - NewTL.setKWLoc(TL.getKWLoc()); - - return Result; -} - - /// Simple iterator that traverses the template arguments in a - /// container that provides a \c getArgLoc() member function. - /// - /// This iterator is intended to be used with the iterator form of - /// \c TreeTransform<Derived>::TransformTemplateArguments(). - template<typename ArgLocContainer> - class TemplateArgumentLocContainerIterator { - ArgLocContainer *Container; - unsigned Index; - - public: - typedef TemplateArgumentLoc value_type; - typedef TemplateArgumentLoc reference; - typedef int difference_type; - typedef std::input_iterator_tag iterator_category; - - class pointer { - TemplateArgumentLoc Arg; - - public: - explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { } - - const TemplateArgumentLoc *operator->() const { - return &Arg; - } - }; - - - TemplateArgumentLocContainerIterator() {} - - TemplateArgumentLocContainerIterator(ArgLocContainer &Container, - unsigned Index) - : Container(&Container), Index(Index) { } - - TemplateArgumentLocContainerIterator &operator++() { - ++Index; - return *this; - } - - TemplateArgumentLocContainerIterator operator++(int) { - TemplateArgumentLocContainerIterator Old(*this); - ++(*this); - return Old; - } - - TemplateArgumentLoc operator*() const { - return Container->getArgLoc(Index); - } - - pointer operator->() const { - return pointer(Container->getArgLoc(Index)); - } - - friend bool operator==(const TemplateArgumentLocContainerIterator &X, - const TemplateArgumentLocContainerIterator &Y) { - return X.Container == Y.Container && X.Index == Y.Index; - } - - friend bool operator!=(const TemplateArgumentLocContainerIterator &X, - const TemplateArgumentLocContainerIterator &Y) { - return !(X == Y); - } - }; - - -template <typename Derived> -QualType TreeTransform<Derived>::TransformTemplateSpecializationType( - TypeLocBuilder &TLB, - TemplateSpecializationTypeLoc TL, - TemplateName Template) { - TemplateArgumentListInfo NewTemplateArgs; - NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); - NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); - typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc> - ArgIterator; - if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), - ArgIterator(TL, TL.getNumArgs()), - NewTemplateArgs)) - return QualType(); - - // FIXME: maybe don't rebuild if all the template arguments are the same. - - QualType Result = - getDerived().RebuildTemplateSpecializationType(Template, - TL.getTemplateNameLoc(), - NewTemplateArgs); - - if (!Result.isNull()) { - // Specializations of template template parameters are represented as - // TemplateSpecializationTypes, and substitution of type alias templates - // within a dependent context can transform them into - // DependentTemplateSpecializationTypes. - if (isa<DependentTemplateSpecializationType>(Result)) { - DependentTemplateSpecializationTypeLoc NewTL - = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); - NewTL.setElaboratedKeywordLoc(SourceLocation()); - NewTL.setQualifierLoc(NestedNameSpecifierLoc()); - NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); - NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); - NewTL.setLAngleLoc(TL.getLAngleLoc()); - NewTL.setRAngleLoc(TL.getRAngleLoc()); - for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) - NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); - return Result; - } - - TemplateSpecializationTypeLoc NewTL - = TLB.push<TemplateSpecializationTypeLoc>(Result); - NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); - NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); - NewTL.setLAngleLoc(TL.getLAngleLoc()); - NewTL.setRAngleLoc(TL.getRAngleLoc()); - for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) - NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); - } - - return Result; -} - -template <typename Derived> -QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType( - TypeLocBuilder &TLB, - DependentTemplateSpecializationTypeLoc TL, - TemplateName Template, - CXXScopeSpec &SS) { - TemplateArgumentListInfo NewTemplateArgs; - NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); - NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); - typedef TemplateArgumentLocContainerIterator< - DependentTemplateSpecializationTypeLoc> ArgIterator; - if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), - ArgIterator(TL, TL.getNumArgs()), - NewTemplateArgs)) - return QualType(); - - // FIXME: maybe don't rebuild if all the template arguments are the same. - - if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { - QualType Result - = getSema().Context.getDependentTemplateSpecializationType( - TL.getTypePtr()->getKeyword(), - DTN->getQualifier(), - DTN->getIdentifier(), - NewTemplateArgs); - - DependentTemplateSpecializationTypeLoc NewTL - = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); - NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); - NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context)); - NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); - NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); - NewTL.setLAngleLoc(TL.getLAngleLoc()); - NewTL.setRAngleLoc(TL.getRAngleLoc()); - for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) - NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); - return Result; - } - - QualType Result - = getDerived().RebuildTemplateSpecializationType(Template, - TL.getTemplateNameLoc(), - NewTemplateArgs); - - if (!Result.isNull()) { - /// FIXME: Wrap this in an elaborated-type-specifier? - TemplateSpecializationTypeLoc NewTL - = TLB.push<TemplateSpecializationTypeLoc>(Result); - NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); - NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); - NewTL.setLAngleLoc(TL.getLAngleLoc()); - NewTL.setRAngleLoc(TL.getRAngleLoc()); - for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) - NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); - } - - return Result; -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB, - ElaboratedTypeLoc TL) { - const ElaboratedType *T = TL.getTypePtr(); - - NestedNameSpecifierLoc QualifierLoc; - // NOTE: the qualifier in an ElaboratedType is optional. - if (TL.getQualifierLoc()) { - QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); - if (!QualifierLoc) - return QualType(); - } - - QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc()); - if (NamedT.isNull()) - return QualType(); - - // C++0x [dcl.type.elab]p2: - // If the identifier resolves to a typedef-name or the simple-template-id - // resolves to an alias template specialization, the - // elaborated-type-specifier is ill-formed. - if (T->getKeyword() != ETK_None && T->getKeyword() != ETK_Typename) { - if (const TemplateSpecializationType *TST = - NamedT->getAs<TemplateSpecializationType>()) { - TemplateName Template = TST->getTemplateName(); - if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>( - Template.getAsTemplateDecl())) { - SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(), - diag::err_tag_reference_non_tag) - << TAT << Sema::NTK_TypeAliasTemplate - << ElaboratedType::getTagTypeKindForKeyword(T->getKeyword()); - SemaRef.Diag(TAT->getLocation(), diag::note_declared_at); - } - } - } - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - QualifierLoc != TL.getQualifierLoc() || - NamedT != T->getNamedType()) { - Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(), - T->getKeyword(), - QualifierLoc, NamedT); - if (Result.isNull()) - return QualType(); - } - - ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); - NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); - NewTL.setQualifierLoc(QualifierLoc); - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformAttributedType( - TypeLocBuilder &TLB, - AttributedTypeLoc TL) { - const AttributedType *oldType = TL.getTypePtr(); - QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc()); - if (modifiedType.isNull()) - return QualType(); - - // oldAttr can be null if we started with a QualType rather than a TypeLoc. - const Attr *oldAttr = TL.getAttr(); - const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr; - if (oldAttr && !newAttr) - return QualType(); - - QualType result = TL.getType(); - - // FIXME: dependent operand expressions? - if (getDerived().AlwaysRebuild() || - modifiedType != oldType->getModifiedType()) { - // TODO: this is really lame; we should really be rebuilding the - // equivalent type from first principles. - QualType equivalentType - = getDerived().TransformType(oldType->getEquivalentType()); - if (equivalentType.isNull()) - return QualType(); - - // Check whether we can add nullability; it is only represented as - // type sugar, and therefore cannot be diagnosed in any other way. - if (auto nullability = oldType->getImmediateNullability()) { - if (!modifiedType->canHaveNullability()) { - SemaRef.Diag(TL.getAttr()->getLocation(), - diag::err_nullability_nonpointer) - << DiagNullabilityKind(*nullability, false) << modifiedType; - return QualType(); - } - } - - result = SemaRef.Context.getAttributedType(TL.getAttrKind(), - modifiedType, - equivalentType); - } - - AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result); - newTL.setAttr(newAttr); - return result; -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB, - ParenTypeLoc TL) { - QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc()); - if (Inner.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - Inner != TL.getInnerLoc().getType()) { - Result = getDerived().RebuildParenType(Inner); - if (Result.isNull()) - return QualType(); - } - - ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result); - NewTL.setLParenLoc(TL.getLParenLoc()); - NewTL.setRParenLoc(TL.getRParenLoc()); - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformDependentNameType( - TypeLocBuilder &TLB, DependentNameTypeLoc TL) { - return TransformDependentNameType(TLB, TL, false); -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformDependentNameType( - TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) { - const DependentNameType *T = TL.getTypePtr(); - - NestedNameSpecifierLoc QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); - if (!QualifierLoc) - return QualType(); - - QualType Result - = getDerived().RebuildDependentNameType(T->getKeyword(), - TL.getElaboratedKeywordLoc(), - QualifierLoc, - T->getIdentifier(), - TL.getNameLoc(), - DeducedTSTContext); - if (Result.isNull()) - return QualType(); - - if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) { - QualType NamedT = ElabT->getNamedType(); - TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc()); - - ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); - NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); - NewTL.setQualifierLoc(QualifierLoc); - } else { - DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result); - NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); - NewTL.setQualifierLoc(QualifierLoc); - NewTL.setNameLoc(TL.getNameLoc()); - } - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>:: - TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, - DependentTemplateSpecializationTypeLoc TL) { - NestedNameSpecifierLoc QualifierLoc; - if (TL.getQualifierLoc()) { - QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); - if (!QualifierLoc) - return QualType(); - } - - return getDerived() - .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc); -} - -template<typename Derived> -QualType TreeTransform<Derived>:: -TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, - DependentTemplateSpecializationTypeLoc TL, - NestedNameSpecifierLoc QualifierLoc) { - const DependentTemplateSpecializationType *T = TL.getTypePtr(); - - TemplateArgumentListInfo NewTemplateArgs; - NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); - NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); - - typedef TemplateArgumentLocContainerIterator< - DependentTemplateSpecializationTypeLoc> ArgIterator; - if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), - ArgIterator(TL, TL.getNumArgs()), - NewTemplateArgs)) - return QualType(); - - QualType Result = getDerived().RebuildDependentTemplateSpecializationType( - T->getKeyword(), QualifierLoc, TL.getTemplateKeywordLoc(), - T->getIdentifier(), TL.getTemplateNameLoc(), NewTemplateArgs, - /*AllowInjectedClassName*/ false); - if (Result.isNull()) - return QualType(); - - if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) { - QualType NamedT = ElabT->getNamedType(); - - // Copy information relevant to the template specialization. - TemplateSpecializationTypeLoc NamedTL - = TLB.push<TemplateSpecializationTypeLoc>(NamedT); - NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); - NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc()); - NamedTL.setLAngleLoc(TL.getLAngleLoc()); - NamedTL.setRAngleLoc(TL.getRAngleLoc()); - for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I) - NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo()); - - // Copy information relevant to the elaborated type. - ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); - NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); - NewTL.setQualifierLoc(QualifierLoc); - } else if (isa<DependentTemplateSpecializationType>(Result)) { - DependentTemplateSpecializationTypeLoc SpecTL - = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); - SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); - SpecTL.setQualifierLoc(QualifierLoc); - SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); - SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc()); - SpecTL.setLAngleLoc(TL.getLAngleLoc()); - SpecTL.setRAngleLoc(TL.getRAngleLoc()); - for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I) - SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo()); - } else { - TemplateSpecializationTypeLoc SpecTL - = TLB.push<TemplateSpecializationTypeLoc>(Result); - SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); - SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc()); - SpecTL.setLAngleLoc(TL.getLAngleLoc()); - SpecTL.setRAngleLoc(TL.getRAngleLoc()); - for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I) - SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo()); - } - return Result; -} - -template<typename Derived> -QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB, - PackExpansionTypeLoc TL) { - QualType Pattern - = getDerived().TransformType(TLB, TL.getPatternLoc()); - if (Pattern.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - Pattern != TL.getPatternLoc().getType()) { - Result = getDerived().RebuildPackExpansionType(Pattern, - TL.getPatternLoc().getSourceRange(), - TL.getEllipsisLoc(), - TL.getTypePtr()->getNumExpansions()); - if (Result.isNull()) - return QualType(); - } - - PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result); - NewT.setEllipsisLoc(TL.getEllipsisLoc()); - return Result; -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB, - ObjCInterfaceTypeLoc TL) { - // ObjCInterfaceType is never dependent. - TLB.pushFullCopy(TL); - return TL.getType(); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB, - ObjCTypeParamTypeLoc TL) { - const ObjCTypeParamType *T = TL.getTypePtr(); - ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>( - getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl())); - if (!OTP) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - OTP != T->getDecl()) { - Result = getDerived().RebuildObjCTypeParamType(OTP, - TL.getProtocolLAngleLoc(), - llvm::makeArrayRef(TL.getTypePtr()->qual_begin(), - TL.getNumProtocols()), - TL.getProtocolLocs(), - TL.getProtocolRAngleLoc()); - if (Result.isNull()) - return QualType(); - } - - ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result); - if (TL.getNumProtocols()) { - NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc()); - for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i) - NewTL.setProtocolLoc(i, TL.getProtocolLoc(i)); - NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc()); - } - return Result; -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB, - ObjCObjectTypeLoc TL) { - // Transform base type. - QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc()); - if (BaseType.isNull()) - return QualType(); - - bool AnyChanged = BaseType != TL.getBaseLoc().getType(); - - // Transform type arguments. - SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos; - for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) { - TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i); - TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc(); - QualType TypeArg = TypeArgInfo->getType(); - if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) { - AnyChanged = true; - - // We have a pack expansion. Instantiate it. - const auto *PackExpansion = PackExpansionLoc.getType() - ->castAs<PackExpansionType>(); - SmallVector<UnexpandedParameterPack, 2> Unexpanded; - SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(), - Unexpanded); - assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); - - // Determine whether the set of unexpanded parameter packs can - // and should be expanded. - TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc(); - bool Expand = false; - bool RetainExpansion = false; - Optional<unsigned> NumExpansions = PackExpansion->getNumExpansions(); - if (getDerived().TryExpandParameterPacks( - PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(), - Unexpanded, Expand, RetainExpansion, NumExpansions)) - return QualType(); - - if (!Expand) { - // We can't expand this pack expansion into separate arguments yet; - // just substitute into the pattern and create a new pack expansion - // type. - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); - - TypeLocBuilder TypeArgBuilder; - TypeArgBuilder.reserve(PatternLoc.getFullDataSize()); - QualType NewPatternType = getDerived().TransformType(TypeArgBuilder, - PatternLoc); - if (NewPatternType.isNull()) - return QualType(); - - QualType NewExpansionType = SemaRef.Context.getPackExpansionType( - NewPatternType, NumExpansions); - auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType); - NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc()); - NewTypeArgInfos.push_back( - TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewExpansionType)); - continue; - } - - // Substitute into the pack expansion pattern for each slice of the - // pack. - for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) { - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), ArgIdx); - - TypeLocBuilder TypeArgBuilder; - TypeArgBuilder.reserve(PatternLoc.getFullDataSize()); - - QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder, - PatternLoc); - if (NewTypeArg.isNull()) - return QualType(); - - NewTypeArgInfos.push_back( - TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg)); - } - - continue; - } - - TypeLocBuilder TypeArgBuilder; - TypeArgBuilder.reserve(TypeArgLoc.getFullDataSize()); - QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder, TypeArgLoc); - if (NewTypeArg.isNull()) - return QualType(); - - // If nothing changed, just keep the old TypeSourceInfo. - if (NewTypeArg == TypeArg) { - NewTypeArgInfos.push_back(TypeArgInfo); - continue; - } - - NewTypeArgInfos.push_back( - TypeArgBuilder.getTypeSourceInfo(SemaRef.Context, NewTypeArg)); - AnyChanged = true; - } - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || AnyChanged) { - // Rebuild the type. - Result = getDerived().RebuildObjCObjectType( - BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos, - TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(), - llvm::makeArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()), - TL.getProtocolLocs(), TL.getProtocolRAngleLoc()); - - if (Result.isNull()) - return QualType(); - } - - ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result); - NewT.setHasBaseTypeAsWritten(true); - NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc()); - for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) - NewT.setTypeArgTInfo(i, NewTypeArgInfos[i]); - NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc()); - NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc()); - for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i) - NewT.setProtocolLoc(i, TL.getProtocolLoc(i)); - NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc()); - return Result; -} - -template<typename Derived> -QualType -TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB, - ObjCObjectPointerTypeLoc TL) { - QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc()); - if (PointeeType.isNull()) - return QualType(); - - QualType Result = TL.getType(); - if (getDerived().AlwaysRebuild() || - PointeeType != TL.getPointeeLoc().getType()) { - Result = getDerived().RebuildObjCObjectPointerType(PointeeType, - TL.getStarLoc()); - if (Result.isNull()) - return QualType(); - } - - ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result); - NewT.setStarLoc(TL.getStarLoc()); - return Result; -} - -//===----------------------------------------------------------------------===// -// Statement transformation -//===----------------------------------------------------------------------===// -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformNullStmt(NullStmt *S) { - return S; -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) { - return getDerived().TransformCompoundStmt(S, false); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S, - bool IsStmtExpr) { - Sema::CompoundScopeRAII CompoundScope(getSema()); - - bool SubStmtInvalid = false; - bool SubStmtChanged = false; - SmallVector<Stmt*, 8> Statements; - for (auto *B : S->body()) { - StmtResult Result = getDerived().TransformStmt(B); - if (Result.isInvalid()) { - // Immediately fail if this was a DeclStmt, since it's very - // likely that this will cause problems for future statements. - if (isa<DeclStmt>(B)) - return StmtError(); - - // Otherwise, just keep processing substatements and fail later. - SubStmtInvalid = true; - continue; - } - - SubStmtChanged = SubStmtChanged || Result.get() != B; - Statements.push_back(Result.getAs<Stmt>()); - } - - if (SubStmtInvalid) - return StmtError(); - - if (!getDerived().AlwaysRebuild() && - !SubStmtChanged) - return S; - - return getDerived().RebuildCompoundStmt(S->getLBracLoc(), - Statements, - S->getRBracLoc(), - IsStmtExpr); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) { - ExprResult LHS, RHS; - { - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated); - - // Transform the left-hand case value. - LHS = getDerived().TransformExpr(S->getLHS()); - LHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), LHS); - if (LHS.isInvalid()) - return StmtError(); - - // Transform the right-hand case value (for the GNU case-range extension). - RHS = getDerived().TransformExpr(S->getRHS()); - RHS = SemaRef.ActOnCaseExpr(S->getCaseLoc(), RHS); - if (RHS.isInvalid()) - return StmtError(); - } - - // Build the case statement. - // Case statements are always rebuilt so that they will attached to their - // transformed switch statement. - StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(), - LHS.get(), - S->getEllipsisLoc(), - RHS.get(), - S->getColonLoc()); - if (Case.isInvalid()) - return StmtError(); - - // Transform the statement following the case - StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt()); - if (SubStmt.isInvalid()) - return StmtError(); - - // Attach the body to the case statement - return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) { - // Transform the statement following the default case - StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt()); - if (SubStmt.isInvalid()) - return StmtError(); - - // Default statements are always rebuilt - return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(), - SubStmt.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) { - StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt()); - if (SubStmt.isInvalid()) - return StmtError(); - - Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(), - S->getDecl()); - if (!LD) - return StmtError(); - - - // FIXME: Pass the real colon location in. - return getDerived().RebuildLabelStmt(S->getIdentLoc(), - cast<LabelDecl>(LD), SourceLocation(), - SubStmt.get()); -} - -template <typename Derived> -const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) { - if (!R) - return R; - - switch (R->getKind()) { -// Transform attributes with a pragma spelling by calling TransformXXXAttr. -#define ATTR(X) -#define PRAGMA_SPELLING_ATTR(X) \ - case attr::X: \ - return getDerived().Transform##X##Attr(cast<X##Attr>(R)); -#include "clang/Basic/AttrList.inc" - default: - return R; - } -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S) { - bool AttrsChanged = false; - SmallVector<const Attr *, 1> Attrs; - - // Visit attributes and keep track if any are transformed. - for (const auto *I : S->getAttrs()) { - const Attr *R = getDerived().TransformAttr(I); - AttrsChanged |= (I != R); - Attrs.push_back(R); - } - - StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt()); - if (SubStmt.isInvalid()) - return StmtError(); - - if (SubStmt.get() == S->getSubStmt() && !AttrsChanged) - return S; - - return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs, - SubStmt.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformIfStmt(IfStmt *S) { - // Transform the initialization statement - StmtResult Init = getDerived().TransformStmt(S->getInit()); - if (Init.isInvalid()) - return StmtError(); - - // Transform the condition - Sema::ConditionResult Cond = getDerived().TransformCondition( - S->getIfLoc(), S->getConditionVariable(), S->getCond(), - S->isConstexpr() ? Sema::ConditionKind::ConstexprIf - : Sema::ConditionKind::Boolean); - if (Cond.isInvalid()) - return StmtError(); - - // If this is a constexpr if, determine which arm we should instantiate. - llvm::Optional<bool> ConstexprConditionValue; - if (S->isConstexpr()) - ConstexprConditionValue = Cond.getKnownValue(); - - // Transform the "then" branch. - StmtResult Then; - if (!ConstexprConditionValue || *ConstexprConditionValue) { - Then = getDerived().TransformStmt(S->getThen()); - if (Then.isInvalid()) - return StmtError(); - } else { - Then = new (getSema().Context) NullStmt(S->getThen()->getBeginLoc()); - } - - // Transform the "else" branch. - StmtResult Else; - if (!ConstexprConditionValue || !*ConstexprConditionValue) { - Else = getDerived().TransformStmt(S->getElse()); - if (Else.isInvalid()) - return StmtError(); - } - - if (!getDerived().AlwaysRebuild() && - Init.get() == S->getInit() && - Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) && - Then.get() == S->getThen() && - Else.get() == S->getElse()) - return S; - - return getDerived().RebuildIfStmt(S->getIfLoc(), S->isConstexpr(), Cond, - Init.get(), Then.get(), S->getElseLoc(), - Else.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) { - // Transform the initialization statement - StmtResult Init = getDerived().TransformStmt(S->getInit()); - if (Init.isInvalid()) - return StmtError(); - - // Transform the condition. - Sema::ConditionResult Cond = getDerived().TransformCondition( - S->getSwitchLoc(), S->getConditionVariable(), S->getCond(), - Sema::ConditionKind::Switch); - if (Cond.isInvalid()) - return StmtError(); - - // Rebuild the switch statement. - StmtResult Switch - = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Init.get(), Cond); - if (Switch.isInvalid()) - return StmtError(); - - // Transform the body of the switch statement. - StmtResult Body = getDerived().TransformStmt(S->getBody()); - if (Body.isInvalid()) - return StmtError(); - - // Complete the switch statement. - return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(), - Body.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) { - // Transform the condition - Sema::ConditionResult Cond = getDerived().TransformCondition( - S->getWhileLoc(), S->getConditionVariable(), S->getCond(), - Sema::ConditionKind::Boolean); - if (Cond.isInvalid()) - return StmtError(); - - // Transform the body - StmtResult Body = getDerived().TransformStmt(S->getBody()); - if (Body.isInvalid()) - return StmtError(); - - if (!getDerived().AlwaysRebuild() && - Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) && - Body.get() == S->getBody()) - return Owned(S); - - return getDerived().RebuildWhileStmt(S->getWhileLoc(), Cond, Body.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformDoStmt(DoStmt *S) { - // Transform the body - StmtResult Body = getDerived().TransformStmt(S->getBody()); - if (Body.isInvalid()) - return StmtError(); - - // Transform the condition - ExprResult Cond = getDerived().TransformExpr(S->getCond()); - if (Cond.isInvalid()) - return StmtError(); - - if (!getDerived().AlwaysRebuild() && - Cond.get() == S->getCond() && - Body.get() == S->getBody()) - return S; - - return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(), - /*FIXME:*/S->getWhileLoc(), Cond.get(), - S->getRParenLoc()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformForStmt(ForStmt *S) { - if (getSema().getLangOpts().OpenMP) - getSema().startOpenMPLoop(); - - // Transform the initialization statement - StmtResult Init = getDerived().TransformStmt(S->getInit()); - if (Init.isInvalid()) - return StmtError(); - - // In OpenMP loop region loop control variable must be captured and be - // private. Perform analysis of first part (if any). - if (getSema().getLangOpts().OpenMP && Init.isUsable()) - getSema().ActOnOpenMPLoopInitialization(S->getForLoc(), Init.get()); - - // Transform the condition - Sema::ConditionResult Cond = getDerived().TransformCondition( - S->getForLoc(), S->getConditionVariable(), S->getCond(), - Sema::ConditionKind::Boolean); - if (Cond.isInvalid()) - return StmtError(); - - // Transform the increment - ExprResult Inc = getDerived().TransformExpr(S->getInc()); - if (Inc.isInvalid()) - return StmtError(); - - Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get())); - if (S->getInc() && !FullInc.get()) - return StmtError(); - - // Transform the body - StmtResult Body = getDerived().TransformStmt(S->getBody()); - if (Body.isInvalid()) - return StmtError(); - - if (!getDerived().AlwaysRebuild() && - Init.get() == S->getInit() && - Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) && - Inc.get() == S->getInc() && - Body.get() == S->getBody()) - return S; - - return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(), - Init.get(), Cond, FullInc, - S->getRParenLoc(), Body.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) { - Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(), - S->getLabel()); - if (!LD) - return StmtError(); - - // Goto statements must always be rebuilt, to resolve the label. - return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(), - cast<LabelDecl>(LD)); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) { - ExprResult Target = getDerived().TransformExpr(S->getTarget()); - if (Target.isInvalid()) - return StmtError(); - Target = SemaRef.MaybeCreateExprWithCleanups(Target.get()); - - if (!getDerived().AlwaysRebuild() && - Target.get() == S->getTarget()) - return S; - - return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(), - Target.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) { - return S; -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) { - return S; -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) { - ExprResult Result = getDerived().TransformInitializer(S->getRetValue(), - /*NotCopyInit*/false); - if (Result.isInvalid()) - return StmtError(); - - // FIXME: We always rebuild the return statement because there is no way - // to tell whether the return type of the function has changed. - return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) { - bool DeclChanged = false; - SmallVector<Decl *, 4> Decls; - for (auto *D : S->decls()) { - Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D); - if (!Transformed) - return StmtError(); - - if (Transformed != D) - DeclChanged = true; - - Decls.push_back(Transformed); - } - - if (!getDerived().AlwaysRebuild() && !DeclChanged) - return S; - - return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) { - - SmallVector<Expr*, 8> Constraints; - SmallVector<Expr*, 8> Exprs; - SmallVector<IdentifierInfo *, 4> Names; - - ExprResult AsmString; - SmallVector<Expr*, 8> Clobbers; - - bool ExprsChanged = false; - - // Go through the outputs. - for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) { - Names.push_back(S->getOutputIdentifier(I)); - - // No need to transform the constraint literal. - Constraints.push_back(S->getOutputConstraintLiteral(I)); - - // Transform the output expr. - Expr *OutputExpr = S->getOutputExpr(I); - ExprResult Result = getDerived().TransformExpr(OutputExpr); - if (Result.isInvalid()) - return StmtError(); - - ExprsChanged |= Result.get() != OutputExpr; - - Exprs.push_back(Result.get()); - } - - // Go through the inputs. - for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) { - Names.push_back(S->getInputIdentifier(I)); - - // No need to transform the constraint literal. - Constraints.push_back(S->getInputConstraintLiteral(I)); - - // Transform the input expr. - Expr *InputExpr = S->getInputExpr(I); - ExprResult Result = getDerived().TransformExpr(InputExpr); - if (Result.isInvalid()) - return StmtError(); - - ExprsChanged |= Result.get() != InputExpr; - - Exprs.push_back(Result.get()); - } - - if (!getDerived().AlwaysRebuild() && !ExprsChanged) - return S; - - // Go through the clobbers. - for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) - Clobbers.push_back(S->getClobberStringLiteral(I)); - - // No need to transform the asm string literal. - AsmString = S->getAsmString(); - return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(), - S->isVolatile(), S->getNumOutputs(), - S->getNumInputs(), Names.data(), - Constraints, Exprs, AsmString.get(), - Clobbers, S->getRParenLoc()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) { - ArrayRef<Token> AsmToks = - llvm::makeArrayRef(S->getAsmToks(), S->getNumAsmToks()); - - bool HadError = false, HadChange = false; - - ArrayRef<Expr*> SrcExprs = S->getAllExprs(); - SmallVector<Expr*, 8> TransformedExprs; - TransformedExprs.reserve(SrcExprs.size()); - for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) { - ExprResult Result = getDerived().TransformExpr(SrcExprs[i]); - if (!Result.isUsable()) { - HadError = true; - } else { - HadChange |= (Result.get() != SrcExprs[i]); - TransformedExprs.push_back(Result.get()); - } - } - - if (HadError) return StmtError(); - if (!HadChange && !getDerived().AlwaysRebuild()) - return Owned(S); - - return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(), - AsmToks, S->getAsmString(), - S->getNumOutputs(), S->getNumInputs(), - S->getAllConstraints(), S->getClobbers(), - TransformedExprs, S->getEndLoc()); -} - -// C++ Coroutines TS - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) { - auto *ScopeInfo = SemaRef.getCurFunction(); - auto *FD = cast<FunctionDecl>(SemaRef.CurContext); - assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise && - ScopeInfo->NeedsCoroutineSuspends && - ScopeInfo->CoroutineSuspends.first == nullptr && - ScopeInfo->CoroutineSuspends.second == nullptr && - "expected clean scope info"); - - // Set that we have (possibly-invalid) suspend points before we do anything - // that may fail. - ScopeInfo->setNeedsCoroutineSuspends(false); - - // The new CoroutinePromise object needs to be built and put into the current - // FunctionScopeInfo before any transformations or rebuilding occurs. - if (!SemaRef.buildCoroutineParameterMoves(FD->getLocation())) - return StmtError(); - auto *Promise = SemaRef.buildCoroutinePromise(FD->getLocation()); - if (!Promise) - return StmtError(); - getDerived().transformedLocalDecl(S->getPromiseDecl(), Promise); - ScopeInfo->CoroutinePromise = Promise; - - // Transform the implicit coroutine statements we built during the initial - // parse. - StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt()); - if (InitSuspend.isInvalid()) - return StmtError(); - StmtResult FinalSuspend = - getDerived().TransformStmt(S->getFinalSuspendStmt()); - if (FinalSuspend.isInvalid()) - return StmtError(); - ScopeInfo->setCoroutineSuspends(InitSuspend.get(), FinalSuspend.get()); - assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get())); - - StmtResult BodyRes = getDerived().TransformStmt(S->getBody()); - if (BodyRes.isInvalid()) - return StmtError(); - - CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get()); - if (Builder.isInvalid()) - return StmtError(); - - Expr *ReturnObject = S->getReturnValueInit(); - assert(ReturnObject && "the return object is expected to be valid"); - ExprResult Res = getDerived().TransformInitializer(ReturnObject, - /*NoCopyInit*/ false); - if (Res.isInvalid()) - return StmtError(); - Builder.ReturnValue = Res.get(); - - if (S->hasDependentPromiseType()) { - assert(!Promise->getType()->isDependentType() && - "the promise type must no longer be dependent"); - assert(!S->getFallthroughHandler() && !S->getExceptionHandler() && - !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() && - "these nodes should not have been built yet"); - if (!Builder.buildDependentStatements()) - return StmtError(); - } else { - if (auto *OnFallthrough = S->getFallthroughHandler()) { - StmtResult Res = getDerived().TransformStmt(OnFallthrough); - if (Res.isInvalid()) - return StmtError(); - Builder.OnFallthrough = Res.get(); - } - - if (auto *OnException = S->getExceptionHandler()) { - StmtResult Res = getDerived().TransformStmt(OnException); - if (Res.isInvalid()) - return StmtError(); - Builder.OnException = Res.get(); - } - - if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) { - StmtResult Res = getDerived().TransformStmt(OnAllocFailure); - if (Res.isInvalid()) - return StmtError(); - Builder.ReturnStmtOnAllocFailure = Res.get(); - } - - // Transform any additional statements we may have already built - assert(S->getAllocate() && S->getDeallocate() && - "allocation and deallocation calls must already be built"); - ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate()); - if (AllocRes.isInvalid()) - return StmtError(); - Builder.Allocate = AllocRes.get(); - - ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate()); - if (DeallocRes.isInvalid()) - return StmtError(); - Builder.Deallocate = DeallocRes.get(); - - assert(S->getResultDecl() && "ResultDecl must already be built"); - StmtResult ResultDecl = getDerived().TransformStmt(S->getResultDecl()); - if (ResultDecl.isInvalid()) - return StmtError(); - Builder.ResultDecl = ResultDecl.get(); - - if (auto *ReturnStmt = S->getReturnStmt()) { - StmtResult Res = getDerived().TransformStmt(ReturnStmt); - if (Res.isInvalid()) - return StmtError(); - Builder.ReturnStmt = Res.get(); - } - } - - return getDerived().RebuildCoroutineBodyStmt(Builder); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) { - ExprResult Result = getDerived().TransformInitializer(S->getOperand(), - /*NotCopyInit*/false); - if (Result.isInvalid()) - return StmtError(); - - // Always rebuild; we don't know if this needs to be injected into a new - // context or if the promise type has changed. - return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(), - S->isImplicit()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) { - ExprResult Result = getDerived().TransformInitializer(E->getOperand(), - /*NotCopyInit*/false); - if (Result.isInvalid()) - return ExprError(); - - // Always rebuild; we don't know if this needs to be injected into a new - // context or if the promise type has changed. - return getDerived().RebuildCoawaitExpr(E->getKeywordLoc(), Result.get(), - E->isImplicit()); -} - -template <typename Derived> -ExprResult -TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) { - ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(), - /*NotCopyInit*/ false); - if (OperandResult.isInvalid()) - return ExprError(); - - ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr( - E->getOperatorCoawaitLookup()); - - if (LookupResult.isInvalid()) - return ExprError(); - - // Always rebuild; we don't know if this needs to be injected into a new - // context or if the promise type has changed. - return getDerived().RebuildDependentCoawaitExpr( - E->getKeywordLoc(), OperandResult.get(), - cast<UnresolvedLookupExpr>(LookupResult.get())); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) { - ExprResult Result = getDerived().TransformInitializer(E->getOperand(), - /*NotCopyInit*/false); - if (Result.isInvalid()) - return ExprError(); - - // Always rebuild; we don't know if this needs to be injected into a new - // context or if the promise type has changed. - return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get()); -} - -// Objective-C Statements. - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) { - // Transform the body of the @try. - StmtResult TryBody = getDerived().TransformStmt(S->getTryBody()); - if (TryBody.isInvalid()) - return StmtError(); - - // Transform the @catch statements (if present). - bool AnyCatchChanged = false; - SmallVector<Stmt*, 8> CatchStmts; - for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) { - StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I)); - if (Catch.isInvalid()) - return StmtError(); - if (Catch.get() != S->getCatchStmt(I)) - AnyCatchChanged = true; - CatchStmts.push_back(Catch.get()); - } - - // Transform the @finally statement (if present). - StmtResult Finally; - if (S->getFinallyStmt()) { - Finally = getDerived().TransformStmt(S->getFinallyStmt()); - if (Finally.isInvalid()) - return StmtError(); - } - - // If nothing changed, just retain this statement. - if (!getDerived().AlwaysRebuild() && - TryBody.get() == S->getTryBody() && - !AnyCatchChanged && - Finally.get() == S->getFinallyStmt()) - return S; - - // Build a new statement. - return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(), - CatchStmts, Finally.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) { - // Transform the @catch parameter, if there is one. - VarDecl *Var = nullptr; - if (VarDecl *FromVar = S->getCatchParamDecl()) { - TypeSourceInfo *TSInfo = nullptr; - if (FromVar->getTypeSourceInfo()) { - TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo()); - if (!TSInfo) - return StmtError(); - } - - QualType T; - if (TSInfo) - T = TSInfo->getType(); - else { - T = getDerived().TransformType(FromVar->getType()); - if (T.isNull()) - return StmtError(); - } - - Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T); - if (!Var) - return StmtError(); - } - - StmtResult Body = getDerived().TransformStmt(S->getCatchBody()); - if (Body.isInvalid()) - return StmtError(); - - return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(), - S->getRParenLoc(), - Var, Body.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) { - // Transform the body. - StmtResult Body = getDerived().TransformStmt(S->getFinallyBody()); - if (Body.isInvalid()) - return StmtError(); - - // If nothing changed, just retain this statement. - if (!getDerived().AlwaysRebuild() && - Body.get() == S->getFinallyBody()) - return S; - - // Build a new statement. - return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(), - Body.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) { - ExprResult Operand; - if (S->getThrowExpr()) { - Operand = getDerived().TransformExpr(S->getThrowExpr()); - if (Operand.isInvalid()) - return StmtError(); - } - - if (!getDerived().AlwaysRebuild() && - Operand.get() == S->getThrowExpr()) - return S; - - return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformObjCAtSynchronizedStmt( - ObjCAtSynchronizedStmt *S) { - // Transform the object we are locking. - ExprResult Object = getDerived().TransformExpr(S->getSynchExpr()); - if (Object.isInvalid()) - return StmtError(); - Object = - getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(), - Object.get()); - if (Object.isInvalid()) - return StmtError(); - - // Transform the body. - StmtResult Body = getDerived().TransformStmt(S->getSynchBody()); - if (Body.isInvalid()) - return StmtError(); - - // If nothing change, just retain the current statement. - if (!getDerived().AlwaysRebuild() && - Object.get() == S->getSynchExpr() && - Body.get() == S->getSynchBody()) - return S; - - // Build a new statement. - return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(), - Object.get(), Body.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt( - ObjCAutoreleasePoolStmt *S) { - // Transform the body. - StmtResult Body = getDerived().TransformStmt(S->getSubStmt()); - if (Body.isInvalid()) - return StmtError(); - - // If nothing changed, just retain this statement. - if (!getDerived().AlwaysRebuild() && - Body.get() == S->getSubStmt()) - return S; - - // Build a new statement. - return getDerived().RebuildObjCAutoreleasePoolStmt( - S->getAtLoc(), Body.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformObjCForCollectionStmt( - ObjCForCollectionStmt *S) { - // Transform the element statement. - StmtResult Element = getDerived().TransformStmt(S->getElement()); - if (Element.isInvalid()) - return StmtError(); - - // Transform the collection expression. - ExprResult Collection = getDerived().TransformExpr(S->getCollection()); - if (Collection.isInvalid()) - return StmtError(); - - // Transform the body. - StmtResult Body = getDerived().TransformStmt(S->getBody()); - if (Body.isInvalid()) - return StmtError(); - - // If nothing changed, just retain this statement. - if (!getDerived().AlwaysRebuild() && - Element.get() == S->getElement() && - Collection.get() == S->getCollection() && - Body.get() == S->getBody()) - return S; - - // Build a new statement. - return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(), - Element.get(), - Collection.get(), - S->getRParenLoc(), - Body.get()); -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) { - // Transform the exception declaration, if any. - VarDecl *Var = nullptr; - if (VarDecl *ExceptionDecl = S->getExceptionDecl()) { - TypeSourceInfo *T = - getDerived().TransformType(ExceptionDecl->getTypeSourceInfo()); - if (!T) - return StmtError(); - - Var = getDerived().RebuildExceptionDecl( - ExceptionDecl, T, ExceptionDecl->getInnerLocStart(), - ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier()); - if (!Var || Var->isInvalidDecl()) - return StmtError(); - } - - // Transform the actual exception handler. - StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock()); - if (Handler.isInvalid()) - return StmtError(); - - if (!getDerived().AlwaysRebuild() && !Var && - Handler.get() == S->getHandlerBlock()) - return S; - - return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get()); -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) { - // Transform the try block itself. - StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock()); - if (TryBlock.isInvalid()) - return StmtError(); - - // Transform the handlers. - bool HandlerChanged = false; - SmallVector<Stmt *, 8> Handlers; - for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) { - StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I)); - if (Handler.isInvalid()) - return StmtError(); - - HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I); - Handlers.push_back(Handler.getAs<Stmt>()); - } - - if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() && - !HandlerChanged) - return S; - - return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(), - Handlers); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) { - StmtResult Init = - S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult(); - if (Init.isInvalid()) - return StmtError(); - - StmtResult Range = getDerived().TransformStmt(S->getRangeStmt()); - if (Range.isInvalid()) - return StmtError(); - - StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt()); - if (Begin.isInvalid()) - return StmtError(); - StmtResult End = getDerived().TransformStmt(S->getEndStmt()); - if (End.isInvalid()) - return StmtError(); - - ExprResult Cond = getDerived().TransformExpr(S->getCond()); - if (Cond.isInvalid()) - return StmtError(); - if (Cond.get()) - Cond = SemaRef.CheckBooleanCondition(S->getColonLoc(), Cond.get()); - if (Cond.isInvalid()) - return StmtError(); - if (Cond.get()) - Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.get()); - - ExprResult Inc = getDerived().TransformExpr(S->getInc()); - if (Inc.isInvalid()) - return StmtError(); - if (Inc.get()) - Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.get()); - - StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt()); - if (LoopVar.isInvalid()) - return StmtError(); - - StmtResult NewStmt = S; - if (getDerived().AlwaysRebuild() || - Init.get() != S->getInit() || - Range.get() != S->getRangeStmt() || - Begin.get() != S->getBeginStmt() || - End.get() != S->getEndStmt() || - Cond.get() != S->getCond() || - Inc.get() != S->getInc() || - LoopVar.get() != S->getLoopVarStmt()) { - NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(), - S->getCoawaitLoc(), Init.get(), - S->getColonLoc(), Range.get(), - Begin.get(), End.get(), - Cond.get(), - Inc.get(), LoopVar.get(), - S->getRParenLoc()); - if (NewStmt.isInvalid()) - return StmtError(); - } - - StmtResult Body = getDerived().TransformStmt(S->getBody()); - if (Body.isInvalid()) - return StmtError(); - - // Body has changed but we didn't rebuild the for-range statement. Rebuild - // it now so we have a new statement to attach the body to. - if (Body.get() != S->getBody() && NewStmt.get() == S) { - NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(), - S->getCoawaitLoc(), Init.get(), - S->getColonLoc(), Range.get(), - Begin.get(), End.get(), - Cond.get(), - Inc.get(), LoopVar.get(), - S->getRParenLoc()); - if (NewStmt.isInvalid()) - return StmtError(); - } - - if (NewStmt.get() == S) - return S; - - return FinishCXXForRangeStmt(NewStmt.get(), Body.get()); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformMSDependentExistsStmt( - MSDependentExistsStmt *S) { - // Transform the nested-name-specifier, if any. - NestedNameSpecifierLoc QualifierLoc; - if (S->getQualifierLoc()) { - QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc()); - if (!QualifierLoc) - return StmtError(); - } - - // Transform the declaration name. - DeclarationNameInfo NameInfo = S->getNameInfo(); - if (NameInfo.getName()) { - NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); - if (!NameInfo.getName()) - return StmtError(); - } - - // Check whether anything changed. - if (!getDerived().AlwaysRebuild() && - QualifierLoc == S->getQualifierLoc() && - NameInfo.getName() == S->getNameInfo().getName()) - return S; - - // Determine whether this name exists, if we can. - CXXScopeSpec SS; - SS.Adopt(QualifierLoc); - bool Dependent = false; - switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) { - case Sema::IER_Exists: - if (S->isIfExists()) - break; - - return new (getSema().Context) NullStmt(S->getKeywordLoc()); - - case Sema::IER_DoesNotExist: - if (S->isIfNotExists()) - break; - - return new (getSema().Context) NullStmt(S->getKeywordLoc()); - - case Sema::IER_Dependent: - Dependent = true; - break; - - case Sema::IER_Error: - return StmtError(); - } - - // We need to continue with the instantiation, so do so now. - StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt()); - if (SubStmt.isInvalid()) - return StmtError(); - - // If we have resolved the name, just transform to the substatement. - if (!Dependent) - return SubStmt; - - // The name is still dependent, so build a dependent expression again. - return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(), - S->isIfExists(), - QualifierLoc, - NameInfo, - SubStmt.get()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) { - NestedNameSpecifierLoc QualifierLoc; - if (E->getQualifierLoc()) { - QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); - if (!QualifierLoc) - return ExprError(); - } - - MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>( - getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl())); - if (!PD) - return ExprError(); - - ExprResult Base = getDerived().TransformExpr(E->getBaseExpr()); - if (Base.isInvalid()) - return ExprError(); - - return new (SemaRef.getASTContext()) - MSPropertyRefExpr(Base.get(), PD, E->isArrow(), - SemaRef.getASTContext().PseudoObjectTy, VK_LValue, - QualifierLoc, E->getMemberLoc()); -} - -template <typename Derived> -ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr( - MSPropertySubscriptExpr *E) { - auto BaseRes = getDerived().TransformExpr(E->getBase()); - if (BaseRes.isInvalid()) - return ExprError(); - auto IdxRes = getDerived().TransformExpr(E->getIdx()); - if (IdxRes.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - BaseRes.get() == E->getBase() && - IdxRes.get() == E->getIdx()) - return E; - - return getDerived().RebuildArraySubscriptExpr( - BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc()); -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) { - StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock()); - if (TryBlock.isInvalid()) - return StmtError(); - - StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler()); - if (Handler.isInvalid()) - return StmtError(); - - if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() && - Handler.get() == S->getHandler()) - return S; - - return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(), - TryBlock.get(), Handler.get()); -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) { - StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock()); - if (Block.isInvalid()) - return StmtError(); - - return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get()); -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) { - ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr()); - if (FilterExpr.isInvalid()) - return StmtError(); - - StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock()); - if (Block.isInvalid()) - return StmtError(); - - return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(), - Block.get()); -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) { - if (isa<SEHFinallyStmt>(Handler)) - return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler)); - else - return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler)); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) { - return S; -} - -//===----------------------------------------------------------------------===// -// OpenMP directive transformation -//===----------------------------------------------------------------------===// -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective( - OMPExecutableDirective *D) { - - // Transform the clauses - llvm::SmallVector<OMPClause *, 16> TClauses; - ArrayRef<OMPClause *> Clauses = D->clauses(); - TClauses.reserve(Clauses.size()); - for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); - I != E; ++I) { - if (*I) { - getDerived().getSema().StartOpenMPClause((*I)->getClauseKind()); - OMPClause *Clause = getDerived().TransformOMPClause(*I); - getDerived().getSema().EndOpenMPClause(); - if (Clause) - TClauses.push_back(Clause); - } else { - TClauses.push_back(nullptr); - } - } - StmtResult AssociatedStmt; - if (D->hasAssociatedStmt() && D->getAssociatedStmt()) { - getDerived().getSema().ActOnOpenMPRegionStart(D->getDirectiveKind(), - /*CurScope=*/nullptr); - StmtResult Body; - { - Sema::CompoundScopeRAII CompoundScope(getSema()); - Stmt *CS = D->getInnermostCapturedStmt()->getCapturedStmt(); - Body = getDerived().TransformStmt(CS); - } - AssociatedStmt = - getDerived().getSema().ActOnOpenMPRegionEnd(Body, TClauses); - if (AssociatedStmt.isInvalid()) { - return StmtError(); - } - } - if (TClauses.size() != Clauses.size()) { - return StmtError(); - } - - // Transform directive name for 'omp critical' directive. - DeclarationNameInfo DirName; - if (D->getDirectiveKind() == OMPD_critical) { - DirName = cast<OMPCriticalDirective>(D)->getDirectiveName(); - DirName = getDerived().TransformDeclarationNameInfo(DirName); - } - OpenMPDirectiveKind CancelRegion = OMPD_unknown; - if (D->getDirectiveKind() == OMPD_cancellation_point) { - CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion(); - } else if (D->getDirectiveKind() == OMPD_cancel) { - CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion(); - } - - return getDerived().RebuildOMPExecutableDirective( - D->getDirectiveKind(), DirName, CancelRegion, TClauses, - AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc()); -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_simd, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_for, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_for_simd, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_sections, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_section, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_single, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_master, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) { - getDerived().getSema().StartOpenMPDSABlock( - OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective( - OMPParallelForDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for, DirName, - nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective( - OMPParallelForSimdDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_for_simd, DirName, - nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective( - OMPParallelSectionsDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_parallel_sections, DirName, - nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_task, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective( - OMPTaskyieldDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_taskyield, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_barrier, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_taskwait, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective( - OMPTaskgroupDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_taskgroup, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_flush, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_ordered, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_atomic, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_target, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective( - OMPTargetDataDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_target_data, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective( - OMPTargetEnterDataDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_target_enter_data, DirName, - nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective( - OMPTargetExitDataDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_target_exit_data, DirName, - nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective( - OMPTargetParallelDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel, DirName, - nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective( - OMPTargetParallelForDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_target_parallel_for, DirName, - nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective( - OMPTargetUpdateDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_target_update, DirName, - nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_teams, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective( - OMPCancellationPointDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_cancellation_point, DirName, - nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_cancel, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective( - OMPTaskLoopSimdDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_taskloop_simd, DirName, - nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective( - OMPDistributeDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective( - OMPDistributeParallelForDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock( - OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective( - OMPDistributeParallelForSimdDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock( - OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective( - OMPDistributeSimdDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_distribute_simd, DirName, - nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective( - OMPTargetParallelForSimdDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock( - OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective( - OMPTargetSimdDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_target_simd, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective( - OMPTeamsDistributeDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_teams_distribute, DirName, - nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective( - OMPTeamsDistributeSimdDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock( - OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective( - OMPTeamsDistributeParallelForSimdDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock( - OMPD_teams_distribute_parallel_for_simd, DirName, nullptr, - D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective( - OMPTeamsDistributeParallelForDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock( - OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc()); - StmtResult Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective( - OMPTargetTeamsDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock(OMPD_target_teams, DirName, - nullptr, D->getBeginLoc()); - auto Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective( - OMPTargetTeamsDistributeDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock( - OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc()); - auto Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective( - OMPTargetTeamsDistributeParallelForDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock( - OMPD_target_teams_distribute_parallel_for, DirName, nullptr, - D->getBeginLoc()); - auto Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult TreeTransform<Derived>:: - TransformOMPTargetTeamsDistributeParallelForSimdDirective( - OMPTargetTeamsDistributeParallelForSimdDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock( - OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr, - D->getBeginLoc()); - auto Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - -template <typename Derived> -StmtResult -TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective( - OMPTargetTeamsDistributeSimdDirective *D) { - DeclarationNameInfo DirName; - getDerived().getSema().StartOpenMPDSABlock( - OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc()); - auto Res = getDerived().TransformOMPExecutableDirective(D); - getDerived().getSema().EndOpenMPDSABlock(Res.get()); - return Res; -} - - -//===----------------------------------------------------------------------===// -// OpenMP clause transformation -//===----------------------------------------------------------------------===// -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) { - ExprResult Cond = getDerived().TransformExpr(C->getCondition()); - if (Cond.isInvalid()) - return nullptr; - return getDerived().RebuildOMPIfClause( - C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(), - C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) { - ExprResult Cond = getDerived().TransformExpr(C->getCondition()); - if (Cond.isInvalid()) - return nullptr; - return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(), - C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) { - ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads()); - if (NumThreads.isInvalid()) - return nullptr; - return getDerived().RebuildOMPNumThreadsClause( - NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) { - ExprResult E = getDerived().TransformExpr(C->getSafelen()); - if (E.isInvalid()) - return nullptr; - return getDerived().RebuildOMPSafelenClause( - E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) { - ExprResult E = getDerived().TransformExpr(C->getSimdlen()); - if (E.isInvalid()) - return nullptr; - return getDerived().RebuildOMPSimdlenClause( - E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) { - ExprResult E = getDerived().TransformExpr(C->getNumForLoops()); - if (E.isInvalid()) - return nullptr; - return getDerived().RebuildOMPCollapseClause( - E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) { - return getDerived().RebuildOMPDefaultClause( - C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(), - C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) { - return getDerived().RebuildOMPProcBindClause( - C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(), - C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) { - ExprResult E = getDerived().TransformExpr(C->getChunkSize()); - if (E.isInvalid()) - return nullptr; - return getDerived().RebuildOMPScheduleClause( - C->getFirstScheduleModifier(), C->getSecondScheduleModifier(), - C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(), - C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(), - C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) { - ExprResult E; - if (auto *Num = C->getNumForLoops()) { - E = getDerived().TransformExpr(Num); - if (E.isInvalid()) - return nullptr; - } - return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(), - C->getLParenLoc(), E.get()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) { - // No need to rebuild this clause, no template-dependent parameters. - return C; -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) { - // No need to rebuild this clause, no template-dependent parameters. - return C; -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) { - // No need to rebuild this clause, no template-dependent parameters. - return C; -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) { - // No need to rebuild this clause, no template-dependent parameters. - return C; -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) { - // No need to rebuild this clause, no template-dependent parameters. - return C; -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) { - // No need to rebuild this clause, no template-dependent parameters. - return C; -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) { - // No need to rebuild this clause, no template-dependent parameters. - return C; -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) { - // No need to rebuild this clause, no template-dependent parameters. - return C; -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) { - // No need to rebuild this clause, no template-dependent parameters. - return C; -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) { - // No need to rebuild this clause, no template-dependent parameters. - return C; -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) { - // No need to rebuild this clause, no template-dependent parameters. - return C; -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause( - OMPUnifiedAddressClause *C) { - llvm_unreachable("unified_address clause cannot appear in dependent context"); -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause( - OMPUnifiedSharedMemoryClause *C) { - llvm_unreachable( - "unified_shared_memory clause cannot appear in dependent context"); -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause( - OMPReverseOffloadClause *C) { - llvm_unreachable("reverse_offload clause cannot appear in dependent context"); -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause( - OMPDynamicAllocatorsClause *C) { - llvm_unreachable( - "dynamic_allocators clause cannot appear in dependent context"); -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause( - OMPAtomicDefaultMemOrderClause *C) { - llvm_unreachable( - "atomic_default_mem_order clause cannot appear in dependent context"); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - return getDerived().RebuildOMPPrivateClause( - Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause( - OMPFirstprivateClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - return getDerived().RebuildOMPFirstprivateClause( - Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - return getDerived().RebuildOMPLastprivateClause( - Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(), - C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - CXXScopeSpec ReductionIdScopeSpec; - ReductionIdScopeSpec.Adopt(C->getQualifierLoc()); - - DeclarationNameInfo NameInfo = C->getNameInfo(); - if (NameInfo.getName()) { - NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); - if (!NameInfo.getName()) - return nullptr; - } - // Build a list of all UDR decls with the same names ranged by the Scopes. - // The Scope boundary is a duplication of the previous decl. - llvm::SmallVector<Expr *, 16> UnresolvedReductions; - for (auto *E : C->reduction_ops()) { - // Transform all the decls. - if (E) { - auto *ULE = cast<UnresolvedLookupExpr>(E); - UnresolvedSet<8> Decls; - for (auto *D : ULE->decls()) { - NamedDecl *InstD = - cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D)); - Decls.addDecl(InstD, InstD->getAccess()); - } - UnresolvedReductions.push_back( - UnresolvedLookupExpr::Create( - SemaRef.Context, /*NamingClass=*/nullptr, - ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), - NameInfo, /*ADL=*/true, ULE->isOverloaded(), - Decls.begin(), Decls.end())); - } else - UnresolvedReductions.push_back(nullptr); - } - return getDerived().RebuildOMPReductionClause( - Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), - C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions); -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause( - OMPTaskReductionClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - CXXScopeSpec ReductionIdScopeSpec; - ReductionIdScopeSpec.Adopt(C->getQualifierLoc()); - - DeclarationNameInfo NameInfo = C->getNameInfo(); - if (NameInfo.getName()) { - NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); - if (!NameInfo.getName()) - return nullptr; - } - // Build a list of all UDR decls with the same names ranged by the Scopes. - // The Scope boundary is a duplication of the previous decl. - llvm::SmallVector<Expr *, 16> UnresolvedReductions; - for (auto *E : C->reduction_ops()) { - // Transform all the decls. - if (E) { - auto *ULE = cast<UnresolvedLookupExpr>(E); - UnresolvedSet<8> Decls; - for (auto *D : ULE->decls()) { - NamedDecl *InstD = - cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D)); - Decls.addDecl(InstD, InstD->getAccess()); - } - UnresolvedReductions.push_back(UnresolvedLookupExpr::Create( - SemaRef.Context, /*NamingClass=*/nullptr, - ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo, - /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end())); - } else - UnresolvedReductions.push_back(nullptr); - } - return getDerived().RebuildOMPTaskReductionClause( - Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), - C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - CXXScopeSpec ReductionIdScopeSpec; - ReductionIdScopeSpec.Adopt(C->getQualifierLoc()); - - DeclarationNameInfo NameInfo = C->getNameInfo(); - if (NameInfo.getName()) { - NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); - if (!NameInfo.getName()) - return nullptr; - } - // Build a list of all UDR decls with the same names ranged by the Scopes. - // The Scope boundary is a duplication of the previous decl. - llvm::SmallVector<Expr *, 16> UnresolvedReductions; - for (auto *E : C->reduction_ops()) { - // Transform all the decls. - if (E) { - auto *ULE = cast<UnresolvedLookupExpr>(E); - UnresolvedSet<8> Decls; - for (auto *D : ULE->decls()) { - NamedDecl *InstD = - cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D)); - Decls.addDecl(InstD, InstD->getAccess()); - } - UnresolvedReductions.push_back(UnresolvedLookupExpr::Create( - SemaRef.Context, /*NamingClass=*/nullptr, - ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo, - /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end())); - } else - UnresolvedReductions.push_back(nullptr); - } - return getDerived().RebuildOMPInReductionClause( - Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), - C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - ExprResult Step = getDerived().TransformExpr(C->getStep()); - if (Step.isInvalid()) - return nullptr; - return getDerived().RebuildOMPLinearClause( - Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(), - C->getModifierLoc(), C->getColonLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - ExprResult Alignment = getDerived().TransformExpr(C->getAlignment()); - if (Alignment.isInvalid()) - return nullptr; - return getDerived().RebuildOMPAlignedClause( - Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(), - C->getColonLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(), - C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - return getDerived().RebuildOMPCopyprivateClause( - Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(), - C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - return getDerived().RebuildOMPDependClause( - C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(), Vars, - C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) { - ExprResult E = getDerived().TransformExpr(C->getDevice()); - if (E.isInvalid()) - return nullptr; - return getDerived().RebuildOMPDeviceClause(E.get(), C->getBeginLoc(), - C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - return getDerived().RebuildOMPMapClause( - C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), C->getMapType(), - C->isImplicitMapType(), C->getMapLoc(), C->getColonLoc(), Vars, - C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) { - ExprResult E = getDerived().TransformExpr(C->getNumTeams()); - if (E.isInvalid()) - return nullptr; - return getDerived().RebuildOMPNumTeamsClause( - E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) { - ExprResult E = getDerived().TransformExpr(C->getThreadLimit()); - if (E.isInvalid()) - return nullptr; - return getDerived().RebuildOMPThreadLimitClause( - E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) { - ExprResult E = getDerived().TransformExpr(C->getPriority()); - if (E.isInvalid()) - return nullptr; - return getDerived().RebuildOMPPriorityClause( - E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) { - ExprResult E = getDerived().TransformExpr(C->getGrainsize()); - if (E.isInvalid()) - return nullptr; - return getDerived().RebuildOMPGrainsizeClause( - E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) { - ExprResult E = getDerived().TransformExpr(C->getNumTasks()); - if (E.isInvalid()) - return nullptr; - return getDerived().RebuildOMPNumTasksClause( - E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) { - ExprResult E = getDerived().TransformExpr(C->getHint()); - if (E.isInvalid()) - return nullptr; - return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(), - C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause( - OMPDistScheduleClause *C) { - ExprResult E = getDerived().TransformExpr(C->getChunkSize()); - if (E.isInvalid()) - return nullptr; - return getDerived().RebuildOMPDistScheduleClause( - C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(), - C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) { - return C; -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return 0; - Vars.push_back(EVar.get()); - } - return getDerived().RebuildOMPToClause(Vars, C->getBeginLoc(), - C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return 0; - Vars.push_back(EVar.get()); - } - return getDerived().RebuildOMPFromClause(Vars, C->getBeginLoc(), - C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause( - OMPUseDevicePtrClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - return getDerived().RebuildOMPUseDevicePtrClause( - Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -template <typename Derived> -OMPClause * -TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) { - llvm::SmallVector<Expr *, 16> Vars; - Vars.reserve(C->varlist_size()); - for (auto *VE : C->varlists()) { - ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE)); - if (EVar.isInvalid()) - return nullptr; - Vars.push_back(EVar.get()); - } - return getDerived().RebuildOMPIsDevicePtrClause( - Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc()); -} - -//===----------------------------------------------------------------------===// -// Expression transformation -//===----------------------------------------------------------------------===// -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) { - return TransformExpr(E->getSubExpr()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) { - if (!E->isTypeDependent()) - return E; - - return getDerived().RebuildPredefinedExpr(E->getLocation(), - E->getIdentKind()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) { - NestedNameSpecifierLoc QualifierLoc; - if (E->getQualifierLoc()) { - QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); - if (!QualifierLoc) - return ExprError(); - } - - ValueDecl *ND - = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(), - E->getDecl())); - if (!ND) - return ExprError(); - - DeclarationNameInfo NameInfo = E->getNameInfo(); - if (NameInfo.getName()) { - NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); - if (!NameInfo.getName()) - return ExprError(); - } - - if (!getDerived().AlwaysRebuild() && - QualifierLoc == E->getQualifierLoc() && - ND == E->getDecl() && - NameInfo.getName() == E->getDecl()->getDeclName() && - !E->hasExplicitTemplateArgs()) { - - // Mark it referenced in the new context regardless. - // FIXME: this is a bit instantiation-specific. - SemaRef.MarkDeclRefReferenced(E); - - return E; - } - - TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr; - if (E->hasExplicitTemplateArgs()) { - TemplateArgs = &TransArgs; - TransArgs.setLAngleLoc(E->getLAngleLoc()); - TransArgs.setRAngleLoc(E->getRAngleLoc()); - if (getDerived().TransformTemplateArguments(E->getTemplateArgs(), - E->getNumTemplateArgs(), - TransArgs)) - return ExprError(); - } - - return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo, - TemplateArgs); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) { - return E; -} - -template <typename Derived> -ExprResult TreeTransform<Derived>::TransformFixedPointLiteral( - FixedPointLiteral *E) { - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) { - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) { - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) { - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) { - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) { - if (FunctionDecl *FD = E->getDirectCallee()) - SemaRef.MarkFunctionReferenced(E->getBeginLoc(), FD); - return SemaRef.MaybeBindToTemporary(E); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) { - ExprResult ControllingExpr = - getDerived().TransformExpr(E->getControllingExpr()); - if (ControllingExpr.isInvalid()) - return ExprError(); - - SmallVector<Expr *, 4> AssocExprs; - SmallVector<TypeSourceInfo *, 4> AssocTypes; - for (unsigned i = 0; i != E->getNumAssocs(); ++i) { - TypeSourceInfo *TS = E->getAssocTypeSourceInfo(i); - if (TS) { - TypeSourceInfo *AssocType = getDerived().TransformType(TS); - if (!AssocType) - return ExprError(); - AssocTypes.push_back(AssocType); - } else { - AssocTypes.push_back(nullptr); - } - - ExprResult AssocExpr = getDerived().TransformExpr(E->getAssocExpr(i)); - if (AssocExpr.isInvalid()) - return ExprError(); - AssocExprs.push_back(AssocExpr.get()); - } - - return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(), - E->getDefaultLoc(), - E->getRParenLoc(), - ControllingExpr.get(), - AssocTypes, - AssocExprs); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) { - ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); - if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr()) - return E; - - return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(), - E->getRParen()); -} - -/// The operand of a unary address-of operator has special rules: it's -/// allowed to refer to a non-static member of a class even if there's no 'this' -/// object available. -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) { - if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E)) - return getDerived().TransformDependentScopeDeclRefExpr(DRE, true, nullptr); - else - return getDerived().TransformExpr(E); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) { - ExprResult SubExpr; - if (E->getOpcode() == UO_AddrOf) - SubExpr = TransformAddressOfOperand(E->getSubExpr()); - else - SubExpr = TransformExpr(E->getSubExpr()); - if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr()) - return E; - - return getDerived().RebuildUnaryOperator(E->getOperatorLoc(), - E->getOpcode(), - SubExpr.get()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) { - // Transform the type. - TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo()); - if (!Type) - return ExprError(); - - // Transform all of the components into components similar to what the - // parser uses. - // FIXME: It would be slightly more efficient in the non-dependent case to - // just map FieldDecls, rather than requiring the rebuilder to look for - // the fields again. However, __builtin_offsetof is rare enough in - // template code that we don't care. - bool ExprChanged = false; - typedef Sema::OffsetOfComponent Component; - SmallVector<Component, 4> Components; - for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) { - const OffsetOfNode &ON = E->getComponent(I); - Component Comp; - Comp.isBrackets = true; - Comp.LocStart = ON.getSourceRange().getBegin(); - Comp.LocEnd = ON.getSourceRange().getEnd(); - switch (ON.getKind()) { - case OffsetOfNode::Array: { - Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex()); - ExprResult Index = getDerived().TransformExpr(FromIndex); - if (Index.isInvalid()) - return ExprError(); - - ExprChanged = ExprChanged || Index.get() != FromIndex; - Comp.isBrackets = true; - Comp.U.E = Index.get(); - break; - } - - case OffsetOfNode::Field: - case OffsetOfNode::Identifier: - Comp.isBrackets = false; - Comp.U.IdentInfo = ON.getFieldName(); - if (!Comp.U.IdentInfo) - continue; - - break; - - case OffsetOfNode::Base: - // Will be recomputed during the rebuild. - continue; - } - - Components.push_back(Comp); - } - - // If nothing changed, retain the existing expression. - if (!getDerived().AlwaysRebuild() && - Type == E->getTypeSourceInfo() && - !ExprChanged) - return E; - - // Build a new offsetof expression. - return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type, - Components, E->getRParenLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) { - assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) && - "opaque value expression requires transformation"); - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) { - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) { - // Rebuild the syntactic form. The original syntactic form has - // opaque-value expressions in it, so strip those away and rebuild - // the result. This is a really awful way of doing this, but the - // better solution (rebuilding the semantic expressions and - // rebinding OVEs as necessary) doesn't work; we'd need - // TreeTransform to not strip away implicit conversions. - Expr *newSyntacticForm = SemaRef.recreateSyntacticForm(E); - ExprResult result = getDerived().TransformExpr(newSyntacticForm); - if (result.isInvalid()) return ExprError(); - - // If that gives us a pseudo-object result back, the pseudo-object - // expression must have been an lvalue-to-rvalue conversion which we - // should reapply. - if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject)) - result = SemaRef.checkPseudoObjectRValue(result.get()); - - return result; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr( - UnaryExprOrTypeTraitExpr *E) { - if (E->isArgumentType()) { - TypeSourceInfo *OldT = E->getArgumentTypeInfo(); - - TypeSourceInfo *NewT = getDerived().TransformType(OldT); - if (!NewT) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && OldT == NewT) - return E; - - return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(), - E->getKind(), - E->getSourceRange()); - } - - // C++0x [expr.sizeof]p1: - // The operand is either an expression, which is an unevaluated operand - // [...] - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, - Sema::ReuseLambdaContextDecl); - - // Try to recover if we have something like sizeof(T::X) where X is a type. - // Notably, there must be *exactly* one set of parens if X is a type. - TypeSourceInfo *RecoveryTSI = nullptr; - ExprResult SubExpr; - auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr()); - if (auto *DRE = - PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr) - SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr( - PE, DRE, false, &RecoveryTSI); - else - SubExpr = getDerived().TransformExpr(E->getArgumentExpr()); - - if (RecoveryTSI) { - return getDerived().RebuildUnaryExprOrTypeTrait( - RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange()); - } else if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr()) - return E; - - return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(), - E->getOperatorLoc(), - E->getKind(), - E->getSourceRange()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) { - ExprResult LHS = getDerived().TransformExpr(E->getLHS()); - if (LHS.isInvalid()) - return ExprError(); - - ExprResult RHS = getDerived().TransformExpr(E->getRHS()); - if (RHS.isInvalid()) - return ExprError(); - - - if (!getDerived().AlwaysRebuild() && - LHS.get() == E->getLHS() && - RHS.get() == E->getRHS()) - return E; - - return getDerived().RebuildArraySubscriptExpr( - LHS.get(), - /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc()); -} - -template <typename Derived> -ExprResult -TreeTransform<Derived>::TransformOMPArraySectionExpr(OMPArraySectionExpr *E) { - ExprResult Base = getDerived().TransformExpr(E->getBase()); - if (Base.isInvalid()) - return ExprError(); - - ExprResult LowerBound; - if (E->getLowerBound()) { - LowerBound = getDerived().TransformExpr(E->getLowerBound()); - if (LowerBound.isInvalid()) - return ExprError(); - } - - ExprResult Length; - if (E->getLength()) { - Length = getDerived().TransformExpr(E->getLength()); - if (Length.isInvalid()) - return ExprError(); - } - - if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() && - LowerBound.get() == E->getLowerBound() && Length.get() == E->getLength()) - return E; - - return getDerived().RebuildOMPArraySectionExpr( - Base.get(), E->getBase()->getEndLoc(), LowerBound.get(), E->getColonLoc(), - Length.get(), E->getRBracketLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCallExpr(CallExpr *E) { - // Transform the callee. - ExprResult Callee = getDerived().TransformExpr(E->getCallee()); - if (Callee.isInvalid()) - return ExprError(); - - // Transform arguments. - bool ArgChanged = false; - SmallVector<Expr*, 8> Args; - if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, - &ArgChanged)) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - Callee.get() == E->getCallee() && - !ArgChanged) - return SemaRef.MaybeBindToTemporary(E); - - // FIXME: Wrong source location information for the '('. - SourceLocation FakeLParenLoc - = ((Expr *)Callee.get())->getSourceRange().getBegin(); - return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc, - Args, - E->getRParenLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) { - ExprResult Base = getDerived().TransformExpr(E->getBase()); - if (Base.isInvalid()) - return ExprError(); - - NestedNameSpecifierLoc QualifierLoc; - if (E->hasQualifier()) { - QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); - - if (!QualifierLoc) - return ExprError(); - } - SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); - - ValueDecl *Member - = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(), - E->getMemberDecl())); - if (!Member) - return ExprError(); - - NamedDecl *FoundDecl = E->getFoundDecl(); - if (FoundDecl == E->getMemberDecl()) { - FoundDecl = Member; - } else { - FoundDecl = cast_or_null<NamedDecl>( - getDerived().TransformDecl(E->getMemberLoc(), FoundDecl)); - if (!FoundDecl) - return ExprError(); - } - - if (!getDerived().AlwaysRebuild() && - Base.get() == E->getBase() && - QualifierLoc == E->getQualifierLoc() && - Member == E->getMemberDecl() && - FoundDecl == E->getFoundDecl() && - !E->hasExplicitTemplateArgs()) { - - // Mark it referenced in the new context regardless. - // FIXME: this is a bit instantiation-specific. - SemaRef.MarkMemberReferenced(E); - - return E; - } - - TemplateArgumentListInfo TransArgs; - if (E->hasExplicitTemplateArgs()) { - TransArgs.setLAngleLoc(E->getLAngleLoc()); - TransArgs.setRAngleLoc(E->getRAngleLoc()); - if (getDerived().TransformTemplateArguments(E->getTemplateArgs(), - E->getNumTemplateArgs(), - TransArgs)) - return ExprError(); - } - - // FIXME: Bogus source location for the operator - SourceLocation FakeOperatorLoc = - SemaRef.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd()); - - // FIXME: to do this check properly, we will need to preserve the - // first-qualifier-in-scope here, just in case we had a dependent - // base (and therefore couldn't do the check) and a - // nested-name-qualifier (and therefore could do the lookup). - NamedDecl *FirstQualifierInScope = nullptr; - DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo(); - if (MemberNameInfo.getName()) { - MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo); - if (!MemberNameInfo.getName()) - return ExprError(); - } - - return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc, - E->isArrow(), - QualifierLoc, - TemplateKWLoc, - MemberNameInfo, - Member, - FoundDecl, - (E->hasExplicitTemplateArgs() - ? &TransArgs : nullptr), - FirstQualifierInScope); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) { - ExprResult LHS = getDerived().TransformExpr(E->getLHS()); - if (LHS.isInvalid()) - return ExprError(); - - ExprResult RHS = getDerived().TransformExpr(E->getRHS()); - if (RHS.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - LHS.get() == E->getLHS() && - RHS.get() == E->getRHS()) - return E; - - Sema::FPContractStateRAII FPContractState(getSema()); - getSema().FPFeatures = E->getFPFeatures(); - - return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(), - LHS.get(), RHS.get()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCompoundAssignOperator( - CompoundAssignOperator *E) { - return getDerived().TransformBinaryOperator(E); -} - -template<typename Derived> -ExprResult TreeTransform<Derived>:: -TransformBinaryConditionalOperator(BinaryConditionalOperator *e) { - // Just rebuild the common and RHS expressions and see whether we - // get any changes. - - ExprResult commonExpr = getDerived().TransformExpr(e->getCommon()); - if (commonExpr.isInvalid()) - return ExprError(); - - ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr()); - if (rhs.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - commonExpr.get() == e->getCommon() && - rhs.get() == e->getFalseExpr()) - return e; - - return getDerived().RebuildConditionalOperator(commonExpr.get(), - e->getQuestionLoc(), - nullptr, - e->getColonLoc(), - rhs.get()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) { - ExprResult Cond = getDerived().TransformExpr(E->getCond()); - if (Cond.isInvalid()) - return ExprError(); - - ExprResult LHS = getDerived().TransformExpr(E->getLHS()); - if (LHS.isInvalid()) - return ExprError(); - - ExprResult RHS = getDerived().TransformExpr(E->getRHS()); - if (RHS.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - Cond.get() == E->getCond() && - LHS.get() == E->getLHS() && - RHS.get() == E->getRHS()) - return E; - - return getDerived().RebuildConditionalOperator(Cond.get(), - E->getQuestionLoc(), - LHS.get(), - E->getColonLoc(), - RHS.get()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) { - // Implicit casts are eliminated during transformation, since they - // will be recomputed by semantic analysis after transformation. - return getDerived().TransformExpr(E->getSubExprAsWritten()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) { - TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten()); - if (!Type) - return ExprError(); - - ExprResult SubExpr - = getDerived().TransformExpr(E->getSubExprAsWritten()); - if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - Type == E->getTypeInfoAsWritten() && - SubExpr.get() == E->getSubExpr()) - return E; - - return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(), - Type, - E->getRParenLoc(), - SubExpr.get()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) { - TypeSourceInfo *OldT = E->getTypeSourceInfo(); - TypeSourceInfo *NewT = getDerived().TransformType(OldT); - if (!NewT) - return ExprError(); - - ExprResult Init = getDerived().TransformExpr(E->getInitializer()); - if (Init.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - OldT == NewT && - Init.get() == E->getInitializer()) - return SemaRef.MaybeBindToTemporary(E); - - // Note: the expression type doesn't necessarily match the - // type-as-written, but that's okay, because it should always be - // derivable from the initializer. - - return getDerived().RebuildCompoundLiteralExpr( - E->getLParenLoc(), NewT, - /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) { - ExprResult Base = getDerived().TransformExpr(E->getBase()); - if (Base.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - Base.get() == E->getBase()) - return E; - - // FIXME: Bad source location - SourceLocation FakeOperatorLoc = - SemaRef.getLocForEndOfToken(E->getBase()->getEndLoc()); - return getDerived().RebuildExtVectorElementExpr(Base.get(), FakeOperatorLoc, - E->getAccessorLoc(), - E->getAccessor()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) { - if (InitListExpr *Syntactic = E->getSyntacticForm()) - E = Syntactic; - - bool InitChanged = false; - - EnterExpressionEvaluationContext Context( - getSema(), EnterExpressionEvaluationContext::InitList); - - SmallVector<Expr*, 4> Inits; - if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false, - Inits, &InitChanged)) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && !InitChanged) { - // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr - // in some cases. We can't reuse it in general, because the syntactic and - // semantic forms are linked, and we can't know that semantic form will - // match even if the syntactic form does. - } - - return getDerived().RebuildInitList(E->getLBraceLoc(), Inits, - E->getRBraceLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) { - Designation Desig; - - // transform the initializer value - ExprResult Init = getDerived().TransformExpr(E->getInit()); - if (Init.isInvalid()) - return ExprError(); - - // transform the designators. - SmallVector<Expr*, 4> ArrayExprs; - bool ExprChanged = false; - for (const DesignatedInitExpr::Designator &D : E->designators()) { - if (D.isFieldDesignator()) { - Desig.AddDesignator(Designator::getField(D.getFieldName(), - D.getDotLoc(), - D.getFieldLoc())); - if (D.getField()) { - FieldDecl *Field = cast_or_null<FieldDecl>( - getDerived().TransformDecl(D.getFieldLoc(), D.getField())); - if (Field != D.getField()) - // Rebuild the expression when the transformed FieldDecl is - // different to the already assigned FieldDecl. - ExprChanged = true; - } else { - // Ensure that the designator expression is rebuilt when there isn't - // a resolved FieldDecl in the designator as we don't want to assign - // a FieldDecl to a pattern designator that will be instantiated again. - ExprChanged = true; - } - continue; - } - - if (D.isArrayDesignator()) { - ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D)); - if (Index.isInvalid()) - return ExprError(); - - Desig.AddDesignator( - Designator::getArray(Index.get(), D.getLBracketLoc())); - - ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(D); - ArrayExprs.push_back(Index.get()); - continue; - } - - assert(D.isArrayRangeDesignator() && "New kind of designator?"); - ExprResult Start - = getDerived().TransformExpr(E->getArrayRangeStart(D)); - if (Start.isInvalid()) - return ExprError(); - - ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D)); - if (End.isInvalid()) - return ExprError(); - - Desig.AddDesignator(Designator::getArrayRange(Start.get(), - End.get(), - D.getLBracketLoc(), - D.getEllipsisLoc())); - - ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) || - End.get() != E->getArrayRangeEnd(D); - - ArrayExprs.push_back(Start.get()); - ArrayExprs.push_back(End.get()); - } - - if (!getDerived().AlwaysRebuild() && - Init.get() == E->getInit() && - !ExprChanged) - return E; - - return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs, - E->getEqualOrColonLoc(), - E->usesGNUSyntax(), Init.get()); -} - -// Seems that if TransformInitListExpr() only works on the syntactic form of an -// InitListExpr, then a DesignatedInitUpdateExpr is not encountered. -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformDesignatedInitUpdateExpr( - DesignatedInitUpdateExpr *E) { - llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of " - "initializer"); - return ExprError(); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformNoInitExpr( - NoInitExpr *E) { - llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer"); - return ExprError(); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) { - llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer"); - return ExprError(); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) { - llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer"); - return ExprError(); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformImplicitValueInitExpr( - ImplicitValueInitExpr *E) { - TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName()); - - // FIXME: Will we ever have proper type location here? Will we actually - // need to transform the type? - QualType T = getDerived().TransformType(E->getType()); - if (T.isNull()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - T == E->getType()) - return E; - - return getDerived().RebuildImplicitValueInitExpr(T); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) { - TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo()); - if (!TInfo) - return ExprError(); - - ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); - if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - TInfo == E->getWrittenTypeInfo() && - SubExpr.get() == E->getSubExpr()) - return E; - - return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(), - TInfo, E->getRParenLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) { - bool ArgumentChanged = false; - SmallVector<Expr*, 4> Inits; - if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits, - &ArgumentChanged)) - return ExprError(); - - return getDerived().RebuildParenListExpr(E->getLParenLoc(), - Inits, - E->getRParenLoc()); -} - -/// Transform an address-of-label expression. -/// -/// By default, the transformation of an address-of-label expression always -/// rebuilds the expression, so that the label identifier can be resolved to -/// the corresponding label statement by semantic analysis. -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) { - Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(), - E->getLabel()); - if (!LD) - return ExprError(); - - return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(), - cast<LabelDecl>(LD)); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) { - SemaRef.ActOnStartStmtExpr(); - StmtResult SubStmt - = getDerived().TransformCompoundStmt(E->getSubStmt(), true); - if (SubStmt.isInvalid()) { - SemaRef.ActOnStmtExprError(); - return ExprError(); - } - - if (!getDerived().AlwaysRebuild() && - SubStmt.get() == E->getSubStmt()) { - // Calling this an 'error' is unintuitive, but it does the right thing. - SemaRef.ActOnStmtExprError(); - return SemaRef.MaybeBindToTemporary(E); - } - - return getDerived().RebuildStmtExpr(E->getLParenLoc(), - SubStmt.get(), - E->getRParenLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) { - ExprResult Cond = getDerived().TransformExpr(E->getCond()); - if (Cond.isInvalid()) - return ExprError(); - - ExprResult LHS = getDerived().TransformExpr(E->getLHS()); - if (LHS.isInvalid()) - return ExprError(); - - ExprResult RHS = getDerived().TransformExpr(E->getRHS()); - if (RHS.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - Cond.get() == E->getCond() && - LHS.get() == E->getLHS() && - RHS.get() == E->getRHS()) - return E; - - return getDerived().RebuildChooseExpr(E->getBuiltinLoc(), - Cond.get(), LHS.get(), RHS.get(), - E->getRParenLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) { - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) { - switch (E->getOperator()) { - case OO_New: - case OO_Delete: - case OO_Array_New: - case OO_Array_Delete: - llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr"); - - case OO_Call: { - // This is a call to an object's operator(). - assert(E->getNumArgs() >= 1 && "Object call is missing arguments"); - - // Transform the object itself. - ExprResult Object = getDerived().TransformExpr(E->getArg(0)); - if (Object.isInvalid()) - return ExprError(); - - // FIXME: Poor location information - SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken( - static_cast<Expr *>(Object.get())->getEndLoc()); - - // Transform the call arguments. - SmallVector<Expr*, 8> Args; - if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true, - Args)) - return ExprError(); - - return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args, - E->getEndLoc()); - } - -#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ - case OO_##Name: -#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) -#include "clang/Basic/OperatorKinds.def" - case OO_Subscript: - // Handled below. - break; - - case OO_Conditional: - llvm_unreachable("conditional operator is not actually overloadable"); - - case OO_None: - case NUM_OVERLOADED_OPERATORS: - llvm_unreachable("not an overloaded operator?"); - } - - ExprResult Callee = getDerived().TransformExpr(E->getCallee()); - if (Callee.isInvalid()) - return ExprError(); - - ExprResult First; - if (E->getOperator() == OO_Amp) - First = getDerived().TransformAddressOfOperand(E->getArg(0)); - else - First = getDerived().TransformExpr(E->getArg(0)); - if (First.isInvalid()) - return ExprError(); - - ExprResult Second; - if (E->getNumArgs() == 2) { - Second = getDerived().TransformExpr(E->getArg(1)); - if (Second.isInvalid()) - return ExprError(); - } - - if (!getDerived().AlwaysRebuild() && - Callee.get() == E->getCallee() && - First.get() == E->getArg(0) && - (E->getNumArgs() != 2 || Second.get() == E->getArg(1))) - return SemaRef.MaybeBindToTemporary(E); - - Sema::FPContractStateRAII FPContractState(getSema()); - getSema().FPFeatures = E->getFPFeatures(); - - return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(), - E->getOperatorLoc(), - Callee.get(), - First.get(), - Second.get()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) { - return getDerived().TransformCallExpr(E); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) { - // Transform the callee. - ExprResult Callee = getDerived().TransformExpr(E->getCallee()); - if (Callee.isInvalid()) - return ExprError(); - - // Transform exec config. - ExprResult EC = getDerived().TransformCallExpr(E->getConfig()); - if (EC.isInvalid()) - return ExprError(); - - // Transform arguments. - bool ArgChanged = false; - SmallVector<Expr*, 8> Args; - if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, - &ArgChanged)) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - Callee.get() == E->getCallee() && - !ArgChanged) - return SemaRef.MaybeBindToTemporary(E); - - // FIXME: Wrong source location information for the '('. - SourceLocation FakeLParenLoc - = ((Expr *)Callee.get())->getSourceRange().getBegin(); - return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc, - Args, - E->getRParenLoc(), EC.get()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) { - TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten()); - if (!Type) - return ExprError(); - - ExprResult SubExpr - = getDerived().TransformExpr(E->getSubExprAsWritten()); - if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - Type == E->getTypeInfoAsWritten() && - SubExpr.get() == E->getSubExpr()) - return E; - return getDerived().RebuildCXXNamedCastExpr( - E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(), - Type, E->getAngleBrackets().getEnd(), - // FIXME. this should be '(' location - E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) { - return getDerived().TransformCXXNamedCastExpr(E); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) { - return getDerived().TransformCXXNamedCastExpr(E); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXReinterpretCastExpr( - CXXReinterpretCastExpr *E) { - return getDerived().TransformCXXNamedCastExpr(E); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) { - return getDerived().TransformCXXNamedCastExpr(E); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXFunctionalCastExpr( - CXXFunctionalCastExpr *E) { - TypeSourceInfo *Type = - getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten()); - if (!Type) - return ExprError(); - - ExprResult SubExpr - = getDerived().TransformExpr(E->getSubExprAsWritten()); - if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - Type == E->getTypeInfoAsWritten() && - SubExpr.get() == E->getSubExpr()) - return E; - - return getDerived().RebuildCXXFunctionalCastExpr(Type, - E->getLParenLoc(), - SubExpr.get(), - E->getRParenLoc(), - E->isListInitialization()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) { - if (E->isTypeOperand()) { - TypeSourceInfo *TInfo - = getDerived().TransformType(E->getTypeOperandSourceInfo()); - if (!TInfo) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - TInfo == E->getTypeOperandSourceInfo()) - return E; - - return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(), - TInfo, E->getEndLoc()); - } - - // We don't know whether the subexpression is potentially evaluated until - // after we perform semantic analysis. We speculatively assume it is - // unevaluated; it will get fixed later if the subexpression is in fact - // potentially evaluated. - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, - Sema::ReuseLambdaContextDecl); - - ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand()); - if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - SubExpr.get() == E->getExprOperand()) - return E; - - return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(), - SubExpr.get(), E->getEndLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) { - if (E->isTypeOperand()) { - TypeSourceInfo *TInfo - = getDerived().TransformType(E->getTypeOperandSourceInfo()); - if (!TInfo) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - TInfo == E->getTypeOperandSourceInfo()) - return E; - - return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(), - TInfo, E->getEndLoc()); - } - - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); - - ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand()); - if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - SubExpr.get() == E->getExprOperand()) - return E; - - return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(), - SubExpr.get(), E->getEndLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr( - CXXNullPtrLiteralExpr *E) { - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) { - QualType T = getSema().getCurrentThisType(); - - if (!getDerived().AlwaysRebuild() && T == E->getType()) { - // Make sure that we capture 'this'. - getSema().CheckCXXThisCapture(E->getBeginLoc()); - return E; - } - - return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) { - ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); - if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - SubExpr.get() == E->getSubExpr()) - return E; - - return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(), - E->isThrownVariableInScope()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) { - ParmVarDecl *Param = cast_or_null<ParmVarDecl>( - getDerived().TransformDecl(E->getBeginLoc(), E->getParam())); - if (!Param) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - Param == E->getParam()) - return E; - - return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) { - FieldDecl *Field = cast_or_null<FieldDecl>( - getDerived().TransformDecl(E->getBeginLoc(), E->getField())); - if (!Field) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && Field == E->getField()) - return E; - - return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXScalarValueInitExpr( - CXXScalarValueInitExpr *E) { - TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo()); - if (!T) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - T == E->getTypeSourceInfo()) - return E; - - return getDerived().RebuildCXXScalarValueInitExpr(T, - /*FIXME:*/T->getTypeLoc().getEndLoc(), - E->getRParenLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) { - // Transform the type that we're allocating - TypeSourceInfo *AllocTypeInfo = - getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo()); - if (!AllocTypeInfo) - return ExprError(); - - // Transform the size of the array we're allocating (if any). - ExprResult ArraySize = getDerived().TransformExpr(E->getArraySize()); - if (ArraySize.isInvalid()) - return ExprError(); - - // Transform the placement arguments (if any). - bool ArgumentChanged = false; - SmallVector<Expr*, 8> PlacementArgs; - if (getDerived().TransformExprs(E->getPlacementArgs(), - E->getNumPlacementArgs(), true, - PlacementArgs, &ArgumentChanged)) - return ExprError(); - - // Transform the initializer (if any). - Expr *OldInit = E->getInitializer(); - ExprResult NewInit; - if (OldInit) - NewInit = getDerived().TransformInitializer(OldInit, true); - if (NewInit.isInvalid()) - return ExprError(); - - // Transform new operator and delete operator. - FunctionDecl *OperatorNew = nullptr; - if (E->getOperatorNew()) { - OperatorNew = cast_or_null<FunctionDecl>( - getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew())); - if (!OperatorNew) - return ExprError(); - } - - FunctionDecl *OperatorDelete = nullptr; - if (E->getOperatorDelete()) { - OperatorDelete = cast_or_null<FunctionDecl>( - getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete())); - if (!OperatorDelete) - return ExprError(); - } - - if (!getDerived().AlwaysRebuild() && - AllocTypeInfo == E->getAllocatedTypeSourceInfo() && - ArraySize.get() == E->getArraySize() && - NewInit.get() == OldInit && - OperatorNew == E->getOperatorNew() && - OperatorDelete == E->getOperatorDelete() && - !ArgumentChanged) { - // Mark any declarations we need as referenced. - // FIXME: instantiation-specific. - if (OperatorNew) - SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorNew); - if (OperatorDelete) - SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete); - - if (E->isArray() && !E->getAllocatedType()->isDependentType()) { - QualType ElementType - = SemaRef.Context.getBaseElementType(E->getAllocatedType()); - if (const RecordType *RecordT = ElementType->getAs<RecordType>()) { - CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl()); - if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) { - SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor); - } - } - } - - return E; - } - - QualType AllocType = AllocTypeInfo->getType(); - if (!ArraySize.get()) { - // If no array size was specified, but the new expression was - // instantiated with an array type (e.g., "new T" where T is - // instantiated with "int[4]"), extract the outer bound from the - // array type as our array size. We do this with constant and - // dependently-sized array types. - const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType); - if (!ArrayT) { - // Do nothing - } else if (const ConstantArrayType *ConsArrayT - = dyn_cast<ConstantArrayType>(ArrayT)) { - ArraySize = IntegerLiteral::Create(SemaRef.Context, ConsArrayT->getSize(), - SemaRef.Context.getSizeType(), - /*FIXME:*/ E->getBeginLoc()); - AllocType = ConsArrayT->getElementType(); - } else if (const DependentSizedArrayType *DepArrayT - = dyn_cast<DependentSizedArrayType>(ArrayT)) { - if (DepArrayT->getSizeExpr()) { - ArraySize = DepArrayT->getSizeExpr(); - AllocType = DepArrayT->getElementType(); - } - } - } - - return getDerived().RebuildCXXNewExpr( - E->getBeginLoc(), E->isGlobalNew(), - /*FIXME:*/ E->getBeginLoc(), PlacementArgs, - /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType, - AllocTypeInfo, ArraySize.get(), E->getDirectInitRange(), NewInit.get()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) { - ExprResult Operand = getDerived().TransformExpr(E->getArgument()); - if (Operand.isInvalid()) - return ExprError(); - - // Transform the delete operator, if known. - FunctionDecl *OperatorDelete = nullptr; - if (E->getOperatorDelete()) { - OperatorDelete = cast_or_null<FunctionDecl>( - getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete())); - if (!OperatorDelete) - return ExprError(); - } - - if (!getDerived().AlwaysRebuild() && - Operand.get() == E->getArgument() && - OperatorDelete == E->getOperatorDelete()) { - // Mark any declarations we need as referenced. - // FIXME: instantiation-specific. - if (OperatorDelete) - SemaRef.MarkFunctionReferenced(E->getBeginLoc(), OperatorDelete); - - if (!E->getArgument()->isTypeDependent()) { - QualType Destroyed = SemaRef.Context.getBaseElementType( - E->getDestroyedType()); - if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) { - CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl()); - SemaRef.MarkFunctionReferenced(E->getBeginLoc(), - SemaRef.LookupDestructor(Record)); - } - } - - return E; - } - - return getDerived().RebuildCXXDeleteExpr( - E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXPseudoDestructorExpr( - CXXPseudoDestructorExpr *E) { - ExprResult Base = getDerived().TransformExpr(E->getBase()); - if (Base.isInvalid()) - return ExprError(); - - ParsedType ObjectTypePtr; - bool MayBePseudoDestructor = false; - Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(), - E->getOperatorLoc(), - E->isArrow()? tok::arrow : tok::period, - ObjectTypePtr, - MayBePseudoDestructor); - if (Base.isInvalid()) - return ExprError(); - - QualType ObjectType = ObjectTypePtr.get(); - NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc(); - if (QualifierLoc) { - QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType); - if (!QualifierLoc) - return ExprError(); - } - CXXScopeSpec SS; - SS.Adopt(QualifierLoc); - - PseudoDestructorTypeStorage Destroyed; - if (E->getDestroyedTypeInfo()) { - TypeSourceInfo *DestroyedTypeInfo - = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(), - ObjectType, nullptr, SS); - if (!DestroyedTypeInfo) - return ExprError(); - Destroyed = DestroyedTypeInfo; - } else if (!ObjectType.isNull() && ObjectType->isDependentType()) { - // We aren't likely to be able to resolve the identifier down to a type - // now anyway, so just retain the identifier. - Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(), - E->getDestroyedTypeLoc()); - } else { - // Look for a destructor known with the given name. - ParsedType T = SemaRef.getDestructorName(E->getTildeLoc(), - *E->getDestroyedTypeIdentifier(), - E->getDestroyedTypeLoc(), - /*Scope=*/nullptr, - SS, ObjectTypePtr, - false); - if (!T) - return ExprError(); - - Destroyed - = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T), - E->getDestroyedTypeLoc()); - } - - TypeSourceInfo *ScopeTypeInfo = nullptr; - if (E->getScopeTypeInfo()) { - CXXScopeSpec EmptySS; - ScopeTypeInfo = getDerived().TransformTypeInObjectScope( - E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS); - if (!ScopeTypeInfo) - return ExprError(); - } - - return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(), - E->getOperatorLoc(), - E->isArrow(), - SS, - ScopeTypeInfo, - E->getColonColonLoc(), - E->getTildeLoc(), - Destroyed); -} - -template <typename Derived> -bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old, - bool RequiresADL, - LookupResult &R) { - // Transform all the decls. - bool AllEmptyPacks = true; - for (auto *OldD : Old->decls()) { - Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD); - if (!InstD) { - // Silently ignore these if a UsingShadowDecl instantiated to nothing. - // This can happen because of dependent hiding. - if (isa<UsingShadowDecl>(OldD)) - continue; - else { - R.clear(); - return true; - } - } - - // Expand using pack declarations. - NamedDecl *SingleDecl = cast<NamedDecl>(InstD); - ArrayRef<NamedDecl*> Decls = SingleDecl; - if (auto *UPD = dyn_cast<UsingPackDecl>(InstD)) - Decls = UPD->expansions(); - - // Expand using declarations. - for (auto *D : Decls) { - if (auto *UD = dyn_cast<UsingDecl>(D)) { - for (auto *SD : UD->shadows()) - R.addDecl(SD); - } else { - R.addDecl(D); - } - } - - AllEmptyPacks &= Decls.empty(); - }; - - // C++ [temp.res]/8.4.2: - // The program is ill-formed, no diagnostic required, if [...] lookup for - // a name in the template definition found a using-declaration, but the - // lookup in the corresponding scope in the instantiation odoes not find - // any declarations because the using-declaration was a pack expansion and - // the corresponding pack is empty - if (AllEmptyPacks && !RequiresADL) { - getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty) - << isa<UnresolvedMemberExpr>(Old) << Old->getName(); - return true; - } - - // Resolve a kind, but don't do any further analysis. If it's - // ambiguous, the callee needs to deal with it. - R.resolveKind(); - return false; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformUnresolvedLookupExpr( - UnresolvedLookupExpr *Old) { - LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(), - Sema::LookupOrdinaryName); - - // Transform the declaration set. - if (TransformOverloadExprDecls(Old, Old->requiresADL(), R)) - return ExprError(); - - // Rebuild the nested-name qualifier, if present. - CXXScopeSpec SS; - if (Old->getQualifierLoc()) { - NestedNameSpecifierLoc QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc()); - if (!QualifierLoc) - return ExprError(); - - SS.Adopt(QualifierLoc); - } - - if (Old->getNamingClass()) { - CXXRecordDecl *NamingClass - = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl( - Old->getNameLoc(), - Old->getNamingClass())); - if (!NamingClass) { - R.clear(); - return ExprError(); - } - - R.setNamingClass(NamingClass); - } - - SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc(); - - // If we have neither explicit template arguments, nor the template keyword, - // it's a normal declaration name or member reference. - if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) { - NamedDecl *D = R.getAsSingle<NamedDecl>(); - // In a C++11 unevaluated context, an UnresolvedLookupExpr might refer to an - // instance member. In other contexts, BuildPossibleImplicitMemberExpr will - // give a good diagnostic. - if (D && D->isCXXInstanceMember()) { - return SemaRef.BuildPossibleImplicitMemberExpr(SS, TemplateKWLoc, R, - /*TemplateArgs=*/nullptr, - /*Scope=*/nullptr); - } - - return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL()); - } - - // If we have template arguments, rebuild them, then rebuild the - // templateid expression. - TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc()); - if (Old->hasExplicitTemplateArgs() && - getDerived().TransformTemplateArguments(Old->getTemplateArgs(), - Old->getNumTemplateArgs(), - TransArgs)) { - R.clear(); - return ExprError(); - } - - return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R, - Old->requiresADL(), &TransArgs); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) { - bool ArgChanged = false; - SmallVector<TypeSourceInfo *, 4> Args; - for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) { - TypeSourceInfo *From = E->getArg(I); - TypeLoc FromTL = From->getTypeLoc(); - if (!FromTL.getAs<PackExpansionTypeLoc>()) { - TypeLocBuilder TLB; - TLB.reserve(FromTL.getFullDataSize()); - QualType To = getDerived().TransformType(TLB, FromTL); - if (To.isNull()) - return ExprError(); - - if (To == From->getType()) - Args.push_back(From); - else { - Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); - ArgChanged = true; - } - continue; - } - - ArgChanged = true; - - // We have a pack expansion. Instantiate it. - PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>(); - TypeLoc PatternTL = ExpansionTL.getPatternLoc(); - SmallVector<UnexpandedParameterPack, 2> Unexpanded; - SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded); - - // Determine whether the set of unexpanded parameter packs can and should - // be expanded. - bool Expand = true; - bool RetainExpansion = false; - Optional<unsigned> OrigNumExpansions = - ExpansionTL.getTypePtr()->getNumExpansions(); - Optional<unsigned> NumExpansions = OrigNumExpansions; - if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(), - PatternTL.getSourceRange(), - Unexpanded, - Expand, RetainExpansion, - NumExpansions)) - return ExprError(); - - if (!Expand) { - // The transform has determined that we should perform a simple - // transformation on the pack expansion, producing another pack - // expansion. - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); - - TypeLocBuilder TLB; - TLB.reserve(From->getTypeLoc().getFullDataSize()); - - QualType To = getDerived().TransformType(TLB, PatternTL); - if (To.isNull()) - return ExprError(); - - To = getDerived().RebuildPackExpansionType(To, - PatternTL.getSourceRange(), - ExpansionTL.getEllipsisLoc(), - NumExpansions); - if (To.isNull()) - return ExprError(); - - PackExpansionTypeLoc ToExpansionTL - = TLB.push<PackExpansionTypeLoc>(To); - ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc()); - Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); - continue; - } - - // Expand the pack expansion by substituting for each argument in the - // pack(s). - for (unsigned I = 0; I != *NumExpansions; ++I) { - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I); - TypeLocBuilder TLB; - TLB.reserve(PatternTL.getFullDataSize()); - QualType To = getDerived().TransformType(TLB, PatternTL); - if (To.isNull()) - return ExprError(); - - if (To->containsUnexpandedParameterPack()) { - To = getDerived().RebuildPackExpansionType(To, - PatternTL.getSourceRange(), - ExpansionTL.getEllipsisLoc(), - NumExpansions); - if (To.isNull()) - return ExprError(); - - PackExpansionTypeLoc ToExpansionTL - = TLB.push<PackExpansionTypeLoc>(To); - ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc()); - } - - Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); - } - - if (!RetainExpansion) - continue; - - // If we're supposed to retain a pack expansion, do so by temporarily - // forgetting the partially-substituted parameter pack. - ForgetPartiallySubstitutedPackRAII Forget(getDerived()); - - TypeLocBuilder TLB; - TLB.reserve(From->getTypeLoc().getFullDataSize()); - - QualType To = getDerived().TransformType(TLB, PatternTL); - if (To.isNull()) - return ExprError(); - - To = getDerived().RebuildPackExpansionType(To, - PatternTL.getSourceRange(), - ExpansionTL.getEllipsisLoc(), - NumExpansions); - if (To.isNull()) - return ExprError(); - - PackExpansionTypeLoc ToExpansionTL - = TLB.push<PackExpansionTypeLoc>(To); - ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc()); - Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); - } - - if (!getDerived().AlwaysRebuild() && !ArgChanged) - return E; - - return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args, - E->getEndLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { - TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo()); - if (!T) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - T == E->getQueriedTypeSourceInfo()) - return E; - - ExprResult SubExpr; - { - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); - SubExpr = getDerived().TransformExpr(E->getDimensionExpression()); - if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression()) - return E; - } - - return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T, - SubExpr.get(), E->getEndLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) { - ExprResult SubExpr; - { - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); - SubExpr = getDerived().TransformExpr(E->getQueriedExpression()); - if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression()) - return E; - } - - return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(), - SubExpr.get(), E->getEndLoc()); -} - -template <typename Derived> -ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr( - ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken, - TypeSourceInfo **RecoveryTSI) { - ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr( - DRE, AddrTaken, RecoveryTSI); - - // Propagate both errors and recovered types, which return ExprEmpty. - if (!NewDRE.isUsable()) - return NewDRE; - - // We got an expr, wrap it up in parens. - if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE) - return PE; - return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(), - PE->getRParen()); -} - -template <typename Derived> -ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr( - DependentScopeDeclRefExpr *E) { - return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false, - nullptr); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformDependentScopeDeclRefExpr( - DependentScopeDeclRefExpr *E, - bool IsAddressOfOperand, - TypeSourceInfo **RecoveryTSI) { - assert(E->getQualifierLoc()); - NestedNameSpecifierLoc QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); - if (!QualifierLoc) - return ExprError(); - SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); - - // TODO: If this is a conversion-function-id, verify that the - // destination type name (if present) resolves the same way after - // instantiation as it did in the local scope. - - DeclarationNameInfo NameInfo - = getDerived().TransformDeclarationNameInfo(E->getNameInfo()); - if (!NameInfo.getName()) - return ExprError(); - - if (!E->hasExplicitTemplateArgs()) { - if (!getDerived().AlwaysRebuild() && - QualifierLoc == E->getQualifierLoc() && - // Note: it is sufficient to compare the Name component of NameInfo: - // if name has not changed, DNLoc has not changed either. - NameInfo.getName() == E->getDeclName()) - return E; - - return getDerived().RebuildDependentScopeDeclRefExpr( - QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr, - IsAddressOfOperand, RecoveryTSI); - } - - TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc()); - if (getDerived().TransformTemplateArguments(E->getTemplateArgs(), - E->getNumTemplateArgs(), - TransArgs)) - return ExprError(); - - return getDerived().RebuildDependentScopeDeclRefExpr( - QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand, - RecoveryTSI); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) { - // CXXConstructExprs other than for list-initialization and - // CXXTemporaryObjectExpr are always implicit, so when we have - // a 1-argument construction we just transform that argument. - if ((E->getNumArgs() == 1 || - (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) && - (!getDerived().DropCallArgument(E->getArg(0))) && - !E->isListInitialization()) - return getDerived().TransformExpr(E->getArg(0)); - - TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName()); - - QualType T = getDerived().TransformType(E->getType()); - if (T.isNull()) - return ExprError(); - - CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>( - getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor())); - if (!Constructor) - return ExprError(); - - bool ArgumentChanged = false; - SmallVector<Expr*, 8> Args; - { - EnterExpressionEvaluationContext Context( - getSema(), EnterExpressionEvaluationContext::InitList, - E->isListInitialization()); - if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, - &ArgumentChanged)) - return ExprError(); - } - - if (!getDerived().AlwaysRebuild() && - T == E->getType() && - Constructor == E->getConstructor() && - !ArgumentChanged) { - // Mark the constructor as referenced. - // FIXME: Instantiation-specific - SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor); - return E; - } - - return getDerived().RebuildCXXConstructExpr( - T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args, - E->hadMultipleCandidates(), E->isListInitialization(), - E->isStdInitListInitialization(), E->requiresZeroInitialization(), - E->getConstructionKind(), E->getParenOrBraceRange()); -} - -template<typename Derived> -ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr( - CXXInheritedCtorInitExpr *E) { - QualType T = getDerived().TransformType(E->getType()); - if (T.isNull()) - return ExprError(); - - CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>( - getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor())); - if (!Constructor) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - T == E->getType() && - Constructor == E->getConstructor()) { - // Mark the constructor as referenced. - // FIXME: Instantiation-specific - SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor); - return E; - } - - return getDerived().RebuildCXXInheritedCtorInitExpr( - T, E->getLocation(), Constructor, - E->constructsVBase(), E->inheritedFromVBase()); -} - -/// Transform a C++ temporary-binding expression. -/// -/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just -/// transform the subexpression and return that. -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { - return getDerived().TransformExpr(E->getSubExpr()); -} - -/// Transform a C++ expression that contains cleanups that should -/// be run after the expression is evaluated. -/// -/// Since ExprWithCleanups nodes are implicitly generated, we -/// just transform the subexpression and return that. -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) { - return getDerived().TransformExpr(E->getSubExpr()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXTemporaryObjectExpr( - CXXTemporaryObjectExpr *E) { - TypeSourceInfo *T = - getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo()); - if (!T) - return ExprError(); - - CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>( - getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor())); - if (!Constructor) - return ExprError(); - - bool ArgumentChanged = false; - SmallVector<Expr*, 8> Args; - Args.reserve(E->getNumArgs()); - { - EnterExpressionEvaluationContext Context( - getSema(), EnterExpressionEvaluationContext::InitList, - E->isListInitialization()); - if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, - &ArgumentChanged)) - return ExprError(); - } - - if (!getDerived().AlwaysRebuild() && - T == E->getTypeSourceInfo() && - Constructor == E->getConstructor() && - !ArgumentChanged) { - // FIXME: Instantiation-specific - SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor); - return SemaRef.MaybeBindToTemporary(E); - } - - // FIXME: We should just pass E->isListInitialization(), but we're not - // prepared to handle list-initialization without a child InitListExpr. - SourceLocation LParenLoc = T->getTypeLoc().getEndLoc(); - return getDerived().RebuildCXXTemporaryObjectExpr( - T, LParenLoc, Args, E->getEndLoc(), - /*ListInitialization=*/LParenLoc.isInvalid()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { - // Transform any init-capture expressions before entering the scope of the - // lambda body, because they are not semantically within that scope. - typedef std::pair<ExprResult, QualType> InitCaptureInfoTy; - SmallVector<InitCaptureInfoTy, 8> InitCaptureExprsAndTypes; - InitCaptureExprsAndTypes.resize(E->explicit_capture_end() - - E->explicit_capture_begin()); - for (LambdaExpr::capture_iterator C = E->capture_begin(), - CEnd = E->capture_end(); - C != CEnd; ++C) { - if (!E->isInitCapture(C)) - continue; - EnterExpressionEvaluationContext EEEC( - getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated); - ExprResult NewExprInitResult = getDerived().TransformInitializer( - C->getCapturedVar()->getInit(), - C->getCapturedVar()->getInitStyle() == VarDecl::CallInit); - - if (NewExprInitResult.isInvalid()) - return ExprError(); - Expr *NewExprInit = NewExprInitResult.get(); - - VarDecl *OldVD = C->getCapturedVar(); - QualType NewInitCaptureType = - getSema().buildLambdaInitCaptureInitialization( - C->getLocation(), OldVD->getType()->isReferenceType(), - OldVD->getIdentifier(), - C->getCapturedVar()->getInitStyle() != VarDecl::CInit, NewExprInit); - NewExprInitResult = NewExprInit; - InitCaptureExprsAndTypes[C - E->capture_begin()] = - std::make_pair(NewExprInitResult, NewInitCaptureType); - } - - // Transform the template parameters, and add them to the current - // instantiation scope. The null case is handled correctly. - auto TPL = getDerived().TransformTemplateParameterList( - E->getTemplateParameterList()); - - // Transform the type of the original lambda's call operator. - // The transformation MUST be done in the CurrentInstantiationScope since - // it introduces a mapping of the original to the newly created - // transformed parameters. - TypeSourceInfo *NewCallOpTSI = nullptr; - { - TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo(); - FunctionProtoTypeLoc OldCallOpFPTL = - OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>(); - - TypeLocBuilder NewCallOpTLBuilder; - SmallVector<QualType, 4> ExceptionStorage; - TreeTransform *This = this; // Work around gcc.gnu.org/PR56135. - QualType NewCallOpType = TransformFunctionProtoType( - NewCallOpTLBuilder, OldCallOpFPTL, nullptr, Qualifiers(), - [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) { - return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI, - ExceptionStorage, Changed); - }); - if (NewCallOpType.isNull()) - return ExprError(); - NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, - NewCallOpType); - } - - LambdaScopeInfo *LSI = getSema().PushLambdaScope(); - Sema::FunctionScopeRAII FuncScopeCleanup(getSema()); - LSI->GLTemplateParameterList = TPL; - - // Create the local class that will describe the lambda. - CXXRecordDecl *Class - = getSema().createLambdaClosureType(E->getIntroducerRange(), - NewCallOpTSI, - /*KnownDependent=*/false, - E->getCaptureDefault()); - getDerived().transformedLocalDecl(E->getLambdaClass(), Class); - - // Build the call operator. - CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition( - Class, E->getIntroducerRange(), NewCallOpTSI, - E->getCallOperator()->getEndLoc(), - NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(), - E->getCallOperator()->isConstexpr()); - - LSI->CallOperator = NewCallOperator; - - for (unsigned I = 0, NumParams = NewCallOperator->getNumParams(); - I != NumParams; ++I) { - auto *P = NewCallOperator->getParamDecl(I); - if (P->hasUninstantiatedDefaultArg()) { - EnterExpressionEvaluationContext Eval( - getSema(), - Sema::ExpressionEvaluationContext::PotentiallyEvaluatedIfUsed, P); - ExprResult R = getDerived().TransformExpr( - E->getCallOperator()->getParamDecl(I)->getDefaultArg()); - P->setDefaultArg(R.get()); - } - } - - getDerived().transformAttrs(E->getCallOperator(), NewCallOperator); - getDerived().transformedLocalDecl(E->getCallOperator(), NewCallOperator); - - // Introduce the context of the call operator. - Sema::ContextRAII SavedContext(getSema(), NewCallOperator, - /*NewThisContext*/false); - - // Enter the scope of the lambda. - getSema().buildLambdaScope(LSI, NewCallOperator, - E->getIntroducerRange(), - E->getCaptureDefault(), - E->getCaptureDefaultLoc(), - E->hasExplicitParameters(), - E->hasExplicitResultType(), - E->isMutable()); - - bool Invalid = false; - - // Transform captures. - bool FinishedExplicitCaptures = false; - for (LambdaExpr::capture_iterator C = E->capture_begin(), - CEnd = E->capture_end(); - C != CEnd; ++C) { - // When we hit the first implicit capture, tell Sema that we've finished - // the list of explicit captures. - if (!FinishedExplicitCaptures && C->isImplicit()) { - getSema().finishLambdaExplicitCaptures(LSI); - FinishedExplicitCaptures = true; - } - - // Capturing 'this' is trivial. - if (C->capturesThis()) { - getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(), - /*BuildAndDiagnose*/ true, nullptr, - C->getCaptureKind() == LCK_StarThis); - continue; - } - // Captured expression will be recaptured during captured variables - // rebuilding. - if (C->capturesVLAType()) - continue; - - // Rebuild init-captures, including the implied field declaration. - if (E->isInitCapture(C)) { - InitCaptureInfoTy InitExprTypePair = - InitCaptureExprsAndTypes[C - E->capture_begin()]; - ExprResult Init = InitExprTypePair.first; - QualType InitQualType = InitExprTypePair.second; - if (Init.isInvalid() || InitQualType.isNull()) { - Invalid = true; - continue; - } - VarDecl *OldVD = C->getCapturedVar(); - VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl( - OldVD->getLocation(), InitExprTypePair.second, OldVD->getIdentifier(), - OldVD->getInitStyle(), Init.get()); - if (!NewVD) - Invalid = true; - else { - getDerived().transformedLocalDecl(OldVD, NewVD); - } - getSema().buildInitCaptureField(LSI, NewVD); - continue; - } - - assert(C->capturesVariable() && "unexpected kind of lambda capture"); - - // Determine the capture kind for Sema. - Sema::TryCaptureKind Kind - = C->isImplicit()? Sema::TryCapture_Implicit - : C->getCaptureKind() == LCK_ByCopy - ? Sema::TryCapture_ExplicitByVal - : Sema::TryCapture_ExplicitByRef; - SourceLocation EllipsisLoc; - if (C->isPackExpansion()) { - UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation()); - bool ShouldExpand = false; - bool RetainExpansion = false; - Optional<unsigned> NumExpansions; - if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(), - C->getLocation(), - Unexpanded, - ShouldExpand, RetainExpansion, - NumExpansions)) { - Invalid = true; - continue; - } - - if (ShouldExpand) { - // The transform has determined that we should perform an expansion; - // transform and capture each of the arguments. - // expansion of the pattern. Do so. - VarDecl *Pack = C->getCapturedVar(); - for (unsigned I = 0; I != *NumExpansions; ++I) { - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); - VarDecl *CapturedVar - = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(), - Pack)); - if (!CapturedVar) { - Invalid = true; - continue; - } - - // Capture the transformed variable. - getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind); - } - - // FIXME: Retain a pack expansion if RetainExpansion is true. - - continue; - } - - EllipsisLoc = C->getEllipsisLoc(); - } - - // Transform the captured variable. - VarDecl *CapturedVar - = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(), - C->getCapturedVar())); - if (!CapturedVar || CapturedVar->isInvalidDecl()) { - Invalid = true; - continue; - } - - // Capture the transformed variable. - getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind, - EllipsisLoc); - } - if (!FinishedExplicitCaptures) - getSema().finishLambdaExplicitCaptures(LSI); - - // Enter a new evaluation context to insulate the lambda from any - // cleanups from the enclosing full-expression. - getSema().PushExpressionEvaluationContext( - Sema::ExpressionEvaluationContext::PotentiallyEvaluated); - - // Instantiate the body of the lambda expression. - StmtResult Body = - Invalid ? StmtError() : getDerived().TransformStmt(E->getBody()); - - // ActOnLambda* will pop the function scope for us. - FuncScopeCleanup.disable(); - - if (Body.isInvalid()) { - SavedContext.pop(); - getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr, - /*IsInstantiation=*/true); - return ExprError(); - } - - // Copy the LSI before ActOnFinishFunctionBody removes it. - // FIXME: This is dumb. Store the lambda information somewhere that outlives - // the call operator. - auto LSICopy = *LSI; - getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(), - /*IsInstantiation*/ true); - SavedContext.pop(); - - return getSema().BuildLambdaExpr(E->getBeginLoc(), Body.get()->getEndLoc(), - &LSICopy); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr( - CXXUnresolvedConstructExpr *E) { - TypeSourceInfo *T = - getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo()); - if (!T) - return ExprError(); - - bool ArgumentChanged = false; - SmallVector<Expr*, 8> Args; - Args.reserve(E->arg_size()); - { - EnterExpressionEvaluationContext Context( - getSema(), EnterExpressionEvaluationContext::InitList, - E->isListInitialization()); - if (getDerived().TransformExprs(E->arg_begin(), E->arg_size(), true, Args, - &ArgumentChanged)) - return ExprError(); - } - - if (!getDerived().AlwaysRebuild() && - T == E->getTypeSourceInfo() && - !ArgumentChanged) - return E; - - // FIXME: we're faking the locations of the commas - return getDerived().RebuildCXXUnresolvedConstructExpr( - T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr( - CXXDependentScopeMemberExpr *E) { - // Transform the base of the expression. - ExprResult Base((Expr*) nullptr); - Expr *OldBase; - QualType BaseType; - QualType ObjectType; - if (!E->isImplicitAccess()) { - OldBase = E->getBase(); - Base = getDerived().TransformExpr(OldBase); - if (Base.isInvalid()) - return ExprError(); - - // Start the member reference and compute the object's type. - ParsedType ObjectTy; - bool MayBePseudoDestructor = false; - Base = SemaRef.ActOnStartCXXMemberReference(nullptr, Base.get(), - E->getOperatorLoc(), - E->isArrow()? tok::arrow : tok::period, - ObjectTy, - MayBePseudoDestructor); - if (Base.isInvalid()) - return ExprError(); - - ObjectType = ObjectTy.get(); - BaseType = ((Expr*) Base.get())->getType(); - } else { - OldBase = nullptr; - BaseType = getDerived().TransformType(E->getBaseType()); - ObjectType = BaseType->getAs<PointerType>()->getPointeeType(); - } - - // Transform the first part of the nested-name-specifier that qualifies - // the member name. - NamedDecl *FirstQualifierInScope - = getDerived().TransformFirstQualifierInScope( - E->getFirstQualifierFoundInScope(), - E->getQualifierLoc().getBeginLoc()); - - NestedNameSpecifierLoc QualifierLoc; - if (E->getQualifier()) { - QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(), - ObjectType, - FirstQualifierInScope); - if (!QualifierLoc) - return ExprError(); - } - - SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); - - // TODO: If this is a conversion-function-id, verify that the - // destination type name (if present) resolves the same way after - // instantiation as it did in the local scope. - - DeclarationNameInfo NameInfo - = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo()); - if (!NameInfo.getName()) - return ExprError(); - - if (!E->hasExplicitTemplateArgs()) { - // This is a reference to a member without an explicitly-specified - // template argument list. Optimize for this common case. - if (!getDerived().AlwaysRebuild() && - Base.get() == OldBase && - BaseType == E->getBaseType() && - QualifierLoc == E->getQualifierLoc() && - NameInfo.getName() == E->getMember() && - FirstQualifierInScope == E->getFirstQualifierFoundInScope()) - return E; - - return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(), - BaseType, - E->isArrow(), - E->getOperatorLoc(), - QualifierLoc, - TemplateKWLoc, - FirstQualifierInScope, - NameInfo, - /*TemplateArgs*/nullptr); - } - - TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc()); - if (getDerived().TransformTemplateArguments(E->getTemplateArgs(), - E->getNumTemplateArgs(), - TransArgs)) - return ExprError(); - - return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(), - BaseType, - E->isArrow(), - E->getOperatorLoc(), - QualifierLoc, - TemplateKWLoc, - FirstQualifierInScope, - NameInfo, - &TransArgs); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) { - // Transform the base of the expression. - ExprResult Base((Expr*) nullptr); - QualType BaseType; - if (!Old->isImplicitAccess()) { - Base = getDerived().TransformExpr(Old->getBase()); - if (Base.isInvalid()) - return ExprError(); - Base = getSema().PerformMemberExprBaseConversion(Base.get(), - Old->isArrow()); - if (Base.isInvalid()) - return ExprError(); - BaseType = Base.get()->getType(); - } else { - BaseType = getDerived().TransformType(Old->getBaseType()); - } - - NestedNameSpecifierLoc QualifierLoc; - if (Old->getQualifierLoc()) { - QualifierLoc - = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc()); - if (!QualifierLoc) - return ExprError(); - } - - SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc(); - - LookupResult R(SemaRef, Old->getMemberNameInfo(), - Sema::LookupOrdinaryName); - - // Transform the declaration set. - if (TransformOverloadExprDecls(Old, /*RequiresADL*/false, R)) - return ExprError(); - - // Determine the naming class. - if (Old->getNamingClass()) { - CXXRecordDecl *NamingClass - = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl( - Old->getMemberLoc(), - Old->getNamingClass())); - if (!NamingClass) - return ExprError(); - - R.setNamingClass(NamingClass); - } - - TemplateArgumentListInfo TransArgs; - if (Old->hasExplicitTemplateArgs()) { - TransArgs.setLAngleLoc(Old->getLAngleLoc()); - TransArgs.setRAngleLoc(Old->getRAngleLoc()); - if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(), - Old->getNumTemplateArgs(), - TransArgs)) - return ExprError(); - } - - // FIXME: to do this check properly, we will need to preserve the - // first-qualifier-in-scope here, just in case we had a dependent - // base (and therefore couldn't do the check) and a - // nested-name-qualifier (and therefore could do the lookup). - NamedDecl *FirstQualifierInScope = nullptr; - - return getDerived().RebuildUnresolvedMemberExpr(Base.get(), - BaseType, - Old->getOperatorLoc(), - Old->isArrow(), - QualifierLoc, - TemplateKWLoc, - FirstQualifierInScope, - R, - (Old->hasExplicitTemplateArgs() - ? &TransArgs : nullptr)); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) { - EnterExpressionEvaluationContext Unevaluated( - SemaRef, Sema::ExpressionEvaluationContext::Unevaluated); - ExprResult SubExpr = getDerived().TransformExpr(E->getOperand()); - if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand()) - return E; - - return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) { - ExprResult Pattern = getDerived().TransformExpr(E->getPattern()); - if (Pattern.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern()) - return E; - - return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(), - E->getNumExpansions()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) { - // If E is not value-dependent, then nothing will change when we transform it. - // Note: This is an instantiation-centric view. - if (!E->isValueDependent()) - return E; - - EnterExpressionEvaluationContext Unevaluated( - getSema(), Sema::ExpressionEvaluationContext::Unevaluated); - - ArrayRef<TemplateArgument> PackArgs; - TemplateArgument ArgStorage; - - // Find the argument list to transform. - if (E->isPartiallySubstituted()) { - PackArgs = E->getPartialArguments(); - } else if (E->isValueDependent()) { - UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc()); - bool ShouldExpand = false; - bool RetainExpansion = false; - Optional<unsigned> NumExpansions; - if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(), - Unexpanded, - ShouldExpand, RetainExpansion, - NumExpansions)) - return ExprError(); - - // If we need to expand the pack, build a template argument from it and - // expand that. - if (ShouldExpand) { - auto *Pack = E->getPack(); - if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Pack)) { - ArgStorage = getSema().Context.getPackExpansionType( - getSema().Context.getTypeDeclType(TTPD), None); - } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) { - ArgStorage = TemplateArgument(TemplateName(TTPD), None); - } else { - auto *VD = cast<ValueDecl>(Pack); - ExprResult DRE = getSema().BuildDeclRefExpr( - VD, VD->getType().getNonLValueExprType(getSema().Context), - VD->getType()->isReferenceType() ? VK_LValue : VK_RValue, - E->getPackLoc()); - if (DRE.isInvalid()) - return ExprError(); - ArgStorage = new (getSema().Context) PackExpansionExpr( - getSema().Context.DependentTy, DRE.get(), E->getPackLoc(), None); - } - PackArgs = ArgStorage; - } - } - - // If we're not expanding the pack, just transform the decl. - if (!PackArgs.size()) { - auto *Pack = cast_or_null<NamedDecl>( - getDerived().TransformDecl(E->getPackLoc(), E->getPack())); - if (!Pack) - return ExprError(); - return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), Pack, - E->getPackLoc(), - E->getRParenLoc(), None, None); - } - - // Try to compute the result without performing a partial substitution. - Optional<unsigned> Result = 0; - for (const TemplateArgument &Arg : PackArgs) { - if (!Arg.isPackExpansion()) { - Result = *Result + 1; - continue; - } - - TemplateArgumentLoc ArgLoc; - InventTemplateArgumentLoc(Arg, ArgLoc); - - // Find the pattern of the pack expansion. - SourceLocation Ellipsis; - Optional<unsigned> OrigNumExpansions; - TemplateArgumentLoc Pattern = - getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis, - OrigNumExpansions); - - // Substitute under the pack expansion. Do not expand the pack (yet). - TemplateArgumentLoc OutPattern; - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); - if (getDerived().TransformTemplateArgument(Pattern, OutPattern, - /*Uneval*/ true)) - return true; - - // See if we can determine the number of arguments from the result. - Optional<unsigned> NumExpansions = - getSema().getFullyPackExpandedSize(OutPattern.getArgument()); - if (!NumExpansions) { - // No: we must be in an alias template expansion, and we're going to need - // to actually expand the packs. - Result = None; - break; - } - - Result = *Result + *NumExpansions; - } - - // Common case: we could determine the number of expansions without - // substituting. - if (Result) - return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(), - E->getPackLoc(), - E->getRParenLoc(), *Result, None); - - TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(), - E->getPackLoc()); - { - TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity()); - typedef TemplateArgumentLocInventIterator< - Derived, const TemplateArgument*> PackLocIterator; - if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()), - PackLocIterator(*this, PackArgs.end()), - TransformedPackArgs, /*Uneval*/true)) - return ExprError(); - } - - // Check whether we managed to fully-expand the pack. - // FIXME: Is it possible for us to do so and not hit the early exit path? - SmallVector<TemplateArgument, 8> Args; - bool PartialSubstitution = false; - for (auto &Loc : TransformedPackArgs.arguments()) { - Args.push_back(Loc.getArgument()); - if (Loc.getArgument().isPackExpansion()) - PartialSubstitution = true; - } - - if (PartialSubstitution) - return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(), - E->getPackLoc(), - E->getRParenLoc(), None, Args); - - return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(), - E->getPackLoc(), E->getRParenLoc(), - Args.size(), None); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr( - SubstNonTypeTemplateParmPackExpr *E) { - // Default behavior is to do nothing with this transformation. - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr( - SubstNonTypeTemplateParmExpr *E) { - // Default behavior is to do nothing with this transformation. - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) { - // Default behavior is to do nothing with this transformation. - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformMaterializeTemporaryExpr( - MaterializeTemporaryExpr *E) { - return getDerived().TransformExpr(E->GetTemporaryExpr()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) { - Expr *Pattern = E->getPattern(); - - SmallVector<UnexpandedParameterPack, 2> Unexpanded; - getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); - assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); - - // Determine whether the set of unexpanded parameter packs can and should - // be expanded. - bool Expand = true; - bool RetainExpansion = false; - Optional<unsigned> NumExpansions; - if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(), - Pattern->getSourceRange(), - Unexpanded, - Expand, RetainExpansion, - NumExpansions)) - return true; - - if (!Expand) { - // Do not expand any packs here, just transform and rebuild a fold - // expression. - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); - - ExprResult LHS = - E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult(); - if (LHS.isInvalid()) - return true; - - ExprResult RHS = - E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult(); - if (RHS.isInvalid()) - return true; - - if (!getDerived().AlwaysRebuild() && - LHS.get() == E->getLHS() && RHS.get() == E->getRHS()) - return E; - - return getDerived().RebuildCXXFoldExpr( - E->getBeginLoc(), LHS.get(), E->getOperator(), E->getEllipsisLoc(), - RHS.get(), E->getEndLoc()); - } - - // The transform has determined that we should perform an elementwise - // expansion of the pattern. Do so. - ExprResult Result = getDerived().TransformExpr(E->getInit()); - if (Result.isInvalid()) - return true; - bool LeftFold = E->isLeftFold(); - - // If we're retaining an expansion for a right fold, it is the innermost - // component and takes the init (if any). - if (!LeftFold && RetainExpansion) { - ForgetPartiallySubstitutedPackRAII Forget(getDerived()); - - ExprResult Out = getDerived().TransformExpr(Pattern); - if (Out.isInvalid()) - return true; - - Result = getDerived().RebuildCXXFoldExpr( - E->getBeginLoc(), Out.get(), E->getOperator(), E->getEllipsisLoc(), - Result.get(), E->getEndLoc()); - if (Result.isInvalid()) - return true; - } - - for (unsigned I = 0; I != *NumExpansions; ++I) { - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex( - getSema(), LeftFold ? I : *NumExpansions - I - 1); - ExprResult Out = getDerived().TransformExpr(Pattern); - if (Out.isInvalid()) - return true; - - if (Out.get()->containsUnexpandedParameterPack()) { - // We still have a pack; retain a pack expansion for this slice. - Result = getDerived().RebuildCXXFoldExpr( - E->getBeginLoc(), LeftFold ? Result.get() : Out.get(), - E->getOperator(), E->getEllipsisLoc(), - LeftFold ? Out.get() : Result.get(), E->getEndLoc()); - } else if (Result.isUsable()) { - // We've got down to a single element; build a binary operator. - Result = getDerived().RebuildBinaryOperator( - E->getEllipsisLoc(), E->getOperator(), - LeftFold ? Result.get() : Out.get(), - LeftFold ? Out.get() : Result.get()); - } else - Result = Out; - - if (Result.isInvalid()) - return true; - } - - // If we're retaining an expansion for a left fold, it is the outermost - // component and takes the complete expansion so far as its init (if any). - if (LeftFold && RetainExpansion) { - ForgetPartiallySubstitutedPackRAII Forget(getDerived()); - - ExprResult Out = getDerived().TransformExpr(Pattern); - if (Out.isInvalid()) - return true; - - Result = getDerived().RebuildCXXFoldExpr( - E->getBeginLoc(), Result.get(), E->getOperator(), E->getEllipsisLoc(), - Out.get(), E->getEndLoc()); - if (Result.isInvalid()) - return true; - } - - // If we had no init and an empty pack, and we're not retaining an expansion, - // then produce a fallback value or error. - if (Result.isUnset()) - return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(), - E->getOperator()); - - return Result; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformCXXStdInitializerListExpr( - CXXStdInitializerListExpr *E) { - return getDerived().TransformExpr(E->getSubExpr()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) { - return SemaRef.MaybeBindToTemporary(E); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) { - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) { - ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); - if (SubExpr.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - SubExpr.get() == E->getSubExpr()) - return E; - - return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) { - // Transform each of the elements. - SmallVector<Expr *, 8> Elements; - bool ArgChanged = false; - if (getDerived().TransformExprs(E->getElements(), E->getNumElements(), - /*IsCall=*/false, Elements, &ArgChanged)) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && !ArgChanged) - return SemaRef.MaybeBindToTemporary(E); - - return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(), - Elements.data(), - Elements.size()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformObjCDictionaryLiteral( - ObjCDictionaryLiteral *E) { - // Transform each of the elements. - SmallVector<ObjCDictionaryElement, 8> Elements; - bool ArgChanged = false; - for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) { - ObjCDictionaryElement OrigElement = E->getKeyValueElement(I); - - if (OrigElement.isPackExpansion()) { - // This key/value element is a pack expansion. - SmallVector<UnexpandedParameterPack, 2> Unexpanded; - getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded); - getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded); - assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); - - // Determine whether the set of unexpanded parameter packs can - // and should be expanded. - bool Expand = true; - bool RetainExpansion = false; - Optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions; - Optional<unsigned> NumExpansions = OrigNumExpansions; - SourceRange PatternRange(OrigElement.Key->getBeginLoc(), - OrigElement.Value->getEndLoc()); - if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc, - PatternRange, Unexpanded, Expand, - RetainExpansion, NumExpansions)) - return ExprError(); - - if (!Expand) { - // The transform has determined that we should perform a simple - // transformation on the pack expansion, producing another pack - // expansion. - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); - ExprResult Key = getDerived().TransformExpr(OrigElement.Key); - if (Key.isInvalid()) - return ExprError(); - - if (Key.get() != OrigElement.Key) - ArgChanged = true; - - ExprResult Value = getDerived().TransformExpr(OrigElement.Value); - if (Value.isInvalid()) - return ExprError(); - - if (Value.get() != OrigElement.Value) - ArgChanged = true; - - ObjCDictionaryElement Expansion = { - Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions - }; - Elements.push_back(Expansion); - continue; - } - - // Record right away that the argument was changed. This needs - // to happen even if the array expands to nothing. - ArgChanged = true; - - // The transform has determined that we should perform an elementwise - // expansion of the pattern. Do so. - for (unsigned I = 0; I != *NumExpansions; ++I) { - Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); - ExprResult Key = getDerived().TransformExpr(OrigElement.Key); - if (Key.isInvalid()) - return ExprError(); - - ExprResult Value = getDerived().TransformExpr(OrigElement.Value); - if (Value.isInvalid()) - return ExprError(); - - ObjCDictionaryElement Element = { - Key.get(), Value.get(), SourceLocation(), NumExpansions - }; - - // If any unexpanded parameter packs remain, we still have a - // pack expansion. - // FIXME: Can this really happen? - if (Key.get()->containsUnexpandedParameterPack() || - Value.get()->containsUnexpandedParameterPack()) - Element.EllipsisLoc = OrigElement.EllipsisLoc; - - Elements.push_back(Element); - } - - // FIXME: Retain a pack expansion if RetainExpansion is true. - - // We've finished with this pack expansion. - continue; - } - - // Transform and check key. - ExprResult Key = getDerived().TransformExpr(OrigElement.Key); - if (Key.isInvalid()) - return ExprError(); - - if (Key.get() != OrigElement.Key) - ArgChanged = true; - - // Transform and check value. - ExprResult Value - = getDerived().TransformExpr(OrigElement.Value); - if (Value.isInvalid()) - return ExprError(); - - if (Value.get() != OrigElement.Value) - ArgChanged = true; - - ObjCDictionaryElement Element = { - Key.get(), Value.get(), SourceLocation(), None - }; - Elements.push_back(Element); - } - - if (!getDerived().AlwaysRebuild() && !ArgChanged) - return SemaRef.MaybeBindToTemporary(E); - - return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(), - Elements); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) { - TypeSourceInfo *EncodedTypeInfo - = getDerived().TransformType(E->getEncodedTypeSourceInfo()); - if (!EncodedTypeInfo) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - EncodedTypeInfo == E->getEncodedTypeSourceInfo()) - return E; - - return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(), - EncodedTypeInfo, - E->getRParenLoc()); -} - -template<typename Derived> -ExprResult TreeTransform<Derived>:: -TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) { - // This is a kind of implicit conversion, and it needs to get dropped - // and recomputed for the same general reasons that ImplicitCastExprs - // do, as well a more specific one: this expression is only valid when - // it appears *immediately* as an argument expression. - return getDerived().TransformExpr(E->getSubExpr()); -} - -template<typename Derived> -ExprResult TreeTransform<Derived>:: -TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) { - TypeSourceInfo *TSInfo - = getDerived().TransformType(E->getTypeInfoAsWritten()); - if (!TSInfo) - return ExprError(); - - ExprResult Result = getDerived().TransformExpr(E->getSubExpr()); - if (Result.isInvalid()) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - TSInfo == E->getTypeInfoAsWritten() && - Result.get() == E->getSubExpr()) - return E; - - return SemaRef.BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(), - E->getBridgeKeywordLoc(), TSInfo, - Result.get()); -} - -template <typename Derived> -ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr( - ObjCAvailabilityCheckExpr *E) { - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) { - // Transform arguments. - bool ArgChanged = false; - SmallVector<Expr*, 8> Args; - Args.reserve(E->getNumArgs()); - if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args, - &ArgChanged)) - return ExprError(); - - if (E->getReceiverKind() == ObjCMessageExpr::Class) { - // Class message: transform the receiver type. - TypeSourceInfo *ReceiverTypeInfo - = getDerived().TransformType(E->getClassReceiverTypeInfo()); - if (!ReceiverTypeInfo) - return ExprError(); - - // If nothing changed, just retain the existing message send. - if (!getDerived().AlwaysRebuild() && - ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged) - return SemaRef.MaybeBindToTemporary(E); - - // Build a new class message send. - SmallVector<SourceLocation, 16> SelLocs; - E->getSelectorLocs(SelLocs); - return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo, - E->getSelector(), - SelLocs, - E->getMethodDecl(), - E->getLeftLoc(), - Args, - E->getRightLoc()); - } - else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass || - E->getReceiverKind() == ObjCMessageExpr::SuperInstance) { - if (!E->getMethodDecl()) - return ExprError(); - - // Build a new class message send to 'super'. - SmallVector<SourceLocation, 16> SelLocs; - E->getSelectorLocs(SelLocs); - return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(), - E->getSelector(), - SelLocs, - E->getReceiverType(), - E->getMethodDecl(), - E->getLeftLoc(), - Args, - E->getRightLoc()); - } - - // Instance message: transform the receiver - assert(E->getReceiverKind() == ObjCMessageExpr::Instance && - "Only class and instance messages may be instantiated"); - ExprResult Receiver - = getDerived().TransformExpr(E->getInstanceReceiver()); - if (Receiver.isInvalid()) - return ExprError(); - - // If nothing changed, just retain the existing message send. - if (!getDerived().AlwaysRebuild() && - Receiver.get() == E->getInstanceReceiver() && !ArgChanged) - return SemaRef.MaybeBindToTemporary(E); - - // Build a new instance message send. - SmallVector<SourceLocation, 16> SelLocs; - E->getSelectorLocs(SelLocs); - return getDerived().RebuildObjCMessageExpr(Receiver.get(), - E->getSelector(), - SelLocs, - E->getMethodDecl(), - E->getLeftLoc(), - Args, - E->getRightLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) { - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) { - return E; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) { - // Transform the base expression. - ExprResult Base = getDerived().TransformExpr(E->getBase()); - if (Base.isInvalid()) - return ExprError(); - - // We don't need to transform the ivar; it will never change. - - // If nothing changed, just retain the existing expression. - if (!getDerived().AlwaysRebuild() && - Base.get() == E->getBase()) - return E; - - return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(), - E->getLocation(), - E->isArrow(), E->isFreeIvar()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { - // 'super' and types never change. Property never changes. Just - // retain the existing expression. - if (!E->isObjectReceiver()) - return E; - - // Transform the base expression. - ExprResult Base = getDerived().TransformExpr(E->getBase()); - if (Base.isInvalid()) - return ExprError(); - - // We don't need to transform the property; it will never change. - - // If nothing changed, just retain the existing expression. - if (!getDerived().AlwaysRebuild() && - Base.get() == E->getBase()) - return E; - - if (E->isExplicitProperty()) - return getDerived().RebuildObjCPropertyRefExpr(Base.get(), - E->getExplicitProperty(), - E->getLocation()); - - return getDerived().RebuildObjCPropertyRefExpr(Base.get(), - SemaRef.Context.PseudoObjectTy, - E->getImplicitPropertyGetter(), - E->getImplicitPropertySetter(), - E->getLocation()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) { - // Transform the base expression. - ExprResult Base = getDerived().TransformExpr(E->getBaseExpr()); - if (Base.isInvalid()) - return ExprError(); - - // Transform the key expression. - ExprResult Key = getDerived().TransformExpr(E->getKeyExpr()); - if (Key.isInvalid()) - return ExprError(); - - // If nothing changed, just retain the existing expression. - if (!getDerived().AlwaysRebuild() && - Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr()) - return E; - - return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(), - Base.get(), Key.get(), - E->getAtIndexMethodDecl(), - E->setAtIndexMethodDecl()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) { - // Transform the base expression. - ExprResult Base = getDerived().TransformExpr(E->getBase()); - if (Base.isInvalid()) - return ExprError(); - - // If nothing changed, just retain the existing expression. - if (!getDerived().AlwaysRebuild() && - Base.get() == E->getBase()) - return E; - - return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(), - E->getOpLoc(), - E->isArrow()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) { - bool ArgumentChanged = false; - SmallVector<Expr*, 8> SubExprs; - SubExprs.reserve(E->getNumSubExprs()); - if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false, - SubExprs, &ArgumentChanged)) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - !ArgumentChanged) - return E; - - return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(), - SubExprs, - E->getRParenLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) { - ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr()); - if (SrcExpr.isInvalid()) - return ExprError(); - - TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo()); - if (!Type) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - Type == E->getTypeSourceInfo() && - SrcExpr.get() == E->getSrcExpr()) - return E; - - return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(), - SrcExpr.get(), Type, - E->getRParenLoc()); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) { - BlockDecl *oldBlock = E->getBlockDecl(); - - SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/nullptr); - BlockScopeInfo *blockScope = SemaRef.getCurBlock(); - - blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic()); - blockScope->TheDecl->setBlockMissingReturnType( - oldBlock->blockMissingReturnType()); - - SmallVector<ParmVarDecl*, 4> params; - SmallVector<QualType, 4> paramTypes; - - const FunctionProtoType *exprFunctionType = E->getFunctionType(); - - // Parameter substitution. - Sema::ExtParameterInfoBuilder extParamInfos; - if (getDerived().TransformFunctionTypeParams( - E->getCaretLocation(), oldBlock->parameters(), nullptr, - exprFunctionType->getExtParameterInfosOrNull(), paramTypes, ¶ms, - extParamInfos)) { - getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr); - return ExprError(); - } - - QualType exprResultType = - getDerived().TransformType(exprFunctionType->getReturnType()); - - auto epi = exprFunctionType->getExtProtoInfo(); - epi.ExtParameterInfos = extParamInfos.getPointerOrNull(paramTypes.size()); - - QualType functionType = - getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi); - blockScope->FunctionType = functionType; - - // Set the parameters on the block decl. - if (!params.empty()) - blockScope->TheDecl->setParams(params); - - if (!oldBlock->blockMissingReturnType()) { - blockScope->HasImplicitReturnType = false; - blockScope->ReturnType = exprResultType; - } - - // Transform the body - StmtResult body = getDerived().TransformStmt(E->getBody()); - if (body.isInvalid()) { - getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr); - return ExprError(); - } - -#ifndef NDEBUG - // In builds with assertions, make sure that we captured everything we - // captured before. - if (!SemaRef.getDiagnostics().hasErrorOccurred()) { - for (const auto &I : oldBlock->captures()) { - VarDecl *oldCapture = I.getVariable(); - - // Ignore parameter packs. - if (isa<ParmVarDecl>(oldCapture) && - cast<ParmVarDecl>(oldCapture)->isParameterPack()) - continue; - - VarDecl *newCapture = - cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(), - oldCapture)); - assert(blockScope->CaptureMap.count(newCapture)); - } - assert(oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured()); - } -#endif - - return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(), - /*Scope=*/nullptr); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) { - llvm_unreachable("Cannot transform asType expressions yet"); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) { - QualType RetTy = getDerived().TransformType(E->getType()); - bool ArgumentChanged = false; - SmallVector<Expr*, 8> SubExprs; - SubExprs.reserve(E->getNumSubExprs()); - if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false, - SubExprs, &ArgumentChanged)) - return ExprError(); - - if (!getDerived().AlwaysRebuild() && - !ArgumentChanged) - return E; - - return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs, - RetTy, E->getOp(), E->getRParenLoc()); -} - -//===----------------------------------------------------------------------===// -// Type reconstruction -//===----------------------------------------------------------------------===// - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType, - SourceLocation Star) { - return SemaRef.BuildPointerType(PointeeType, Star, - getDerived().getBaseEntity()); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType, - SourceLocation Star) { - return SemaRef.BuildBlockPointerType(PointeeType, Star, - getDerived().getBaseEntity()); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType, - bool WrittenAsLValue, - SourceLocation Sigil) { - return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue, - Sigil, getDerived().getBaseEntity()); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType, - QualType ClassType, - SourceLocation Sigil) { - return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Sigil, - getDerived().getBaseEntity()); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildObjCTypeParamType( - const ObjCTypeParamDecl *Decl, - SourceLocation ProtocolLAngleLoc, - ArrayRef<ObjCProtocolDecl *> Protocols, - ArrayRef<SourceLocation> ProtocolLocs, - SourceLocation ProtocolRAngleLoc) { - return SemaRef.BuildObjCTypeParamType(Decl, - ProtocolLAngleLoc, Protocols, - ProtocolLocs, ProtocolRAngleLoc, - /*FailOnError=*/true); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildObjCObjectType( - QualType BaseType, - SourceLocation Loc, - SourceLocation TypeArgsLAngleLoc, - ArrayRef<TypeSourceInfo *> TypeArgs, - SourceLocation TypeArgsRAngleLoc, - SourceLocation ProtocolLAngleLoc, - ArrayRef<ObjCProtocolDecl *> Protocols, - ArrayRef<SourceLocation> ProtocolLocs, - SourceLocation ProtocolRAngleLoc) { - return SemaRef.BuildObjCObjectType(BaseType, Loc, TypeArgsLAngleLoc, - TypeArgs, TypeArgsRAngleLoc, - ProtocolLAngleLoc, Protocols, ProtocolLocs, - ProtocolRAngleLoc, - /*FailOnError=*/true); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildObjCObjectPointerType( - QualType PointeeType, - SourceLocation Star) { - return SemaRef.Context.getObjCObjectPointerType(PointeeType); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::RebuildArrayType(QualType ElementType, - ArrayType::ArraySizeModifier SizeMod, - const llvm::APInt *Size, - Expr *SizeExpr, - unsigned IndexTypeQuals, - SourceRange BracketsRange) { - if (SizeExpr || !Size) - return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr, - IndexTypeQuals, BracketsRange, - getDerived().getBaseEntity()); - - QualType Types[] = { - SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy, - SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy, - SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty - }; - const unsigned NumTypes = llvm::array_lengthof(Types); - QualType SizeType; - for (unsigned I = 0; I != NumTypes; ++I) - if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) { - SizeType = Types[I]; - break; - } - - // Note that we can return a VariableArrayType here in the case where - // the element type was a dependent VariableArrayType. - IntegerLiteral *ArraySize - = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType, - /*FIXME*/BracketsRange.getBegin()); - return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize, - IndexTypeQuals, BracketsRange, - getDerived().getBaseEntity()); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType, - ArrayType::ArraySizeModifier SizeMod, - const llvm::APInt &Size, - unsigned IndexTypeQuals, - SourceRange BracketsRange) { - return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, nullptr, - IndexTypeQuals, BracketsRange); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType, - ArrayType::ArraySizeModifier SizeMod, - unsigned IndexTypeQuals, - SourceRange BracketsRange) { - return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr, - IndexTypeQuals, BracketsRange); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType, - ArrayType::ArraySizeModifier SizeMod, - Expr *SizeExpr, - unsigned IndexTypeQuals, - SourceRange BracketsRange) { - return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, - SizeExpr, - IndexTypeQuals, BracketsRange); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType, - ArrayType::ArraySizeModifier SizeMod, - Expr *SizeExpr, - unsigned IndexTypeQuals, - SourceRange BracketsRange) { - return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, - SizeExpr, - IndexTypeQuals, BracketsRange); -} - -template <typename Derived> -QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType( - QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) { - return SemaRef.BuildAddressSpaceAttr(PointeeType, AddrSpaceExpr, - AttributeLoc); -} - -template <typename Derived> -QualType -TreeTransform<Derived>::RebuildVectorType(QualType ElementType, - unsigned NumElements, - VectorType::VectorKind VecKind) { - // FIXME: semantic checking! - return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind); -} - -template <typename Derived> -QualType TreeTransform<Derived>::RebuildDependentVectorType( - QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc, - VectorType::VectorKind VecKind) { - return SemaRef.BuildVectorType(ElementType, SizeExpr, AttributeLoc); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType, - unsigned NumElements, - SourceLocation AttributeLoc) { - llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy), - NumElements, true); - IntegerLiteral *VectorSize - = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy, - AttributeLoc); - return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc); -} - -template<typename Derived> -QualType -TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType, - Expr *SizeExpr, - SourceLocation AttributeLoc) { - return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildFunctionProtoType( - QualType T, - MutableArrayRef<QualType> ParamTypes, - const FunctionProtoType::ExtProtoInfo &EPI) { - return SemaRef.BuildFunctionType(T, ParamTypes, - getDerived().getBaseLocation(), - getDerived().getBaseEntity(), - EPI); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) { - return SemaRef.Context.getFunctionNoProtoType(T); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc, - Decl *D) { - assert(D && "no decl found"); - if (D->isInvalidDecl()) return QualType(); - - // FIXME: Doesn't account for ObjCInterfaceDecl! - TypeDecl *Ty; - if (auto *UPD = dyn_cast<UsingPackDecl>(D)) { - // A valid resolved using typename pack expansion decl can have multiple - // UsingDecls, but they must each have exactly one type, and it must be - // the same type in every case. But we must have at least one expansion! - if (UPD->expansions().empty()) { - getSema().Diag(Loc, diag::err_using_pack_expansion_empty) - << UPD->isCXXClassMember() << UPD; - return QualType(); - } - - // We might still have some unresolved types. Try to pick a resolved type - // if we can. The final instantiation will check that the remaining - // unresolved types instantiate to the type we pick. - QualType FallbackT; - QualType T; - for (auto *E : UPD->expansions()) { - QualType ThisT = RebuildUnresolvedUsingType(Loc, E); - if (ThisT.isNull()) - continue; - else if (ThisT->getAs<UnresolvedUsingType>()) - FallbackT = ThisT; - else if (T.isNull()) - T = ThisT; - else - assert(getSema().Context.hasSameType(ThisT, T) && - "mismatched resolved types in using pack expansion"); - } - return T.isNull() ? FallbackT : T; - } else if (auto *Using = dyn_cast<UsingDecl>(D)) { - assert(Using->hasTypename() && - "UnresolvedUsingTypenameDecl transformed to non-typename using"); - - // A valid resolved using typename decl points to exactly one type decl. - assert(++Using->shadow_begin() == Using->shadow_end()); - Ty = cast<TypeDecl>((*Using->shadow_begin())->getTargetDecl()); - } else { - assert(isa<UnresolvedUsingTypenameDecl>(D) && - "UnresolvedUsingTypenameDecl transformed to non-using decl"); - Ty = cast<UnresolvedUsingTypenameDecl>(D); - } - - return SemaRef.Context.getTypeDeclType(Ty); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, - SourceLocation Loc) { - return SemaRef.BuildTypeofExprType(E, Loc); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) { - return SemaRef.Context.getTypeOfType(Underlying); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, - SourceLocation Loc) { - return SemaRef.BuildDecltypeType(E, Loc); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType, - UnaryTransformType::UTTKind UKind, - SourceLocation Loc) { - return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildTemplateSpecializationType( - TemplateName Template, - SourceLocation TemplateNameLoc, - TemplateArgumentListInfo &TemplateArgs) { - return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType, - SourceLocation KWLoc) { - return SemaRef.BuildAtomicType(ValueType, KWLoc); -} - -template<typename Derived> -QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType, - SourceLocation KWLoc, - bool isReadPipe) { - return isReadPipe ? SemaRef.BuildReadPipeType(ValueType, KWLoc) - : SemaRef.BuildWritePipeType(ValueType, KWLoc); -} - -template<typename Derived> -TemplateName -TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, - bool TemplateKW, - TemplateDecl *Template) { - return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW, - Template); -} - -template<typename Derived> -TemplateName -TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - const IdentifierInfo &Name, - SourceLocation NameLoc, - QualType ObjectType, - NamedDecl *FirstQualifierInScope, - bool AllowInjectedClassName) { - UnqualifiedId TemplateName; - TemplateName.setIdentifier(&Name, NameLoc); - Sema::TemplateTy Template; - getSema().ActOnDependentTemplateName(/*Scope=*/nullptr, - SS, TemplateKWLoc, TemplateName, - ParsedType::make(ObjectType), - /*EnteringContext=*/false, - Template, AllowInjectedClassName); - return Template.get(); -} - -template<typename Derived> -TemplateName -TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, - SourceLocation TemplateKWLoc, - OverloadedOperatorKind Operator, - SourceLocation NameLoc, - QualType ObjectType, - bool AllowInjectedClassName) { - UnqualifiedId Name; - // FIXME: Bogus location information. - SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc }; - Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations); - Sema::TemplateTy Template; - getSema().ActOnDependentTemplateName(/*Scope=*/nullptr, - SS, TemplateKWLoc, Name, - ParsedType::make(ObjectType), - /*EnteringContext=*/false, - Template, AllowInjectedClassName); - return Template.get(); -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op, - SourceLocation OpLoc, - Expr *OrigCallee, - Expr *First, - Expr *Second) { - Expr *Callee = OrigCallee->IgnoreParenCasts(); - bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus); - - if (First->getObjectKind() == OK_ObjCProperty) { - BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op); - if (BinaryOperator::isAssignmentOp(Opc)) - return SemaRef.checkPseudoObjectAssignment(/*Scope=*/nullptr, OpLoc, Opc, - First, Second); - ExprResult Result = SemaRef.CheckPlaceholderExpr(First); - if (Result.isInvalid()) - return ExprError(); - First = Result.get(); - } - - if (Second && Second->getObjectKind() == OK_ObjCProperty) { - ExprResult Result = SemaRef.CheckPlaceholderExpr(Second); - if (Result.isInvalid()) - return ExprError(); - Second = Result.get(); - } - - // Determine whether this should be a builtin operation. - if (Op == OO_Subscript) { - if (!First->getType()->isOverloadableType() && - !Second->getType()->isOverloadableType()) - return getSema().CreateBuiltinArraySubscriptExpr( - First, Callee->getBeginLoc(), Second, OpLoc); - } else if (Op == OO_Arrow) { - // -> is never a builtin operation. - return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc); - } else if (Second == nullptr || isPostIncDec) { - if (!First->getType()->isOverloadableType() || - (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) { - // The argument is not of overloadable type, or this is an expression - // of the form &Class::member, so try to create a built-in unary - // operation. - UnaryOperatorKind Opc - = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec); - - return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First); - } - } else { - if (!First->getType()->isOverloadableType() && - !Second->getType()->isOverloadableType()) { - // Neither of the arguments is an overloadable type, so try to - // create a built-in binary operation. - BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op); - ExprResult Result - = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second); - if (Result.isInvalid()) - return ExprError(); - - return Result; - } - } - - // Compute the transformed set of functions (and function templates) to be - // used during overload resolution. - UnresolvedSet<16> Functions; - bool RequiresADL; - - if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) { - Functions.append(ULE->decls_begin(), ULE->decls_end()); - // If the overload could not be resolved in the template definition - // (because we had a dependent argument), ADL is performed as part of - // template instantiation. - RequiresADL = ULE->requiresADL(); - } else { - // If we've resolved this to a particular non-member function, just call - // that function. If we resolved it to a member function, - // CreateOverloaded* will find that function for us. - NamedDecl *ND = cast<DeclRefExpr>(Callee)->getDecl(); - if (!isa<CXXMethodDecl>(ND)) - Functions.addDecl(ND); - RequiresADL = false; - } - - // Add any functions found via argument-dependent lookup. - Expr *Args[2] = { First, Second }; - unsigned NumArgs = 1 + (Second != nullptr); - - // Create the overloaded operator invocation for unary operators. - if (NumArgs == 1 || isPostIncDec) { - UnaryOperatorKind Opc - = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec); - return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First, - RequiresADL); - } - - if (Op == OO_Subscript) { - SourceLocation LBrace; - SourceLocation RBrace; - - if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee)) { - DeclarationNameLoc NameLoc = DRE->getNameInfo().getInfo(); - LBrace = SourceLocation::getFromRawEncoding( - NameLoc.CXXOperatorName.BeginOpNameLoc); - RBrace = SourceLocation::getFromRawEncoding( - NameLoc.CXXOperatorName.EndOpNameLoc); - } else { - LBrace = Callee->getBeginLoc(); - RBrace = OpLoc; - } - - return SemaRef.CreateOverloadedArraySubscriptExpr(LBrace, RBrace, - First, Second); - } - - // Create the overloaded operator invocation for binary operators. - BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op); - ExprResult Result = SemaRef.CreateOverloadedBinOp( - OpLoc, Opc, Functions, Args[0], Args[1], RequiresADL); - if (Result.isInvalid()) - return ExprError(); - - return Result; -} - -template<typename Derived> -ExprResult -TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base, - SourceLocation OperatorLoc, - bool isArrow, - CXXScopeSpec &SS, - TypeSourceInfo *ScopeType, - SourceLocation CCLoc, - SourceLocation TildeLoc, - PseudoDestructorTypeStorage Destroyed) { - QualType BaseType = Base->getType(); - if (Base->isTypeDependent() || Destroyed.getIdentifier() || - (!isArrow && !BaseType->getAs<RecordType>()) || - (isArrow && BaseType->getAs<PointerType>() && - !BaseType->getAs<PointerType>()->getPointeeType() - ->template getAs<RecordType>())){ - // This pseudo-destructor expression is still a pseudo-destructor. - return SemaRef.BuildPseudoDestructorExpr( - Base, OperatorLoc, isArrow ? tok::arrow : tok::period, SS, ScopeType, - CCLoc, TildeLoc, Destroyed); - } - - TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo(); - DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName( - SemaRef.Context.getCanonicalType(DestroyedType->getType()))); - DeclarationNameInfo NameInfo(Name, Destroyed.getLocation()); - NameInfo.setNamedTypeInfo(DestroyedType); - - // The scope type is now known to be a valid nested name specifier - // component. Tack it on to the end of the nested name specifier. - if (ScopeType) { - if (!ScopeType->getType()->getAs<TagType>()) { - getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(), - diag::err_expected_class_or_namespace) - << ScopeType->getType() << getSema().getLangOpts().CPlusPlus; - return ExprError(); - } - SS.Extend(SemaRef.Context, SourceLocation(), ScopeType->getTypeLoc(), - CCLoc); - } - - SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller. - return getSema().BuildMemberReferenceExpr(Base, BaseType, - OperatorLoc, isArrow, - SS, TemplateKWLoc, - /*FIXME: FirstQualifier*/ nullptr, - NameInfo, - /*TemplateArgs*/ nullptr, - /*S*/nullptr); -} - -template<typename Derived> -StmtResult -TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) { - SourceLocation Loc = S->getBeginLoc(); - CapturedDecl *CD = S->getCapturedDecl(); - unsigned NumParams = CD->getNumParams(); - unsigned ContextParamPos = CD->getContextParamPosition(); - SmallVector<Sema::CapturedParamNameType, 4> Params; - for (unsigned I = 0; I < NumParams; ++I) { - if (I != ContextParamPos) { - Params.push_back( - std::make_pair( - CD->getParam(I)->getName(), - getDerived().TransformType(CD->getParam(I)->getType()))); - } else { - Params.push_back(std::make_pair(StringRef(), QualType())); - } - } - getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr, - S->getCapturedRegionKind(), Params); - StmtResult Body; - { - Sema::CompoundScopeRAII CompoundScope(getSema()); - Body = getDerived().TransformStmt(S->getCapturedStmt()); - } - - if (Body.isInvalid()) { - getSema().ActOnCapturedRegionError(); - return StmtError(); - } - - return getSema().ActOnCapturedRegionEnd(Body.get()); -} - -} // end namespace clang - -#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H |
