1218893Sdim//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===// 2198092Srdivacky// 3198092Srdivacky// The LLVM Compiler Infrastructure 4198092Srdivacky// 5198092Srdivacky// This file is distributed under the University of Illinois Open Source 6198092Srdivacky// License. See LICENSE.TXT for details. 7218893Sdim//===----------------------------------------------------------------------===// 8198092Srdivacky// 9198092Srdivacky// This file implements a semantic tree transformation that takes a given 10198092Srdivacky// AST and rebuilds it, possibly transforming some nodes in the process. 11198092Srdivacky// 12218893Sdim//===----------------------------------------------------------------------===// 13218893Sdim 14198092Srdivacky#ifndef LLVM_CLANG_SEMA_TREETRANSFORM_H 15198092Srdivacky#define LLVM_CLANG_SEMA_TREETRANSFORM_H 16198092Srdivacky 17249423Sdim#include "TypeLocBuilder.h" 18198092Srdivacky#include "clang/AST/Decl.h" 19212904Sdim#include "clang/AST/DeclObjC.h" 20223017Sdim#include "clang/AST/DeclTemplate.h" 21198092Srdivacky#include "clang/AST/Expr.h" 22198092Srdivacky#include "clang/AST/ExprCXX.h" 23198092Srdivacky#include "clang/AST/ExprObjC.h" 24198092Srdivacky#include "clang/AST/Stmt.h" 25198092Srdivacky#include "clang/AST/StmtCXX.h" 26198092Srdivacky#include "clang/AST/StmtObjC.h" 27263508Sdim#include "clang/AST/StmtOpenMP.h" 28249423Sdim#include "clang/Lex/Preprocessor.h" 29249423Sdim#include "clang/Sema/Designator.h" 30249423Sdim#include "clang/Sema/Lookup.h" 31212904Sdim#include "clang/Sema/Ownership.h" 32249423Sdim#include "clang/Sema/ParsedTemplate.h" 33249423Sdim#include "clang/Sema/ScopeInfo.h" 34249423Sdim#include "clang/Sema/SemaDiagnostic.h" 35249423Sdim#include "clang/Sema/SemaInternal.h" 36226633Sdim#include "llvm/ADT/ArrayRef.h" 37198398Srdivacky#include "llvm/Support/ErrorHandling.h" 38198092Srdivacky#include <algorithm> 39198092Srdivacky 40198092Srdivackynamespace clang { 41212904Sdimusing namespace sema; 42198092Srdivacky 43198092Srdivacky/// \brief A semantic tree transformation that allows one to transform one 44198092Srdivacky/// abstract syntax tree into another. 45198092Srdivacky/// 46198092Srdivacky/// A new tree transformation is defined by creating a new subclass \c X of 47198092Srdivacky/// \c TreeTransform<X> and then overriding certain operations to provide 48198092Srdivacky/// behavior specific to that transformation. For example, template 49198092Srdivacky/// instantiation is implemented as a tree transformation where the 50198092Srdivacky/// transformation of TemplateTypeParmType nodes involves substituting the 51198092Srdivacky/// template arguments for their corresponding template parameters; a similar 52198092Srdivacky/// transformation is performed for non-type template parameters and 53198092Srdivacky/// template template parameters. 54198092Srdivacky/// 55198092Srdivacky/// This tree-transformation template uses static polymorphism to allow 56198092Srdivacky/// subclasses to customize any of its operations. Thus, a subclass can 57198092Srdivacky/// override any of the transformation or rebuild operators by providing an 58198092Srdivacky/// operation with the same signature as the default implementation. The 59198092Srdivacky/// overridding function should not be virtual. 60198092Srdivacky/// 61198092Srdivacky/// Semantic tree transformations are split into two stages, either of which 62198092Srdivacky/// can be replaced by a subclass. The "transform" step transforms an AST node 63198092Srdivacky/// or the parts of an AST node using the various transformation functions, 64198092Srdivacky/// then passes the pieces on to the "rebuild" step, which constructs a new AST 65198092Srdivacky/// node of the appropriate kind from the pieces. The default transformation 66198092Srdivacky/// routines recursively transform the operands to composite AST nodes (e.g., 67198092Srdivacky/// the pointee type of a PointerType node) and, if any of those operand nodes 68198092Srdivacky/// were changed by the transformation, invokes the rebuild operation to create 69198092Srdivacky/// a new AST node. 70198092Srdivacky/// 71198092Srdivacky/// Subclasses can customize the transformation at various levels. The 72198092Srdivacky/// most coarse-grained transformations involve replacing TransformType(), 73221345Sdim/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(), 74198092Srdivacky/// TransformTemplateName(), or TransformTemplateArgument() with entirely 75198092Srdivacky/// new implementations. 76198092Srdivacky/// 77198092Srdivacky/// For more fine-grained transformations, subclasses can replace any of the 78198092Srdivacky/// \c TransformXXX functions (where XXX is the name of an AST node, e.g., 79198092Srdivacky/// PointerType, StmtExpr) to alter the transformation. As mentioned previously, 80198092Srdivacky/// replacing TransformTemplateTypeParmType() allows template instantiation 81198092Srdivacky/// to substitute template arguments for their corresponding template 82198092Srdivacky/// parameters. Additionally, subclasses can override the \c RebuildXXX 83198092Srdivacky/// functions to control how AST nodes are rebuilt when their operands change. 84198092Srdivacky/// By default, \c TreeTransform will invoke semantic analysis to rebuild 85198092Srdivacky/// AST nodes. However, certain other tree transformations (e.g, cloning) may 86198092Srdivacky/// be able to use more efficient rebuild steps. 87198092Srdivacky/// 88198092Srdivacky/// There are a handful of other functions that can be overridden, allowing one 89198092Srdivacky/// to avoid traversing nodes that don't need any transformation 90198092Srdivacky/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their 91198092Srdivacky/// operands have not changed (\c AlwaysRebuild()), and customize the 92198092Srdivacky/// default locations and entity names used for type-checking 93198092Srdivacky/// (\c getBaseLocation(), \c getBaseEntity()). 94198092Srdivackytemplate<typename Derived> 95198092Srdivackyclass TreeTransform { 96218893Sdim /// \brief Private RAII object that helps us forget and then re-remember 97218893Sdim /// the template argument corresponding to a partially-substituted parameter 98218893Sdim /// pack. 99218893Sdim class ForgetPartiallySubstitutedPackRAII { 100218893Sdim Derived &Self; 101218893Sdim TemplateArgument Old; 102239462Sdim 103218893Sdim public: 104218893Sdim ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) { 105218893Sdim Old = Self.ForgetPartiallySubstitutedPack(); 106218893Sdim } 107239462Sdim 108218893Sdim ~ForgetPartiallySubstitutedPackRAII() { 109218893Sdim Self.RememberPartiallySubstitutedPack(Old); 110218893Sdim } 111218893Sdim }; 112239462Sdim 113198092Srdivackyprotected: 114198092Srdivacky Sema &SemaRef; 115239462Sdim 116234353Sdim /// \brief The set of local declarations that have been transformed, for 117234353Sdim /// cases where we are forced to build new declarations within the transformer 118234353Sdim /// rather than in the subclass (e.g., lambda closure types). 119234353Sdim llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls; 120239462Sdim 121198092Srdivackypublic: 122198092Srdivacky /// \brief Initializes a new tree transformer. 123198092Srdivacky TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { } 124198092Srdivacky 125198092Srdivacky /// \brief Retrieves a reference to the derived class. 126198092Srdivacky Derived &getDerived() { return static_cast<Derived&>(*this); } 127198092Srdivacky 128198092Srdivacky /// \brief Retrieves a reference to the derived class. 129198092Srdivacky const Derived &getDerived() const { 130198092Srdivacky return static_cast<const Derived&>(*this); 131198092Srdivacky } 132198092Srdivacky 133212904Sdim static inline ExprResult Owned(Expr *E) { return E; } 134212904Sdim static inline StmtResult Owned(Stmt *S) { return S; } 135212904Sdim 136198092Srdivacky /// \brief Retrieves a reference to the semantic analysis object used for 137198092Srdivacky /// this tree transform. 138198092Srdivacky Sema &getSema() const { return SemaRef; } 139198092Srdivacky 140198092Srdivacky /// \brief Whether the transformation should always rebuild AST nodes, even 141198092Srdivacky /// if none of the children have changed. 142198092Srdivacky /// 143198092Srdivacky /// Subclasses may override this function to specify when the transformation 144198092Srdivacky /// should rebuild all AST nodes. 145263508Sdim /// 146263508Sdim /// We must always rebuild all AST nodes when performing variadic template 147263508Sdim /// pack expansion, in order to avoid violating the AST invariant that each 148263508Sdim /// statement node appears at most once in its containing declaration. 149263508Sdim bool AlwaysRebuild() { return SemaRef.ArgumentPackSubstitutionIndex != -1; } 150198092Srdivacky 151198092Srdivacky /// \brief Returns the location of the entity being transformed, if that 152198092Srdivacky /// information was not available elsewhere in the AST. 153198092Srdivacky /// 154198092Srdivacky /// By default, returns no source-location information. Subclasses can 155198092Srdivacky /// provide an alternative implementation that provides better location 156198092Srdivacky /// information. 157198092Srdivacky SourceLocation getBaseLocation() { return SourceLocation(); } 158198092Srdivacky 159198092Srdivacky /// \brief Returns the name of the entity being transformed, if that 160198092Srdivacky /// information was not available elsewhere in the AST. 161198092Srdivacky /// 162198092Srdivacky /// By default, returns an empty name. Subclasses can provide an alternative 163198092Srdivacky /// implementation with a more precise name. 164198092Srdivacky DeclarationName getBaseEntity() { return DeclarationName(); } 165198092Srdivacky 166198092Srdivacky /// \brief Sets the "base" location and entity when that 167198092Srdivacky /// information is known based on another transformation. 168198092Srdivacky /// 169198092Srdivacky /// By default, the source location and entity are ignored. Subclasses can 170198092Srdivacky /// override this function to provide a customized implementation. 171198092Srdivacky void setBase(SourceLocation Loc, DeclarationName Entity) { } 172198092Srdivacky 173198092Srdivacky /// \brief RAII object that temporarily sets the base location and entity 174198092Srdivacky /// used for reporting diagnostics in types. 175198092Srdivacky class TemporaryBase { 176198092Srdivacky TreeTransform &Self; 177198092Srdivacky SourceLocation OldLocation; 178198092Srdivacky DeclarationName OldEntity; 179198092Srdivacky 180198092Srdivacky public: 181198092Srdivacky TemporaryBase(TreeTransform &Self, SourceLocation Location, 182198092Srdivacky DeclarationName Entity) : Self(Self) { 183198092Srdivacky OldLocation = Self.getDerived().getBaseLocation(); 184198092Srdivacky OldEntity = Self.getDerived().getBaseEntity(); 185239462Sdim 186218893Sdim if (Location.isValid()) 187218893Sdim Self.getDerived().setBase(Location, Entity); 188198092Srdivacky } 189198092Srdivacky 190198092Srdivacky ~TemporaryBase() { 191198092Srdivacky Self.getDerived().setBase(OldLocation, OldEntity); 192198092Srdivacky } 193198092Srdivacky }; 194198092Srdivacky 195198092Srdivacky /// \brief Determine whether the given type \p T has already been 196198092Srdivacky /// transformed. 197198092Srdivacky /// 198198092Srdivacky /// Subclasses can provide an alternative implementation of this routine 199198092Srdivacky /// to short-circuit evaluation when it is known that a given type will 200198092Srdivacky /// not change. For example, template instantiation need not traverse 201198092Srdivacky /// non-dependent types. 202198092Srdivacky bool AlreadyTransformed(QualType T) { 203198092Srdivacky return T.isNull(); 204198092Srdivacky } 205198092Srdivacky 206200583Srdivacky /// \brief Determine whether the given call argument should be dropped, e.g., 207200583Srdivacky /// because it is a default argument. 208200583Srdivacky /// 209200583Srdivacky /// Subclasses can provide an alternative implementation of this routine to 210200583Srdivacky /// determine which kinds of call arguments get dropped. By default, 211200583Srdivacky /// CXXDefaultArgument nodes are dropped (prior to transformation). 212200583Srdivacky bool DropCallArgument(Expr *E) { 213200583Srdivacky return E->isDefaultArgument(); 214200583Srdivacky } 215239462Sdim 216218893Sdim /// \brief Determine whether we should expand a pack expansion with the 217218893Sdim /// given set of parameter packs into separate arguments by repeatedly 218218893Sdim /// transforming the pattern. 219218893Sdim /// 220218893Sdim /// By default, the transformer never tries to expand pack expansions. 221218893Sdim /// Subclasses can override this routine to provide different behavior. 222218893Sdim /// 223218893Sdim /// \param EllipsisLoc The location of the ellipsis that identifies the 224218893Sdim /// pack expansion. 225218893Sdim /// 226218893Sdim /// \param PatternRange The source range that covers the entire pattern of 227218893Sdim /// the pack expansion. 228218893Sdim /// 229239462Sdim /// \param Unexpanded The set of unexpanded parameter packs within the 230218893Sdim /// pattern. 231218893Sdim /// 232218893Sdim /// \param ShouldExpand Will be set to \c true if the transformer should 233218893Sdim /// expand the corresponding pack expansions into separate arguments. When 234218893Sdim /// set, \c NumExpansions must also be set. 235218893Sdim /// 236218893Sdim /// \param RetainExpansion Whether the caller should add an unexpanded 237218893Sdim /// pack expansion after all of the expanded arguments. This is used 238218893Sdim /// when extending explicitly-specified template argument packs per 239218893Sdim /// C++0x [temp.arg.explicit]p9. 240218893Sdim /// 241218893Sdim /// \param NumExpansions The number of separate arguments that will be in 242218893Sdim /// the expanded form of the corresponding pack expansion. This is both an 243218893Sdim /// input and an output parameter, which can be set by the caller if the 244218893Sdim /// number of expansions is known a priori (e.g., due to a prior substitution) 245218893Sdim /// and will be set by the callee when the number of expansions is known. 246218893Sdim /// The callee must set this value when \c ShouldExpand is \c true; it may 247218893Sdim /// set this value in other cases. 248218893Sdim /// 249239462Sdim /// \returns true if an error occurred (e.g., because the parameter packs 250239462Sdim /// are to be instantiated with arguments of different lengths), false 251239462Sdim /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions) 252218893Sdim /// must be set. 253218893Sdim bool TryExpandParameterPacks(SourceLocation EllipsisLoc, 254218893Sdim SourceRange PatternRange, 255249423Sdim ArrayRef<UnexpandedParameterPack> Unexpanded, 256218893Sdim bool &ShouldExpand, 257218893Sdim bool &RetainExpansion, 258249423Sdim Optional<unsigned> &NumExpansions) { 259218893Sdim ShouldExpand = false; 260218893Sdim return false; 261218893Sdim } 262239462Sdim 263218893Sdim /// \brief "Forget" about the partially-substituted pack template argument, 264218893Sdim /// when performing an instantiation that must preserve the parameter pack 265218893Sdim /// use. 266218893Sdim /// 267218893Sdim /// This routine is meant to be overridden by the template instantiator. 268218893Sdim TemplateArgument ForgetPartiallySubstitutedPack() { 269218893Sdim return TemplateArgument(); 270218893Sdim } 271239462Sdim 272218893Sdim /// \brief "Remember" the partially-substituted pack template argument 273218893Sdim /// after performing an instantiation that must preserve the parameter pack 274218893Sdim /// use. 275218893Sdim /// 276218893Sdim /// This routine is meant to be overridden by the template instantiator. 277218893Sdim void RememberPartiallySubstitutedPack(TemplateArgument Arg) { } 278239462Sdim 279218893Sdim /// \brief Note to the derived class when a function parameter pack is 280218893Sdim /// being expanded. 281218893Sdim void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { } 282239462Sdim 283198092Srdivacky /// \brief Transforms the given type into another type. 284198092Srdivacky /// 285198398Srdivacky /// By default, this routine transforms a type by creating a 286200583Srdivacky /// TypeSourceInfo for it and delegating to the appropriate 287198398Srdivacky /// function. This is expensive, but we don't mind, because 288198398Srdivacky /// this method is deprecated anyway; all users should be 289200583Srdivacky /// switched to storing TypeSourceInfos. 290198092Srdivacky /// 291198092Srdivacky /// \returns the transformed type. 292218893Sdim QualType TransformType(QualType T); 293198092Srdivacky 294198398Srdivacky /// \brief Transforms the given type-with-location into a new 295198398Srdivacky /// type-with-location. 296198092Srdivacky /// 297198398Srdivacky /// By default, this routine transforms a type by delegating to the 298198398Srdivacky /// appropriate TransformXXXType to build a new type. Subclasses 299198398Srdivacky /// may override this function (to take over all type 300198398Srdivacky /// transformations) or some set of the TransformXXXType functions 301198398Srdivacky /// to alter the transformation. 302218893Sdim TypeSourceInfo *TransformType(TypeSourceInfo *DI); 303198092Srdivacky 304198398Srdivacky /// \brief Transform the given type-with-location into a new 305198398Srdivacky /// type, collecting location information in the given builder 306198398Srdivacky /// as necessary. 307198398Srdivacky /// 308218893Sdim QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL); 309198398Srdivacky 310198092Srdivacky /// \brief Transform the given statement. 311198092Srdivacky /// 312198092Srdivacky /// By default, this routine transforms a statement by delegating to the 313198092Srdivacky /// appropriate TransformXXXStmt function to transform a specific kind of 314198092Srdivacky /// statement or the TransformExpr() function to transform an expression. 315198092Srdivacky /// Subclasses may override this function to transform statements using some 316198092Srdivacky /// other mechanism. 317198092Srdivacky /// 318198092Srdivacky /// \returns the transformed statement. 319212904Sdim StmtResult TransformStmt(Stmt *S); 320198092Srdivacky 321263508Sdim /// \brief Transform the given statement. 322263508Sdim /// 323263508Sdim /// By default, this routine transforms a statement by delegating to the 324263508Sdim /// appropriate TransformOMPXXXClause function to transform a specific kind 325263508Sdim /// of clause. Subclasses may override this function to transform statements 326263508Sdim /// using some other mechanism. 327263508Sdim /// 328263508Sdim /// \returns the transformed OpenMP clause. 329263508Sdim OMPClause *TransformOMPClause(OMPClause *S); 330263508Sdim 331198092Srdivacky /// \brief Transform the given expression. 332198092Srdivacky /// 333198092Srdivacky /// By default, this routine transforms an expression by delegating to the 334198092Srdivacky /// appropriate TransformXXXExpr function to build a new expression. 335198092Srdivacky /// Subclasses may override this function to transform expressions using some 336198092Srdivacky /// other mechanism. 337198092Srdivacky /// 338198092Srdivacky /// \returns the transformed expression. 339212904Sdim ExprResult TransformExpr(Expr *E); 340198092Srdivacky 341249423Sdim /// \brief Transform the given initializer. 342249423Sdim /// 343249423Sdim /// By default, this routine transforms an initializer by stripping off the 344249423Sdim /// semantic nodes added by initialization, then passing the result to 345249423Sdim /// TransformExpr or TransformExprs. 346249423Sdim /// 347249423Sdim /// \returns the transformed initializer. 348249423Sdim ExprResult TransformInitializer(Expr *Init, bool CXXDirectInit); 349249423Sdim 350218893Sdim /// \brief Transform the given list of expressions. 351218893Sdim /// 352239462Sdim /// This routine transforms a list of expressions by invoking 353239462Sdim /// \c TransformExpr() for each subexpression. However, it also provides 354218893Sdim /// support for variadic templates by expanding any pack expansions (if the 355218893Sdim /// derived class permits such expansion) along the way. When pack expansions 356218893Sdim /// are present, the number of outputs may not equal the number of inputs. 357218893Sdim /// 358218893Sdim /// \param Inputs The set of expressions to be transformed. 359218893Sdim /// 360218893Sdim /// \param NumInputs The number of expressions in \c Inputs. 361218893Sdim /// 362218893Sdim /// \param IsCall If \c true, then this transform is being performed on 363239462Sdim /// function-call arguments, and any arguments that should be dropped, will 364218893Sdim /// be. 365218893Sdim /// 366218893Sdim /// \param Outputs The transformed input expressions will be added to this 367218893Sdim /// vector. 368218893Sdim /// 369218893Sdim /// \param ArgChanged If non-NULL, will be set \c true if any argument changed 370218893Sdim /// due to transformation. 371218893Sdim /// 372218893Sdim /// \returns true if an error occurred, false otherwise. 373218893Sdim bool TransformExprs(Expr **Inputs, unsigned NumInputs, bool IsCall, 374226633Sdim SmallVectorImpl<Expr *> &Outputs, 375218893Sdim bool *ArgChanged = 0); 376239462Sdim 377198092Srdivacky /// \brief Transform the given declaration, which is referenced from a type 378198092Srdivacky /// or expression. 379198092Srdivacky /// 380234353Sdim /// By default, acts as the identity function on declarations, unless the 381234353Sdim /// transformer has had to transform the declaration itself. Subclasses 382198092Srdivacky /// may override this function to provide alternate behavior. 383239462Sdim Decl *TransformDecl(SourceLocation Loc, Decl *D) { 384234353Sdim llvm::DenseMap<Decl *, Decl *>::iterator Known 385234353Sdim = TransformedLocalDecls.find(D); 386234353Sdim if (Known != TransformedLocalDecls.end()) 387234353Sdim return Known->second; 388239462Sdim 389239462Sdim return D; 390234353Sdim } 391198092Srdivacky 392239462Sdim /// \brief Transform the attributes associated with the given declaration and 393234353Sdim /// place them on the new declaration. 394234353Sdim /// 395234353Sdim /// By default, this operation does nothing. Subclasses may override this 396234353Sdim /// behavior to transform attributes. 397234353Sdim void transformAttrs(Decl *Old, Decl *New) { } 398239462Sdim 399234353Sdim /// \brief Note that a local declaration has been transformed by this 400234353Sdim /// transformer. 401234353Sdim /// 402239462Sdim /// Local declarations are typically transformed via a call to 403234353Sdim /// TransformDefinition. However, in some cases (e.g., lambda expressions), 404234353Sdim /// the transformer itself has to transform the declarations. This routine 405234353Sdim /// can be overridden by a subclass that keeps track of such mappings. 406234353Sdim void transformedLocalDecl(Decl *Old, Decl *New) { 407234353Sdim TransformedLocalDecls[Old] = New; 408234353Sdim } 409239462Sdim 410198092Srdivacky /// \brief Transform the definition of the given declaration. 411198092Srdivacky /// 412198092Srdivacky /// By default, invokes TransformDecl() to transform the declaration. 413198092Srdivacky /// Subclasses may override this function to provide alternate behavior. 414239462Sdim Decl *TransformDefinition(SourceLocation Loc, Decl *D) { 415239462Sdim return getDerived().TransformDecl(Loc, D); 416204643Srdivacky } 417198092Srdivacky 418198398Srdivacky /// \brief Transform the given declaration, which was the first part of a 419198398Srdivacky /// nested-name-specifier in a member access expression. 420198398Srdivacky /// 421239462Sdim /// This specific declaration transformation only applies to the first 422198398Srdivacky /// identifier in a nested-name-specifier of a member access expression, e.g., 423198398Srdivacky /// the \c T in \c x->T::member 424198398Srdivacky /// 425198398Srdivacky /// By default, invokes TransformDecl() to transform the declaration. 426198398Srdivacky /// Subclasses may override this function to provide alternate behavior. 427239462Sdim NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) { 428239462Sdim return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D)); 429198398Srdivacky } 430239462Sdim 431219077Sdim /// \brief Transform the given nested-name-specifier with source-location 432219077Sdim /// information. 433219077Sdim /// 434219077Sdim /// By default, transforms all of the types and declarations within the 435219077Sdim /// nested-name-specifier. Subclasses may override this function to provide 436219077Sdim /// alternate behavior. 437219077Sdim NestedNameSpecifierLoc TransformNestedNameSpecifierLoc( 438219077Sdim NestedNameSpecifierLoc NNS, 439219077Sdim QualType ObjectType = QualType(), 440219077Sdim NamedDecl *FirstQualifierInScope = 0); 441219077Sdim 442198092Srdivacky /// \brief Transform the given declaration name. 443198092Srdivacky /// 444198092Srdivacky /// By default, transforms the types of conversion function, constructor, 445198092Srdivacky /// and destructor names and then (if needed) rebuilds the declaration name. 446198092Srdivacky /// Identifiers and selectors are returned unmodified. Sublcasses may 447198092Srdivacky /// override this function to provide alternate behavior. 448212904Sdim DeclarationNameInfo 449218893Sdim TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo); 450198092Srdivacky 451198092Srdivacky /// \brief Transform the given template name. 452198092Srdivacky /// 453221345Sdim /// \param SS The nested-name-specifier that qualifies the template 454221345Sdim /// name. This nested-name-specifier must already have been transformed. 455221345Sdim /// 456221345Sdim /// \param Name The template name to transform. 457221345Sdim /// 458221345Sdim /// \param NameLoc The source location of the template name. 459221345Sdim /// 460239462Sdim /// \param ObjectType If we're translating a template name within a member 461221345Sdim /// access expression, this is the type of the object whose member template 462221345Sdim /// is being referenced. 463221345Sdim /// 464221345Sdim /// \param FirstQualifierInScope If the first part of a nested-name-specifier 465221345Sdim /// also refers to a name within the current (lexical) scope, this is the 466221345Sdim /// declaration it refers to. 467221345Sdim /// 468198092Srdivacky /// By default, transforms the template name by transforming the declarations 469198092Srdivacky /// and nested-name-specifiers that occur within the template name. 470198092Srdivacky /// Subclasses may override this function to provide alternate behavior. 471221345Sdim TemplateName TransformTemplateName(CXXScopeSpec &SS, 472221345Sdim TemplateName Name, 473234353Sdim SourceLocation NameLoc, 474218893Sdim QualType ObjectType = QualType(), 475218893Sdim NamedDecl *FirstQualifierInScope = 0); 476198092Srdivacky 477198092Srdivacky /// \brief Transform the given template argument. 478198092Srdivacky /// 479198092Srdivacky /// By default, this operation transforms the type, expression, or 480198092Srdivacky /// declaration stored within the template argument and constructs a 481198092Srdivacky /// new template argument from the transformed result. Subclasses may 482198092Srdivacky /// override this function to provide alternate behavior. 483198893Srdivacky /// 484198893Srdivacky /// Returns true if there was an error. 485198893Srdivacky bool TransformTemplateArgument(const TemplateArgumentLoc &Input, 486198893Srdivacky TemplateArgumentLoc &Output); 487198092Srdivacky 488218893Sdim /// \brief Transform the given set of template arguments. 489218893Sdim /// 490239462Sdim /// By default, this operation transforms all of the template arguments 491218893Sdim /// in the input set using \c TransformTemplateArgument(), and appends 492218893Sdim /// the transformed arguments to the output list. 493218893Sdim /// 494218893Sdim /// Note that this overload of \c TransformTemplateArguments() is merely 495218893Sdim /// a convenience function. Subclasses that wish to override this behavior 496218893Sdim /// should override the iterator-based member template version. 497218893Sdim /// 498218893Sdim /// \param Inputs The set of template arguments to be transformed. 499218893Sdim /// 500218893Sdim /// \param NumInputs The number of template arguments in \p Inputs. 501218893Sdim /// 502218893Sdim /// \param Outputs The set of transformed template arguments output by this 503218893Sdim /// routine. 504218893Sdim /// 505218893Sdim /// Returns true if an error occurred. 506218893Sdim bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs, 507218893Sdim unsigned NumInputs, 508218893Sdim TemplateArgumentListInfo &Outputs) { 509218893Sdim return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs); 510218893Sdim } 511218893Sdim 512218893Sdim /// \brief Transform the given set of template arguments. 513218893Sdim /// 514239462Sdim /// By default, this operation transforms all of the template arguments 515218893Sdim /// in the input set using \c TransformTemplateArgument(), and appends 516239462Sdim /// the transformed arguments to the output list. 517218893Sdim /// 518218893Sdim /// \param First An iterator to the first template argument. 519218893Sdim /// 520218893Sdim /// \param Last An iterator one step past the last template argument. 521218893Sdim /// 522218893Sdim /// \param Outputs The set of transformed template arguments output by this 523218893Sdim /// routine. 524218893Sdim /// 525218893Sdim /// Returns true if an error occurred. 526218893Sdim template<typename InputIterator> 527218893Sdim bool TransformTemplateArguments(InputIterator First, 528218893Sdim InputIterator Last, 529218893Sdim TemplateArgumentListInfo &Outputs); 530218893Sdim 531198893Srdivacky /// \brief Fakes up a TemplateArgumentLoc for a given TemplateArgument. 532198893Srdivacky void InventTemplateArgumentLoc(const TemplateArgument &Arg, 533198893Srdivacky TemplateArgumentLoc &ArgLoc); 534198893Srdivacky 535200583Srdivacky /// \brief Fakes up a TypeSourceInfo for a type. 536200583Srdivacky TypeSourceInfo *InventTypeSourceInfo(QualType T) { 537200583Srdivacky return SemaRef.Context.getTrivialTypeSourceInfo(T, 538198893Srdivacky getDerived().getBaseLocation()); 539198893Srdivacky } 540198893Srdivacky 541198398Srdivacky#define ABSTRACT_TYPELOC(CLASS, PARENT) 542198398Srdivacky#define TYPELOC(CLASS, PARENT) \ 543218893Sdim QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T); 544198398Srdivacky#include "clang/AST/TypeLocNodes.def" 545198092Srdivacky 546234982Sdim QualType TransformFunctionProtoType(TypeLocBuilder &TLB, 547234982Sdim FunctionProtoTypeLoc TL, 548234982Sdim CXXRecordDecl *ThisContext, 549234982Sdim unsigned ThisTypeQuals); 550234982Sdim 551263508Sdim StmtResult TransformSEHHandler(Stmt *Handler); 552221345Sdim 553239462Sdim QualType 554218893Sdim TransformTemplateSpecializationType(TypeLocBuilder &TLB, 555218893Sdim TemplateSpecializationTypeLoc TL, 556218893Sdim TemplateName Template); 557218893Sdim 558239462Sdim QualType 559218893Sdim TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, 560218893Sdim DependentTemplateSpecializationTypeLoc TL, 561221345Sdim TemplateName Template, 562221345Sdim CXXScopeSpec &SS); 563218893Sdim 564239462Sdim QualType 565221345Sdim TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, 566221345Sdim DependentTemplateSpecializationTypeLoc TL, 567221345Sdim NestedNameSpecifierLoc QualifierLoc); 568221345Sdim 569205219Srdivacky /// \brief Transforms the parameters of a function type into the 570205219Srdivacky /// given vectors. 571205219Srdivacky /// 572205219Srdivacky /// The result vectors should be kept in sync; null entries in the 573205219Srdivacky /// variables vector are acceptable. 574205219Srdivacky /// 575205219Srdivacky /// Return true on error. 576218893Sdim bool TransformFunctionTypeParams(SourceLocation Loc, 577218893Sdim ParmVarDecl **Params, unsigned NumParams, 578218893Sdim const QualType *ParamTypes, 579226633Sdim SmallVectorImpl<QualType> &PTypes, 580226633Sdim SmallVectorImpl<ParmVarDecl*> *PVars); 581205219Srdivacky 582205219Srdivacky /// \brief Transforms a single function-type parameter. Return null 583205219Srdivacky /// on error. 584221345Sdim /// 585221345Sdim /// \param indexAdjustment - A number to add to the parameter's 586221345Sdim /// scope index; can be negative 587218893Sdim ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm, 588221345Sdim int indexAdjustment, 589249423Sdim Optional<unsigned> NumExpansions, 590234353Sdim bool ExpectParameterPack); 591205219Srdivacky 592218893Sdim QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL); 593198893Srdivacky 594212904Sdim StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr); 595212904Sdim ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E); 596263508Sdim 597263508Sdim typedef std::pair<ExprResult, QualType> InitCaptureInfoTy; 598239462Sdim /// \brief Transform the captures and body of a lambda expression. 599263508Sdim ExprResult TransformLambdaScope(LambdaExpr *E, CXXMethodDecl *CallOperator, 600263508Sdim ArrayRef<InitCaptureInfoTy> InitCaptureExprsAndTypes); 601239462Sdim 602263508Sdim TemplateParameterList *TransformTemplateParameterList( 603263508Sdim TemplateParameterList *TPL) { 604263508Sdim return TPL; 605263508Sdim } 606263508Sdim 607243830Sdim ExprResult TransformAddressOfOperand(Expr *E); 608243830Sdim ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E, 609243830Sdim bool IsAddressOfOperand); 610243830Sdim 611263508Sdim// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous 612263508Sdim// amount of stack usage with clang. 613198092Srdivacky#define STMT(Node, Parent) \ 614263508Sdim LLVM_ATTRIBUTE_NOINLINE \ 615212904Sdim StmtResult Transform##Node(Node *S); 616198092Srdivacky#define EXPR(Node, Parent) \ 617263508Sdim LLVM_ATTRIBUTE_NOINLINE \ 618212904Sdim ExprResult Transform##Node(Node *E); 619208600Srdivacky#define ABSTRACT_STMT(Stmt) 620208600Srdivacky#include "clang/AST/StmtNodes.inc" 621198092Srdivacky 622263508Sdim#define OPENMP_CLAUSE(Name, Class) \ 623263508Sdim LLVM_ATTRIBUTE_NOINLINE \ 624263508Sdim OMPClause *Transform ## Class(Class *S); 625263508Sdim#include "clang/Basic/OpenMPKinds.def" 626263508Sdim 627198092Srdivacky /// \brief Build a new pointer type given its pointee type. 628198092Srdivacky /// 629198092Srdivacky /// By default, performs semantic analysis when building the pointer type. 630198092Srdivacky /// Subclasses may override this routine to provide different behavior. 631198893Srdivacky QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil); 632198092Srdivacky 633198092Srdivacky /// \brief Build a new block pointer type given its pointee type. 634198092Srdivacky /// 635198092Srdivacky /// By default, performs semantic analysis when building the block pointer 636198092Srdivacky /// type. Subclasses may override this routine to provide different behavior. 637198893Srdivacky QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil); 638198092Srdivacky 639198893Srdivacky /// \brief Build a new reference type given the type it references. 640198092Srdivacky /// 641198893Srdivacky /// By default, performs semantic analysis when building the 642198893Srdivacky /// reference type. Subclasses may override this routine to provide 643198893Srdivacky /// different behavior. 644198092Srdivacky /// 645198893Srdivacky /// \param LValue whether the type was written with an lvalue sigil 646198893Srdivacky /// or an rvalue sigil. 647198893Srdivacky QualType RebuildReferenceType(QualType ReferentType, 648198893Srdivacky bool LValue, 649198893Srdivacky SourceLocation Sigil); 650198092Srdivacky 651198092Srdivacky /// \brief Build a new member pointer type given the pointee type and the 652198092Srdivacky /// class type it refers into. 653198092Srdivacky /// 654198092Srdivacky /// By default, performs semantic analysis when building the member pointer 655198092Srdivacky /// type. Subclasses may override this routine to provide different behavior. 656198893Srdivacky QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType, 657198893Srdivacky SourceLocation Sigil); 658198092Srdivacky 659198092Srdivacky /// \brief Build a new array type given the element type, size 660198092Srdivacky /// modifier, size of the array (if known), size expression, and index type 661198092Srdivacky /// qualifiers. 662198092Srdivacky /// 663198092Srdivacky /// By default, performs semantic analysis when building the array type. 664198092Srdivacky /// Subclasses may override this routine to provide different behavior. 665198092Srdivacky /// Also by default, all of the other Rebuild*Array 666198092Srdivacky QualType RebuildArrayType(QualType ElementType, 667198092Srdivacky ArrayType::ArraySizeModifier SizeMod, 668198092Srdivacky const llvm::APInt *Size, 669198092Srdivacky Expr *SizeExpr, 670198092Srdivacky unsigned IndexTypeQuals, 671198092Srdivacky SourceRange BracketsRange); 672198092Srdivacky 673198092Srdivacky /// \brief Build a new constant array type given the element type, size 674198092Srdivacky /// modifier, (known) size of the array, and index type qualifiers. 675198092Srdivacky /// 676198092Srdivacky /// By default, performs semantic analysis when building the array type. 677198092Srdivacky /// Subclasses may override this routine to provide different behavior. 678198092Srdivacky QualType RebuildConstantArrayType(QualType ElementType, 679198092Srdivacky ArrayType::ArraySizeModifier SizeMod, 680198092Srdivacky const llvm::APInt &Size, 681198893Srdivacky unsigned IndexTypeQuals, 682198893Srdivacky SourceRange BracketsRange); 683198092Srdivacky 684198092Srdivacky /// \brief Build a new incomplete array type given the element type, size 685198092Srdivacky /// modifier, and index type qualifiers. 686198092Srdivacky /// 687198092Srdivacky /// By default, performs semantic analysis when building the array type. 688198092Srdivacky /// Subclasses may override this routine to provide different behavior. 689198092Srdivacky QualType RebuildIncompleteArrayType(QualType ElementType, 690198092Srdivacky ArrayType::ArraySizeModifier SizeMod, 691198893Srdivacky unsigned IndexTypeQuals, 692198893Srdivacky SourceRange BracketsRange); 693198092Srdivacky 694198092Srdivacky /// \brief Build a new variable-length array type given the element type, 695198092Srdivacky /// size modifier, size expression, and index type qualifiers. 696198092Srdivacky /// 697198092Srdivacky /// By default, performs semantic analysis when building the array type. 698198092Srdivacky /// Subclasses may override this routine to provide different behavior. 699198092Srdivacky QualType RebuildVariableArrayType(QualType ElementType, 700198092Srdivacky ArrayType::ArraySizeModifier SizeMod, 701212904Sdim Expr *SizeExpr, 702198092Srdivacky unsigned IndexTypeQuals, 703198092Srdivacky SourceRange BracketsRange); 704198092Srdivacky 705198092Srdivacky /// \brief Build a new dependent-sized array type given the element type, 706198092Srdivacky /// size modifier, size expression, and index type qualifiers. 707198092Srdivacky /// 708198092Srdivacky /// By default, performs semantic analysis when building the array type. 709198092Srdivacky /// Subclasses may override this routine to provide different behavior. 710198092Srdivacky QualType RebuildDependentSizedArrayType(QualType ElementType, 711198092Srdivacky ArrayType::ArraySizeModifier SizeMod, 712212904Sdim Expr *SizeExpr, 713198092Srdivacky unsigned IndexTypeQuals, 714198092Srdivacky SourceRange BracketsRange); 715198092Srdivacky 716198092Srdivacky /// \brief Build a new vector type given the element type and 717198092Srdivacky /// number of elements. 718198092Srdivacky /// 719198092Srdivacky /// By default, performs semantic analysis when building the vector type. 720198092Srdivacky /// Subclasses may override this routine to provide different behavior. 721203955Srdivacky QualType RebuildVectorType(QualType ElementType, unsigned NumElements, 722218893Sdim VectorType::VectorKind VecKind); 723198092Srdivacky 724198092Srdivacky /// \brief Build a new extended vector type given the element type and 725198092Srdivacky /// number of elements. 726198092Srdivacky /// 727198092Srdivacky /// By default, performs semantic analysis when building the vector type. 728198092Srdivacky /// Subclasses may override this routine to provide different behavior. 729198092Srdivacky QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements, 730198092Srdivacky SourceLocation AttributeLoc); 731198092Srdivacky 732198092Srdivacky /// \brief Build a new potentially dependently-sized extended vector type 733198092Srdivacky /// given the element type and number of elements. 734198092Srdivacky /// 735198092Srdivacky /// By default, performs semantic analysis when building the vector type. 736198092Srdivacky /// Subclasses may override this routine to provide different behavior. 737198092Srdivacky QualType RebuildDependentSizedExtVectorType(QualType ElementType, 738212904Sdim Expr *SizeExpr, 739198092Srdivacky SourceLocation AttributeLoc); 740198092Srdivacky 741198092Srdivacky /// \brief Build a new function type. 742198092Srdivacky /// 743198092Srdivacky /// By default, performs semantic analysis when building the function type. 744198092Srdivacky /// Subclasses may override this routine to provide different behavior. 745198092Srdivacky QualType RebuildFunctionProtoType(QualType T, 746249423Sdim llvm::MutableArrayRef<QualType> ParamTypes, 747249423Sdim const FunctionProtoType::ExtProtoInfo &EPI); 748198092Srdivacky 749198398Srdivacky /// \brief Build a new unprototyped function type. 750198398Srdivacky QualType RebuildFunctionNoProtoType(QualType ResultType); 751198398Srdivacky 752200583Srdivacky /// \brief Rebuild an unresolved typename type, given the decl that 753200583Srdivacky /// the UnresolvedUsingTypenameDecl was transformed to. 754200583Srdivacky QualType RebuildUnresolvedUsingType(Decl *D); 755200583Srdivacky 756198092Srdivacky /// \brief Build a new typedef type. 757221345Sdim QualType RebuildTypedefType(TypedefNameDecl *Typedef) { 758198092Srdivacky return SemaRef.Context.getTypeDeclType(Typedef); 759198092Srdivacky } 760198092Srdivacky 761198092Srdivacky /// \brief Build a new class/struct/union type. 762198092Srdivacky QualType RebuildRecordType(RecordDecl *Record) { 763198092Srdivacky return SemaRef.Context.getTypeDeclType(Record); 764198092Srdivacky } 765198092Srdivacky 766198092Srdivacky /// \brief Build a new Enum type. 767198092Srdivacky QualType RebuildEnumType(EnumDecl *Enum) { 768198092Srdivacky return SemaRef.Context.getTypeDeclType(Enum); 769198092Srdivacky } 770198092Srdivacky 771198092Srdivacky /// \brief Build a new typeof(expr) type. 772198092Srdivacky /// 773198092Srdivacky /// By default, performs semantic analysis when building the typeof type. 774198092Srdivacky /// Subclasses may override this routine to provide different behavior. 775218893Sdim QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc); 776198092Srdivacky 777198092Srdivacky /// \brief Build a new typeof(type) type. 778198092Srdivacky /// 779198092Srdivacky /// By default, builds a new TypeOfType with the given underlying type. 780198092Srdivacky QualType RebuildTypeOfType(QualType Underlying); 781198092Srdivacky 782223017Sdim /// \brief Build a new unary transform type. 783223017Sdim QualType RebuildUnaryTransformType(QualType BaseType, 784223017Sdim UnaryTransformType::UTTKind UKind, 785223017Sdim SourceLocation Loc); 786223017Sdim 787251662Sdim /// \brief Build a new C++11 decltype type. 788198092Srdivacky /// 789198092Srdivacky /// By default, performs semantic analysis when building the decltype type. 790198092Srdivacky /// Subclasses may override this routine to provide different behavior. 791218893Sdim QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc); 792198092Srdivacky 793251662Sdim /// \brief Build a new C++11 auto type. 794218893Sdim /// 795218893Sdim /// By default, builds a new AutoType with the given deduced type. 796251662Sdim QualType RebuildAutoType(QualType Deduced, bool IsDecltypeAuto) { 797251662Sdim // Note, IsDependent is always false here: we implicitly convert an 'auto' 798251662Sdim // which has been deduced to a dependent type into an undeduced 'auto', so 799251662Sdim // that we'll retry deduction after the transformation. 800263508Sdim return SemaRef.Context.getAutoType(Deduced, IsDecltypeAuto, 801263508Sdim /*IsDependent*/ false); 802218893Sdim } 803218893Sdim 804198092Srdivacky /// \brief Build a new template specialization type. 805198092Srdivacky /// 806198092Srdivacky /// By default, performs semantic analysis when building the template 807198092Srdivacky /// specialization type. Subclasses may override this routine to provide 808198092Srdivacky /// different behavior. 809198092Srdivacky QualType RebuildTemplateSpecializationType(TemplateName Template, 810198893Srdivacky SourceLocation TemplateLoc, 811221345Sdim TemplateArgumentListInfo &Args); 812198092Srdivacky 813218893Sdim /// \brief Build a new parenthesized type. 814218893Sdim /// 815218893Sdim /// By default, builds a new ParenType type from the inner type. 816218893Sdim /// Subclasses may override this routine to provide different behavior. 817218893Sdim QualType RebuildParenType(QualType InnerType) { 818218893Sdim return SemaRef.Context.getParenType(InnerType); 819218893Sdim } 820218893Sdim 821198092Srdivacky /// \brief Build a new qualified name type. 822198092Srdivacky /// 823208600Srdivacky /// By default, builds a new ElaboratedType type from the keyword, 824208600Srdivacky /// the nested-name-specifier and the named type. 825208600Srdivacky /// Subclasses may override this routine to provide different behavior. 826218893Sdim QualType RebuildElaboratedType(SourceLocation KeywordLoc, 827218893Sdim ElaboratedTypeKeyword Keyword, 828221345Sdim NestedNameSpecifierLoc QualifierLoc, 829221345Sdim QualType Named) { 830239462Sdim return SemaRef.Context.getElaboratedType(Keyword, 831239462Sdim QualifierLoc.getNestedNameSpecifier(), 832221345Sdim Named); 833198092Srdivacky } 834198092Srdivacky 835198092Srdivacky /// \brief Build a new typename type that refers to a template-id. 836198092Srdivacky /// 837208600Srdivacky /// By default, builds a new DependentNameType type from the 838208600Srdivacky /// nested-name-specifier and the given type. Subclasses may override 839208600Srdivacky /// this routine to provide different behavior. 840210299Sed QualType RebuildDependentTemplateSpecializationType( 841221345Sdim ElaboratedTypeKeyword Keyword, 842221345Sdim NestedNameSpecifierLoc QualifierLoc, 843221345Sdim const IdentifierInfo *Name, 844221345Sdim SourceLocation NameLoc, 845221345Sdim TemplateArgumentListInfo &Args) { 846210299Sed // Rebuild the template name. 847210299Sed // TODO: avoid TemplateName abstraction 848221345Sdim CXXScopeSpec SS; 849221345Sdim SS.Adopt(QualifierLoc); 850239462Sdim TemplateName InstName 851221345Sdim = getDerived().RebuildTemplateName(SS, *Name, NameLoc, QualType(), 0); 852239462Sdim 853210299Sed if (InstName.isNull()) 854210299Sed return QualType(); 855239462Sdim 856210299Sed // If it's still dependent, make a dependent specialization. 857210299Sed if (InstName.getAsDependentTemplateName()) 858239462Sdim return SemaRef.Context.getDependentTemplateSpecializationType(Keyword, 859239462Sdim QualifierLoc.getNestedNameSpecifier(), 860239462Sdim Name, 861221345Sdim Args); 862239462Sdim 863210299Sed // Otherwise, make an elaborated type wrapping a non-dependent 864210299Sed // specialization. 865210299Sed QualType T = 866221345Sdim getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args); 867210299Sed if (T.isNull()) return QualType(); 868239462Sdim 869221345Sdim if (Keyword == ETK_None && QualifierLoc.getNestedNameSpecifier() == 0) 870221345Sdim return T; 871239462Sdim 872239462Sdim return SemaRef.Context.getElaboratedType(Keyword, 873239462Sdim QualifierLoc.getNestedNameSpecifier(), 874221345Sdim T); 875198092Srdivacky } 876198092Srdivacky 877198092Srdivacky /// \brief Build a new typename type that refers to an identifier. 878198092Srdivacky /// 879198092Srdivacky /// By default, performs semantic analysis when building the typename type 880208600Srdivacky /// (or elaborated type). Subclasses may override this routine to provide 881198092Srdivacky /// different behavior. 882208600Srdivacky QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword, 883221345Sdim SourceLocation KeywordLoc, 884221345Sdim NestedNameSpecifierLoc QualifierLoc, 885206084Srdivacky const IdentifierInfo *Id, 886208600Srdivacky SourceLocation IdLoc) { 887206084Srdivacky CXXScopeSpec SS; 888221345Sdim SS.Adopt(QualifierLoc); 889208600Srdivacky 890221345Sdim if (QualifierLoc.getNestedNameSpecifier()->isDependent()) { 891206084Srdivacky // If the name is still dependent, just build a new dependent name type. 892206084Srdivacky if (!SemaRef.computeDeclContext(SS)) 893239462Sdim return SemaRef.Context.getDependentNameType(Keyword, 894239462Sdim QualifierLoc.getNestedNameSpecifier(), 895221345Sdim Id); 896206084Srdivacky } 897206084Srdivacky 898208600Srdivacky if (Keyword == ETK_None || Keyword == ETK_Typename) 899221345Sdim return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc, 900221345Sdim *Id, IdLoc); 901208600Srdivacky 902208600Srdivacky TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword); 903208600Srdivacky 904208600Srdivacky // We had a dependent elaborated-type-specifier that has been transformed 905206084Srdivacky // into a non-dependent elaborated-type-specifier. Find the tag we're 906206084Srdivacky // referring to. 907208600Srdivacky LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName); 908206084Srdivacky DeclContext *DC = SemaRef.computeDeclContext(SS, false); 909206084Srdivacky if (!DC) 910206084Srdivacky return QualType(); 911206084Srdivacky 912208600Srdivacky if (SemaRef.RequireCompleteDeclContext(SS, DC)) 913208600Srdivacky return QualType(); 914208600Srdivacky 915206084Srdivacky TagDecl *Tag = 0; 916206084Srdivacky SemaRef.LookupQualifiedName(Result, DC); 917206084Srdivacky switch (Result.getResultKind()) { 918206084Srdivacky case LookupResult::NotFound: 919206084Srdivacky case LookupResult::NotFoundInCurrentInstantiation: 920206084Srdivacky break; 921239462Sdim 922206084Srdivacky case LookupResult::Found: 923206084Srdivacky Tag = Result.getAsSingle<TagDecl>(); 924206084Srdivacky break; 925239462Sdim 926206084Srdivacky case LookupResult::FoundOverloaded: 927206084Srdivacky case LookupResult::FoundUnresolvedValue: 928206084Srdivacky llvm_unreachable("Tag lookup cannot find non-tags"); 929239462Sdim 930206084Srdivacky case LookupResult::Ambiguous: 931206084Srdivacky // Let the LookupResult structure handle ambiguities. 932206084Srdivacky return QualType(); 933206084Srdivacky } 934206084Srdivacky 935206084Srdivacky if (!Tag) { 936218893Sdim // Check where the name exists but isn't a tag type and use that to emit 937218893Sdim // better diagnostics. 938218893Sdim LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName); 939218893Sdim SemaRef.LookupQualifiedName(Result, DC); 940218893Sdim switch (Result.getResultKind()) { 941218893Sdim case LookupResult::Found: 942218893Sdim case LookupResult::FoundOverloaded: 943218893Sdim case LookupResult::FoundUnresolvedValue: { 944223017Sdim NamedDecl *SomeDecl = Result.getRepresentativeDecl(); 945218893Sdim unsigned Kind = 0; 946218893Sdim if (isa<TypedefDecl>(SomeDecl)) Kind = 1; 947221345Sdim else if (isa<TypeAliasDecl>(SomeDecl)) Kind = 2; 948221345Sdim else if (isa<ClassTemplateDecl>(SomeDecl)) Kind = 3; 949218893Sdim SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag) << Kind; 950218893Sdim SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at); 951218893Sdim break; 952223017Sdim } 953218893Sdim default: 954218893Sdim // FIXME: Would be nice to highlight just the source range. 955218893Sdim SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope) 956218893Sdim << Kind << Id << DC; 957218893Sdim break; 958218893Sdim } 959206084Srdivacky return QualType(); 960206084Srdivacky } 961208600Srdivacky 962223017Sdim if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false, 963223017Sdim IdLoc, *Id)) { 964208600Srdivacky SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id; 965206084Srdivacky SemaRef.Diag(Tag->getLocation(), diag::note_previous_use); 966206084Srdivacky return QualType(); 967206084Srdivacky } 968206084Srdivacky 969206084Srdivacky // Build the elaborated-type-specifier type. 970206084Srdivacky QualType T = SemaRef.Context.getTypeDeclType(Tag); 971239462Sdim return SemaRef.Context.getElaboratedType(Keyword, 972239462Sdim QualifierLoc.getNestedNameSpecifier(), 973221345Sdim T); 974198092Srdivacky } 975198092Srdivacky 976218893Sdim /// \brief Build a new pack expansion type. 977218893Sdim /// 978218893Sdim /// By default, builds a new PackExpansionType type from the given pattern. 979218893Sdim /// Subclasses may override this routine to provide different behavior. 980239462Sdim QualType RebuildPackExpansionType(QualType Pattern, 981218893Sdim SourceRange PatternRange, 982218893Sdim SourceLocation EllipsisLoc, 983249423Sdim Optional<unsigned> NumExpansions) { 984218893Sdim return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc, 985218893Sdim NumExpansions); 986218893Sdim } 987218893Sdim 988226633Sdim /// \brief Build a new atomic type given its value type. 989226633Sdim /// 990226633Sdim /// By default, performs semantic analysis when building the atomic type. 991226633Sdim /// Subclasses may override this routine to provide different behavior. 992226633Sdim QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc); 993226633Sdim 994198092Srdivacky /// \brief Build a new template name given a nested name specifier, a flag 995198092Srdivacky /// indicating whether the "template" keyword was provided, and the template 996198092Srdivacky /// that the template name refers to. 997198092Srdivacky /// 998198092Srdivacky /// By default, builds the new template name directly. Subclasses may override 999198092Srdivacky /// this routine to provide different behavior. 1000221345Sdim TemplateName RebuildTemplateName(CXXScopeSpec &SS, 1001198092Srdivacky bool TemplateKW, 1002198092Srdivacky TemplateDecl *Template); 1003198092Srdivacky 1004198092Srdivacky /// \brief Build a new template name given a nested name specifier and the 1005198092Srdivacky /// name that is referred to as a template. 1006198092Srdivacky /// 1007198092Srdivacky /// By default, performs semantic analysis to determine whether the name can 1008198092Srdivacky /// be resolved to a specific template, then builds the appropriate kind of 1009198092Srdivacky /// template name. Subclasses may override this routine to provide different 1010198092Srdivacky /// behavior. 1011221345Sdim TemplateName RebuildTemplateName(CXXScopeSpec &SS, 1012221345Sdim const IdentifierInfo &Name, 1013221345Sdim SourceLocation NameLoc, 1014218893Sdim QualType ObjectType, 1015218893Sdim NamedDecl *FirstQualifierInScope); 1016198092Srdivacky 1017198893Srdivacky /// \brief Build a new template name given a nested name specifier and the 1018198893Srdivacky /// overloaded operator name that is referred to as a template. 1019198893Srdivacky /// 1020198893Srdivacky /// By default, performs semantic analysis to determine whether the name can 1021198893Srdivacky /// be resolved to a specific template, then builds the appropriate kind of 1022198893Srdivacky /// template name. Subclasses may override this routine to provide different 1023198893Srdivacky /// behavior. 1024221345Sdim TemplateName RebuildTemplateName(CXXScopeSpec &SS, 1025198893Srdivacky OverloadedOperatorKind Operator, 1026221345Sdim SourceLocation NameLoc, 1027198893Srdivacky QualType ObjectType); 1028218893Sdim 1029218893Sdim /// \brief Build a new template name given a template template parameter pack 1030239462Sdim /// and the 1031218893Sdim /// 1032218893Sdim /// By default, performs semantic analysis to determine whether the name can 1033218893Sdim /// be resolved to a specific template, then builds the appropriate kind of 1034218893Sdim /// template name. Subclasses may override this routine to provide different 1035218893Sdim /// behavior. 1036218893Sdim TemplateName RebuildTemplateName(TemplateTemplateParmDecl *Param, 1037218893Sdim const TemplateArgument &ArgPack) { 1038218893Sdim return getSema().Context.getSubstTemplateTemplateParmPack(Param, ArgPack); 1039218893Sdim } 1040218893Sdim 1041198092Srdivacky /// \brief Build a new compound statement. 1042198092Srdivacky /// 1043198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1044198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1045212904Sdim StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc, 1046198092Srdivacky MultiStmtArg Statements, 1047198092Srdivacky SourceLocation RBraceLoc, 1048198092Srdivacky bool IsStmtExpr) { 1049212904Sdim return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements, 1050198092Srdivacky IsStmtExpr); 1051198092Srdivacky } 1052198092Srdivacky 1053198092Srdivacky /// \brief Build a new case statement. 1054198092Srdivacky /// 1055198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1056198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1057212904Sdim StmtResult RebuildCaseStmt(SourceLocation CaseLoc, 1058212904Sdim Expr *LHS, 1059198092Srdivacky SourceLocation EllipsisLoc, 1060212904Sdim Expr *RHS, 1061198092Srdivacky SourceLocation ColonLoc) { 1062212904Sdim return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS, 1063198092Srdivacky ColonLoc); 1064198092Srdivacky } 1065198092Srdivacky 1066198092Srdivacky /// \brief Attach the body to a new case statement. 1067198092Srdivacky /// 1068198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1069198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1070212904Sdim StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) { 1071212904Sdim getSema().ActOnCaseStmtBody(S, Body); 1072212904Sdim return S; 1073198092Srdivacky } 1074198092Srdivacky 1075198092Srdivacky /// \brief Build a new default statement. 1076198092Srdivacky /// 1077198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1078198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1079212904Sdim StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc, 1080198092Srdivacky SourceLocation ColonLoc, 1081212904Sdim Stmt *SubStmt) { 1082212904Sdim return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt, 1083198092Srdivacky /*CurScope=*/0); 1084198092Srdivacky } 1085198092Srdivacky 1086198092Srdivacky /// \brief Build a new label statement. 1087198092Srdivacky /// 1088198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1089198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1090218893Sdim StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L, 1091218893Sdim SourceLocation ColonLoc, Stmt *SubStmt) { 1092218893Sdim return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt); 1093198092Srdivacky } 1094198092Srdivacky 1095234982Sdim /// \brief Build a new label statement. 1096234982Sdim /// 1097234982Sdim /// By default, performs semantic analysis to build the new statement. 1098234982Sdim /// Subclasses may override this routine to provide different behavior. 1099239462Sdim StmtResult RebuildAttributedStmt(SourceLocation AttrLoc, 1100239462Sdim ArrayRef<const Attr*> Attrs, 1101234982Sdim Stmt *SubStmt) { 1102234982Sdim return SemaRef.ActOnAttributedStmt(AttrLoc, Attrs, SubStmt); 1103234982Sdim } 1104234982Sdim 1105198092Srdivacky /// \brief Build a new "if" statement. 1106198092Srdivacky /// 1107198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1108198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1109212904Sdim StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond, 1110239462Sdim VarDecl *CondVar, Stmt *Then, 1111218893Sdim SourceLocation ElseLoc, Stmt *Else) { 1112212904Sdim return getSema().ActOnIfStmt(IfLoc, Cond, CondVar, Then, ElseLoc, Else); 1113198092Srdivacky } 1114198092Srdivacky 1115198092Srdivacky /// \brief Start building a new switch statement. 1116198092Srdivacky /// 1117198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1118198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1119212904Sdim StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc, 1120218893Sdim Expr *Cond, VarDecl *CondVar) { 1121239462Sdim return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond, 1122212904Sdim CondVar); 1123198092Srdivacky } 1124198092Srdivacky 1125198092Srdivacky /// \brief Attach the body to the switch statement. 1126198092Srdivacky /// 1127198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1128198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1129212904Sdim StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc, 1130218893Sdim Stmt *Switch, Stmt *Body) { 1131212904Sdim return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body); 1132198092Srdivacky } 1133198092Srdivacky 1134198092Srdivacky /// \brief Build a new while statement. 1135198092Srdivacky /// 1136198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1137198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1138218893Sdim StmtResult RebuildWhileStmt(SourceLocation WhileLoc, Sema::FullExprArg Cond, 1139218893Sdim VarDecl *CondVar, Stmt *Body) { 1140212904Sdim return getSema().ActOnWhileStmt(WhileLoc, Cond, CondVar, Body); 1141198092Srdivacky } 1142198092Srdivacky 1143198092Srdivacky /// \brief Build a new do-while statement. 1144198092Srdivacky /// 1145198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1146198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1147212904Sdim StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body, 1148218893Sdim SourceLocation WhileLoc, SourceLocation LParenLoc, 1149218893Sdim Expr *Cond, SourceLocation RParenLoc) { 1150212904Sdim return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc, 1151212904Sdim Cond, RParenLoc); 1152198092Srdivacky } 1153198092Srdivacky 1154198092Srdivacky /// \brief Build a new for statement. 1155198092Srdivacky /// 1156198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1157198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1158218893Sdim StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, 1159239462Sdim Stmt *Init, Sema::FullExprArg Cond, 1160218893Sdim VarDecl *CondVar, Sema::FullExprArg Inc, 1161218893Sdim SourceLocation RParenLoc, Stmt *Body) { 1162239462Sdim return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond, 1163218893Sdim CondVar, Inc, RParenLoc, Body); 1164198092Srdivacky } 1165198092Srdivacky 1166198092Srdivacky /// \brief Build a new goto statement. 1167198092Srdivacky /// 1168198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1169198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1170218893Sdim StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, 1171218893Sdim LabelDecl *Label) { 1172218893Sdim return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label); 1173198092Srdivacky } 1174198092Srdivacky 1175198092Srdivacky /// \brief Build a new indirect goto statement. 1176198092Srdivacky /// 1177198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1178198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1179212904Sdim StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc, 1180218893Sdim SourceLocation StarLoc, 1181218893Sdim Expr *Target) { 1182212904Sdim return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target); 1183198092Srdivacky } 1184198092Srdivacky 1185198092Srdivacky /// \brief Build a new return statement. 1186198092Srdivacky /// 1187198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1188198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1189218893Sdim StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) { 1190212904Sdim return getSema().ActOnReturnStmt(ReturnLoc, Result); 1191198092Srdivacky } 1192198092Srdivacky 1193198092Srdivacky /// \brief Build a new declaration statement. 1194198092Srdivacky /// 1195198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1196198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1197263508Sdim StmtResult RebuildDeclStmt(llvm::MutableArrayRef<Decl *> Decls, 1198263508Sdim SourceLocation StartLoc, SourceLocation EndLoc) { 1199263508Sdim Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls); 1200219077Sdim return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc); 1201198092Srdivacky } 1202198092Srdivacky 1203203955Srdivacky /// \brief Build a new inline asm statement. 1204203955Srdivacky /// 1205203955Srdivacky /// By default, performs semantic analysis to build the new statement. 1206203955Srdivacky /// Subclasses may override this routine to provide different behavior. 1207243830Sdim StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, 1208243830Sdim bool IsVolatile, unsigned NumOutputs, 1209243830Sdim unsigned NumInputs, IdentifierInfo **Names, 1210243830Sdim MultiExprArg Constraints, MultiExprArg Exprs, 1211243830Sdim Expr *AsmString, MultiExprArg Clobbers, 1212243830Sdim SourceLocation RParenLoc) { 1213243830Sdim return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs, 1214243830Sdim NumInputs, Names, Constraints, Exprs, 1215243830Sdim AsmString, Clobbers, RParenLoc); 1216203955Srdivacky } 1217207619Srdivacky 1218239462Sdim /// \brief Build a new MS style inline asm statement. 1219207619Srdivacky /// 1220207619Srdivacky /// By default, performs semantic analysis to build the new statement. 1221207619Srdivacky /// Subclasses may override this routine to provide different behavior. 1222243830Sdim StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, 1223251662Sdim ArrayRef<Token> AsmToks, 1224251662Sdim StringRef AsmString, 1225251662Sdim unsigned NumOutputs, unsigned NumInputs, 1226251662Sdim ArrayRef<StringRef> Constraints, 1227251662Sdim ArrayRef<StringRef> Clobbers, 1228251662Sdim ArrayRef<Expr*> Exprs, 1229251662Sdim SourceLocation EndLoc) { 1230251662Sdim return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString, 1231251662Sdim NumOutputs, NumInputs, 1232251662Sdim Constraints, Clobbers, Exprs, EndLoc); 1233239462Sdim } 1234239462Sdim 1235239462Sdim /// \brief Build a new Objective-C \@try statement. 1236239462Sdim /// 1237239462Sdim /// By default, performs semantic analysis to build the new statement. 1238239462Sdim /// Subclasses may override this routine to provide different behavior. 1239212904Sdim StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc, 1240212904Sdim Stmt *TryBody, 1241207619Srdivacky MultiStmtArg CatchStmts, 1242212904Sdim Stmt *Finally) { 1243243830Sdim return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts, 1244212904Sdim Finally); 1245207619Srdivacky } 1246207619Srdivacky 1247207619Srdivacky /// \brief Rebuild an Objective-C exception declaration. 1248207619Srdivacky /// 1249207619Srdivacky /// By default, performs semantic analysis to build the new declaration. 1250207619Srdivacky /// Subclasses may override this routine to provide different behavior. 1251207619Srdivacky VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl, 1252207619Srdivacky TypeSourceInfo *TInfo, QualType T) { 1253221345Sdim return getSema().BuildObjCExceptionDecl(TInfo, T, 1254221345Sdim ExceptionDecl->getInnerLocStart(), 1255221345Sdim ExceptionDecl->getLocation(), 1256221345Sdim ExceptionDecl->getIdentifier()); 1257207619Srdivacky } 1258239462Sdim 1259239462Sdim /// \brief Build a new Objective-C \@catch statement. 1260207619Srdivacky /// 1261207619Srdivacky /// By default, performs semantic analysis to build the new statement. 1262207619Srdivacky /// Subclasses may override this routine to provide different behavior. 1263212904Sdim StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc, 1264207619Srdivacky SourceLocation RParenLoc, 1265207619Srdivacky VarDecl *Var, 1266212904Sdim Stmt *Body) { 1267207619Srdivacky return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, 1268212904Sdim Var, Body); 1269207619Srdivacky } 1270239462Sdim 1271239462Sdim /// \brief Build a new Objective-C \@finally statement. 1272207619Srdivacky /// 1273207619Srdivacky /// By default, performs semantic analysis to build the new statement. 1274207619Srdivacky /// Subclasses may override this routine to provide different behavior. 1275212904Sdim StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc, 1276212904Sdim Stmt *Body) { 1277212904Sdim return getSema().ActOnObjCAtFinallyStmt(AtLoc, Body); 1278207619Srdivacky } 1279239462Sdim 1280239462Sdim /// \brief Build a new Objective-C \@throw statement. 1281207619Srdivacky /// 1282207619Srdivacky /// By default, performs semantic analysis to build the new statement. 1283207619Srdivacky /// Subclasses may override this routine to provide different behavior. 1284212904Sdim StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc, 1285212904Sdim Expr *Operand) { 1286212904Sdim return getSema().BuildObjCAtThrowStmt(AtLoc, Operand); 1287207619Srdivacky } 1288239462Sdim 1289263508Sdim /// \brief Build a new OpenMP parallel directive. 1290263508Sdim /// 1291263508Sdim /// By default, performs semantic analysis to build the new statement. 1292263508Sdim /// Subclasses may override this routine to provide different behavior. 1293263508Sdim StmtResult RebuildOMPParallelDirective(ArrayRef<OMPClause *> Clauses, 1294263508Sdim Stmt *AStmt, 1295263508Sdim SourceLocation StartLoc, 1296263508Sdim SourceLocation EndLoc) { 1297263508Sdim return getSema().ActOnOpenMPParallelDirective(Clauses, AStmt, 1298263508Sdim StartLoc, EndLoc); 1299263508Sdim } 1300263508Sdim 1301263508Sdim /// \brief Build a new OpenMP 'default' clause. 1302263508Sdim /// 1303263508Sdim /// By default, performs semantic analysis to build the new statement. 1304263508Sdim /// Subclasses may override this routine to provide different behavior. 1305263508Sdim OMPClause *RebuildOMPDefaultClause(OpenMPDefaultClauseKind Kind, 1306263508Sdim SourceLocation KindKwLoc, 1307263508Sdim SourceLocation StartLoc, 1308263508Sdim SourceLocation LParenLoc, 1309263508Sdim SourceLocation EndLoc) { 1310263508Sdim return getSema().ActOnOpenMPDefaultClause(Kind, KindKwLoc, 1311263508Sdim StartLoc, LParenLoc, EndLoc); 1312263508Sdim } 1313263508Sdim 1314263508Sdim /// \brief Build a new OpenMP 'private' clause. 1315263508Sdim /// 1316263508Sdim /// By default, performs semantic analysis to build the new statement. 1317263508Sdim /// Subclasses may override this routine to provide different behavior. 1318263508Sdim OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList, 1319263508Sdim SourceLocation StartLoc, 1320263508Sdim SourceLocation LParenLoc, 1321263508Sdim SourceLocation EndLoc) { 1322263508Sdim return getSema().ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, 1323263508Sdim EndLoc); 1324263508Sdim } 1325263508Sdim 1326263508Sdim /// \brief Build a new OpenMP 'firstprivate' clause. 1327263508Sdim /// 1328263508Sdim /// By default, performs semantic analysis to build the new statement. 1329263508Sdim /// Subclasses may override this routine to provide different behavior. 1330263508Sdim OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList, 1331263508Sdim SourceLocation StartLoc, 1332263508Sdim SourceLocation LParenLoc, 1333263508Sdim SourceLocation EndLoc) { 1334263508Sdim return getSema().ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, 1335263508Sdim EndLoc); 1336263508Sdim } 1337263508Sdim 1338263508Sdim OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList, 1339263508Sdim SourceLocation StartLoc, 1340263508Sdim SourceLocation LParenLoc, 1341263508Sdim SourceLocation EndLoc) { 1342263508Sdim return getSema().ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, 1343263508Sdim EndLoc); 1344263508Sdim } 1345263508Sdim 1346239462Sdim /// \brief Rebuild the operand to an Objective-C \@synchronized statement. 1347226633Sdim /// 1348226633Sdim /// By default, performs semantic analysis to build the new statement. 1349226633Sdim /// Subclasses may override this routine to provide different behavior. 1350226633Sdim ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc, 1351226633Sdim Expr *object) { 1352226633Sdim return getSema().ActOnObjCAtSynchronizedOperand(atLoc, object); 1353226633Sdim } 1354226633Sdim 1355239462Sdim /// \brief Build a new Objective-C \@synchronized statement. 1356207619Srdivacky /// 1357207619Srdivacky /// By default, performs semantic analysis to build the new statement. 1358207619Srdivacky /// Subclasses may override this routine to provide different behavior. 1359212904Sdim StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc, 1360226633Sdim Expr *Object, Stmt *Body) { 1361226633Sdim return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body); 1362207619Srdivacky } 1363207619Srdivacky 1364239462Sdim /// \brief Build a new Objective-C \@autoreleasepool statement. 1365224145Sdim /// 1366224145Sdim /// By default, performs semantic analysis to build the new statement. 1367224145Sdim /// Subclasses may override this routine to provide different behavior. 1368224145Sdim StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc, 1369224145Sdim Stmt *Body) { 1370224145Sdim return getSema().ActOnObjCAutoreleasePoolStmt(AtLoc, Body); 1371224145Sdim } 1372224145Sdim 1373207619Srdivacky /// \brief Build a new Objective-C fast enumeration statement. 1374207619Srdivacky /// 1375207619Srdivacky /// By default, performs semantic analysis to build the new statement. 1376207619Srdivacky /// Subclasses may override this routine to provide different behavior. 1377212904Sdim StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc, 1378212904Sdim Stmt *Element, 1379212904Sdim Expr *Collection, 1380212904Sdim SourceLocation RParenLoc, 1381212904Sdim Stmt *Body) { 1382239462Sdim StmtResult ForEachStmt = getSema().ActOnObjCForCollectionStmt(ForLoc, 1383239462Sdim Element, 1384212904Sdim Collection, 1385239462Sdim RParenLoc); 1386239462Sdim if (ForEachStmt.isInvalid()) 1387239462Sdim return StmtError(); 1388239462Sdim 1389239462Sdim return getSema().FinishObjCForCollectionStmt(ForEachStmt.take(), Body); 1390207619Srdivacky } 1391239462Sdim 1392198092Srdivacky /// \brief Build a new C++ exception declaration. 1393198092Srdivacky /// 1394198092Srdivacky /// By default, performs semantic analysis to build the new decaration. 1395198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1396221345Sdim VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, 1397200583Srdivacky TypeSourceInfo *Declarator, 1398221345Sdim SourceLocation StartLoc, 1399221345Sdim SourceLocation IdLoc, 1400221345Sdim IdentifierInfo *Id) { 1401221345Sdim VarDecl *Var = getSema().BuildExceptionDeclaration(0, Declarator, 1402221345Sdim StartLoc, IdLoc, Id); 1403221345Sdim if (Var) 1404221345Sdim getSema().CurContext->addDecl(Var); 1405221345Sdim return Var; 1406198092Srdivacky } 1407198092Srdivacky 1408198092Srdivacky /// \brief Build a new C++ catch statement. 1409198092Srdivacky /// 1410198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1411198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1412212904Sdim StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc, 1413212904Sdim VarDecl *ExceptionDecl, 1414212904Sdim Stmt *Handler) { 1415212904Sdim return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl, 1416212904Sdim Handler)); 1417198092Srdivacky } 1418198092Srdivacky 1419198092Srdivacky /// \brief Build a new C++ try statement. 1420198092Srdivacky /// 1421198092Srdivacky /// By default, performs semantic analysis to build the new statement. 1422198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1423263508Sdim StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock, 1424263508Sdim ArrayRef<Stmt *> Handlers) { 1425243830Sdim return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers); 1426198092Srdivacky } 1427198092Srdivacky 1428221345Sdim /// \brief Build a new C++0x range-based for statement. 1429221345Sdim /// 1430221345Sdim /// By default, performs semantic analysis to build the new statement. 1431221345Sdim /// Subclasses may override this routine to provide different behavior. 1432221345Sdim StmtResult RebuildCXXForRangeStmt(SourceLocation ForLoc, 1433221345Sdim SourceLocation ColonLoc, 1434221345Sdim Stmt *Range, Stmt *BeginEnd, 1435221345Sdim Expr *Cond, Expr *Inc, 1436221345Sdim Stmt *LoopVar, 1437221345Sdim SourceLocation RParenLoc) { 1438251662Sdim // If we've just learned that the range is actually an Objective-C 1439251662Sdim // collection, treat this as an Objective-C fast enumeration loop. 1440251662Sdim if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) { 1441251662Sdim if (RangeStmt->isSingleDecl()) { 1442251662Sdim if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) { 1443251662Sdim if (RangeVar->isInvalidDecl()) 1444251662Sdim return StmtError(); 1445251662Sdim 1446251662Sdim Expr *RangeExpr = RangeVar->getInit(); 1447251662Sdim if (!RangeExpr->isTypeDependent() && 1448251662Sdim RangeExpr->getType()->isObjCObjectPointerType()) 1449251662Sdim return getSema().ActOnObjCForCollectionStmt(ForLoc, LoopVar, RangeExpr, 1450251662Sdim RParenLoc); 1451251662Sdim } 1452251662Sdim } 1453251662Sdim } 1454251662Sdim 1455221345Sdim return getSema().BuildCXXForRangeStmt(ForLoc, ColonLoc, Range, BeginEnd, 1456243830Sdim Cond, Inc, LoopVar, RParenLoc, 1457243830Sdim Sema::BFRK_Rebuild); 1458221345Sdim } 1459234353Sdim 1460234353Sdim /// \brief Build a new C++0x range-based for statement. 1461234353Sdim /// 1462234353Sdim /// By default, performs semantic analysis to build the new statement. 1463234353Sdim /// Subclasses may override this routine to provide different behavior. 1464239462Sdim StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc, 1465234353Sdim bool IsIfExists, 1466234353Sdim NestedNameSpecifierLoc QualifierLoc, 1467234353Sdim DeclarationNameInfo NameInfo, 1468234353Sdim Stmt *Nested) { 1469234353Sdim return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists, 1470234353Sdim QualifierLoc, NameInfo, Nested); 1471234353Sdim } 1472234353Sdim 1473221345Sdim /// \brief Attach body to a C++0x range-based for statement. 1474221345Sdim /// 1475221345Sdim /// By default, performs semantic analysis to finish the new statement. 1476221345Sdim /// Subclasses may override this routine to provide different behavior. 1477221345Sdim StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) { 1478221345Sdim return getSema().FinishCXXForRangeStmt(ForRange, Body); 1479221345Sdim } 1480239462Sdim 1481263508Sdim StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc, 1482263508Sdim Stmt *TryBlock, Stmt *Handler) { 1483263508Sdim return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler); 1484221345Sdim } 1485221345Sdim 1486263508Sdim StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr, 1487221345Sdim Stmt *Block) { 1488263508Sdim return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block); 1489221345Sdim } 1490221345Sdim 1491263508Sdim StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) { 1492263508Sdim return getSema().ActOnSEHFinallyBlock(Loc, Block); 1493221345Sdim } 1494221345Sdim 1495198092Srdivacky /// \brief Build a new expression that references a declaration. 1496198092Srdivacky /// 1497198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1498198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1499212904Sdim ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS, 1500212904Sdim LookupResult &R, 1501212904Sdim bool RequiresADL) { 1502199990Srdivacky return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL); 1503199990Srdivacky } 1504199990Srdivacky 1505199990Srdivacky 1506199990Srdivacky /// \brief Build a new expression that references a declaration. 1507199990Srdivacky /// 1508199990Srdivacky /// By default, performs semantic analysis to build the new expression. 1509199990Srdivacky /// Subclasses may override this routine to provide different behavior. 1510221345Sdim ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc, 1511212904Sdim ValueDecl *VD, 1512212904Sdim const DeclarationNameInfo &NameInfo, 1513212904Sdim TemplateArgumentListInfo *TemplateArgs) { 1514198893Srdivacky CXXScopeSpec SS; 1515221345Sdim SS.Adopt(QualifierLoc); 1516200583Srdivacky 1517200583Srdivacky // FIXME: loses template args. 1518212904Sdim 1519212904Sdim return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD); 1520198092Srdivacky } 1521198092Srdivacky 1522198092Srdivacky /// \brief Build a new expression in parentheses. 1523198092Srdivacky /// 1524198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1525198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1526212904Sdim ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen, 1527198092Srdivacky SourceLocation RParen) { 1528212904Sdim return getSema().ActOnParenExpr(LParen, RParen, SubExpr); 1529198092Srdivacky } 1530198092Srdivacky 1531198092Srdivacky /// \brief Build a new pseudo-destructor expression. 1532198092Srdivacky /// 1533198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1534198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1535212904Sdim ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base, 1536219077Sdim SourceLocation OperatorLoc, 1537219077Sdim bool isArrow, 1538219077Sdim CXXScopeSpec &SS, 1539219077Sdim TypeSourceInfo *ScopeType, 1540219077Sdim SourceLocation CCLoc, 1541219077Sdim SourceLocation TildeLoc, 1542204643Srdivacky PseudoDestructorTypeStorage Destroyed); 1543198092Srdivacky 1544198092Srdivacky /// \brief Build a new unary operator expression. 1545198092Srdivacky /// 1546198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1547198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1548212904Sdim ExprResult RebuildUnaryOperator(SourceLocation OpLoc, 1549212904Sdim UnaryOperatorKind Opc, 1550212904Sdim Expr *SubExpr) { 1551212904Sdim return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, SubExpr); 1552198092Srdivacky } 1553198092Srdivacky 1554207619Srdivacky /// \brief Build a new builtin offsetof expression. 1555207619Srdivacky /// 1556207619Srdivacky /// By default, performs semantic analysis to build the new expression. 1557207619Srdivacky /// Subclasses may override this routine to provide different behavior. 1558212904Sdim ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc, 1559207619Srdivacky TypeSourceInfo *Type, 1560212904Sdim Sema::OffsetOfComponent *Components, 1561207619Srdivacky unsigned NumComponents, 1562207619Srdivacky SourceLocation RParenLoc) { 1563207619Srdivacky return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components, 1564207619Srdivacky NumComponents, RParenLoc); 1565207619Srdivacky } 1566239462Sdim 1567239462Sdim /// \brief Build a new sizeof, alignof or vec_step expression with a 1568221345Sdim /// type argument. 1569198092Srdivacky /// 1570198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1571198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1572221345Sdim ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo, 1573221345Sdim SourceLocation OpLoc, 1574221345Sdim UnaryExprOrTypeTrait ExprKind, 1575221345Sdim SourceRange R) { 1576221345Sdim return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R); 1577198092Srdivacky } 1578198092Srdivacky 1579221345Sdim /// \brief Build a new sizeof, alignof or vec step expression with an 1580221345Sdim /// expression argument. 1581198092Srdivacky /// 1582198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1583198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1584221345Sdim ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc, 1585221345Sdim UnaryExprOrTypeTrait ExprKind, 1586221345Sdim SourceRange R) { 1587212904Sdim ExprResult Result 1588223017Sdim = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind); 1589198092Srdivacky if (Result.isInvalid()) 1590212904Sdim return ExprError(); 1591198092Srdivacky 1592243830Sdim return Result; 1593198092Srdivacky } 1594198092Srdivacky 1595198092Srdivacky /// \brief Build a new array subscript expression. 1596198092Srdivacky /// 1597198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1598198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1599212904Sdim ExprResult RebuildArraySubscriptExpr(Expr *LHS, 1600198092Srdivacky SourceLocation LBracketLoc, 1601212904Sdim Expr *RHS, 1602198092Srdivacky SourceLocation RBracketLoc) { 1603212904Sdim return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, LHS, 1604212904Sdim LBracketLoc, RHS, 1605198092Srdivacky RBracketLoc); 1606198092Srdivacky } 1607198092Srdivacky 1608198092Srdivacky /// \brief Build a new call expression. 1609198092Srdivacky /// 1610198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1611198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1612212904Sdim ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc, 1613198092Srdivacky MultiExprArg Args, 1614218893Sdim SourceLocation RParenLoc, 1615218893Sdim Expr *ExecConfig = 0) { 1616212904Sdim return getSema().ActOnCallExpr(/*Scope=*/0, Callee, LParenLoc, 1617243830Sdim Args, RParenLoc, ExecConfig); 1618198092Srdivacky } 1619198092Srdivacky 1620198092Srdivacky /// \brief Build a new member access expression. 1621198092Srdivacky /// 1622198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1623198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1624212904Sdim ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc, 1625218893Sdim bool isArrow, 1626221345Sdim NestedNameSpecifierLoc QualifierLoc, 1627234353Sdim SourceLocation TemplateKWLoc, 1628218893Sdim const DeclarationNameInfo &MemberNameInfo, 1629218893Sdim ValueDecl *Member, 1630218893Sdim NamedDecl *FoundDecl, 1631199990Srdivacky const TemplateArgumentListInfo *ExplicitTemplateArgs, 1632218893Sdim NamedDecl *FirstQualifierInScope) { 1633234353Sdim ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base, 1634234353Sdim isArrow); 1635198092Srdivacky if (!Member->getDeclName()) { 1636218893Sdim // We have a reference to an unnamed field. This is always the 1637218893Sdim // base of an anonymous struct/union member access, i.e. the 1638218893Sdim // field is always of record type. 1639221345Sdim assert(!QualifierLoc && "Can't have an unnamed field with a qualifier!"); 1640218893Sdim assert(Member->getType()->isRecordType() && 1641218893Sdim "unnamed member not of record type?"); 1642198092Srdivacky 1643234353Sdim BaseResult = 1644234353Sdim getSema().PerformObjectMemberConversion(BaseResult.take(), 1645221345Sdim QualifierLoc.getNestedNameSpecifier(), 1646221345Sdim FoundDecl, Member); 1647221345Sdim if (BaseResult.isInvalid()) 1648212904Sdim return ExprError(); 1649221345Sdim Base = BaseResult.take(); 1650218893Sdim ExprValueKind VK = isArrow ? VK_LValue : Base->getValueKind(); 1651198092Srdivacky MemberExpr *ME = 1652212904Sdim new (getSema().Context) MemberExpr(Base, isArrow, 1653212904Sdim Member, MemberNameInfo, 1654218893Sdim cast<FieldDecl>(Member)->getType(), 1655218893Sdim VK, OK_Ordinary); 1656198092Srdivacky return getSema().Owned(ME); 1657198092Srdivacky } 1658198092Srdivacky 1659198092Srdivacky CXXScopeSpec SS; 1660221345Sdim SS.Adopt(QualifierLoc); 1661198092Srdivacky 1662221345Sdim Base = BaseResult.take(); 1663212904Sdim QualType BaseType = Base->getType(); 1664200583Srdivacky 1665206084Srdivacky // FIXME: this involves duplicating earlier analysis in a lot of 1666206084Srdivacky // cases; we should avoid this when possible. 1667212904Sdim LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName); 1668206084Srdivacky R.addDecl(FoundDecl); 1669202379Srdivacky R.resolveKind(); 1670202379Srdivacky 1671212904Sdim return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow, 1672234353Sdim SS, TemplateKWLoc, 1673234353Sdim FirstQualifierInScope, 1674202379Srdivacky R, ExplicitTemplateArgs); 1675198092Srdivacky } 1676198092Srdivacky 1677198092Srdivacky /// \brief Build a new binary operator expression. 1678198092Srdivacky /// 1679198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1680198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1681212904Sdim ExprResult RebuildBinaryOperator(SourceLocation OpLoc, 1682212904Sdim BinaryOperatorKind Opc, 1683212904Sdim Expr *LHS, Expr *RHS) { 1684212904Sdim return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc, LHS, RHS); 1685198092Srdivacky } 1686198092Srdivacky 1687198092Srdivacky /// \brief Build a new conditional operator expression. 1688198092Srdivacky /// 1689198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1690198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1691212904Sdim ExprResult RebuildConditionalOperator(Expr *Cond, 1692218893Sdim SourceLocation QuestionLoc, 1693218893Sdim Expr *LHS, 1694218893Sdim SourceLocation ColonLoc, 1695218893Sdim Expr *RHS) { 1696212904Sdim return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond, 1697212904Sdim LHS, RHS); 1698198092Srdivacky } 1699198092Srdivacky 1700198092Srdivacky /// \brief Build a new C-style cast expression. 1701198092Srdivacky /// 1702198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1703198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1704212904Sdim ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc, 1705202879Srdivacky TypeSourceInfo *TInfo, 1706198092Srdivacky SourceLocation RParenLoc, 1707212904Sdim Expr *SubExpr) { 1708202879Srdivacky return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc, 1709212904Sdim SubExpr); 1710198092Srdivacky } 1711198092Srdivacky 1712198092Srdivacky /// \brief Build a new compound literal expression. 1713198092Srdivacky /// 1714198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1715198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1716212904Sdim ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc, 1717202879Srdivacky TypeSourceInfo *TInfo, 1718198092Srdivacky SourceLocation RParenLoc, 1719212904Sdim Expr *Init) { 1720202879Srdivacky return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc, 1721212904Sdim Init); 1722198092Srdivacky } 1723198092Srdivacky 1724198092Srdivacky /// \brief Build a new extended vector element access expression. 1725198092Srdivacky /// 1726198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1727198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1728212904Sdim ExprResult RebuildExtVectorElementExpr(Expr *Base, 1729198092Srdivacky SourceLocation OpLoc, 1730198092Srdivacky SourceLocation AccessorLoc, 1731198092Srdivacky IdentifierInfo &Accessor) { 1732200583Srdivacky 1733199990Srdivacky CXXScopeSpec SS; 1734212904Sdim DeclarationNameInfo NameInfo(&Accessor, AccessorLoc); 1735212904Sdim return getSema().BuildMemberReferenceExpr(Base, Base->getType(), 1736199990Srdivacky OpLoc, /*IsArrow*/ false, 1737234353Sdim SS, SourceLocation(), 1738234353Sdim /*FirstQualifierInScope*/ 0, 1739212904Sdim NameInfo, 1740199990Srdivacky /* TemplateArgs */ 0); 1741198092Srdivacky } 1742198092Srdivacky 1743198092Srdivacky /// \brief Build a new initializer list expression. 1744198092Srdivacky /// 1745198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1746198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1747212904Sdim ExprResult RebuildInitList(SourceLocation LBraceLoc, 1748224145Sdim MultiExprArg Inits, 1749224145Sdim SourceLocation RBraceLoc, 1750224145Sdim QualType ResultTy) { 1751212904Sdim ExprResult Result 1752243830Sdim = SemaRef.ActOnInitList(LBraceLoc, Inits, RBraceLoc); 1753199482Srdivacky if (Result.isInvalid() || ResultTy->isDependentType()) 1754243830Sdim return Result; 1755239462Sdim 1756199482Srdivacky // Patch in the result type we were given, which may have been computed 1757199482Srdivacky // when the initial InitListExpr was built. 1758199482Srdivacky InitListExpr *ILE = cast<InitListExpr>((Expr *)Result.get()); 1759199482Srdivacky ILE->setType(ResultTy); 1760243830Sdim return Result; 1761198092Srdivacky } 1762198092Srdivacky 1763198092Srdivacky /// \brief Build a new designated initializer expression. 1764198092Srdivacky /// 1765198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1766198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1767212904Sdim ExprResult RebuildDesignatedInitExpr(Designation &Desig, 1768198092Srdivacky MultiExprArg ArrayExprs, 1769198092Srdivacky SourceLocation EqualOrColonLoc, 1770198092Srdivacky bool GNUSyntax, 1771212904Sdim Expr *Init) { 1772212904Sdim ExprResult Result 1773198092Srdivacky = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax, 1774212904Sdim Init); 1775198092Srdivacky if (Result.isInvalid()) 1776212904Sdim return ExprError(); 1777198092Srdivacky 1778243830Sdim return Result; 1779198092Srdivacky } 1780198092Srdivacky 1781198092Srdivacky /// \brief Build a new value-initialized expression. 1782198092Srdivacky /// 1783198092Srdivacky /// By default, builds the implicit value initialization without performing 1784198092Srdivacky /// any semantic analysis. Subclasses may override this routine to provide 1785198092Srdivacky /// different behavior. 1786212904Sdim ExprResult RebuildImplicitValueInitExpr(QualType T) { 1787198092Srdivacky return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T)); 1788198092Srdivacky } 1789198092Srdivacky 1790198092Srdivacky /// \brief Build a new \c va_arg expression. 1791198092Srdivacky /// 1792198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1793198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1794212904Sdim ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, 1795212904Sdim Expr *SubExpr, TypeSourceInfo *TInfo, 1796212904Sdim SourceLocation RParenLoc) { 1797212904Sdim return getSema().BuildVAArgExpr(BuiltinLoc, 1798212904Sdim SubExpr, TInfo, 1799212904Sdim RParenLoc); 1800198092Srdivacky } 1801198092Srdivacky 1802198092Srdivacky /// \brief Build a new expression list in parentheses. 1803198092Srdivacky /// 1804198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1805198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1806212904Sdim ExprResult RebuildParenListExpr(SourceLocation LParenLoc, 1807234353Sdim MultiExprArg SubExprs, 1808234353Sdim SourceLocation RParenLoc) { 1809243830Sdim return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs); 1810198092Srdivacky } 1811198092Srdivacky 1812198092Srdivacky /// \brief Build a new address-of-label expression. 1813198092Srdivacky /// 1814198092Srdivacky /// By default, performs semantic analysis, using the name of the label 1815198092Srdivacky /// rather than attempting to map the label statement itself. 1816198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1817212904Sdim ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc, 1818218893Sdim SourceLocation LabelLoc, LabelDecl *Label) { 1819218893Sdim return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label); 1820198092Srdivacky } 1821198092Srdivacky 1822198092Srdivacky /// \brief Build a new GNU statement expression. 1823198092Srdivacky /// 1824198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1825198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1826212904Sdim ExprResult RebuildStmtExpr(SourceLocation LParenLoc, 1827212904Sdim Stmt *SubStmt, 1828198092Srdivacky SourceLocation RParenLoc) { 1829212904Sdim return getSema().ActOnStmtExpr(LParenLoc, SubStmt, RParenLoc); 1830198092Srdivacky } 1831198092Srdivacky 1832198092Srdivacky /// \brief Build a new __builtin_choose_expr expression. 1833198092Srdivacky /// 1834198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1835198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1836212904Sdim ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc, 1837212904Sdim Expr *Cond, Expr *LHS, Expr *RHS, 1838198092Srdivacky SourceLocation RParenLoc) { 1839198092Srdivacky return SemaRef.ActOnChooseExpr(BuiltinLoc, 1840212904Sdim Cond, LHS, RHS, 1841198092Srdivacky RParenLoc); 1842198092Srdivacky } 1843198092Srdivacky 1844221345Sdim /// \brief Build a new generic selection expression. 1845221345Sdim /// 1846221345Sdim /// By default, performs semantic analysis to build the new expression. 1847221345Sdim /// Subclasses may override this routine to provide different behavior. 1848221345Sdim ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc, 1849221345Sdim SourceLocation DefaultLoc, 1850221345Sdim SourceLocation RParenLoc, 1851221345Sdim Expr *ControllingExpr, 1852263508Sdim ArrayRef<TypeSourceInfo *> Types, 1853263508Sdim ArrayRef<Expr *> Exprs) { 1854221345Sdim return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc, 1855263508Sdim ControllingExpr, Types, Exprs); 1856221345Sdim } 1857221345Sdim 1858198092Srdivacky /// \brief Build a new overloaded operator call expression. 1859198092Srdivacky /// 1860198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1861198092Srdivacky /// The semantic analysis provides the behavior of template instantiation, 1862198092Srdivacky /// copying with transformations that turn what looks like an overloaded 1863198092Srdivacky /// operator call into a use of a builtin operator, performing 1864198092Srdivacky /// argument-dependent lookup, etc. Subclasses may override this routine to 1865198092Srdivacky /// provide different behavior. 1866212904Sdim ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op, 1867198092Srdivacky SourceLocation OpLoc, 1868212904Sdim Expr *Callee, 1869212904Sdim Expr *First, 1870212904Sdim Expr *Second); 1871198092Srdivacky 1872198092Srdivacky /// \brief Build a new C++ "named" cast expression, such as static_cast or 1873198092Srdivacky /// reinterpret_cast. 1874198092Srdivacky /// 1875198092Srdivacky /// By default, this routine dispatches to one of the more-specific routines 1876198092Srdivacky /// for a particular named case, e.g., RebuildCXXStaticCastExpr(). 1877198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1878212904Sdim ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc, 1879198092Srdivacky Stmt::StmtClass Class, 1880198092Srdivacky SourceLocation LAngleLoc, 1881202879Srdivacky TypeSourceInfo *TInfo, 1882198092Srdivacky SourceLocation RAngleLoc, 1883198092Srdivacky SourceLocation LParenLoc, 1884212904Sdim Expr *SubExpr, 1885198092Srdivacky SourceLocation RParenLoc) { 1886198092Srdivacky switch (Class) { 1887198092Srdivacky case Stmt::CXXStaticCastExprClass: 1888202879Srdivacky return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo, 1889198092Srdivacky RAngleLoc, LParenLoc, 1890212904Sdim SubExpr, RParenLoc); 1891198092Srdivacky 1892198092Srdivacky case Stmt::CXXDynamicCastExprClass: 1893202879Srdivacky return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo, 1894198092Srdivacky RAngleLoc, LParenLoc, 1895212904Sdim SubExpr, RParenLoc); 1896198092Srdivacky 1897198092Srdivacky case Stmt::CXXReinterpretCastExprClass: 1898202879Srdivacky return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo, 1899198092Srdivacky RAngleLoc, LParenLoc, 1900212904Sdim SubExpr, 1901198092Srdivacky RParenLoc); 1902198092Srdivacky 1903198092Srdivacky case Stmt::CXXConstCastExprClass: 1904202879Srdivacky return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo, 1905198092Srdivacky RAngleLoc, LParenLoc, 1906212904Sdim SubExpr, RParenLoc); 1907198092Srdivacky 1908198092Srdivacky default: 1909226633Sdim llvm_unreachable("Invalid C++ named cast"); 1910198092Srdivacky } 1911198092Srdivacky } 1912198092Srdivacky 1913198092Srdivacky /// \brief Build a new C++ static_cast expression. 1914198092Srdivacky /// 1915198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1916198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1917212904Sdim ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc, 1918198092Srdivacky SourceLocation LAngleLoc, 1919202879Srdivacky TypeSourceInfo *TInfo, 1920198092Srdivacky SourceLocation RAngleLoc, 1921198092Srdivacky SourceLocation LParenLoc, 1922212904Sdim Expr *SubExpr, 1923198092Srdivacky SourceLocation RParenLoc) { 1924202879Srdivacky return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast, 1925212904Sdim TInfo, SubExpr, 1926202879Srdivacky SourceRange(LAngleLoc, RAngleLoc), 1927202879Srdivacky SourceRange(LParenLoc, RParenLoc)); 1928198092Srdivacky } 1929198092Srdivacky 1930198092Srdivacky /// \brief Build a new C++ dynamic_cast expression. 1931198092Srdivacky /// 1932198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1933198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1934212904Sdim ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc, 1935198092Srdivacky SourceLocation LAngleLoc, 1936202879Srdivacky TypeSourceInfo *TInfo, 1937198092Srdivacky SourceLocation RAngleLoc, 1938198092Srdivacky SourceLocation LParenLoc, 1939212904Sdim Expr *SubExpr, 1940198092Srdivacky SourceLocation RParenLoc) { 1941202879Srdivacky return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast, 1942212904Sdim TInfo, SubExpr, 1943202879Srdivacky SourceRange(LAngleLoc, RAngleLoc), 1944202879Srdivacky SourceRange(LParenLoc, RParenLoc)); 1945198092Srdivacky } 1946198092Srdivacky 1947198092Srdivacky /// \brief Build a new C++ reinterpret_cast expression. 1948198092Srdivacky /// 1949198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1950198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1951212904Sdim ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc, 1952198092Srdivacky SourceLocation LAngleLoc, 1953202879Srdivacky TypeSourceInfo *TInfo, 1954198092Srdivacky SourceLocation RAngleLoc, 1955198092Srdivacky SourceLocation LParenLoc, 1956212904Sdim Expr *SubExpr, 1957198092Srdivacky SourceLocation RParenLoc) { 1958202879Srdivacky return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast, 1959212904Sdim TInfo, SubExpr, 1960202879Srdivacky SourceRange(LAngleLoc, RAngleLoc), 1961202879Srdivacky SourceRange(LParenLoc, RParenLoc)); 1962198092Srdivacky } 1963198092Srdivacky 1964198092Srdivacky /// \brief Build a new C++ const_cast expression. 1965198092Srdivacky /// 1966198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1967198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1968212904Sdim ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc, 1969198092Srdivacky SourceLocation LAngleLoc, 1970202879Srdivacky TypeSourceInfo *TInfo, 1971198092Srdivacky SourceLocation RAngleLoc, 1972198092Srdivacky SourceLocation LParenLoc, 1973212904Sdim Expr *SubExpr, 1974198092Srdivacky SourceLocation RParenLoc) { 1975202879Srdivacky return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast, 1976212904Sdim TInfo, SubExpr, 1977202879Srdivacky SourceRange(LAngleLoc, RAngleLoc), 1978202879Srdivacky SourceRange(LParenLoc, RParenLoc)); 1979198092Srdivacky } 1980198092Srdivacky 1981198092Srdivacky /// \brief Build a new C++ functional-style cast expression. 1982198092Srdivacky /// 1983198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1984198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1985218893Sdim ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, 1986218893Sdim SourceLocation LParenLoc, 1987218893Sdim Expr *Sub, 1988218893Sdim SourceLocation RParenLoc) { 1989218893Sdim return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc, 1990212904Sdim MultiExprArg(&Sub, 1), 1991198092Srdivacky RParenLoc); 1992198092Srdivacky } 1993198092Srdivacky 1994198092Srdivacky /// \brief Build a new C++ typeid(type) expression. 1995198092Srdivacky /// 1996198092Srdivacky /// By default, performs semantic analysis to build the new expression. 1997198092Srdivacky /// Subclasses may override this routine to provide different behavior. 1998212904Sdim ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType, 1999207619Srdivacky SourceLocation TypeidLoc, 2000207619Srdivacky TypeSourceInfo *Operand, 2001198092Srdivacky SourceLocation RParenLoc) { 2002239462Sdim return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand, 2003207619Srdivacky RParenLoc); 2004198092Srdivacky } 2005198092Srdivacky 2006218893Sdim 2007198092Srdivacky /// \brief Build a new C++ typeid(expr) expression. 2008198092Srdivacky /// 2009198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2010198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2011212904Sdim ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType, 2012207619Srdivacky SourceLocation TypeidLoc, 2013212904Sdim Expr *Operand, 2014198092Srdivacky SourceLocation RParenLoc) { 2015212904Sdim return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand, 2016207619Srdivacky RParenLoc); 2017198092Srdivacky } 2018198092Srdivacky 2019218893Sdim /// \brief Build a new C++ __uuidof(type) expression. 2020218893Sdim /// 2021218893Sdim /// By default, performs semantic analysis to build the new expression. 2022218893Sdim /// Subclasses may override this routine to provide different behavior. 2023218893Sdim ExprResult RebuildCXXUuidofExpr(QualType TypeInfoType, 2024218893Sdim SourceLocation TypeidLoc, 2025218893Sdim TypeSourceInfo *Operand, 2026218893Sdim SourceLocation RParenLoc) { 2027239462Sdim return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand, 2028218893Sdim RParenLoc); 2029218893Sdim } 2030218893Sdim 2031218893Sdim /// \brief Build a new C++ __uuidof(expr) expression. 2032218893Sdim /// 2033218893Sdim /// By default, performs semantic analysis to build the new expression. 2034218893Sdim /// Subclasses may override this routine to provide different behavior. 2035218893Sdim ExprResult RebuildCXXUuidofExpr(QualType TypeInfoType, 2036218893Sdim SourceLocation TypeidLoc, 2037218893Sdim Expr *Operand, 2038218893Sdim SourceLocation RParenLoc) { 2039218893Sdim return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand, 2040218893Sdim RParenLoc); 2041218893Sdim } 2042218893Sdim 2043198092Srdivacky /// \brief Build a new C++ "this" expression. 2044198092Srdivacky /// 2045198092Srdivacky /// By default, builds a new "this" expression without performing any 2046198092Srdivacky /// semantic analysis. Subclasses may override this routine to provide 2047198092Srdivacky /// different behavior. 2048212904Sdim ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc, 2049218893Sdim QualType ThisType, 2050218893Sdim bool isImplicit) { 2051234353Sdim getSema().CheckCXXThisCapture(ThisLoc); 2052198092Srdivacky return getSema().Owned( 2053202379Srdivacky new (getSema().Context) CXXThisExpr(ThisLoc, ThisType, 2054202379Srdivacky isImplicit)); 2055198092Srdivacky } 2056198092Srdivacky 2057198092Srdivacky /// \brief Build a new C++ throw expression. 2058198092Srdivacky /// 2059198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2060198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2061224145Sdim ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub, 2062224145Sdim bool IsThrownVariableInScope) { 2063224145Sdim return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope); 2064198092Srdivacky } 2065198092Srdivacky 2066198092Srdivacky /// \brief Build a new C++ default-argument expression. 2067198092Srdivacky /// 2068198092Srdivacky /// By default, builds a new default-argument expression, which does not 2069198092Srdivacky /// require any semantic analysis. Subclasses may override this routine to 2070198092Srdivacky /// provide different behavior. 2071239462Sdim ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, 2072201361Srdivacky ParmVarDecl *Param) { 2073201361Srdivacky return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Loc, 2074201361Srdivacky Param)); 2075198092Srdivacky } 2076198092Srdivacky 2077251662Sdim /// \brief Build a new C++11 default-initialization expression. 2078251662Sdim /// 2079251662Sdim /// By default, builds a new default field initialization expression, which 2080251662Sdim /// does not require any semantic analysis. Subclasses may override this 2081251662Sdim /// routine to provide different behavior. 2082251662Sdim ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc, 2083251662Sdim FieldDecl *Field) { 2084251662Sdim return getSema().Owned(CXXDefaultInitExpr::Create(getSema().Context, Loc, 2085251662Sdim Field)); 2086251662Sdim } 2087251662Sdim 2088198092Srdivacky /// \brief Build a new C++ zero-initialization expression. 2089198092Srdivacky /// 2090198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2091198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2092218893Sdim ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo, 2093218893Sdim SourceLocation LParenLoc, 2094218893Sdim SourceLocation RParenLoc) { 2095218893Sdim return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, 2096251662Sdim None, RParenLoc); 2097198092Srdivacky } 2098198092Srdivacky 2099198092Srdivacky /// \brief Build a new C++ "new" expression. 2100198092Srdivacky /// 2101198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2102198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2103212904Sdim ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, 2104218893Sdim bool UseGlobal, 2105218893Sdim SourceLocation PlacementLParen, 2106218893Sdim MultiExprArg PlacementArgs, 2107218893Sdim SourceLocation PlacementRParen, 2108218893Sdim SourceRange TypeIdParens, 2109218893Sdim QualType AllocatedType, 2110218893Sdim TypeSourceInfo *AllocatedTypeInfo, 2111218893Sdim Expr *ArraySize, 2112234353Sdim SourceRange DirectInitRange, 2113234353Sdim Expr *Initializer) { 2114198092Srdivacky return getSema().BuildCXXNew(StartLoc, UseGlobal, 2115198092Srdivacky PlacementLParen, 2116243830Sdim PlacementArgs, 2117198092Srdivacky PlacementRParen, 2118210299Sed TypeIdParens, 2119218893Sdim AllocatedType, 2120218893Sdim AllocatedTypeInfo, 2121212904Sdim ArraySize, 2122234353Sdim DirectInitRange, 2123234353Sdim Initializer); 2124198092Srdivacky } 2125198092Srdivacky 2126198092Srdivacky /// \brief Build a new C++ "delete" expression. 2127198092Srdivacky /// 2128198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2129198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2130212904Sdim ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc, 2131198092Srdivacky bool IsGlobalDelete, 2132198092Srdivacky bool IsArrayForm, 2133212904Sdim Expr *Operand) { 2134198092Srdivacky return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm, 2135212904Sdim Operand); 2136198092Srdivacky } 2137198092Srdivacky 2138198092Srdivacky /// \brief Build a new unary type trait expression. 2139198092Srdivacky /// 2140198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2141198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2142212904Sdim ExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait, 2143218893Sdim SourceLocation StartLoc, 2144218893Sdim TypeSourceInfo *T, 2145218893Sdim SourceLocation RParenLoc) { 2146218893Sdim return getSema().BuildUnaryTypeTrait(Trait, StartLoc, T, RParenLoc); 2147198092Srdivacky } 2148198092Srdivacky 2149218893Sdim /// \brief Build a new binary type trait expression. 2150218893Sdim /// 2151218893Sdim /// By default, performs semantic analysis to build the new expression. 2152218893Sdim /// Subclasses may override this routine to provide different behavior. 2153218893Sdim ExprResult RebuildBinaryTypeTrait(BinaryTypeTrait Trait, 2154218893Sdim SourceLocation StartLoc, 2155218893Sdim TypeSourceInfo *LhsT, 2156218893Sdim TypeSourceInfo *RhsT, 2157218893Sdim SourceLocation RParenLoc) { 2158218893Sdim return getSema().BuildBinaryTypeTrait(Trait, StartLoc, LhsT, RhsT, RParenLoc); 2159218893Sdim } 2160218893Sdim 2161234353Sdim /// \brief Build a new type trait expression. 2162234353Sdim /// 2163234353Sdim /// By default, performs semantic analysis to build the new expression. 2164234353Sdim /// Subclasses may override this routine to provide different behavior. 2165234353Sdim ExprResult RebuildTypeTrait(TypeTrait Trait, 2166234353Sdim SourceLocation StartLoc, 2167234353Sdim ArrayRef<TypeSourceInfo *> Args, 2168234353Sdim SourceLocation RParenLoc) { 2169234353Sdim return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc); 2170234353Sdim } 2171239462Sdim 2172221345Sdim /// \brief Build a new array type trait expression. 2173221345Sdim /// 2174221345Sdim /// By default, performs semantic analysis to build the new expression. 2175221345Sdim /// Subclasses may override this routine to provide different behavior. 2176221345Sdim ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait, 2177221345Sdim SourceLocation StartLoc, 2178221345Sdim TypeSourceInfo *TSInfo, 2179221345Sdim Expr *DimExpr, 2180221345Sdim SourceLocation RParenLoc) { 2181221345Sdim return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc); 2182221345Sdim } 2183221345Sdim 2184221345Sdim /// \brief Build a new expression trait expression. 2185221345Sdim /// 2186221345Sdim /// By default, performs semantic analysis to build the new expression. 2187221345Sdim /// Subclasses may override this routine to provide different behavior. 2188221345Sdim ExprResult RebuildExpressionTrait(ExpressionTrait Trait, 2189221345Sdim SourceLocation StartLoc, 2190221345Sdim Expr *Queried, 2191221345Sdim SourceLocation RParenLoc) { 2192221345Sdim return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc); 2193221345Sdim } 2194221345Sdim 2195198092Srdivacky /// \brief Build a new (previously unresolved) declaration reference 2196198092Srdivacky /// expression. 2197198092Srdivacky /// 2198198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2199198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2200219077Sdim ExprResult RebuildDependentScopeDeclRefExpr( 2201219077Sdim NestedNameSpecifierLoc QualifierLoc, 2202234353Sdim SourceLocation TemplateKWLoc, 2203212904Sdim const DeclarationNameInfo &NameInfo, 2204243830Sdim const TemplateArgumentListInfo *TemplateArgs, 2205243830Sdim bool IsAddressOfOperand) { 2206198092Srdivacky CXXScopeSpec SS; 2207219077Sdim SS.Adopt(QualifierLoc); 2208199990Srdivacky 2209234353Sdim if (TemplateArgs || TemplateKWLoc.isValid()) 2210234353Sdim return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc, 2211234353Sdim NameInfo, TemplateArgs); 2212199990Srdivacky 2213243830Sdim return getSema().BuildQualifiedDeclarationNameExpr(SS, NameInfo, 2214243830Sdim IsAddressOfOperand); 2215198092Srdivacky } 2216198092Srdivacky 2217198092Srdivacky /// \brief Build a new template-id expression. 2218198092Srdivacky /// 2219198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2220198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2221212904Sdim ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS, 2222234353Sdim SourceLocation TemplateKWLoc, 2223234353Sdim LookupResult &R, 2224234353Sdim bool RequiresADL, 2225234353Sdim const TemplateArgumentListInfo *TemplateArgs) { 2226234353Sdim return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL, 2227234353Sdim TemplateArgs); 2228198092Srdivacky } 2229198092Srdivacky 2230198092Srdivacky /// \brief Build a new object-construction expression. 2231198092Srdivacky /// 2232198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2233198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2234212904Sdim ExprResult RebuildCXXConstructExpr(QualType T, 2235226633Sdim SourceLocation Loc, 2236226633Sdim CXXConstructorDecl *Constructor, 2237226633Sdim bool IsElidable, 2238226633Sdim MultiExprArg Args, 2239226633Sdim bool HadMultipleCandidates, 2240249423Sdim bool ListInitialization, 2241226633Sdim bool RequiresZeroInit, 2242218893Sdim CXXConstructExpr::ConstructionKind ConstructKind, 2243226633Sdim SourceRange ParenRange) { 2244243830Sdim SmallVector<Expr*, 8> ConvertedArgs; 2245243830Sdim if (getSema().CompleteConstructorCall(Constructor, Args, Loc, 2246200583Srdivacky ConvertedArgs)) 2247212904Sdim return ExprError(); 2248239462Sdim 2249200583Srdivacky return getSema().BuildCXXConstructExpr(Loc, T, Constructor, IsElidable, 2250243830Sdim ConvertedArgs, 2251226633Sdim HadMultipleCandidates, 2252249423Sdim ListInitialization, 2253218893Sdim RequiresZeroInit, ConstructKind, 2254218893Sdim ParenRange); 2255198092Srdivacky } 2256198092Srdivacky 2257198092Srdivacky /// \brief Build a new object-construction expression. 2258198092Srdivacky /// 2259198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2260198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2261218893Sdim ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo, 2262218893Sdim SourceLocation LParenLoc, 2263218893Sdim MultiExprArg Args, 2264218893Sdim SourceLocation RParenLoc) { 2265218893Sdim return getSema().BuildCXXTypeConstructExpr(TSInfo, 2266198092Srdivacky LParenLoc, 2267243830Sdim Args, 2268198092Srdivacky RParenLoc); 2269198092Srdivacky } 2270198092Srdivacky 2271198092Srdivacky /// \brief Build a new object-construction expression. 2272198092Srdivacky /// 2273198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2274198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2275218893Sdim ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo, 2276218893Sdim SourceLocation LParenLoc, 2277218893Sdim MultiExprArg Args, 2278218893Sdim SourceLocation RParenLoc) { 2279218893Sdim return getSema().BuildCXXTypeConstructExpr(TSInfo, 2280198092Srdivacky LParenLoc, 2281243830Sdim Args, 2282198092Srdivacky RParenLoc); 2283198092Srdivacky } 2284198092Srdivacky 2285198092Srdivacky /// \brief Build a new member reference expression. 2286198092Srdivacky /// 2287198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2288198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2289212904Sdim ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE, 2290221345Sdim QualType BaseType, 2291221345Sdim bool IsArrow, 2292221345Sdim SourceLocation OperatorLoc, 2293221345Sdim NestedNameSpecifierLoc QualifierLoc, 2294234353Sdim SourceLocation TemplateKWLoc, 2295199990Srdivacky NamedDecl *FirstQualifierInScope, 2296212904Sdim const DeclarationNameInfo &MemberNameInfo, 2297199990Srdivacky const TemplateArgumentListInfo *TemplateArgs) { 2298198092Srdivacky CXXScopeSpec SS; 2299221345Sdim SS.Adopt(QualifierLoc); 2300198092Srdivacky 2301212904Sdim return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType, 2302200583Srdivacky OperatorLoc, IsArrow, 2303234353Sdim SS, TemplateKWLoc, 2304234353Sdim FirstQualifierInScope, 2305212904Sdim MemberNameInfo, 2306212904Sdim TemplateArgs); 2307198092Srdivacky } 2308198092Srdivacky 2309199990Srdivacky /// \brief Build a new member reference expression. 2310198092Srdivacky /// 2311198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2312198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2313234353Sdim ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType, 2314234353Sdim SourceLocation OperatorLoc, 2315234353Sdim bool IsArrow, 2316234353Sdim NestedNameSpecifierLoc QualifierLoc, 2317234353Sdim SourceLocation TemplateKWLoc, 2318234353Sdim NamedDecl *FirstQualifierInScope, 2319234353Sdim LookupResult &R, 2320199990Srdivacky const TemplateArgumentListInfo *TemplateArgs) { 2321198092Srdivacky CXXScopeSpec SS; 2322221345Sdim SS.Adopt(QualifierLoc); 2323198092Srdivacky 2324212904Sdim return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType, 2325200583Srdivacky OperatorLoc, IsArrow, 2326234353Sdim SS, TemplateKWLoc, 2327234353Sdim FirstQualifierInScope, 2328202379Srdivacky R, TemplateArgs); 2329198092Srdivacky } 2330198092Srdivacky 2331218893Sdim /// \brief Build a new noexcept expression. 2332218893Sdim /// 2333218893Sdim /// By default, performs semantic analysis to build the new expression. 2334218893Sdim /// Subclasses may override this routine to provide different behavior. 2335218893Sdim ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) { 2336218893Sdim return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd()); 2337218893Sdim } 2338218893Sdim 2339218893Sdim /// \brief Build a new expression to compute the length of a parameter pack. 2340239462Sdim ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack, 2341239462Sdim SourceLocation PackLoc, 2342218893Sdim SourceLocation RParenLoc, 2343249423Sdim Optional<unsigned> Length) { 2344226633Sdim if (Length) 2345239462Sdim return new (SemaRef.Context) SizeOfPackExpr(SemaRef.Context.getSizeType(), 2346239462Sdim OperatorLoc, Pack, PackLoc, 2347226633Sdim RParenLoc, *Length); 2348239462Sdim 2349239462Sdim return new (SemaRef.Context) SizeOfPackExpr(SemaRef.Context.getSizeType(), 2350239462Sdim OperatorLoc, Pack, PackLoc, 2351226633Sdim RParenLoc); 2352218893Sdim } 2353234353Sdim 2354239462Sdim /// \brief Build a new Objective-C boxed expression. 2355239462Sdim /// 2356239462Sdim /// By default, performs semantic analysis to build the new expression. 2357239462Sdim /// Subclasses may override this routine to provide different behavior. 2358239462Sdim ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) { 2359239462Sdim return getSema().BuildObjCBoxedExpr(SR, ValueExpr); 2360239462Sdim } 2361239462Sdim 2362234353Sdim /// \brief Build a new Objective-C array literal. 2363234353Sdim /// 2364234353Sdim /// By default, performs semantic analysis to build the new expression. 2365234353Sdim /// Subclasses may override this routine to provide different behavior. 2366234353Sdim ExprResult RebuildObjCArrayLiteral(SourceRange Range, 2367234353Sdim Expr **Elements, unsigned NumElements) { 2368239462Sdim return getSema().BuildObjCArrayLiteral(Range, 2369234353Sdim MultiExprArg(Elements, NumElements)); 2370234353Sdim } 2371239462Sdim 2372239462Sdim ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB, 2373234353Sdim Expr *Base, Expr *Key, 2374234353Sdim ObjCMethodDecl *getterMethod, 2375234353Sdim ObjCMethodDecl *setterMethod) { 2376234353Sdim return getSema().BuildObjCSubscriptExpression(RB, Base, Key, 2377234353Sdim getterMethod, setterMethod); 2378234353Sdim } 2379234353Sdim 2380234353Sdim /// \brief Build a new Objective-C dictionary literal. 2381234353Sdim /// 2382234353Sdim /// By default, performs semantic analysis to build the new expression. 2383234353Sdim /// Subclasses may override this routine to provide different behavior. 2384234353Sdim ExprResult RebuildObjCDictionaryLiteral(SourceRange Range, 2385234353Sdim ObjCDictionaryElement *Elements, 2386234353Sdim unsigned NumElements) { 2387234353Sdim return getSema().BuildObjCDictionaryLiteral(Range, Elements, NumElements); 2388234353Sdim } 2389239462Sdim 2390239462Sdim /// \brief Build a new Objective-C \@encode expression. 2391198092Srdivacky /// 2392198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2393198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2394212904Sdim ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc, 2395207619Srdivacky TypeSourceInfo *EncodeTypeInfo, 2396198092Srdivacky SourceLocation RParenLoc) { 2397207619Srdivacky return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo, 2398198092Srdivacky RParenLoc)); 2399198092Srdivacky } 2400198092Srdivacky 2401207619Srdivacky /// \brief Build a new Objective-C class message. 2402212904Sdim ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo, 2403207619Srdivacky Selector Sel, 2404226633Sdim ArrayRef<SourceLocation> SelectorLocs, 2405207619Srdivacky ObjCMethodDecl *Method, 2406239462Sdim SourceLocation LBracLoc, 2407207619Srdivacky MultiExprArg Args, 2408207619Srdivacky SourceLocation RBracLoc) { 2409207619Srdivacky return SemaRef.BuildClassMessage(ReceiverTypeInfo, 2410207619Srdivacky ReceiverTypeInfo->getType(), 2411207619Srdivacky /*SuperLoc=*/SourceLocation(), 2412226633Sdim Sel, Method, LBracLoc, SelectorLocs, 2413243830Sdim RBracLoc, Args); 2414207619Srdivacky } 2415207619Srdivacky 2416207619Srdivacky /// \brief Build a new Objective-C instance message. 2417212904Sdim ExprResult RebuildObjCMessageExpr(Expr *Receiver, 2418207619Srdivacky Selector Sel, 2419226633Sdim ArrayRef<SourceLocation> SelectorLocs, 2420207619Srdivacky ObjCMethodDecl *Method, 2421239462Sdim SourceLocation LBracLoc, 2422207619Srdivacky MultiExprArg Args, 2423207619Srdivacky SourceLocation RBracLoc) { 2424212904Sdim return SemaRef.BuildInstanceMessage(Receiver, 2425212904Sdim Receiver->getType(), 2426207619Srdivacky /*SuperLoc=*/SourceLocation(), 2427226633Sdim Sel, Method, LBracLoc, SelectorLocs, 2428243830Sdim RBracLoc, Args); 2429207619Srdivacky } 2430207619Srdivacky 2431207619Srdivacky /// \brief Build a new Objective-C ivar reference expression. 2432198092Srdivacky /// 2433198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2434198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2435212904Sdim ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar, 2436207619Srdivacky SourceLocation IvarLoc, 2437207619Srdivacky bool IsArrow, bool IsFreeIvar) { 2438207619Srdivacky // FIXME: We lose track of the IsFreeIvar bit. 2439207619Srdivacky CXXScopeSpec SS; 2440221345Sdim ExprResult Base = getSema().Owned(BaseArg); 2441207619Srdivacky LookupResult R(getSema(), Ivar->getDeclName(), IvarLoc, 2442207619Srdivacky Sema::LookupMemberName); 2443212904Sdim ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow, 2444207619Srdivacky /*FIME:*/IvarLoc, 2445212904Sdim SS, 0, 2446210299Sed false); 2447221345Sdim if (Result.isInvalid() || Base.isInvalid()) 2448212904Sdim return ExprError(); 2449239462Sdim 2450207619Srdivacky if (Result.get()) 2451243830Sdim return Result; 2452239462Sdim 2453221345Sdim return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(), 2454234353Sdim /*FIXME:*/IvarLoc, IsArrow, 2455234353Sdim SS, SourceLocation(), 2456207619Srdivacky /*FirstQualifierInScope=*/0, 2457239462Sdim R, 2458207619Srdivacky /*TemplateArgs=*/0); 2459198092Srdivacky } 2460198092Srdivacky 2461207619Srdivacky /// \brief Build a new Objective-C property reference expression. 2462207619Srdivacky /// 2463207619Srdivacky /// By default, performs semantic analysis to build the new expression. 2464207619Srdivacky /// Subclasses may override this routine to provide different behavior. 2465239462Sdim ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg, 2466234353Sdim ObjCPropertyDecl *Property, 2467234353Sdim SourceLocation PropertyLoc) { 2468207619Srdivacky CXXScopeSpec SS; 2469221345Sdim ExprResult Base = getSema().Owned(BaseArg); 2470207619Srdivacky LookupResult R(getSema(), Property->getDeclName(), PropertyLoc, 2471207619Srdivacky Sema::LookupMemberName); 2472207619Srdivacky bool IsArrow = false; 2473212904Sdim ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow, 2474207619Srdivacky /*FIME:*/PropertyLoc, 2475212904Sdim SS, 0, false); 2476221345Sdim if (Result.isInvalid() || Base.isInvalid()) 2477212904Sdim return ExprError(); 2478239462Sdim 2479207619Srdivacky if (Result.get()) 2480243830Sdim return Result; 2481239462Sdim 2482221345Sdim return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(), 2483239462Sdim /*FIXME:*/PropertyLoc, IsArrow, 2484234353Sdim SS, SourceLocation(), 2485207619Srdivacky /*FirstQualifierInScope=*/0, 2486239462Sdim R, 2487207619Srdivacky /*TemplateArgs=*/0); 2488207619Srdivacky } 2489239462Sdim 2490218893Sdim /// \brief Build a new Objective-C property reference expression. 2491207619Srdivacky /// 2492207619Srdivacky /// By default, performs semantic analysis to build the new expression. 2493218893Sdim /// Subclasses may override this routine to provide different behavior. 2494218893Sdim ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T, 2495218893Sdim ObjCMethodDecl *Getter, 2496218893Sdim ObjCMethodDecl *Setter, 2497218893Sdim SourceLocation PropertyLoc) { 2498218893Sdim // Since these expressions can only be value-dependent, we do not 2499218893Sdim // need to perform semantic analysis again. 2500212904Sdim return Owned( 2501218893Sdim new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T, 2502218893Sdim VK_LValue, OK_ObjCProperty, 2503218893Sdim PropertyLoc, Base)); 2504207619Srdivacky } 2505207619Srdivacky 2506207619Srdivacky /// \brief Build a new Objective-C "isa" expression. 2507207619Srdivacky /// 2508207619Srdivacky /// By default, performs semantic analysis to build the new expression. 2509207619Srdivacky /// Subclasses may override this routine to provide different behavior. 2510212904Sdim ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc, 2511249423Sdim SourceLocation OpLoc, 2512207619Srdivacky bool IsArrow) { 2513207619Srdivacky CXXScopeSpec SS; 2514221345Sdim ExprResult Base = getSema().Owned(BaseArg); 2515207619Srdivacky LookupResult R(getSema(), &getSema().Context.Idents.get("isa"), IsaLoc, 2516207619Srdivacky Sema::LookupMemberName); 2517212904Sdim ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow, 2518249423Sdim OpLoc, 2519212904Sdim SS, 0, false); 2520221345Sdim if (Result.isInvalid() || Base.isInvalid()) 2521212904Sdim return ExprError(); 2522239462Sdim 2523207619Srdivacky if (Result.get()) 2524243830Sdim return Result; 2525239462Sdim 2526221345Sdim return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(), 2527249423Sdim OpLoc, IsArrow, 2528234353Sdim SS, SourceLocation(), 2529207619Srdivacky /*FirstQualifierInScope=*/0, 2530239462Sdim R, 2531207619Srdivacky /*TemplateArgs=*/0); 2532207619Srdivacky } 2533239462Sdim 2534198092Srdivacky /// \brief Build a new shuffle vector expression. 2535198092Srdivacky /// 2536198092Srdivacky /// By default, performs semantic analysis to build the new expression. 2537198092Srdivacky /// Subclasses may override this routine to provide different behavior. 2538212904Sdim ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc, 2539218893Sdim MultiExprArg SubExprs, 2540218893Sdim SourceLocation RParenLoc) { 2541198092Srdivacky // Find the declaration for __builtin_shufflevector 2542198092Srdivacky const IdentifierInfo &Name 2543198092Srdivacky = SemaRef.Context.Idents.get("__builtin_shufflevector"); 2544198092Srdivacky TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl(); 2545198092Srdivacky DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name)); 2546249423Sdim assert(!Lookup.empty() && "No __builtin_shufflevector?"); 2547198092Srdivacky 2548198092Srdivacky // Build a reference to the __builtin_shufflevector builtin 2549249423Sdim FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front()); 2550243830Sdim Expr *Callee = new (SemaRef.Context) DeclRefExpr(Builtin, false, 2551243830Sdim SemaRef.Context.BuiltinFnTy, 2552243830Sdim VK_RValue, BuiltinLoc); 2553243830Sdim QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType()); 2554243830Sdim Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy, 2555243830Sdim CK_BuiltinFnToFnPtr).take(); 2556198092Srdivacky 2557198092Srdivacky // Build the CallExpr 2558221345Sdim ExprResult TheCall = SemaRef.Owned( 2559243830Sdim new (SemaRef.Context) CallExpr(SemaRef.Context, Callee, SubExprs, 2560243830Sdim Builtin->getCallResultType(), 2561218893Sdim Expr::getValueKindForType(Builtin->getResultType()), 2562221345Sdim RParenLoc)); 2563198092Srdivacky 2564198092Srdivacky // Type-check the __builtin_shufflevector expression. 2565221345Sdim return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.take())); 2566198092Srdivacky } 2567218893Sdim 2568263508Sdim /// \brief Build a new convert vector expression. 2569263508Sdim ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc, 2570263508Sdim Expr *SrcExpr, TypeSourceInfo *DstTInfo, 2571263508Sdim SourceLocation RParenLoc) { 2572263508Sdim return SemaRef.SemaConvertVectorExpr(SrcExpr, DstTInfo, 2573263508Sdim BuiltinLoc, RParenLoc); 2574263508Sdim } 2575263508Sdim 2576218893Sdim /// \brief Build a new template argument pack expansion. 2577218893Sdim /// 2578218893Sdim /// By default, performs semantic analysis to build a new pack expansion 2579239462Sdim /// for a template argument. Subclasses may override this routine to provide 2580218893Sdim /// different behavior. 2581218893Sdim TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern, 2582218893Sdim SourceLocation EllipsisLoc, 2583249423Sdim Optional<unsigned> NumExpansions) { 2584218893Sdim switch (Pattern.getArgument().getKind()) { 2585218893Sdim case TemplateArgument::Expression: { 2586218893Sdim ExprResult Result 2587218893Sdim = getSema().CheckPackExpansion(Pattern.getSourceExpression(), 2588218893Sdim EllipsisLoc, NumExpansions); 2589218893Sdim if (Result.isInvalid()) 2590218893Sdim return TemplateArgumentLoc(); 2591239462Sdim 2592218893Sdim return TemplateArgumentLoc(Result.get(), Result.get()); 2593218893Sdim } 2594239462Sdim 2595218893Sdim case TemplateArgument::Template: 2596218893Sdim return TemplateArgumentLoc(TemplateArgument( 2597218893Sdim Pattern.getArgument().getAsTemplate(), 2598218893Sdim NumExpansions), 2599221345Sdim Pattern.getTemplateQualifierLoc(), 2600218893Sdim Pattern.getTemplateNameLoc(), 2601218893Sdim EllipsisLoc); 2602239462Sdim 2603218893Sdim case TemplateArgument::Null: 2604218893Sdim case TemplateArgument::Integral: 2605218893Sdim case TemplateArgument::Declaration: 2606218893Sdim case TemplateArgument::Pack: 2607218893Sdim case TemplateArgument::TemplateExpansion: 2608243830Sdim case TemplateArgument::NullPtr: 2609218893Sdim llvm_unreachable("Pack expansion pattern has no parameter packs"); 2610239462Sdim 2611218893Sdim case TemplateArgument::Type: 2612239462Sdim if (TypeSourceInfo *Expansion 2613218893Sdim = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(), 2614218893Sdim EllipsisLoc, 2615218893Sdim NumExpansions)) 2616218893Sdim return TemplateArgumentLoc(TemplateArgument(Expansion->getType()), 2617218893Sdim Expansion); 2618218893Sdim break; 2619218893Sdim } 2620239462Sdim 2621218893Sdim return TemplateArgumentLoc(); 2622218893Sdim } 2623239462Sdim 2624218893Sdim /// \brief Build a new expression pack expansion. 2625218893Sdim /// 2626218893Sdim /// By default, performs semantic analysis to build a new pack expansion 2627239462Sdim /// for an expression. Subclasses may override this routine to provide 2628218893Sdim /// different behavior. 2629218893Sdim ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc, 2630249423Sdim Optional<unsigned> NumExpansions) { 2631218893Sdim return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions); 2632218893Sdim } 2633226633Sdim 2634226633Sdim /// \brief Build a new atomic operation expression. 2635226633Sdim /// 2636226633Sdim /// By default, performs semantic analysis to build the new expression. 2637226633Sdim /// Subclasses may override this routine to provide different behavior. 2638226633Sdim ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, 2639226633Sdim MultiExprArg SubExprs, 2640226633Sdim QualType RetTy, 2641226633Sdim AtomicExpr::AtomicOp Op, 2642226633Sdim SourceLocation RParenLoc) { 2643226633Sdim // Just create the expression; there is not any interesting semantic 2644226633Sdim // analysis here because we can't actually build an AtomicExpr until 2645226633Sdim // we are sure it is semantically sound. 2646243830Sdim return new (SemaRef.Context) AtomicExpr(BuiltinLoc, SubExprs, RetTy, Op, 2647226633Sdim RParenLoc); 2648226633Sdim } 2649226633Sdim 2650218893Sdimprivate: 2651219077Sdim TypeLoc TransformTypeInObjectScope(TypeLoc TL, 2652219077Sdim QualType ObjectType, 2653219077Sdim NamedDecl *FirstQualifierInScope, 2654219077Sdim CXXScopeSpec &SS); 2655221345Sdim 2656221345Sdim TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo, 2657221345Sdim QualType ObjectType, 2658221345Sdim NamedDecl *FirstQualifierInScope, 2659221345Sdim CXXScopeSpec &SS); 2660198092Srdivacky}; 2661198092Srdivacky 2662198092Srdivackytemplate<typename Derived> 2663212904SdimStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) { 2664198092Srdivacky if (!S) 2665198092Srdivacky return SemaRef.Owned(S); 2666198092Srdivacky 2667198092Srdivacky switch (S->getStmtClass()) { 2668198092Srdivacky case Stmt::NoStmtClass: break; 2669198092Srdivacky 2670198092Srdivacky // Transform individual statement nodes 2671198092Srdivacky#define STMT(Node, Parent) \ 2672198092Srdivacky case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S)); 2673218893Sdim#define ABSTRACT_STMT(Node) 2674198092Srdivacky#define EXPR(Node, Parent) 2675208600Srdivacky#include "clang/AST/StmtNodes.inc" 2676198092Srdivacky 2677198092Srdivacky // Transform expressions by calling TransformExpr. 2678198092Srdivacky#define STMT(Node, Parent) 2679208600Srdivacky#define ABSTRACT_STMT(Stmt) 2680198092Srdivacky#define EXPR(Node, Parent) case Stmt::Node##Class: 2681208600Srdivacky#include "clang/AST/StmtNodes.inc" 2682198092Srdivacky { 2683212904Sdim ExprResult E = getDerived().TransformExpr(cast<Expr>(S)); 2684198092Srdivacky if (E.isInvalid()) 2685212904Sdim return StmtError(); 2686198092Srdivacky 2687249423Sdim return getSema().ActOnExprStmt(E); 2688198092Srdivacky } 2689198092Srdivacky } 2690198092Srdivacky 2691218893Sdim return SemaRef.Owned(S); 2692198092Srdivacky} 2693198092Srdivacky 2694263508Sdimtemplate<typename Derived> 2695263508SdimOMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) { 2696263508Sdim if (!S) 2697263508Sdim return S; 2698198092Srdivacky 2699263508Sdim switch (S->getClauseKind()) { 2700263508Sdim default: break; 2701263508Sdim // Transform individual clause nodes 2702263508Sdim#define OPENMP_CLAUSE(Name, Class) \ 2703263508Sdim case OMPC_ ## Name : \ 2704263508Sdim return getDerived().Transform ## Class(cast<Class>(S)); 2705263508Sdim#include "clang/Basic/OpenMPKinds.def" 2706263508Sdim } 2707263508Sdim 2708263508Sdim return S; 2709263508Sdim} 2710263508Sdim 2711263508Sdim 2712198092Srdivackytemplate<typename Derived> 2713212904SdimExprResult TreeTransform<Derived>::TransformExpr(Expr *E) { 2714198092Srdivacky if (!E) 2715198092Srdivacky return SemaRef.Owned(E); 2716198092Srdivacky 2717198092Srdivacky switch (E->getStmtClass()) { 2718198092Srdivacky case Stmt::NoStmtClass: break; 2719198092Srdivacky#define STMT(Node, Parent) case Stmt::Node##Class: break; 2720208600Srdivacky#define ABSTRACT_STMT(Stmt) 2721198092Srdivacky#define EXPR(Node, Parent) \ 2722200583Srdivacky case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E)); 2723208600Srdivacky#include "clang/AST/StmtNodes.inc" 2724198092Srdivacky } 2725198092Srdivacky 2726218893Sdim return SemaRef.Owned(E); 2727198092Srdivacky} 2728198092Srdivacky 2729198092Srdivackytemplate<typename Derived> 2730249423SdimExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init, 2731249423Sdim bool CXXDirectInit) { 2732249423Sdim // Initializers are instantiated like expressions, except that various outer 2733249423Sdim // layers are stripped. 2734249423Sdim if (!Init) 2735249423Sdim return SemaRef.Owned(Init); 2736249423Sdim 2737249423Sdim if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init)) 2738249423Sdim Init = ExprTemp->getSubExpr(); 2739249423Sdim 2740263508Sdim if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init)) 2741263508Sdim Init = MTE->GetTemporaryExpr(); 2742263508Sdim 2743249423Sdim while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init)) 2744249423Sdim Init = Binder->getSubExpr(); 2745249423Sdim 2746249423Sdim if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init)) 2747249423Sdim Init = ICE->getSubExprAsWritten(); 2748249423Sdim 2749263508Sdim if (CXXStdInitializerListExpr *ILE = 2750263508Sdim dyn_cast<CXXStdInitializerListExpr>(Init)) 2751263508Sdim return TransformInitializer(ILE->getSubExpr(), CXXDirectInit); 2752263508Sdim 2753249423Sdim // If this is not a direct-initializer, we only need to reconstruct 2754249423Sdim // InitListExprs. Other forms of copy-initialization will be a no-op if 2755249423Sdim // the initializer is already the right type. 2756249423Sdim CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init); 2757249423Sdim if (!CXXDirectInit && !(Construct && Construct->isListInitialization())) 2758249423Sdim return getDerived().TransformExpr(Init); 2759249423Sdim 2760249423Sdim // Revert value-initialization back to empty parens. 2761249423Sdim if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) { 2762249423Sdim SourceRange Parens = VIE->getSourceRange(); 2763251662Sdim return getDerived().RebuildParenListExpr(Parens.getBegin(), None, 2764249423Sdim Parens.getEnd()); 2765249423Sdim } 2766249423Sdim 2767249423Sdim // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization. 2768249423Sdim if (isa<ImplicitValueInitExpr>(Init)) 2769251662Sdim return getDerived().RebuildParenListExpr(SourceLocation(), None, 2770249423Sdim SourceLocation()); 2771249423Sdim 2772249423Sdim // Revert initialization by constructor back to a parenthesized or braced list 2773249423Sdim // of expressions. Any other form of initializer can just be reused directly. 2774249423Sdim if (!Construct || isa<CXXTemporaryObjectExpr>(Construct)) 2775249423Sdim return getDerived().TransformExpr(Init); 2776249423Sdim 2777249423Sdim SmallVector<Expr*, 8> NewArgs; 2778249423Sdim bool ArgChanged = false; 2779249423Sdim if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(), 2780249423Sdim /*IsCall*/true, NewArgs, &ArgChanged)) 2781249423Sdim return ExprError(); 2782249423Sdim 2783249423Sdim // If this was list initialization, revert to list form. 2784249423Sdim if (Construct->isListInitialization()) 2785249423Sdim return getDerived().RebuildInitList(Construct->getLocStart(), NewArgs, 2786249423Sdim Construct->getLocEnd(), 2787249423Sdim Construct->getType()); 2788249423Sdim 2789249423Sdim // Build a ParenListExpr to represent anything else. 2790263508Sdim SourceRange Parens = Construct->getParenOrBraceRange(); 2791249423Sdim return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs, 2792249423Sdim Parens.getEnd()); 2793249423Sdim} 2794249423Sdim 2795249423Sdimtemplate<typename Derived> 2796239462Sdimbool TreeTransform<Derived>::TransformExprs(Expr **Inputs, 2797239462Sdim unsigned NumInputs, 2798218893Sdim bool IsCall, 2799226633Sdim SmallVectorImpl<Expr *> &Outputs, 2800218893Sdim bool *ArgChanged) { 2801218893Sdim for (unsigned I = 0; I != NumInputs; ++I) { 2802218893Sdim // If requested, drop call arguments that need to be dropped. 2803218893Sdim if (IsCall && getDerived().DropCallArgument(Inputs[I])) { 2804218893Sdim if (ArgChanged) 2805218893Sdim *ArgChanged = true; 2806239462Sdim 2807218893Sdim break; 2808218893Sdim } 2809239462Sdim 2810218893Sdim if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) { 2811218893Sdim Expr *Pattern = Expansion->getPattern(); 2812239462Sdim 2813226633Sdim SmallVector<UnexpandedParameterPack, 2> Unexpanded; 2814218893Sdim getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); 2815218893Sdim assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); 2816239462Sdim 2817218893Sdim // Determine whether the set of unexpanded parameter packs can and should 2818218893Sdim // be expanded. 2819218893Sdim bool Expand = true; 2820218893Sdim bool RetainExpansion = false; 2821249423Sdim Optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions(); 2822249423Sdim Optional<unsigned> NumExpansions = OrigNumExpansions; 2823218893Sdim if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(), 2824218893Sdim Pattern->getSourceRange(), 2825226633Sdim Unexpanded, 2826218893Sdim Expand, RetainExpansion, 2827218893Sdim NumExpansions)) 2828218893Sdim return true; 2829239462Sdim 2830218893Sdim if (!Expand) { 2831218893Sdim // The transform has determined that we should perform a simple 2832239462Sdim // transformation on the pack expansion, producing another pack 2833218893Sdim // expansion. 2834218893Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); 2835218893Sdim ExprResult OutPattern = getDerived().TransformExpr(Pattern); 2836218893Sdim if (OutPattern.isInvalid()) 2837218893Sdim return true; 2838239462Sdim 2839239462Sdim ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(), 2840218893Sdim Expansion->getEllipsisLoc(), 2841218893Sdim NumExpansions); 2842218893Sdim if (Out.isInvalid()) 2843218893Sdim return true; 2844239462Sdim 2845218893Sdim if (ArgChanged) 2846218893Sdim *ArgChanged = true; 2847218893Sdim Outputs.push_back(Out.get()); 2848218893Sdim continue; 2849218893Sdim } 2850224145Sdim 2851224145Sdim // Record right away that the argument was changed. This needs 2852224145Sdim // to happen even if the array expands to nothing. 2853224145Sdim if (ArgChanged) *ArgChanged = true; 2854239462Sdim 2855218893Sdim // The transform has determined that we should perform an elementwise 2856218893Sdim // expansion of the pattern. Do so. 2857218893Sdim for (unsigned I = 0; I != *NumExpansions; ++I) { 2858218893Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); 2859218893Sdim ExprResult Out = getDerived().TransformExpr(Pattern); 2860218893Sdim if (Out.isInvalid()) 2861218893Sdim return true; 2862218893Sdim 2863218893Sdim if (Out.get()->containsUnexpandedParameterPack()) { 2864218893Sdim Out = RebuildPackExpansion(Out.get(), Expansion->getEllipsisLoc(), 2865218893Sdim OrigNumExpansions); 2866218893Sdim if (Out.isInvalid()) 2867218893Sdim return true; 2868218893Sdim } 2869239462Sdim 2870218893Sdim Outputs.push_back(Out.get()); 2871218893Sdim } 2872239462Sdim 2873218893Sdim continue; 2874218893Sdim } 2875239462Sdim 2876249423Sdim ExprResult Result = 2877249423Sdim IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false) 2878249423Sdim : getDerived().TransformExpr(Inputs[I]); 2879218893Sdim if (Result.isInvalid()) 2880218893Sdim return true; 2881239462Sdim 2882218893Sdim if (Result.get() != Inputs[I] && ArgChanged) 2883218893Sdim *ArgChanged = true; 2884239462Sdim 2885239462Sdim Outputs.push_back(Result.get()); 2886218893Sdim } 2887239462Sdim 2888218893Sdim return false; 2889218893Sdim} 2890218893Sdim 2891218893Sdimtemplate<typename Derived> 2892219077SdimNestedNameSpecifierLoc 2893219077SdimTreeTransform<Derived>::TransformNestedNameSpecifierLoc( 2894219077Sdim NestedNameSpecifierLoc NNS, 2895219077Sdim QualType ObjectType, 2896219077Sdim NamedDecl *FirstQualifierInScope) { 2897226633Sdim SmallVector<NestedNameSpecifierLoc, 4> Qualifiers; 2898239462Sdim for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier; 2899219077Sdim Qualifier = Qualifier.getPrefix()) 2900219077Sdim Qualifiers.push_back(Qualifier); 2901219077Sdim 2902219077Sdim CXXScopeSpec SS; 2903219077Sdim while (!Qualifiers.empty()) { 2904219077Sdim NestedNameSpecifierLoc Q = Qualifiers.pop_back_val(); 2905219077Sdim NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier(); 2906239462Sdim 2907219077Sdim switch (QNNS->getKind()) { 2908219077Sdim case NestedNameSpecifier::Identifier: 2909239462Sdim if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/0, 2910219077Sdim *QNNS->getAsIdentifier(), 2911239462Sdim Q.getLocalBeginLoc(), 2912219077Sdim Q.getLocalEndLoc(), 2913239462Sdim ObjectType, false, SS, 2914219077Sdim FirstQualifierInScope, false)) 2915219077Sdim return NestedNameSpecifierLoc(); 2916239462Sdim 2917219077Sdim break; 2918239462Sdim 2919219077Sdim case NestedNameSpecifier::Namespace: { 2920219077Sdim NamespaceDecl *NS 2921219077Sdim = cast_or_null<NamespaceDecl>( 2922219077Sdim getDerived().TransformDecl( 2923219077Sdim Q.getLocalBeginLoc(), 2924219077Sdim QNNS->getAsNamespace())); 2925219077Sdim SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc()); 2926219077Sdim break; 2927219077Sdim } 2928239462Sdim 2929219077Sdim case NestedNameSpecifier::NamespaceAlias: { 2930219077Sdim NamespaceAliasDecl *Alias 2931219077Sdim = cast_or_null<NamespaceAliasDecl>( 2932219077Sdim getDerived().TransformDecl(Q.getLocalBeginLoc(), 2933219077Sdim QNNS->getAsNamespaceAlias())); 2934239462Sdim SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(), 2935219077Sdim Q.getLocalEndLoc()); 2936219077Sdim break; 2937219077Sdim } 2938239462Sdim 2939219077Sdim case NestedNameSpecifier::Global: 2940219077Sdim // There is no meaningful transformation that one could perform on the 2941219077Sdim // global scope. 2942219077Sdim SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc()); 2943219077Sdim break; 2944239462Sdim 2945219077Sdim case NestedNameSpecifier::TypeSpecWithTemplate: 2946219077Sdim case NestedNameSpecifier::TypeSpec: { 2947219077Sdim TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType, 2948219077Sdim FirstQualifierInScope, SS); 2949239462Sdim 2950219077Sdim if (!TL) 2951219077Sdim return NestedNameSpecifierLoc(); 2952239462Sdim 2953219077Sdim if (TL.getType()->isDependentType() || TL.getType()->isRecordType() || 2954249423Sdim (SemaRef.getLangOpts().CPlusPlus11 && 2955219077Sdim TL.getType()->isEnumeralType())) { 2956239462Sdim assert(!TL.getType().hasLocalQualifiers() && 2957219077Sdim "Can't get cv-qualifiers here"); 2958234353Sdim if (TL.getType()->isEnumeralType()) 2959234353Sdim SemaRef.Diag(TL.getBeginLoc(), 2960234353Sdim diag::warn_cxx98_compat_enum_nested_name_spec); 2961219077Sdim SS.Extend(SemaRef.Context, /*FIXME:*/SourceLocation(), TL, 2962219077Sdim Q.getLocalEndLoc()); 2963219077Sdim break; 2964219077Sdim } 2965223017Sdim // If the nested-name-specifier is an invalid type def, don't emit an 2966223017Sdim // error because a previous error should have already been emitted. 2967249423Sdim TypedefTypeLoc TTL = TL.getAs<TypedefTypeLoc>(); 2968249423Sdim if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) { 2969239462Sdim SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag) 2970223017Sdim << TL.getType() << SS.getRange(); 2971223017Sdim } 2972219077Sdim return NestedNameSpecifierLoc(); 2973219077Sdim } 2974221345Sdim } 2975239462Sdim 2976221345Sdim // The qualifier-in-scope and object type only apply to the leftmost entity. 2977219077Sdim FirstQualifierInScope = 0; 2978221345Sdim ObjectType = QualType(); 2979219077Sdim } 2980239462Sdim 2981219077Sdim // Don't rebuild the nested-name-specifier if we don't have to. 2982239462Sdim if (SS.getScopeRep() == NNS.getNestedNameSpecifier() && 2983219077Sdim !getDerived().AlwaysRebuild()) 2984219077Sdim return NNS; 2985239462Sdim 2986239462Sdim // If we can re-use the source-location data from the original 2987219077Sdim // nested-name-specifier, do so. 2988219077Sdim if (SS.location_size() == NNS.getDataLength() && 2989219077Sdim memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0) 2990219077Sdim return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData()); 2991219077Sdim 2992219077Sdim // Allocate new nested-name-specifier location information. 2993219077Sdim return SS.getWithLocInContext(SemaRef.Context); 2994219077Sdim} 2995219077Sdim 2996219077Sdimtemplate<typename Derived> 2997212904SdimDeclarationNameInfo 2998212904SdimTreeTransform<Derived> 2999218893Sdim::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) { 3000212904Sdim DeclarationName Name = NameInfo.getName(); 3001198092Srdivacky if (!Name) 3002212904Sdim return DeclarationNameInfo(); 3003198092Srdivacky 3004198092Srdivacky switch (Name.getNameKind()) { 3005198092Srdivacky case DeclarationName::Identifier: 3006198092Srdivacky case DeclarationName::ObjCZeroArgSelector: 3007198092Srdivacky case DeclarationName::ObjCOneArgSelector: 3008198092Srdivacky case DeclarationName::ObjCMultiArgSelector: 3009198092Srdivacky case DeclarationName::CXXOperatorName: 3010199990Srdivacky case DeclarationName::CXXLiteralOperatorName: 3011198092Srdivacky case DeclarationName::CXXUsingDirective: 3012212904Sdim return NameInfo; 3013198092Srdivacky 3014198092Srdivacky case DeclarationName::CXXConstructorName: 3015198092Srdivacky case DeclarationName::CXXDestructorName: 3016198092Srdivacky case DeclarationName::CXXConversionFunctionName: { 3017212904Sdim TypeSourceInfo *NewTInfo; 3018212904Sdim CanQualType NewCanTy; 3019212904Sdim if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) { 3020218893Sdim NewTInfo = getDerived().TransformType(OldTInfo); 3021218893Sdim if (!NewTInfo) 3022218893Sdim return DeclarationNameInfo(); 3023218893Sdim NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType()); 3024212904Sdim } 3025212904Sdim else { 3026212904Sdim NewTInfo = 0; 3027212904Sdim TemporaryBase Rebase(*this, NameInfo.getLoc(), Name); 3028218893Sdim QualType NewT = getDerived().TransformType(Name.getCXXNameType()); 3029212904Sdim if (NewT.isNull()) 3030212904Sdim return DeclarationNameInfo(); 3031212904Sdim NewCanTy = SemaRef.Context.getCanonicalType(NewT); 3032212904Sdim } 3033198092Srdivacky 3034212904Sdim DeclarationName NewName 3035212904Sdim = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(), 3036212904Sdim NewCanTy); 3037212904Sdim DeclarationNameInfo NewNameInfo(NameInfo); 3038212904Sdim NewNameInfo.setName(NewName); 3039212904Sdim NewNameInfo.setNamedTypeInfo(NewTInfo); 3040212904Sdim return NewNameInfo; 3041198092Srdivacky } 3042198092Srdivacky } 3043198092Srdivacky 3044226633Sdim llvm_unreachable("Unknown name kind."); 3045198092Srdivacky} 3046198092Srdivacky 3047198092Srdivackytemplate<typename Derived> 3048198092SrdivackyTemplateName 3049221345SdimTreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS, 3050221345Sdim TemplateName Name, 3051221345Sdim SourceLocation NameLoc, 3052218893Sdim QualType ObjectType, 3053218893Sdim NamedDecl *FirstQualifierInScope) { 3054198092Srdivacky if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) { 3055221345Sdim TemplateDecl *Template = QTN->getTemplateDecl(); 3056221345Sdim assert(Template && "qualified template name must refer to a template"); 3057239462Sdim 3058221345Sdim TemplateDecl *TransTemplate 3059239462Sdim = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc, 3060221345Sdim Template)); 3061221345Sdim if (!TransTemplate) 3062198092Srdivacky return TemplateName(); 3063239462Sdim 3064221345Sdim if (!getDerived().AlwaysRebuild() && 3065221345Sdim SS.getScopeRep() == QTN->getQualifier() && 3066221345Sdim TransTemplate == Template) 3067221345Sdim return Name; 3068239462Sdim 3069221345Sdim return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(), 3070221345Sdim TransTemplate); 3071198092Srdivacky } 3072239462Sdim 3073198092Srdivacky if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) { 3074221345Sdim if (SS.getScopeRep()) { 3075218893Sdim // These apply to the scope specifier, not the template. 3076218893Sdim ObjectType = QualType(); 3077218893Sdim FirstQualifierInScope = 0; 3078239462Sdim } 3079239462Sdim 3080198092Srdivacky if (!getDerived().AlwaysRebuild() && 3081221345Sdim SS.getScopeRep() == DTN->getQualifier() && 3082198398Srdivacky ObjectType.isNull()) 3083198092Srdivacky return Name; 3084239462Sdim 3085218893Sdim if (DTN->isIdentifier()) { 3086221345Sdim return getDerived().RebuildTemplateName(SS, 3087239462Sdim *DTN->getIdentifier(), 3088221345Sdim NameLoc, 3089218893Sdim ObjectType, 3090218893Sdim FirstQualifierInScope); 3091218893Sdim } 3092239462Sdim 3093221345Sdim return getDerived().RebuildTemplateName(SS, DTN->getOperator(), NameLoc, 3094198893Srdivacky ObjectType); 3095198092Srdivacky } 3096239462Sdim 3097198092Srdivacky if (TemplateDecl *Template = Name.getAsTemplateDecl()) { 3098198092Srdivacky TemplateDecl *TransTemplate 3099239462Sdim = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc, 3100221345Sdim Template)); 3101198092Srdivacky if (!TransTemplate) 3102198092Srdivacky return TemplateName(); 3103239462Sdim 3104198092Srdivacky if (!getDerived().AlwaysRebuild() && 3105198092Srdivacky TransTemplate == Template) 3106198092Srdivacky return Name; 3107239462Sdim 3108198092Srdivacky return TemplateName(TransTemplate); 3109198092Srdivacky } 3110239462Sdim 3111218893Sdim if (SubstTemplateTemplateParmPackStorage *SubstPack 3112221345Sdim = Name.getAsSubstTemplateTemplateParmPack()) { 3113218893Sdim TemplateTemplateParmDecl *TransParam 3114221345Sdim = cast_or_null<TemplateTemplateParmDecl>( 3115221345Sdim getDerived().TransformDecl(NameLoc, SubstPack->getParameterPack())); 3116218893Sdim if (!TransParam) 3117218893Sdim return TemplateName(); 3118239462Sdim 3119218893Sdim if (!getDerived().AlwaysRebuild() && 3120218893Sdim TransParam == SubstPack->getParameterPack()) 3121218893Sdim return Name; 3122239462Sdim 3123239462Sdim return getDerived().RebuildTemplateName(TransParam, 3124218893Sdim SubstPack->getArgumentPack()); 3125218893Sdim } 3126239462Sdim 3127199990Srdivacky // These should be getting filtered out before they reach the AST. 3128218893Sdim llvm_unreachable("overloaded function decl survived to here"); 3129198092Srdivacky} 3130198092Srdivacky 3131198092Srdivackytemplate<typename Derived> 3132198893Srdivackyvoid TreeTransform<Derived>::InventTemplateArgumentLoc( 3133198893Srdivacky const TemplateArgument &Arg, 3134198893Srdivacky TemplateArgumentLoc &Output) { 3135198893Srdivacky SourceLocation Loc = getDerived().getBaseLocation(); 3136198092Srdivacky switch (Arg.getKind()) { 3137198092Srdivacky case TemplateArgument::Null: 3138200583Srdivacky llvm_unreachable("null template argument in TreeTransform"); 3139198893Srdivacky break; 3140198893Srdivacky 3141198893Srdivacky case TemplateArgument::Type: 3142198893Srdivacky Output = TemplateArgumentLoc(Arg, 3143200583Srdivacky SemaRef.Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc)); 3144239462Sdim 3145198893Srdivacky break; 3146198893Srdivacky 3147199482Srdivacky case TemplateArgument::Template: 3148221345Sdim case TemplateArgument::TemplateExpansion: { 3149221345Sdim NestedNameSpecifierLocBuilder Builder; 3150221345Sdim TemplateName Template = Arg.getAsTemplate(); 3151221345Sdim if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) 3152221345Sdim Builder.MakeTrivial(SemaRef.Context, DTN->getQualifier(), Loc); 3153221345Sdim else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) 3154221345Sdim Builder.MakeTrivial(SemaRef.Context, QTN->getQualifier(), Loc); 3155239462Sdim 3156221345Sdim if (Arg.getKind() == TemplateArgument::Template) 3157239462Sdim Output = TemplateArgumentLoc(Arg, 3158221345Sdim Builder.getWithLocInContext(SemaRef.Context), 3159221345Sdim Loc); 3160221345Sdim else 3161239462Sdim Output = TemplateArgumentLoc(Arg, 3162221345Sdim Builder.getWithLocInContext(SemaRef.Context), 3163221345Sdim Loc, Loc); 3164239462Sdim 3165199482Srdivacky break; 3166221345Sdim } 3167218893Sdim 3168198893Srdivacky case TemplateArgument::Expression: 3169198893Srdivacky Output = TemplateArgumentLoc(Arg, Arg.getAsExpr()); 3170198893Srdivacky break; 3171198893Srdivacky 3172198893Srdivacky case TemplateArgument::Declaration: 3173198092Srdivacky case TemplateArgument::Integral: 3174198893Srdivacky case TemplateArgument::Pack: 3175243830Sdim case TemplateArgument::NullPtr: 3176198893Srdivacky Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo()); 3177198893Srdivacky break; 3178198893Srdivacky } 3179198893Srdivacky} 3180198092Srdivacky 3181198893Srdivackytemplate<typename Derived> 3182198893Srdivackybool TreeTransform<Derived>::TransformTemplateArgument( 3183198893Srdivacky const TemplateArgumentLoc &Input, 3184198893Srdivacky TemplateArgumentLoc &Output) { 3185198893Srdivacky const TemplateArgument &Arg = Input.getArgument(); 3186198893Srdivacky switch (Arg.getKind()) { 3187198893Srdivacky case TemplateArgument::Null: 3188198893Srdivacky case TemplateArgument::Integral: 3189243830Sdim case TemplateArgument::Pack: 3190243830Sdim case TemplateArgument::Declaration: 3191243830Sdim case TemplateArgument::NullPtr: 3192243830Sdim llvm_unreachable("Unexpected TemplateArgument"); 3193198893Srdivacky 3194198092Srdivacky case TemplateArgument::Type: { 3195200583Srdivacky TypeSourceInfo *DI = Input.getTypeSourceInfo(); 3196198893Srdivacky if (DI == NULL) 3197200583Srdivacky DI = InventTypeSourceInfo(Input.getArgument().getAsType()); 3198198893Srdivacky 3199198893Srdivacky DI = getDerived().TransformType(DI); 3200198893Srdivacky if (!DI) return true; 3201198893Srdivacky 3202198893Srdivacky Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI); 3203198893Srdivacky return false; 3204198092Srdivacky } 3205198092Srdivacky 3206199482Srdivacky case TemplateArgument::Template: { 3207221345Sdim NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc(); 3208221345Sdim if (QualifierLoc) { 3209221345Sdim QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc); 3210221345Sdim if (!QualifierLoc) 3211221345Sdim return true; 3212221345Sdim } 3213239462Sdim 3214221345Sdim CXXScopeSpec SS; 3215221345Sdim SS.Adopt(QualifierLoc); 3216199482Srdivacky TemplateName Template 3217221345Sdim = getDerived().TransformTemplateName(SS, Arg.getAsTemplate(), 3218221345Sdim Input.getTemplateNameLoc()); 3219199482Srdivacky if (Template.isNull()) 3220199482Srdivacky return true; 3221239462Sdim 3222221345Sdim Output = TemplateArgumentLoc(TemplateArgument(Template), QualifierLoc, 3223199482Srdivacky Input.getTemplateNameLoc()); 3224199482Srdivacky return false; 3225199482Srdivacky } 3226218893Sdim 3227218893Sdim case TemplateArgument::TemplateExpansion: 3228218893Sdim llvm_unreachable("Caller should expand pack expansions"); 3229218893Sdim 3230198092Srdivacky case TemplateArgument::Expression: { 3231234353Sdim // Template argument expressions are constant expressions. 3232198092Srdivacky EnterExpressionEvaluationContext Unevaluated(getSema(), 3233234353Sdim Sema::ConstantEvaluated); 3234198092Srdivacky 3235198893Srdivacky Expr *InputExpr = Input.getSourceExpression(); 3236198893Srdivacky if (!InputExpr) InputExpr = Input.getArgument().getAsExpr(); 3237198893Srdivacky 3238221345Sdim ExprResult E = getDerived().TransformExpr(InputExpr); 3239234353Sdim E = SemaRef.ActOnConstantExpression(E); 3240198893Srdivacky if (E.isInvalid()) return true; 3241212904Sdim Output = TemplateArgumentLoc(TemplateArgument(E.take()), E.take()); 3242198893Srdivacky return false; 3243198092Srdivacky } 3244198092Srdivacky } 3245198092Srdivacky 3246198092Srdivacky // Work around bogus GCC warning 3247198893Srdivacky return true; 3248198092Srdivacky} 3249198092Srdivacky 3250218893Sdim/// \brief Iterator adaptor that invents template argument location information 3251218893Sdim/// for each of the template arguments in its underlying iterator. 3252218893Sdimtemplate<typename Derived, typename InputIterator> 3253218893Sdimclass TemplateArgumentLocInventIterator { 3254218893Sdim TreeTransform<Derived> &Self; 3255218893Sdim InputIterator Iter; 3256239462Sdim 3257218893Sdimpublic: 3258218893Sdim typedef TemplateArgumentLoc value_type; 3259218893Sdim typedef TemplateArgumentLoc reference; 3260218893Sdim typedef typename std::iterator_traits<InputIterator>::difference_type 3261218893Sdim difference_type; 3262218893Sdim typedef std::input_iterator_tag iterator_category; 3263239462Sdim 3264218893Sdim class pointer { 3265218893Sdim TemplateArgumentLoc Arg; 3266239462Sdim 3267218893Sdim public: 3268218893Sdim explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { } 3269239462Sdim 3270218893Sdim const TemplateArgumentLoc *operator->() const { return &Arg; } 3271218893Sdim }; 3272239462Sdim 3273218893Sdim TemplateArgumentLocInventIterator() { } 3274239462Sdim 3275218893Sdim explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self, 3276218893Sdim InputIterator Iter) 3277218893Sdim : Self(Self), Iter(Iter) { } 3278239462Sdim 3279218893Sdim TemplateArgumentLocInventIterator &operator++() { 3280218893Sdim ++Iter; 3281218893Sdim return *this; 3282218893Sdim } 3283239462Sdim 3284218893Sdim TemplateArgumentLocInventIterator operator++(int) { 3285218893Sdim TemplateArgumentLocInventIterator Old(*this); 3286218893Sdim ++(*this); 3287218893Sdim return Old; 3288218893Sdim } 3289239462Sdim 3290218893Sdim reference operator*() const { 3291218893Sdim TemplateArgumentLoc Result; 3292218893Sdim Self.InventTemplateArgumentLoc(*Iter, Result); 3293218893Sdim return Result; 3294218893Sdim } 3295239462Sdim 3296218893Sdim pointer operator->() const { return pointer(**this); } 3297239462Sdim 3298218893Sdim friend bool operator==(const TemplateArgumentLocInventIterator &X, 3299218893Sdim const TemplateArgumentLocInventIterator &Y) { 3300218893Sdim return X.Iter == Y.Iter; 3301218893Sdim } 3302218893Sdim 3303218893Sdim friend bool operator!=(const TemplateArgumentLocInventIterator &X, 3304218893Sdim const TemplateArgumentLocInventIterator &Y) { 3305218893Sdim return X.Iter != Y.Iter; 3306218893Sdim } 3307218893Sdim}; 3308239462Sdim 3309218893Sdimtemplate<typename Derived> 3310218893Sdimtemplate<typename InputIterator> 3311218893Sdimbool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First, 3312218893Sdim InputIterator Last, 3313218893Sdim TemplateArgumentListInfo &Outputs) { 3314218893Sdim for (; First != Last; ++First) { 3315218893Sdim TemplateArgumentLoc Out; 3316218893Sdim TemplateArgumentLoc In = *First; 3317239462Sdim 3318218893Sdim if (In.getArgument().getKind() == TemplateArgument::Pack) { 3319218893Sdim // Unpack argument packs, which we translate them into separate 3320218893Sdim // arguments. 3321218893Sdim // FIXME: We could do much better if we could guarantee that the 3322218893Sdim // TemplateArgumentLocInfo for the pack expansion would be usable for 3323218893Sdim // all of the template arguments in the argument pack. 3324239462Sdim typedef TemplateArgumentLocInventIterator<Derived, 3325218893Sdim TemplateArgument::pack_iterator> 3326218893Sdim PackLocIterator; 3327239462Sdim if (TransformTemplateArguments(PackLocIterator(*this, 3328218893Sdim In.getArgument().pack_begin()), 3329218893Sdim PackLocIterator(*this, 3330218893Sdim In.getArgument().pack_end()), 3331218893Sdim Outputs)) 3332218893Sdim return true; 3333239462Sdim 3334218893Sdim continue; 3335218893Sdim } 3336239462Sdim 3337218893Sdim if (In.getArgument().isPackExpansion()) { 3338218893Sdim // We have a pack expansion, for which we will be substituting into 3339218893Sdim // the pattern. 3340218893Sdim SourceLocation Ellipsis; 3341249423Sdim Optional<unsigned> OrigNumExpansions; 3342218893Sdim TemplateArgumentLoc Pattern 3343263508Sdim = getSema().getTemplateArgumentPackExpansionPattern( 3344263508Sdim In, Ellipsis, OrigNumExpansions); 3345239462Sdim 3346226633Sdim SmallVector<UnexpandedParameterPack, 2> Unexpanded; 3347218893Sdim getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); 3348218893Sdim assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); 3349239462Sdim 3350218893Sdim // Determine whether the set of unexpanded parameter packs can and should 3351218893Sdim // be expanded. 3352218893Sdim bool Expand = true; 3353218893Sdim bool RetainExpansion = false; 3354249423Sdim Optional<unsigned> NumExpansions = OrigNumExpansions; 3355218893Sdim if (getDerived().TryExpandParameterPacks(Ellipsis, 3356218893Sdim Pattern.getSourceRange(), 3357226633Sdim Unexpanded, 3358239462Sdim Expand, 3359218893Sdim RetainExpansion, 3360218893Sdim NumExpansions)) 3361218893Sdim return true; 3362239462Sdim 3363218893Sdim if (!Expand) { 3364218893Sdim // The transform has determined that we should perform a simple 3365239462Sdim // transformation on the pack expansion, producing another pack 3366218893Sdim // expansion. 3367218893Sdim TemplateArgumentLoc OutPattern; 3368218893Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); 3369218893Sdim if (getDerived().TransformTemplateArgument(Pattern, OutPattern)) 3370218893Sdim return true; 3371239462Sdim 3372218893Sdim Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis, 3373218893Sdim NumExpansions); 3374218893Sdim if (Out.getArgument().isNull()) 3375218893Sdim return true; 3376239462Sdim 3377218893Sdim Outputs.addArgument(Out); 3378218893Sdim continue; 3379218893Sdim } 3380239462Sdim 3381218893Sdim // The transform has determined that we should perform an elementwise 3382218893Sdim // expansion of the pattern. Do so. 3383218893Sdim for (unsigned I = 0; I != *NumExpansions; ++I) { 3384218893Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); 3385218893Sdim 3386218893Sdim if (getDerived().TransformTemplateArgument(Pattern, Out)) 3387218893Sdim return true; 3388239462Sdim 3389218893Sdim if (Out.getArgument().containsUnexpandedParameterPack()) { 3390218893Sdim Out = getDerived().RebuildPackExpansion(Out, Ellipsis, 3391218893Sdim OrigNumExpansions); 3392218893Sdim if (Out.getArgument().isNull()) 3393218893Sdim return true; 3394218893Sdim } 3395239462Sdim 3396218893Sdim Outputs.addArgument(Out); 3397218893Sdim } 3398239462Sdim 3399218893Sdim // If we're supposed to retain a pack expansion, do so by temporarily 3400218893Sdim // forgetting the partially-substituted parameter pack. 3401218893Sdim if (RetainExpansion) { 3402218893Sdim ForgetPartiallySubstitutedPackRAII Forget(getDerived()); 3403239462Sdim 3404218893Sdim if (getDerived().TransformTemplateArgument(Pattern, Out)) 3405218893Sdim return true; 3406239462Sdim 3407218893Sdim Out = getDerived().RebuildPackExpansion(Out, Ellipsis, 3408218893Sdim OrigNumExpansions); 3409218893Sdim if (Out.getArgument().isNull()) 3410218893Sdim return true; 3411239462Sdim 3412218893Sdim Outputs.addArgument(Out); 3413218893Sdim } 3414239462Sdim 3415218893Sdim continue; 3416218893Sdim } 3417239462Sdim 3418239462Sdim // The simple case: 3419218893Sdim if (getDerived().TransformTemplateArgument(In, Out)) 3420218893Sdim return true; 3421239462Sdim 3422218893Sdim Outputs.addArgument(Out); 3423218893Sdim } 3424239462Sdim 3425218893Sdim return false; 3426218893Sdim 3427218893Sdim} 3428218893Sdim 3429198092Srdivacky//===----------------------------------------------------------------------===// 3430198092Srdivacky// Type transformation 3431198092Srdivacky//===----------------------------------------------------------------------===// 3432198092Srdivacky 3433198092Srdivackytemplate<typename Derived> 3434218893SdimQualType TreeTransform<Derived>::TransformType(QualType T) { 3435198092Srdivacky if (getDerived().AlreadyTransformed(T)) 3436198092Srdivacky return T; 3437198092Srdivacky 3438198398Srdivacky // Temporary workaround. All of these transformations should 3439198398Srdivacky // eventually turn into transformations on TypeLocs. 3440218893Sdim TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T, 3441218893Sdim getDerived().getBaseLocation()); 3442239462Sdim 3443218893Sdim TypeSourceInfo *NewDI = getDerived().TransformType(DI); 3444198092Srdivacky 3445198398Srdivacky if (!NewDI) 3446198398Srdivacky return QualType(); 3447198092Srdivacky 3448198398Srdivacky return NewDI->getType(); 3449198092Srdivacky} 3450198092Srdivacky 3451198092Srdivackytemplate<typename Derived> 3452218893SdimTypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) { 3453234353Sdim // Refine the base location to the type's location. 3454234353Sdim TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(), 3455234353Sdim getDerived().getBaseEntity()); 3456198398Srdivacky if (getDerived().AlreadyTransformed(DI->getType())) 3457198398Srdivacky return DI; 3458198092Srdivacky 3459198398Srdivacky TypeLocBuilder TLB; 3460198398Srdivacky 3461198398Srdivacky TypeLoc TL = DI->getTypeLoc(); 3462198398Srdivacky TLB.reserve(TL.getFullDataSize()); 3463198398Srdivacky 3464218893Sdim QualType Result = getDerived().TransformType(TLB, TL); 3465198398Srdivacky if (Result.isNull()) 3466198398Srdivacky return 0; 3467198398Srdivacky 3468200583Srdivacky return TLB.getTypeSourceInfo(SemaRef.Context, Result); 3469198092Srdivacky} 3470198092Srdivacky 3471198092Srdivackytemplate<typename Derived> 3472198398SrdivackyQualType 3473218893SdimTreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) { 3474198398Srdivacky switch (T.getTypeLocClass()) { 3475198398Srdivacky#define ABSTRACT_TYPELOC(CLASS, PARENT) 3476249423Sdim#define TYPELOC(CLASS, PARENT) \ 3477249423Sdim case TypeLoc::CLASS: \ 3478249423Sdim return getDerived().Transform##CLASS##Type(TLB, \ 3479249423Sdim T.castAs<CLASS##TypeLoc>()); 3480198398Srdivacky#include "clang/AST/TypeLocNodes.def" 3481198398Srdivacky } 3482198092Srdivacky 3483200583Srdivacky llvm_unreachable("unhandled type loc!"); 3484198092Srdivacky} 3485198092Srdivacky 3486198398Srdivacky/// FIXME: By default, this routine adds type qualifiers only to types 3487198398Srdivacky/// that can have qualifiers, and silently suppresses those qualifiers 3488198398Srdivacky/// that are not permitted (e.g., qualifiers on reference or function 3489198398Srdivacky/// types). This is the right thing for template instantiation, but 3490198398Srdivacky/// probably not for other clients. 3491198092Srdivackytemplate<typename Derived> 3492198398SrdivackyQualType 3493198398SrdivackyTreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB, 3494218893Sdim QualifiedTypeLoc T) { 3495199482Srdivacky Qualifiers Quals = T.getType().getLocalQualifiers(); 3496198092Srdivacky 3497218893Sdim QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc()); 3498198398Srdivacky if (Result.isNull()) 3499198092Srdivacky return QualType(); 3500198092Srdivacky 3501198398Srdivacky // Silently suppress qualifiers if the result type can't be qualified. 3502198398Srdivacky // FIXME: this is the right thing for template instantiation, but 3503198398Srdivacky // probably not for other clients. 3504198398Srdivacky if (Result->isFunctionType() || Result->isReferenceType()) 3505198398Srdivacky return Result; 3506198092Srdivacky 3507224145Sdim // Suppress Objective-C lifetime qualifiers if they don't make sense for the 3508224145Sdim // resulting type. 3509224145Sdim if (Quals.hasObjCLifetime()) { 3510224145Sdim if (!Result->isObjCLifetimeType() && !Result->isDependentType()) 3511224145Sdim Quals.removeObjCLifetime(); 3512224145Sdim else if (Result.getObjCLifetime()) { 3513239462Sdim // Objective-C ARC: 3514224145Sdim // A lifetime qualifier applied to a substituted template parameter 3515224145Sdim // overrides the lifetime qualifier from the template argument. 3516249423Sdim const AutoType *AutoTy; 3517239462Sdim if (const SubstTemplateTypeParmType *SubstTypeParam 3518224145Sdim = dyn_cast<SubstTemplateTypeParmType>(Result)) { 3519224145Sdim QualType Replacement = SubstTypeParam->getReplacementType(); 3520224145Sdim Qualifiers Qs = Replacement.getQualifiers(); 3521224145Sdim Qs.removeObjCLifetime(); 3522239462Sdim Replacement 3523224145Sdim = SemaRef.Context.getQualifiedType(Replacement.getUnqualifiedType(), 3524224145Sdim Qs); 3525224145Sdim Result = SemaRef.Context.getSubstTemplateTypeParmType( 3526239462Sdim SubstTypeParam->getReplacedParameter(), 3527224145Sdim Replacement); 3528224145Sdim TLB.TypeWasModifiedSafely(Result); 3529249423Sdim } else if ((AutoTy = dyn_cast<AutoType>(Result)) && AutoTy->isDeduced()) { 3530249423Sdim // 'auto' types behave the same way as template parameters. 3531249423Sdim QualType Deduced = AutoTy->getDeducedType(); 3532249423Sdim Qualifiers Qs = Deduced.getQualifiers(); 3533249423Sdim Qs.removeObjCLifetime(); 3534249423Sdim Deduced = SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(), 3535249423Sdim Qs); 3536263508Sdim Result = SemaRef.Context.getAutoType(Deduced, AutoTy->isDecltypeAuto(), 3537263508Sdim AutoTy->isDependentType()); 3538249423Sdim TLB.TypeWasModifiedSafely(Result); 3539224145Sdim } else { 3540224145Sdim // Otherwise, complain about the addition of a qualifier to an 3541224145Sdim // already-qualified type. 3542263508Sdim SourceRange R = T.getUnqualifiedLoc().getSourceRange(); 3543224145Sdim SemaRef.Diag(R.getBegin(), diag::err_attr_objc_ownership_redundant) 3544224145Sdim << Result << R; 3545239462Sdim 3546224145Sdim Quals.removeObjCLifetime(); 3547224145Sdim } 3548224145Sdim } 3549224145Sdim } 3550210299Sed if (!Quals.empty()) { 3551210299Sed Result = SemaRef.BuildQualifiedType(Result, T.getBeginLoc(), Quals); 3552249423Sdim // BuildQualifiedType might not add qualifiers if they are invalid. 3553249423Sdim if (Result.hasLocalQualifiers()) 3554249423Sdim TLB.push<QualifiedTypeLoc>(Result); 3555210299Sed // No location information to preserve. 3556210299Sed } 3557198398Srdivacky 3558198398Srdivacky return Result; 3559198092Srdivacky} 3560198092Srdivacky 3561218893Sdimtemplate<typename Derived> 3562221345SdimTypeLoc 3563221345SdimTreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL, 3564218893Sdim QualType ObjectType, 3565218893Sdim NamedDecl *UnqualLookup, 3566221345Sdim CXXScopeSpec &SS) { 3567221345Sdim QualType T = TL.getType(); 3568218893Sdim if (getDerived().AlreadyTransformed(T)) 3569221345Sdim return TL; 3570239462Sdim 3571218893Sdim TypeLocBuilder TLB; 3572218893Sdim QualType Result; 3573239462Sdim 3574218893Sdim if (isa<TemplateSpecializationType>(T)) { 3575249423Sdim TemplateSpecializationTypeLoc SpecTL = 3576249423Sdim TL.castAs<TemplateSpecializationTypeLoc>(); 3577239462Sdim 3578218893Sdim TemplateName Template = 3579221345Sdim getDerived().TransformTemplateName(SS, 3580221345Sdim SpecTL.getTypePtr()->getTemplateName(), 3581221345Sdim SpecTL.getTemplateNameLoc(), 3582218893Sdim ObjectType, UnqualLookup); 3583239462Sdim if (Template.isNull()) 3584221345Sdim return TypeLoc(); 3585239462Sdim 3586239462Sdim Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL, 3587221345Sdim Template); 3588218893Sdim } else if (isa<DependentTemplateSpecializationType>(T)) { 3589249423Sdim DependentTemplateSpecializationTypeLoc SpecTL = 3590249423Sdim TL.castAs<DependentTemplateSpecializationTypeLoc>(); 3591239462Sdim 3592221345Sdim TemplateName Template 3593239462Sdim = getDerived().RebuildTemplateName(SS, 3594239462Sdim *SpecTL.getTypePtr()->getIdentifier(), 3595234353Sdim SpecTL.getTemplateNameLoc(), 3596221345Sdim ObjectType, UnqualLookup); 3597221345Sdim if (Template.isNull()) 3598221345Sdim return TypeLoc(); 3599239462Sdim 3600239462Sdim Result = getDerived().TransformDependentTemplateSpecializationType(TLB, 3601221345Sdim SpecTL, 3602221345Sdim Template, 3603221345Sdim SS); 3604218893Sdim } else { 3605218893Sdim // Nothing special needs to be done for these. 3606221345Sdim Result = getDerived().TransformType(TLB, TL); 3607218893Sdim } 3608239462Sdim 3609239462Sdim if (Result.isNull()) 3610221345Sdim return TypeLoc(); 3611239462Sdim 3612221345Sdim return TLB.getTypeSourceInfo(SemaRef.Context, Result)->getTypeLoc(); 3613218893Sdim} 3614218893Sdim 3615219077Sdimtemplate<typename Derived> 3616221345SdimTypeSourceInfo * 3617221345SdimTreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo, 3618219077Sdim QualType ObjectType, 3619219077Sdim NamedDecl *UnqualLookup, 3620219077Sdim CXXScopeSpec &SS) { 3621219077Sdim // FIXME: Painfully copy-paste from the above! 3622239462Sdim 3623221345Sdim QualType T = TSInfo->getType(); 3624219077Sdim if (getDerived().AlreadyTransformed(T)) 3625221345Sdim return TSInfo; 3626239462Sdim 3627219077Sdim TypeLocBuilder TLB; 3628219077Sdim QualType Result; 3629239462Sdim 3630221345Sdim TypeLoc TL = TSInfo->getTypeLoc(); 3631219077Sdim if (isa<TemplateSpecializationType>(T)) { 3632249423Sdim TemplateSpecializationTypeLoc SpecTL = 3633249423Sdim TL.castAs<TemplateSpecializationTypeLoc>(); 3634239462Sdim 3635221345Sdim TemplateName Template 3636221345Sdim = getDerived().TransformTemplateName(SS, 3637221345Sdim SpecTL.getTypePtr()->getTemplateName(), 3638221345Sdim SpecTL.getTemplateNameLoc(), 3639219077Sdim ObjectType, UnqualLookup); 3640239462Sdim if (Template.isNull()) 3641221345Sdim return 0; 3642239462Sdim 3643239462Sdim Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL, 3644219077Sdim Template); 3645219077Sdim } else if (isa<DependentTemplateSpecializationType>(T)) { 3646249423Sdim DependentTemplateSpecializationTypeLoc SpecTL = 3647249423Sdim TL.castAs<DependentTemplateSpecializationTypeLoc>(); 3648239462Sdim 3649221345Sdim TemplateName Template 3650239462Sdim = getDerived().RebuildTemplateName(SS, 3651239462Sdim *SpecTL.getTypePtr()->getIdentifier(), 3652234353Sdim SpecTL.getTemplateNameLoc(), 3653221345Sdim ObjectType, UnqualLookup); 3654221345Sdim if (Template.isNull()) 3655221345Sdim return 0; 3656239462Sdim 3657239462Sdim Result = getDerived().TransformDependentTemplateSpecializationType(TLB, 3658221345Sdim SpecTL, 3659221345Sdim Template, 3660221345Sdim SS); 3661219077Sdim } else { 3662219077Sdim // Nothing special needs to be done for these. 3663219077Sdim Result = getDerived().TransformType(TLB, TL); 3664219077Sdim } 3665239462Sdim 3666239462Sdim if (Result.isNull()) 3667221345Sdim return 0; 3668239462Sdim 3669221345Sdim return TLB.getTypeSourceInfo(SemaRef.Context, Result); 3670219077Sdim} 3671219077Sdim 3672198398Srdivackytemplate <class TyLoc> static inline 3673198398SrdivackyQualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) { 3674198398Srdivacky TyLoc NewT = TLB.push<TyLoc>(T.getType()); 3675198398Srdivacky NewT.setNameLoc(T.getNameLoc()); 3676198398Srdivacky return T.getType(); 3677198398Srdivacky} 3678198092Srdivacky 3679198398Srdivackytemplate<typename Derived> 3680198398SrdivackyQualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB, 3681218893Sdim BuiltinTypeLoc T) { 3682202879Srdivacky BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType()); 3683202879Srdivacky NewT.setBuiltinLoc(T.getBuiltinLoc()); 3684202879Srdivacky if (T.needsExtraLocalData()) 3685202879Srdivacky NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs(); 3686202879Srdivacky return T.getType(); 3687198092Srdivacky} 3688198092Srdivacky 3689198092Srdivackytemplate<typename Derived> 3690198398SrdivackyQualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB, 3691218893Sdim ComplexTypeLoc T) { 3692198398Srdivacky // FIXME: recurse? 3693198398Srdivacky return TransformTypeSpecType(TLB, T); 3694198398Srdivacky} 3695198092Srdivacky 3696198398Srdivackytemplate<typename Derived> 3697263508SdimQualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB, 3698263508Sdim DecayedTypeLoc TL) { 3699263508Sdim QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc()); 3700263508Sdim if (OriginalType.isNull()) 3701263508Sdim return QualType(); 3702263508Sdim 3703263508Sdim QualType Result = TL.getType(); 3704263508Sdim if (getDerived().AlwaysRebuild() || 3705263508Sdim OriginalType != TL.getOriginalLoc().getType()) 3706263508Sdim Result = SemaRef.Context.getDecayedType(OriginalType); 3707263508Sdim TLB.push<DecayedTypeLoc>(Result); 3708263508Sdim // Nothing to set for DecayedTypeLoc. 3709263508Sdim return Result; 3710263508Sdim} 3711263508Sdim 3712263508Sdimtemplate<typename Derived> 3713198398SrdivackyQualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB, 3714218893Sdim PointerTypeLoc TL) { 3715239462Sdim QualType PointeeType 3716239462Sdim = getDerived().TransformType(TLB, TL.getPointeeLoc()); 3717207619Srdivacky if (PointeeType.isNull()) 3718207619Srdivacky return QualType(); 3719207619Srdivacky 3720207619Srdivacky QualType Result = TL.getType(); 3721208600Srdivacky if (PointeeType->getAs<ObjCObjectType>()) { 3722207619Srdivacky // A dependent pointer type 'T *' has is being transformed such 3723207619Srdivacky // that an Objective-C class type is being replaced for 'T'. The 3724207619Srdivacky // resulting pointer type is an ObjCObjectPointerType, not a 3725207619Srdivacky // PointerType. 3726208600Srdivacky Result = SemaRef.Context.getObjCObjectPointerType(PointeeType); 3727239462Sdim 3728208600Srdivacky ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result); 3729208600Srdivacky NewT.setStarLoc(TL.getStarLoc()); 3730207619Srdivacky return Result; 3731207619Srdivacky } 3732218893Sdim 3733207619Srdivacky if (getDerived().AlwaysRebuild() || 3734207619Srdivacky PointeeType != TL.getPointeeLoc().getType()) { 3735207619Srdivacky Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc()); 3736207619Srdivacky if (Result.isNull()) 3737207619Srdivacky return QualType(); 3738207619Srdivacky } 3739239462Sdim 3740224145Sdim // Objective-C ARC can add lifetime qualifiers to the type that we're 3741224145Sdim // pointing to. 3742224145Sdim TLB.TypeWasModifiedSafely(Result->getPointeeType()); 3743239462Sdim 3744207619Srdivacky PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result); 3745207619Srdivacky NewT.setSigilLoc(TL.getSigilLoc()); 3746239462Sdim return Result; 3747198092Srdivacky} 3748198092Srdivacky 3749198092Srdivackytemplate<typename Derived> 3750198092SrdivackyQualType 3751198398SrdivackyTreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB, 3752218893Sdim BlockPointerTypeLoc TL) { 3753207619Srdivacky QualType PointeeType 3754239462Sdim = getDerived().TransformType(TLB, TL.getPointeeLoc()); 3755239462Sdim if (PointeeType.isNull()) 3756239462Sdim return QualType(); 3757239462Sdim 3758239462Sdim QualType Result = TL.getType(); 3759239462Sdim if (getDerived().AlwaysRebuild() || 3760239462Sdim PointeeType != TL.getPointeeLoc().getType()) { 3761239462Sdim Result = getDerived().RebuildBlockPointerType(PointeeType, 3762207619Srdivacky TL.getSigilLoc()); 3763207619Srdivacky if (Result.isNull()) 3764207619Srdivacky return QualType(); 3765207619Srdivacky } 3766207619Srdivacky 3767207619Srdivacky BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result); 3768207619Srdivacky NewT.setSigilLoc(TL.getSigilLoc()); 3769207619Srdivacky return Result; 3770198092Srdivacky} 3771198092Srdivacky 3772198893Srdivacky/// Transforms a reference type. Note that somewhat paradoxically we 3773198893Srdivacky/// don't care whether the type itself is an l-value type or an r-value 3774198893Srdivacky/// type; we only care if the type was *written* as an l-value type 3775198893Srdivacky/// or an r-value type. 3776198092Srdivackytemplate<typename Derived> 3777198092SrdivackyQualType 3778198893SrdivackyTreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB, 3779218893Sdim ReferenceTypeLoc TL) { 3780198893Srdivacky const ReferenceType *T = TL.getTypePtr(); 3781198893Srdivacky 3782198893Srdivacky // Note that this works with the pointee-as-written. 3783198893Srdivacky QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc()); 3784198893Srdivacky if (PointeeType.isNull()) 3785198893Srdivacky return QualType(); 3786198893Srdivacky 3787198893Srdivacky QualType Result = TL.getType(); 3788198893Srdivacky if (getDerived().AlwaysRebuild() || 3789198893Srdivacky PointeeType != T->getPointeeTypeAsWritten()) { 3790198893Srdivacky Result = getDerived().RebuildReferenceType(PointeeType, 3791198893Srdivacky T->isSpelledAsLValue(), 3792198893Srdivacky TL.getSigilLoc()); 3793198893Srdivacky if (Result.isNull()) 3794198893Srdivacky return QualType(); 3795198893Srdivacky } 3796198893Srdivacky 3797224145Sdim // Objective-C ARC can add lifetime qualifiers to the type that we're 3798224145Sdim // referring to. 3799224145Sdim TLB.TypeWasModifiedSafely( 3800224145Sdim Result->getAs<ReferenceType>()->getPointeeTypeAsWritten()); 3801224145Sdim 3802198893Srdivacky // r-value references can be rebuilt as l-value references. 3803198893Srdivacky ReferenceTypeLoc NewTL; 3804198893Srdivacky if (isa<LValueReferenceType>(Result)) 3805198893Srdivacky NewTL = TLB.push<LValueReferenceTypeLoc>(Result); 3806198893Srdivacky else 3807198893Srdivacky NewTL = TLB.push<RValueReferenceTypeLoc>(Result); 3808198893Srdivacky NewTL.setSigilLoc(TL.getSigilLoc()); 3809198893Srdivacky 3810198893Srdivacky return Result; 3811198893Srdivacky} 3812198893Srdivacky 3813198893Srdivackytemplate<typename Derived> 3814198893SrdivackyQualType 3815198398SrdivackyTreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB, 3816218893Sdim LValueReferenceTypeLoc TL) { 3817218893Sdim return TransformReferenceType(TLB, TL); 3818198092Srdivacky} 3819198092Srdivacky 3820198092Srdivackytemplate<typename Derived> 3821198092SrdivackyQualType 3822198398SrdivackyTreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB, 3823218893Sdim RValueReferenceTypeLoc TL) { 3824218893Sdim return TransformReferenceType(TLB, TL); 3825198092Srdivacky} 3826198092Srdivacky 3827198092Srdivackytemplate<typename Derived> 3828198092SrdivackyQualType 3829198398SrdivackyTreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB, 3830218893Sdim MemberPointerTypeLoc TL) { 3831198398Srdivacky QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc()); 3832198398Srdivacky if (PointeeType.isNull()) 3833198092Srdivacky return QualType(); 3834198092Srdivacky 3835221345Sdim TypeSourceInfo* OldClsTInfo = TL.getClassTInfo(); 3836221345Sdim TypeSourceInfo* NewClsTInfo = 0; 3837221345Sdim if (OldClsTInfo) { 3838221345Sdim NewClsTInfo = getDerived().TransformType(OldClsTInfo); 3839221345Sdim if (!NewClsTInfo) 3840221345Sdim return QualType(); 3841221345Sdim } 3842198092Srdivacky 3843221345Sdim const MemberPointerType *T = TL.getTypePtr(); 3844221345Sdim QualType OldClsType = QualType(T->getClass(), 0); 3845221345Sdim QualType NewClsType; 3846221345Sdim if (NewClsTInfo) 3847221345Sdim NewClsType = NewClsTInfo->getType(); 3848221345Sdim else { 3849221345Sdim NewClsType = getDerived().TransformType(OldClsType); 3850221345Sdim if (NewClsType.isNull()) 3851221345Sdim return QualType(); 3852221345Sdim } 3853221345Sdim 3854198398Srdivacky QualType Result = TL.getType(); 3855198398Srdivacky if (getDerived().AlwaysRebuild() || 3856198398Srdivacky PointeeType != T->getPointeeType() || 3857221345Sdim NewClsType != OldClsType) { 3858221345Sdim Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType, 3859198893Srdivacky TL.getStarLoc()); 3860198398Srdivacky if (Result.isNull()) 3861198398Srdivacky return QualType(); 3862198398Srdivacky } 3863198092Srdivacky 3864198398Srdivacky MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result); 3865198398Srdivacky NewTL.setSigilLoc(TL.getSigilLoc()); 3866221345Sdim NewTL.setClassTInfo(NewClsTInfo); 3867198398Srdivacky 3868198398Srdivacky return Result; 3869198092Srdivacky} 3870198092Srdivacky 3871198092Srdivackytemplate<typename Derived> 3872198092SrdivackyQualType 3873198398SrdivackyTreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB, 3874218893Sdim ConstantArrayTypeLoc TL) { 3875218893Sdim const ConstantArrayType *T = TL.getTypePtr(); 3876198398Srdivacky QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); 3877198092Srdivacky if (ElementType.isNull()) 3878198092Srdivacky return QualType(); 3879198092Srdivacky 3880198398Srdivacky QualType Result = TL.getType(); 3881198398Srdivacky if (getDerived().AlwaysRebuild() || 3882198398Srdivacky ElementType != T->getElementType()) { 3883198398Srdivacky Result = getDerived().RebuildConstantArrayType(ElementType, 3884198398Srdivacky T->getSizeModifier(), 3885198398Srdivacky T->getSize(), 3886198893Srdivacky T->getIndexTypeCVRQualifiers(), 3887198893Srdivacky TL.getBracketsRange()); 3888198398Srdivacky if (Result.isNull()) 3889198398Srdivacky return QualType(); 3890198398Srdivacky } 3891234353Sdim 3892234353Sdim // We might have either a ConstantArrayType or a VariableArrayType now: 3893234353Sdim // a ConstantArrayType is allowed to have an element type which is a 3894234353Sdim // VariableArrayType if the type is dependent. Fortunately, all array 3895234353Sdim // types have the same location layout. 3896234353Sdim ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result); 3897198398Srdivacky NewTL.setLBracketLoc(TL.getLBracketLoc()); 3898198398Srdivacky NewTL.setRBracketLoc(TL.getRBracketLoc()); 3899198092Srdivacky 3900198398Srdivacky Expr *Size = TL.getSizeExpr(); 3901198398Srdivacky if (Size) { 3902234353Sdim EnterExpressionEvaluationContext Unevaluated(SemaRef, 3903234353Sdim Sema::ConstantEvaluated); 3904198398Srdivacky Size = getDerived().TransformExpr(Size).template takeAs<Expr>(); 3905234353Sdim Size = SemaRef.ActOnConstantExpression(Size).take(); 3906198398Srdivacky } 3907198398Srdivacky NewTL.setSizeExpr(Size); 3908198398Srdivacky 3909198398Srdivacky return Result; 3910198092Srdivacky} 3911198092Srdivacky 3912198092Srdivackytemplate<typename Derived> 3913198092SrdivackyQualType TreeTransform<Derived>::TransformIncompleteArrayType( 3914198398Srdivacky TypeLocBuilder &TLB, 3915218893Sdim IncompleteArrayTypeLoc TL) { 3916218893Sdim const IncompleteArrayType *T = TL.getTypePtr(); 3917198398Srdivacky QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); 3918198092Srdivacky if (ElementType.isNull()) 3919198092Srdivacky return QualType(); 3920198092Srdivacky 3921198398Srdivacky QualType Result = TL.getType(); 3922198398Srdivacky if (getDerived().AlwaysRebuild() || 3923198398Srdivacky ElementType != T->getElementType()) { 3924198398Srdivacky Result = getDerived().RebuildIncompleteArrayType(ElementType, 3925198398Srdivacky T->getSizeModifier(), 3926198893Srdivacky T->getIndexTypeCVRQualifiers(), 3927198893Srdivacky TL.getBracketsRange()); 3928198398Srdivacky if (Result.isNull()) 3929198398Srdivacky return QualType(); 3930198398Srdivacky } 3931239462Sdim 3932198398Srdivacky IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result); 3933198398Srdivacky NewTL.setLBracketLoc(TL.getLBracketLoc()); 3934198398Srdivacky NewTL.setRBracketLoc(TL.getRBracketLoc()); 3935198398Srdivacky NewTL.setSizeExpr(0); 3936198092Srdivacky 3937198398Srdivacky return Result; 3938198092Srdivacky} 3939198092Srdivacky 3940198092Srdivackytemplate<typename Derived> 3941198398SrdivackyQualType 3942198398SrdivackyTreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB, 3943218893Sdim VariableArrayTypeLoc TL) { 3944218893Sdim const VariableArrayType *T = TL.getTypePtr(); 3945198398Srdivacky QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); 3946198092Srdivacky if (ElementType.isNull()) 3947198092Srdivacky return QualType(); 3948198092Srdivacky 3949212904Sdim ExprResult SizeResult 3950198398Srdivacky = getDerived().TransformExpr(T->getSizeExpr()); 3951198398Srdivacky if (SizeResult.isInvalid()) 3952198092Srdivacky return QualType(); 3953198092Srdivacky 3954212904Sdim Expr *Size = SizeResult.take(); 3955198398Srdivacky 3956198398Srdivacky QualType Result = TL.getType(); 3957198398Srdivacky if (getDerived().AlwaysRebuild() || 3958198398Srdivacky ElementType != T->getElementType() || 3959198398Srdivacky Size != T->getSizeExpr()) { 3960198398Srdivacky Result = getDerived().RebuildVariableArrayType(ElementType, 3961198398Srdivacky T->getSizeModifier(), 3962212904Sdim Size, 3963198398Srdivacky T->getIndexTypeCVRQualifiers(), 3964198893Srdivacky TL.getBracketsRange()); 3965198398Srdivacky if (Result.isNull()) 3966198398Srdivacky return QualType(); 3967198092Srdivacky } 3968239462Sdim 3969261794Sdim // We might have constant size array now, but fortunately it has the same 3970261794Sdim // location layout. 3971261794Sdim ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result); 3972198398Srdivacky NewTL.setLBracketLoc(TL.getLBracketLoc()); 3973198398Srdivacky NewTL.setRBracketLoc(TL.getRBracketLoc()); 3974198398Srdivacky NewTL.setSizeExpr(Size); 3975198092Srdivacky 3976198398Srdivacky return Result; 3977198092Srdivacky} 3978198092Srdivacky 3979198092Srdivackytemplate<typename Derived> 3980198398SrdivackyQualType 3981198398SrdivackyTreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB, 3982218893Sdim DependentSizedArrayTypeLoc TL) { 3983218893Sdim const DependentSizedArrayType *T = TL.getTypePtr(); 3984198398Srdivacky QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc()); 3985198092Srdivacky if (ElementType.isNull()) 3986198092Srdivacky return QualType(); 3987198092Srdivacky 3988234353Sdim // Array bounds are constant expressions. 3989234353Sdim EnterExpressionEvaluationContext Unevaluated(SemaRef, 3990234353Sdim Sema::ConstantEvaluated); 3991198092Srdivacky 3992218893Sdim // Prefer the expression from the TypeLoc; the other may have been uniqued. 3993218893Sdim Expr *origSize = TL.getSizeExpr(); 3994218893Sdim if (!origSize) origSize = T->getSizeExpr(); 3995218893Sdim 3996218893Sdim ExprResult sizeResult 3997218893Sdim = getDerived().TransformExpr(origSize); 3998234353Sdim sizeResult = SemaRef.ActOnConstantExpression(sizeResult); 3999218893Sdim if (sizeResult.isInvalid()) 4000198092Srdivacky return QualType(); 4001198092Srdivacky 4002218893Sdim Expr *size = sizeResult.get(); 4003198398Srdivacky 4004198398Srdivacky QualType Result = TL.getType(); 4005198398Srdivacky if (getDerived().AlwaysRebuild() || 4006198398Srdivacky ElementType != T->getElementType() || 4007218893Sdim size != origSize) { 4008198398Srdivacky Result = getDerived().RebuildDependentSizedArrayType(ElementType, 4009198398Srdivacky T->getSizeModifier(), 4010218893Sdim size, 4011198398Srdivacky T->getIndexTypeCVRQualifiers(), 4012198893Srdivacky TL.getBracketsRange()); 4013198398Srdivacky if (Result.isNull()) 4014198398Srdivacky return QualType(); 4015198092Srdivacky } 4016198092Srdivacky 4017198398Srdivacky // We might have any sort of array type now, but fortunately they 4018198398Srdivacky // all have the same location layout. 4019198398Srdivacky ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result); 4020198398Srdivacky NewTL.setLBracketLoc(TL.getLBracketLoc()); 4021198398Srdivacky NewTL.setRBracketLoc(TL.getRBracketLoc()); 4022218893Sdim NewTL.setSizeExpr(size); 4023198398Srdivacky 4024198398Srdivacky return Result; 4025198092Srdivacky} 4026198092Srdivacky 4027198092Srdivackytemplate<typename Derived> 4028198092SrdivackyQualType TreeTransform<Derived>::TransformDependentSizedExtVectorType( 4029198398Srdivacky TypeLocBuilder &TLB, 4030218893Sdim DependentSizedExtVectorTypeLoc TL) { 4031218893Sdim const DependentSizedExtVectorType *T = TL.getTypePtr(); 4032198398Srdivacky 4033198398Srdivacky // FIXME: ext vector locs should be nested 4034198092Srdivacky QualType ElementType = getDerived().TransformType(T->getElementType()); 4035198092Srdivacky if (ElementType.isNull()) 4036198092Srdivacky return QualType(); 4037198092Srdivacky 4038234353Sdim // Vector sizes are constant expressions. 4039234353Sdim EnterExpressionEvaluationContext Unevaluated(SemaRef, 4040234353Sdim Sema::ConstantEvaluated); 4041198092Srdivacky 4042212904Sdim ExprResult Size = getDerived().TransformExpr(T->getSizeExpr()); 4043234353Sdim Size = SemaRef.ActOnConstantExpression(Size); 4044198092Srdivacky if (Size.isInvalid()) 4045198092Srdivacky return QualType(); 4046198092Srdivacky 4047198398Srdivacky QualType Result = TL.getType(); 4048198398Srdivacky if (getDerived().AlwaysRebuild() || 4049198893Srdivacky ElementType != T->getElementType() || 4050198893Srdivacky Size.get() != T->getSizeExpr()) { 4051198398Srdivacky Result = getDerived().RebuildDependentSizedExtVectorType(ElementType, 4052212904Sdim Size.take(), 4053198398Srdivacky T->getAttributeLoc()); 4054198398Srdivacky if (Result.isNull()) 4055198398Srdivacky return QualType(); 4056198092Srdivacky } 4057198092Srdivacky 4058198398Srdivacky // Result might be dependent or not. 4059198398Srdivacky if (isa<DependentSizedExtVectorType>(Result)) { 4060198398Srdivacky DependentSizedExtVectorTypeLoc NewTL 4061198398Srdivacky = TLB.push<DependentSizedExtVectorTypeLoc>(Result); 4062198398Srdivacky NewTL.setNameLoc(TL.getNameLoc()); 4063198398Srdivacky } else { 4064198398Srdivacky ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result); 4065198398Srdivacky NewTL.setNameLoc(TL.getNameLoc()); 4066198398Srdivacky } 4067198398Srdivacky 4068198398Srdivacky return Result; 4069198092Srdivacky} 4070198092Srdivacky 4071198092Srdivackytemplate<typename Derived> 4072198398SrdivackyQualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB, 4073218893Sdim VectorTypeLoc TL) { 4074218893Sdim const VectorType *T = TL.getTypePtr(); 4075198092Srdivacky QualType ElementType = getDerived().TransformType(T->getElementType()); 4076198092Srdivacky if (ElementType.isNull()) 4077198092Srdivacky return QualType(); 4078198092Srdivacky 4079198398Srdivacky QualType Result = TL.getType(); 4080198398Srdivacky if (getDerived().AlwaysRebuild() || 4081198398Srdivacky ElementType != T->getElementType()) { 4082203955Srdivacky Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(), 4083218893Sdim T->getVectorKind()); 4084198398Srdivacky if (Result.isNull()) 4085198398Srdivacky return QualType(); 4086198398Srdivacky } 4087239462Sdim 4088198398Srdivacky VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result); 4089198398Srdivacky NewTL.setNameLoc(TL.getNameLoc()); 4090198092Srdivacky 4091198398Srdivacky return Result; 4092198092Srdivacky} 4093198092Srdivacky 4094198092Srdivackytemplate<typename Derived> 4095198398SrdivackyQualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB, 4096218893Sdim ExtVectorTypeLoc TL) { 4097218893Sdim const VectorType *T = TL.getTypePtr(); 4098198092Srdivacky QualType ElementType = getDerived().TransformType(T->getElementType()); 4099198092Srdivacky if (ElementType.isNull()) 4100198092Srdivacky return QualType(); 4101198092Srdivacky 4102198398Srdivacky QualType Result = TL.getType(); 4103198398Srdivacky if (getDerived().AlwaysRebuild() || 4104198398Srdivacky ElementType != T->getElementType()) { 4105198398Srdivacky Result = getDerived().RebuildExtVectorType(ElementType, 4106198398Srdivacky T->getNumElements(), 4107198398Srdivacky /*FIXME*/ SourceLocation()); 4108198398Srdivacky if (Result.isNull()) 4109198398Srdivacky return QualType(); 4110198398Srdivacky } 4111239462Sdim 4112198398Srdivacky ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result); 4113198398Srdivacky NewTL.setNameLoc(TL.getNameLoc()); 4114198092Srdivacky 4115198398Srdivacky return Result; 4116198092Srdivacky} 4117198092Srdivacky 4118249423Sdimtemplate <typename Derived> 4119249423SdimParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam( 4120249423Sdim ParmVarDecl *OldParm, int indexAdjustment, Optional<unsigned> NumExpansions, 4121249423Sdim bool ExpectParameterPack) { 4122205219Srdivacky TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo(); 4123218893Sdim TypeSourceInfo *NewDI = 0; 4124239462Sdim 4125218893Sdim if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) { 4126239462Sdim // If we're substituting into a pack expansion type and we know the 4127234353Sdim // length we want to expand to, just substitute for the pattern. 4128218893Sdim TypeLoc OldTL = OldDI->getTypeLoc(); 4129249423Sdim PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>(); 4130239462Sdim 4131218893Sdim TypeLocBuilder TLB; 4132218893Sdim TypeLoc NewTL = OldDI->getTypeLoc(); 4133218893Sdim TLB.reserve(NewTL.getFullDataSize()); 4134239462Sdim 4135239462Sdim QualType Result = getDerived().TransformType(TLB, 4136218893Sdim OldExpansionTL.getPatternLoc()); 4137218893Sdim if (Result.isNull()) 4138218893Sdim return 0; 4139239462Sdim 4140239462Sdim Result = RebuildPackExpansionType(Result, 4141239462Sdim OldExpansionTL.getPatternLoc().getSourceRange(), 4142218893Sdim OldExpansionTL.getEllipsisLoc(), 4143218893Sdim NumExpansions); 4144218893Sdim if (Result.isNull()) 4145218893Sdim return 0; 4146239462Sdim 4147218893Sdim PackExpansionTypeLoc NewExpansionTL 4148218893Sdim = TLB.push<PackExpansionTypeLoc>(Result); 4149218893Sdim NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc()); 4150218893Sdim NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result); 4151218893Sdim } else 4152218893Sdim NewDI = getDerived().TransformType(OldDI); 4153205219Srdivacky if (!NewDI) 4154205219Srdivacky return 0; 4155205219Srdivacky 4156221345Sdim if (NewDI == OldDI && indexAdjustment == 0) 4157205219Srdivacky return OldParm; 4158221345Sdim 4159221345Sdim ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context, 4160221345Sdim OldParm->getDeclContext(), 4161221345Sdim OldParm->getInnerLocStart(), 4162221345Sdim OldParm->getLocation(), 4163221345Sdim OldParm->getIdentifier(), 4164221345Sdim NewDI->getType(), 4165221345Sdim NewDI, 4166221345Sdim OldParm->getStorageClass(), 4167221345Sdim /* DefArg */ NULL); 4168221345Sdim newParm->setScopeInfo(OldParm->getFunctionScopeDepth(), 4169221345Sdim OldParm->getFunctionScopeIndex() + indexAdjustment); 4170221345Sdim return newParm; 4171205219Srdivacky} 4172205219Srdivacky 4173205219Srdivackytemplate<typename Derived> 4174205219Srdivackybool TreeTransform<Derived>:: 4175218893Sdim TransformFunctionTypeParams(SourceLocation Loc, 4176218893Sdim ParmVarDecl **Params, unsigned NumParams, 4177218893Sdim const QualType *ParamTypes, 4178226633Sdim SmallVectorImpl<QualType> &OutParamTypes, 4179226633Sdim SmallVectorImpl<ParmVarDecl*> *PVars) { 4180221345Sdim int indexAdjustment = 0; 4181221345Sdim 4182218893Sdim for (unsigned i = 0; i != NumParams; ++i) { 4183218893Sdim if (ParmVarDecl *OldParm = Params[i]) { 4184221345Sdim assert(OldParm->getFunctionScopeIndex() == i); 4185221345Sdim 4186249423Sdim Optional<unsigned> NumExpansions; 4187221345Sdim ParmVarDecl *NewParm = 0; 4188218893Sdim if (OldParm->isParameterPack()) { 4189218893Sdim // We have a function parameter pack that may need to be expanded. 4190226633Sdim SmallVector<UnexpandedParameterPack, 2> Unexpanded; 4191198092Srdivacky 4192218893Sdim // Find the parameter packs that could be expanded. 4193218893Sdim TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc(); 4194249423Sdim PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>(); 4195218893Sdim TypeLoc Pattern = ExpansionTL.getPatternLoc(); 4196218893Sdim SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded); 4197221345Sdim assert(Unexpanded.size() > 0 && "Could not find parameter packs!"); 4198221345Sdim 4199218893Sdim // Determine whether we should expand the parameter packs. 4200218893Sdim bool ShouldExpand = false; 4201218893Sdim bool RetainExpansion = false; 4202249423Sdim Optional<unsigned> OrigNumExpansions = 4203249423Sdim ExpansionTL.getTypePtr()->getNumExpansions(); 4204218893Sdim NumExpansions = OrigNumExpansions; 4205218893Sdim if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(), 4206218893Sdim Pattern.getSourceRange(), 4207239462Sdim Unexpanded, 4208239462Sdim ShouldExpand, 4209218893Sdim RetainExpansion, 4210218893Sdim NumExpansions)) { 4211218893Sdim return true; 4212218893Sdim } 4213239462Sdim 4214218893Sdim if (ShouldExpand) { 4215218893Sdim // Expand the function parameter pack into multiple, separate 4216218893Sdim // parameters. 4217218893Sdim getDerived().ExpandingFunctionParameterPack(OldParm); 4218218893Sdim for (unsigned I = 0; I != *NumExpansions; ++I) { 4219218893Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); 4220239462Sdim ParmVarDecl *NewParm 4221218893Sdim = getDerived().TransformFunctionTypeParam(OldParm, 4222221345Sdim indexAdjustment++, 4223234353Sdim OrigNumExpansions, 4224234353Sdim /*ExpectParameterPack=*/false); 4225218893Sdim if (!NewParm) 4226218893Sdim return true; 4227239462Sdim 4228218893Sdim OutParamTypes.push_back(NewParm->getType()); 4229218893Sdim if (PVars) 4230218893Sdim PVars->push_back(NewParm); 4231218893Sdim } 4232198092Srdivacky 4233218893Sdim // If we're supposed to retain a pack expansion, do so by temporarily 4234218893Sdim // forgetting the partially-substituted parameter pack. 4235218893Sdim if (RetainExpansion) { 4236218893Sdim ForgetPartiallySubstitutedPackRAII Forget(getDerived()); 4237239462Sdim ParmVarDecl *NewParm 4238218893Sdim = getDerived().TransformFunctionTypeParam(OldParm, 4239221345Sdim indexAdjustment++, 4240234353Sdim OrigNumExpansions, 4241234353Sdim /*ExpectParameterPack=*/false); 4242218893Sdim if (!NewParm) 4243218893Sdim return true; 4244239462Sdim 4245218893Sdim OutParamTypes.push_back(NewParm->getType()); 4246218893Sdim if (PVars) 4247218893Sdim PVars->push_back(NewParm); 4248218893Sdim } 4249198398Srdivacky 4250221345Sdim // The next parameter should have the same adjustment as the 4251221345Sdim // last thing we pushed, but we post-incremented indexAdjustment 4252221345Sdim // on every push. Also, if we push nothing, the adjustment should 4253221345Sdim // go down by one. 4254221345Sdim indexAdjustment--; 4255221345Sdim 4256218893Sdim // We're done with the pack expansion. 4257218893Sdim continue; 4258218893Sdim } 4259239462Sdim 4260239462Sdim // We'll substitute the parameter now without expanding the pack 4261218893Sdim // expansion. 4262221345Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); 4263221345Sdim NewParm = getDerived().TransformFunctionTypeParam(OldParm, 4264221345Sdim indexAdjustment, 4265234353Sdim NumExpansions, 4266234353Sdim /*ExpectParameterPack=*/true); 4267221345Sdim } else { 4268249423Sdim NewParm = getDerived().TransformFunctionTypeParam( 4269249423Sdim OldParm, indexAdjustment, None, /*ExpectParameterPack=*/ false); 4270218893Sdim } 4271221345Sdim 4272205219Srdivacky if (!NewParm) 4273205219Srdivacky return true; 4274239462Sdim 4275218893Sdim OutParamTypes.push_back(NewParm->getType()); 4276218893Sdim if (PVars) 4277218893Sdim PVars->push_back(NewParm); 4278218893Sdim continue; 4279218893Sdim } 4280198398Srdivacky 4281198398Srdivacky // Deal with the possibility that we don't have a parameter 4282198398Srdivacky // declaration for this parameter. 4283218893Sdim QualType OldType = ParamTypes[i]; 4284218893Sdim bool IsPackExpansion = false; 4285249423Sdim Optional<unsigned> NumExpansions; 4286221345Sdim QualType NewType; 4287239462Sdim if (const PackExpansionType *Expansion 4288218893Sdim = dyn_cast<PackExpansionType>(OldType)) { 4289218893Sdim // We have a function parameter pack that may need to be expanded. 4290218893Sdim QualType Pattern = Expansion->getPattern(); 4291226633Sdim SmallVector<UnexpandedParameterPack, 2> Unexpanded; 4292218893Sdim getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded); 4293239462Sdim 4294218893Sdim // Determine whether we should expand the parameter packs. 4295218893Sdim bool ShouldExpand = false; 4296218893Sdim bool RetainExpansion = false; 4297218893Sdim if (getDerived().TryExpandParameterPacks(Loc, SourceRange(), 4298239462Sdim Unexpanded, 4299239462Sdim ShouldExpand, 4300218893Sdim RetainExpansion, 4301218893Sdim NumExpansions)) { 4302218893Sdim return true; 4303218893Sdim } 4304239462Sdim 4305218893Sdim if (ShouldExpand) { 4306239462Sdim // Expand the function parameter pack into multiple, separate 4307218893Sdim // parameters. 4308218893Sdim for (unsigned I = 0; I != *NumExpansions; ++I) { 4309218893Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); 4310218893Sdim QualType NewType = getDerived().TransformType(Pattern); 4311218893Sdim if (NewType.isNull()) 4312218893Sdim return true; 4313198398Srdivacky 4314218893Sdim OutParamTypes.push_back(NewType); 4315218893Sdim if (PVars) 4316218893Sdim PVars->push_back(0); 4317218893Sdim } 4318239462Sdim 4319218893Sdim // We're done with the pack expansion. 4320218893Sdim continue; 4321218893Sdim } 4322239462Sdim 4323218893Sdim // If we're supposed to retain a pack expansion, do so by temporarily 4324218893Sdim // forgetting the partially-substituted parameter pack. 4325218893Sdim if (RetainExpansion) { 4326218893Sdim ForgetPartiallySubstitutedPackRAII Forget(getDerived()); 4327218893Sdim QualType NewType = getDerived().TransformType(Pattern); 4328218893Sdim if (NewType.isNull()) 4329218893Sdim return true; 4330239462Sdim 4331218893Sdim OutParamTypes.push_back(NewType); 4332218893Sdim if (PVars) 4333218893Sdim PVars->push_back(0); 4334218893Sdim } 4335218893Sdim 4336239462Sdim // We'll substitute the parameter now without expanding the pack 4337218893Sdim // expansion. 4338218893Sdim OldType = Expansion->getPattern(); 4339218893Sdim IsPackExpansion = true; 4340221345Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); 4341221345Sdim NewType = getDerived().TransformType(OldType); 4342221345Sdim } else { 4343221345Sdim NewType = getDerived().TransformType(OldType); 4344198398Srdivacky } 4345239462Sdim 4346218893Sdim if (NewType.isNull()) 4347218893Sdim return true; 4348198398Srdivacky 4349218893Sdim if (IsPackExpansion) 4350218893Sdim NewType = getSema().Context.getPackExpansionType(NewType, 4351218893Sdim NumExpansions); 4352239462Sdim 4353218893Sdim OutParamTypes.push_back(NewType); 4354218893Sdim if (PVars) 4355218893Sdim PVars->push_back(0); 4356198092Srdivacky } 4357198092Srdivacky 4358221345Sdim#ifndef NDEBUG 4359221345Sdim if (PVars) { 4360221345Sdim for (unsigned i = 0, e = PVars->size(); i != e; ++i) 4361221345Sdim if (ParmVarDecl *parm = (*PVars)[i]) 4362221345Sdim assert(parm->getFunctionScopeIndex() == i); 4363218893Sdim } 4364221345Sdim#endif 4365205219Srdivacky 4366221345Sdim return false; 4367221345Sdim} 4368221345Sdim 4369205219Srdivackytemplate<typename Derived> 4370205219SrdivackyQualType 4371205219SrdivackyTreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, 4372218893Sdim FunctionProtoTypeLoc TL) { 4373234982Sdim return getDerived().TransformFunctionProtoType(TLB, TL, 0, 0); 4374234982Sdim} 4375234982Sdim 4376234982Sdimtemplate<typename Derived> 4377234982SdimQualType 4378234982SdimTreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB, 4379234982Sdim FunctionProtoTypeLoc TL, 4380234982Sdim CXXRecordDecl *ThisContext, 4381234982Sdim unsigned ThisTypeQuals) { 4382212904Sdim // Transform the parameters and return type. 4383212904Sdim // 4384234982Sdim // We are required to instantiate the params and return type in source order. 4385218893Sdim // When the function has a trailing return type, we instantiate the 4386218893Sdim // parameters before the return type, since the return type can then refer 4387218893Sdim // to the parameters themselves (via decltype, sizeof, etc.). 4388218893Sdim // 4389226633Sdim SmallVector<QualType, 4> ParamTypes; 4390226633Sdim SmallVector<ParmVarDecl*, 4> ParamDecls; 4391218893Sdim const FunctionProtoType *T = TL.getTypePtr(); 4392212904Sdim 4393218893Sdim QualType ResultType; 4394218893Sdim 4395239462Sdim if (T->hasTrailingReturn()) { 4396239462Sdim if (getDerived().TransformFunctionTypeParams(TL.getBeginLoc(), 4397218893Sdim TL.getParmArray(), 4398218893Sdim TL.getNumArgs(), 4399239462Sdim TL.getTypePtr()->arg_type_begin(), 4400218893Sdim ParamTypes, &ParamDecls)) 4401218893Sdim return QualType(); 4402218893Sdim 4403234982Sdim { 4404234982Sdim // C++11 [expr.prim.general]p3: 4405239462Sdim // If a declaration declares a member function or member function 4406239462Sdim // template of a class X, the expression this is a prvalue of type 4407234982Sdim // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq 4408239462Sdim // and the end of the function-definition, member-declarator, or 4409234982Sdim // declarator. 4410234982Sdim Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals); 4411239462Sdim 4412234982Sdim ResultType = getDerived().TransformType(TLB, TL.getResultLoc()); 4413234982Sdim if (ResultType.isNull()) 4414234982Sdim return QualType(); 4415234982Sdim } 4416218893Sdim } 4417218893Sdim else { 4418218893Sdim ResultType = getDerived().TransformType(TLB, TL.getResultLoc()); 4419218893Sdim if (ResultType.isNull()) 4420218893Sdim return QualType(); 4421218893Sdim 4422239462Sdim if (getDerived().TransformFunctionTypeParams(TL.getBeginLoc(), 4423218893Sdim TL.getParmArray(), 4424218893Sdim TL.getNumArgs(), 4425239462Sdim TL.getTypePtr()->arg_type_begin(), 4426218893Sdim ParamTypes, &ParamDecls)) 4427218893Sdim return QualType(); 4428218893Sdim } 4429218893Sdim 4430234982Sdim // FIXME: Need to transform the exception-specification too. 4431234982Sdim 4432198398Srdivacky QualType Result = TL.getType(); 4433198398Srdivacky if (getDerived().AlwaysRebuild() || 4434198398Srdivacky ResultType != T->getResultType() || 4435218893Sdim T->getNumArgs() != ParamTypes.size() || 4436198398Srdivacky !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) { 4437249423Sdim Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, 4438249423Sdim T->getExtProtoInfo()); 4439198398Srdivacky if (Result.isNull()) 4440198398Srdivacky return QualType(); 4441198398Srdivacky } 4442198092Srdivacky 4443198398Srdivacky FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result); 4444221345Sdim NewTL.setLocalRangeBegin(TL.getLocalRangeBegin()); 4445243830Sdim NewTL.setLParenLoc(TL.getLParenLoc()); 4446243830Sdim NewTL.setRParenLoc(TL.getRParenLoc()); 4447221345Sdim NewTL.setLocalRangeEnd(TL.getLocalRangeEnd()); 4448198398Srdivacky for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i) 4449198398Srdivacky NewTL.setArg(i, ParamDecls[i]); 4450198398Srdivacky 4451198398Srdivacky return Result; 4452198092Srdivacky} 4453198092Srdivacky 4454198092Srdivackytemplate<typename Derived> 4455198092SrdivackyQualType TreeTransform<Derived>::TransformFunctionNoProtoType( 4456198398Srdivacky TypeLocBuilder &TLB, 4457218893Sdim FunctionNoProtoTypeLoc TL) { 4458218893Sdim const FunctionNoProtoType *T = TL.getTypePtr(); 4459198398Srdivacky QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc()); 4460198398Srdivacky if (ResultType.isNull()) 4461198398Srdivacky return QualType(); 4462198398Srdivacky 4463198398Srdivacky QualType Result = TL.getType(); 4464198398Srdivacky if (getDerived().AlwaysRebuild() || 4465198398Srdivacky ResultType != T->getResultType()) 4466198398Srdivacky Result = getDerived().RebuildFunctionNoProtoType(ResultType); 4467198398Srdivacky 4468198398Srdivacky FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result); 4469221345Sdim NewTL.setLocalRangeBegin(TL.getLocalRangeBegin()); 4470243830Sdim NewTL.setLParenLoc(TL.getLParenLoc()); 4471243830Sdim NewTL.setRParenLoc(TL.getRParenLoc()); 4472221345Sdim NewTL.setLocalRangeEnd(TL.getLocalRangeEnd()); 4473198398Srdivacky 4474198398Srdivacky return Result; 4475198092Srdivacky} 4476198092Srdivacky 4477200583Srdivackytemplate<typename Derived> QualType 4478200583SrdivackyTreeTransform<Derived>::TransformUnresolvedUsingType(TypeLocBuilder &TLB, 4479218893Sdim UnresolvedUsingTypeLoc TL) { 4480218893Sdim const UnresolvedUsingType *T = TL.getTypePtr(); 4481204643Srdivacky Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()); 4482200583Srdivacky if (!D) 4483200583Srdivacky return QualType(); 4484200583Srdivacky 4485200583Srdivacky QualType Result = TL.getType(); 4486200583Srdivacky if (getDerived().AlwaysRebuild() || D != T->getDecl()) { 4487200583Srdivacky Result = getDerived().RebuildUnresolvedUsingType(D); 4488200583Srdivacky if (Result.isNull()) 4489200583Srdivacky return QualType(); 4490200583Srdivacky } 4491200583Srdivacky 4492200583Srdivacky // We might get an arbitrary type spec type back. We should at 4493200583Srdivacky // least always get a type spec type, though. 4494200583Srdivacky TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result); 4495200583Srdivacky NewTL.setNameLoc(TL.getNameLoc()); 4496200583Srdivacky 4497200583Srdivacky return Result; 4498200583Srdivacky} 4499200583Srdivacky 4500198092Srdivackytemplate<typename Derived> 4501198398SrdivackyQualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB, 4502218893Sdim TypedefTypeLoc TL) { 4503218893Sdim const TypedefType *T = TL.getTypePtr(); 4504221345Sdim TypedefNameDecl *Typedef 4505221345Sdim = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(), 4506221345Sdim T->getDecl())); 4507198092Srdivacky if (!Typedef) 4508198092Srdivacky return QualType(); 4509198092Srdivacky 4510198398Srdivacky QualType Result = TL.getType(); 4511198398Srdivacky if (getDerived().AlwaysRebuild() || 4512198398Srdivacky Typedef != T->getDecl()) { 4513198398Srdivacky Result = getDerived().RebuildTypedefType(Typedef); 4514198398Srdivacky if (Result.isNull()) 4515198398Srdivacky return QualType(); 4516198398Srdivacky } 4517198092Srdivacky 4518198398Srdivacky TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result); 4519198398Srdivacky NewTL.setNameLoc(TL.getNameLoc()); 4520198398Srdivacky 4521198398Srdivacky return Result; 4522198092Srdivacky} 4523198092Srdivacky 4524198092Srdivackytemplate<typename Derived> 4525198398SrdivackyQualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB, 4526218893Sdim TypeOfExprTypeLoc TL) { 4527198092Srdivacky // typeof expressions are not potentially evaluated contexts 4528243830Sdim EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated, 4529243830Sdim Sema::ReuseLambdaContextDecl); 4530198092Srdivacky 4531212904Sdim ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr()); 4532198092Srdivacky if (E.isInvalid()) 4533198092Srdivacky return QualType(); 4534198092Srdivacky 4535234353Sdim E = SemaRef.HandleExprEvaluationContextForTypeof(E.get()); 4536234353Sdim if (E.isInvalid()) 4537234353Sdim return QualType(); 4538234353Sdim 4539198398Srdivacky QualType Result = TL.getType(); 4540198398Srdivacky if (getDerived().AlwaysRebuild() || 4541202379Srdivacky E.get() != TL.getUnderlyingExpr()) { 4542218893Sdim Result = getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc()); 4543198398Srdivacky if (Result.isNull()) 4544198398Srdivacky return QualType(); 4545198092Srdivacky } 4546198398Srdivacky else E.take(); 4547198092Srdivacky 4548198398Srdivacky TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result); 4549202379Srdivacky NewTL.setTypeofLoc(TL.getTypeofLoc()); 4550202379Srdivacky NewTL.setLParenLoc(TL.getLParenLoc()); 4551202379Srdivacky NewTL.setRParenLoc(TL.getRParenLoc()); 4552198398Srdivacky 4553198398Srdivacky return Result; 4554198092Srdivacky} 4555198092Srdivacky 4556198092Srdivackytemplate<typename Derived> 4557198398SrdivackyQualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB, 4558218893Sdim TypeOfTypeLoc TL) { 4559202379Srdivacky TypeSourceInfo* Old_Under_TI = TL.getUnderlyingTInfo(); 4560202379Srdivacky TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI); 4561202379Srdivacky if (!New_Under_TI) 4562198092Srdivacky return QualType(); 4563198092Srdivacky 4564198398Srdivacky QualType Result = TL.getType(); 4565202379Srdivacky if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) { 4566202379Srdivacky Result = getDerived().RebuildTypeOfType(New_Under_TI->getType()); 4567198398Srdivacky if (Result.isNull()) 4568198398Srdivacky return QualType(); 4569198398Srdivacky } 4570198092Srdivacky 4571198398Srdivacky TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result); 4572202379Srdivacky NewTL.setTypeofLoc(TL.getTypeofLoc()); 4573202379Srdivacky NewTL.setLParenLoc(TL.getLParenLoc()); 4574202379Srdivacky NewTL.setRParenLoc(TL.getRParenLoc()); 4575202379Srdivacky NewTL.setUnderlyingTInfo(New_Under_TI); 4576198398Srdivacky 4577198398Srdivacky return Result; 4578198092Srdivacky} 4579198092Srdivacky 4580198092Srdivackytemplate<typename Derived> 4581198398SrdivackyQualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB, 4582218893Sdim DecltypeTypeLoc TL) { 4583218893Sdim const DecltypeType *T = TL.getTypePtr(); 4584198398Srdivacky 4585198092Srdivacky // decltype expressions are not potentially evaluated contexts 4586234353Sdim EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated, 0, 4587234353Sdim /*IsDecltype=*/ true); 4588198092Srdivacky 4589212904Sdim ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr()); 4590198092Srdivacky if (E.isInvalid()) 4591198092Srdivacky return QualType(); 4592198092Srdivacky 4593234353Sdim E = getSema().ActOnDecltypeExpression(E.take()); 4594234353Sdim if (E.isInvalid()) 4595234353Sdim return QualType(); 4596234353Sdim 4597198398Srdivacky QualType Result = TL.getType(); 4598198398Srdivacky if (getDerived().AlwaysRebuild() || 4599198398Srdivacky E.get() != T->getUnderlyingExpr()) { 4600218893Sdim Result = getDerived().RebuildDecltypeType(E.get(), TL.getNameLoc()); 4601198398Srdivacky if (Result.isNull()) 4602198398Srdivacky return QualType(); 4603198092Srdivacky } 4604198398Srdivacky else E.take(); 4605198092Srdivacky 4606198398Srdivacky DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result); 4607198398Srdivacky NewTL.setNameLoc(TL.getNameLoc()); 4608198398Srdivacky 4609198398Srdivacky return Result; 4610198092Srdivacky} 4611198092Srdivacky 4612198092Srdivackytemplate<typename Derived> 4613223017SdimQualType TreeTransform<Derived>::TransformUnaryTransformType( 4614223017Sdim TypeLocBuilder &TLB, 4615223017Sdim UnaryTransformTypeLoc TL) { 4616223017Sdim QualType Result = TL.getType(); 4617223017Sdim if (Result->isDependentType()) { 4618223017Sdim const UnaryTransformType *T = TL.getTypePtr(); 4619223017Sdim QualType NewBase = 4620223017Sdim getDerived().TransformType(TL.getUnderlyingTInfo())->getType(); 4621223017Sdim Result = getDerived().RebuildUnaryTransformType(NewBase, 4622223017Sdim T->getUTTKind(), 4623223017Sdim TL.getKWLoc()); 4624223017Sdim if (Result.isNull()) 4625223017Sdim return QualType(); 4626223017Sdim } 4627223017Sdim 4628223017Sdim UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result); 4629223017Sdim NewTL.setKWLoc(TL.getKWLoc()); 4630223017Sdim NewTL.setParensRange(TL.getParensRange()); 4631223017Sdim NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo()); 4632223017Sdim return Result; 4633223017Sdim} 4634223017Sdim 4635223017Sdimtemplate<typename Derived> 4636218893SdimQualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB, 4637218893Sdim AutoTypeLoc TL) { 4638218893Sdim const AutoType *T = TL.getTypePtr(); 4639218893Sdim QualType OldDeduced = T->getDeducedType(); 4640218893Sdim QualType NewDeduced; 4641218893Sdim if (!OldDeduced.isNull()) { 4642218893Sdim NewDeduced = getDerived().TransformType(OldDeduced); 4643218893Sdim if (NewDeduced.isNull()) 4644218893Sdim return QualType(); 4645218893Sdim } 4646218893Sdim 4647218893Sdim QualType Result = TL.getType(); 4648251662Sdim if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced || 4649251662Sdim T->isDependentType()) { 4650251662Sdim Result = getDerived().RebuildAutoType(NewDeduced, T->isDecltypeAuto()); 4651218893Sdim if (Result.isNull()) 4652218893Sdim return QualType(); 4653218893Sdim } 4654218893Sdim 4655218893Sdim AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result); 4656218893Sdim NewTL.setNameLoc(TL.getNameLoc()); 4657218893Sdim 4658218893Sdim return Result; 4659218893Sdim} 4660218893Sdim 4661218893Sdimtemplate<typename Derived> 4662198398SrdivackyQualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB, 4663218893Sdim RecordTypeLoc TL) { 4664218893Sdim const RecordType *T = TL.getTypePtr(); 4665198092Srdivacky RecordDecl *Record 4666204643Srdivacky = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(), 4667204643Srdivacky T->getDecl())); 4668198092Srdivacky if (!Record) 4669198092Srdivacky return QualType(); 4670198092Srdivacky 4671198398Srdivacky QualType Result = TL.getType(); 4672198398Srdivacky if (getDerived().AlwaysRebuild() || 4673198398Srdivacky Record != T->getDecl()) { 4674198398Srdivacky Result = getDerived().RebuildRecordType(Record); 4675198398Srdivacky if (Result.isNull()) 4676198398Srdivacky return QualType(); 4677198398Srdivacky } 4678198092Srdivacky 4679198398Srdivacky RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result); 4680198398Srdivacky NewTL.setNameLoc(TL.getNameLoc()); 4681198398Srdivacky 4682198398Srdivacky return Result; 4683198092Srdivacky} 4684198092Srdivacky 4685198092Srdivackytemplate<typename Derived> 4686198398SrdivackyQualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB, 4687218893Sdim EnumTypeLoc TL) { 4688218893Sdim const EnumType *T = TL.getTypePtr(); 4689198092Srdivacky EnumDecl *Enum 4690204643Srdivacky = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(), 4691204643Srdivacky T->getDecl())); 4692198092Srdivacky if (!Enum) 4693198092Srdivacky return QualType(); 4694198092Srdivacky 4695198398Srdivacky QualType Result = TL.getType(); 4696198398Srdivacky if (getDerived().AlwaysRebuild() || 4697198398Srdivacky Enum != T->getDecl()) { 4698198398Srdivacky Result = getDerived().RebuildEnumType(Enum); 4699198398Srdivacky if (Result.isNull()) 4700198398Srdivacky return QualType(); 4701198398Srdivacky } 4702198092Srdivacky 4703198398Srdivacky EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result); 4704198398Srdivacky NewTL.setNameLoc(TL.getNameLoc()); 4705198398Srdivacky 4706198398Srdivacky return Result; 4707198092Srdivacky} 4708198092Srdivacky 4709204962Srdivackytemplate<typename Derived> 4710204962SrdivackyQualType TreeTransform<Derived>::TransformInjectedClassNameType( 4711204962Srdivacky TypeLocBuilder &TLB, 4712218893Sdim InjectedClassNameTypeLoc TL) { 4713204962Srdivacky Decl *D = getDerived().TransformDecl(TL.getNameLoc(), 4714204962Srdivacky TL.getTypePtr()->getDecl()); 4715204962Srdivacky if (!D) return QualType(); 4716198092Srdivacky 4717204962Srdivacky QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D)); 4718204962Srdivacky TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc()); 4719204962Srdivacky return T; 4720204962Srdivacky} 4721204962Srdivacky 4722198092Srdivackytemplate<typename Derived> 4723198092SrdivackyQualType TreeTransform<Derived>::TransformTemplateTypeParmType( 4724198398Srdivacky TypeLocBuilder &TLB, 4725218893Sdim TemplateTypeParmTypeLoc TL) { 4726198398Srdivacky return TransformTypeSpecType(TLB, TL); 4727198092Srdivacky} 4728198092Srdivacky 4729198092Srdivackytemplate<typename Derived> 4730198398SrdivackyQualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType( 4731198398Srdivacky TypeLocBuilder &TLB, 4732218893Sdim SubstTemplateTypeParmTypeLoc TL) { 4733221345Sdim const SubstTemplateTypeParmType *T = TL.getTypePtr(); 4734239462Sdim 4735221345Sdim // Substitute into the replacement type, which itself might involve something 4736221345Sdim // that needs to be transformed. This only tends to occur with default 4737221345Sdim // template arguments of template template parameters. 4738221345Sdim TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName()); 4739221345Sdim QualType Replacement = getDerived().TransformType(T->getReplacementType()); 4740221345Sdim if (Replacement.isNull()) 4741221345Sdim return QualType(); 4742239462Sdim 4743221345Sdim // Always canonicalize the replacement type. 4744221345Sdim Replacement = SemaRef.Context.getCanonicalType(Replacement); 4745221345Sdim QualType Result 4746239462Sdim = SemaRef.Context.getSubstTemplateTypeParmType(T->getReplacedParameter(), 4747221345Sdim Replacement); 4748239462Sdim 4749221345Sdim // Propagate type-source information. 4750221345Sdim SubstTemplateTypeParmTypeLoc NewTL 4751221345Sdim = TLB.push<SubstTemplateTypeParmTypeLoc>(Result); 4752221345Sdim NewTL.setNameLoc(TL.getNameLoc()); 4753221345Sdim return Result; 4754221345Sdim 4755198398Srdivacky} 4756198398Srdivacky 4757198398Srdivackytemplate<typename Derived> 4758218893SdimQualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType( 4759218893Sdim TypeLocBuilder &TLB, 4760218893Sdim SubstTemplateTypeParmPackTypeLoc TL) { 4761218893Sdim return TransformTypeSpecType(TLB, TL); 4762218893Sdim} 4763198398Srdivacky 4764198398Srdivackytemplate<typename Derived> 4765198092SrdivackyQualType TreeTransform<Derived>::TransformTemplateSpecializationType( 4766198893Srdivacky TypeLocBuilder &TLB, 4767218893Sdim TemplateSpecializationTypeLoc TL) { 4768198893Srdivacky const TemplateSpecializationType *T = TL.getTypePtr(); 4769198893Srdivacky 4770221345Sdim // The nested-name-specifier never matters in a TemplateSpecializationType, 4771221345Sdim // because we can't have a dependent nested-name-specifier anyway. 4772221345Sdim CXXScopeSpec SS; 4773198092Srdivacky TemplateName Template 4774221345Sdim = getDerived().TransformTemplateName(SS, T->getTemplateName(), 4775221345Sdim TL.getTemplateNameLoc()); 4776198092Srdivacky if (Template.isNull()) 4777198092Srdivacky return QualType(); 4778198092Srdivacky 4779218893Sdim return getDerived().TransformTemplateSpecializationType(TLB, TL, Template); 4780218893Sdim} 4781218893Sdim 4782226633Sdimtemplate<typename Derived> 4783226633SdimQualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB, 4784226633Sdim AtomicTypeLoc TL) { 4785226633Sdim QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc()); 4786226633Sdim if (ValueType.isNull()) 4787226633Sdim return QualType(); 4788226633Sdim 4789226633Sdim QualType Result = TL.getType(); 4790226633Sdim if (getDerived().AlwaysRebuild() || 4791226633Sdim ValueType != TL.getValueLoc().getType()) { 4792226633Sdim Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc()); 4793226633Sdim if (Result.isNull()) 4794226633Sdim return QualType(); 4795226633Sdim } 4796226633Sdim 4797226633Sdim AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result); 4798226633Sdim NewTL.setKWLoc(TL.getKWLoc()); 4799226633Sdim NewTL.setLParenLoc(TL.getLParenLoc()); 4800226633Sdim NewTL.setRParenLoc(TL.getRParenLoc()); 4801226633Sdim 4802226633Sdim return Result; 4803226633Sdim} 4804226633Sdim 4805239462Sdim /// \brief Simple iterator that traverses the template arguments in a 4806218893Sdim /// container that provides a \c getArgLoc() member function. 4807218893Sdim /// 4808218893Sdim /// This iterator is intended to be used with the iterator form of 4809218893Sdim /// \c TreeTransform<Derived>::TransformTemplateArguments(). 4810218893Sdim template<typename ArgLocContainer> 4811218893Sdim class TemplateArgumentLocContainerIterator { 4812218893Sdim ArgLocContainer *Container; 4813218893Sdim unsigned Index; 4814239462Sdim 4815218893Sdim public: 4816218893Sdim typedef TemplateArgumentLoc value_type; 4817218893Sdim typedef TemplateArgumentLoc reference; 4818218893Sdim typedef int difference_type; 4819218893Sdim typedef std::input_iterator_tag iterator_category; 4820239462Sdim 4821218893Sdim class pointer { 4822218893Sdim TemplateArgumentLoc Arg; 4823239462Sdim 4824218893Sdim public: 4825218893Sdim explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { } 4826239462Sdim 4827218893Sdim const TemplateArgumentLoc *operator->() const { 4828218893Sdim return &Arg; 4829218893Sdim } 4830218893Sdim }; 4831239462Sdim 4832239462Sdim 4833218893Sdim TemplateArgumentLocContainerIterator() {} 4834239462Sdim 4835218893Sdim TemplateArgumentLocContainerIterator(ArgLocContainer &Container, 4836218893Sdim unsigned Index) 4837218893Sdim : Container(&Container), Index(Index) { } 4838239462Sdim 4839218893Sdim TemplateArgumentLocContainerIterator &operator++() { 4840218893Sdim ++Index; 4841218893Sdim return *this; 4842218893Sdim } 4843239462Sdim 4844218893Sdim TemplateArgumentLocContainerIterator operator++(int) { 4845218893Sdim TemplateArgumentLocContainerIterator Old(*this); 4846218893Sdim ++(*this); 4847218893Sdim return Old; 4848218893Sdim } 4849239462Sdim 4850218893Sdim TemplateArgumentLoc operator*() const { 4851218893Sdim return Container->getArgLoc(Index); 4852218893Sdim } 4853239462Sdim 4854218893Sdim pointer operator->() const { 4855218893Sdim return pointer(Container->getArgLoc(Index)); 4856218893Sdim } 4857239462Sdim 4858218893Sdim friend bool operator==(const TemplateArgumentLocContainerIterator &X, 4859218893Sdim const TemplateArgumentLocContainerIterator &Y) { 4860218893Sdim return X.Container == Y.Container && X.Index == Y.Index; 4861218893Sdim } 4862239462Sdim 4863218893Sdim friend bool operator!=(const TemplateArgumentLocContainerIterator &X, 4864218893Sdim const TemplateArgumentLocContainerIterator &Y) { 4865218893Sdim return !(X == Y); 4866218893Sdim } 4867218893Sdim }; 4868239462Sdim 4869239462Sdim 4870218893Sdimtemplate <typename Derived> 4871218893SdimQualType TreeTransform<Derived>::TransformTemplateSpecializationType( 4872218893Sdim TypeLocBuilder &TLB, 4873218893Sdim TemplateSpecializationTypeLoc TL, 4874218893Sdim TemplateName Template) { 4875199990Srdivacky TemplateArgumentListInfo NewTemplateArgs; 4876199990Srdivacky NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); 4877199990Srdivacky NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); 4878218893Sdim typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc> 4879218893Sdim ArgIterator; 4880239462Sdim if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), 4881218893Sdim ArgIterator(TL, TL.getNumArgs()), 4882218893Sdim NewTemplateArgs)) 4883218893Sdim return QualType(); 4884199990Srdivacky 4885198893Srdivacky // FIXME: maybe don't rebuild if all the template arguments are the same. 4886198893Srdivacky 4887198893Srdivacky QualType Result = 4888198893Srdivacky getDerived().RebuildTemplateSpecializationType(Template, 4889198893Srdivacky TL.getTemplateNameLoc(), 4890199990Srdivacky NewTemplateArgs); 4891198893Srdivacky 4892198893Srdivacky if (!Result.isNull()) { 4893223017Sdim // Specializations of template template parameters are represented as 4894223017Sdim // TemplateSpecializationTypes, and substitution of type alias templates 4895223017Sdim // within a dependent context can transform them into 4896223017Sdim // DependentTemplateSpecializationTypes. 4897223017Sdim if (isa<DependentTemplateSpecializationType>(Result)) { 4898223017Sdim DependentTemplateSpecializationTypeLoc NewTL 4899223017Sdim = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); 4900234353Sdim NewTL.setElaboratedKeywordLoc(SourceLocation()); 4901223017Sdim NewTL.setQualifierLoc(NestedNameSpecifierLoc()); 4902234353Sdim NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); 4903234353Sdim NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); 4904223017Sdim NewTL.setLAngleLoc(TL.getLAngleLoc()); 4905223017Sdim NewTL.setRAngleLoc(TL.getRAngleLoc()); 4906223017Sdim for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) 4907223017Sdim NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); 4908223017Sdim return Result; 4909223017Sdim } 4910223017Sdim 4911198893Srdivacky TemplateSpecializationTypeLoc NewTL 4912198893Srdivacky = TLB.push<TemplateSpecializationTypeLoc>(Result); 4913234353Sdim NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); 4914198893Srdivacky NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); 4915198893Srdivacky NewTL.setLAngleLoc(TL.getLAngleLoc()); 4916198893Srdivacky NewTL.setRAngleLoc(TL.getRAngleLoc()); 4917198893Srdivacky for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) 4918198893Srdivacky NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); 4919198092Srdivacky } 4920198092Srdivacky 4921198893Srdivacky return Result; 4922198092Srdivacky} 4923198092Srdivacky 4924221345Sdimtemplate <typename Derived> 4925221345SdimQualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType( 4926221345Sdim TypeLocBuilder &TLB, 4927221345Sdim DependentTemplateSpecializationTypeLoc TL, 4928221345Sdim TemplateName Template, 4929221345Sdim CXXScopeSpec &SS) { 4930221345Sdim TemplateArgumentListInfo NewTemplateArgs; 4931221345Sdim NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); 4932221345Sdim NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); 4933221345Sdim typedef TemplateArgumentLocContainerIterator< 4934221345Sdim DependentTemplateSpecializationTypeLoc> ArgIterator; 4935239462Sdim if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), 4936221345Sdim ArgIterator(TL, TL.getNumArgs()), 4937221345Sdim NewTemplateArgs)) 4938221345Sdim return QualType(); 4939239462Sdim 4940221345Sdim // FIXME: maybe don't rebuild if all the template arguments are the same. 4941239462Sdim 4942221345Sdim if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { 4943221345Sdim QualType Result 4944221345Sdim = getSema().Context.getDependentTemplateSpecializationType( 4945221345Sdim TL.getTypePtr()->getKeyword(), 4946221345Sdim DTN->getQualifier(), 4947221345Sdim DTN->getIdentifier(), 4948221345Sdim NewTemplateArgs); 4949239462Sdim 4950221345Sdim DependentTemplateSpecializationTypeLoc NewTL 4951221345Sdim = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); 4952234353Sdim NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); 4953221345Sdim NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context)); 4954234353Sdim NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); 4955234353Sdim NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); 4956221345Sdim NewTL.setLAngleLoc(TL.getLAngleLoc()); 4957221345Sdim NewTL.setRAngleLoc(TL.getRAngleLoc()); 4958221345Sdim for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) 4959221345Sdim NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); 4960221345Sdim return Result; 4961221345Sdim } 4962239462Sdim 4963239462Sdim QualType Result 4964221345Sdim = getDerived().RebuildTemplateSpecializationType(Template, 4965234353Sdim TL.getTemplateNameLoc(), 4966221345Sdim NewTemplateArgs); 4967239462Sdim 4968221345Sdim if (!Result.isNull()) { 4969221345Sdim /// FIXME: Wrap this in an elaborated-type-specifier? 4970221345Sdim TemplateSpecializationTypeLoc NewTL 4971221345Sdim = TLB.push<TemplateSpecializationTypeLoc>(Result); 4972234353Sdim NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); 4973234353Sdim NewTL.setTemplateNameLoc(TL.getTemplateNameLoc()); 4974221345Sdim NewTL.setLAngleLoc(TL.getLAngleLoc()); 4975221345Sdim NewTL.setRAngleLoc(TL.getRAngleLoc()); 4976221345Sdim for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i) 4977221345Sdim NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo()); 4978221345Sdim } 4979239462Sdim 4980221345Sdim return Result; 4981221345Sdim} 4982221345Sdim 4983198092Srdivackytemplate<typename Derived> 4984198398SrdivackyQualType 4985208600SrdivackyTreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB, 4986218893Sdim ElaboratedTypeLoc TL) { 4987218893Sdim const ElaboratedType *T = TL.getTypePtr(); 4988198092Srdivacky 4989221345Sdim NestedNameSpecifierLoc QualifierLoc; 4990208600Srdivacky // NOTE: the qualifier in an ElaboratedType is optional. 4991221345Sdim if (TL.getQualifierLoc()) { 4992239462Sdim QualifierLoc 4993221345Sdim = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); 4994221345Sdim if (!QualifierLoc) 4995208600Srdivacky return QualType(); 4996208600Srdivacky } 4997198092Srdivacky 4998218893Sdim QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc()); 4999218893Sdim if (NamedT.isNull()) 5000218893Sdim return QualType(); 5001208600Srdivacky 5002223017Sdim // C++0x [dcl.type.elab]p2: 5003223017Sdim // If the identifier resolves to a typedef-name or the simple-template-id 5004223017Sdim // resolves to an alias template specialization, the 5005223017Sdim // elaborated-type-specifier is ill-formed. 5006223017Sdim if (T->getKeyword() != ETK_None && T->getKeyword() != ETK_Typename) { 5007223017Sdim if (const TemplateSpecializationType *TST = 5008223017Sdim NamedT->getAs<TemplateSpecializationType>()) { 5009223017Sdim TemplateName Template = TST->getTemplateName(); 5010223017Sdim if (TypeAliasTemplateDecl *TAT = 5011223017Sdim dyn_cast_or_null<TypeAliasTemplateDecl>(Template.getAsTemplateDecl())) { 5012223017Sdim SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(), 5013223017Sdim diag::err_tag_reference_non_tag) << 4; 5014223017Sdim SemaRef.Diag(TAT->getLocation(), diag::note_declared_at); 5015223017Sdim } 5016223017Sdim } 5017223017Sdim } 5018223017Sdim 5019198398Srdivacky QualType Result = TL.getType(); 5020198398Srdivacky if (getDerived().AlwaysRebuild() || 5021221345Sdim QualifierLoc != TL.getQualifierLoc() || 5022208600Srdivacky NamedT != T->getNamedType()) { 5023234353Sdim Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(), 5024239462Sdim T->getKeyword(), 5025221345Sdim QualifierLoc, NamedT); 5026198398Srdivacky if (Result.isNull()) 5027198398Srdivacky return QualType(); 5028198398Srdivacky } 5029198092Srdivacky 5030208600Srdivacky ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); 5031234353Sdim NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); 5032221345Sdim NewTL.setQualifierLoc(QualifierLoc); 5033198398Srdivacky return Result; 5034198092Srdivacky} 5035198092Srdivacky 5036198092Srdivackytemplate<typename Derived> 5037218893SdimQualType TreeTransform<Derived>::TransformAttributedType( 5038218893Sdim TypeLocBuilder &TLB, 5039218893Sdim AttributedTypeLoc TL) { 5040218893Sdim const AttributedType *oldType = TL.getTypePtr(); 5041218893Sdim QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc()); 5042218893Sdim if (modifiedType.isNull()) 5043218893Sdim return QualType(); 5044218893Sdim 5045218893Sdim QualType result = TL.getType(); 5046218893Sdim 5047218893Sdim // FIXME: dependent operand expressions? 5048218893Sdim if (getDerived().AlwaysRebuild() || 5049218893Sdim modifiedType != oldType->getModifiedType()) { 5050218893Sdim // TODO: this is really lame; we should really be rebuilding the 5051218893Sdim // equivalent type from first principles. 5052218893Sdim QualType equivalentType 5053218893Sdim = getDerived().TransformType(oldType->getEquivalentType()); 5054218893Sdim if (equivalentType.isNull()) 5055218893Sdim return QualType(); 5056218893Sdim result = SemaRef.Context.getAttributedType(oldType->getAttrKind(), 5057218893Sdim modifiedType, 5058218893Sdim equivalentType); 5059218893Sdim } 5060218893Sdim 5061218893Sdim AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result); 5062218893Sdim newTL.setAttrNameLoc(TL.getAttrNameLoc()); 5063218893Sdim if (TL.hasAttrOperand()) 5064218893Sdim newTL.setAttrOperandParensRange(TL.getAttrOperandParensRange()); 5065218893Sdim if (TL.hasAttrExprOperand()) 5066218893Sdim newTL.setAttrExprOperand(TL.getAttrExprOperand()); 5067218893Sdim else if (TL.hasAttrEnumOperand()) 5068218893Sdim newTL.setAttrEnumOperandLoc(TL.getAttrEnumOperandLoc()); 5069218893Sdim 5070218893Sdim return result; 5071218893Sdim} 5072218893Sdim 5073218893Sdimtemplate<typename Derived> 5074218893SdimQualType 5075218893SdimTreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB, 5076218893Sdim ParenTypeLoc TL) { 5077218893Sdim QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc()); 5078218893Sdim if (Inner.isNull()) 5079218893Sdim return QualType(); 5080218893Sdim 5081218893Sdim QualType Result = TL.getType(); 5082218893Sdim if (getDerived().AlwaysRebuild() || 5083218893Sdim Inner != TL.getInnerLoc().getType()) { 5084218893Sdim Result = getDerived().RebuildParenType(Inner); 5085218893Sdim if (Result.isNull()) 5086218893Sdim return QualType(); 5087218893Sdim } 5088218893Sdim 5089218893Sdim ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result); 5090218893Sdim NewTL.setLParenLoc(TL.getLParenLoc()); 5091218893Sdim NewTL.setRParenLoc(TL.getRParenLoc()); 5092218893Sdim return Result; 5093218893Sdim} 5094218893Sdim 5095218893Sdimtemplate<typename Derived> 5096206084SrdivackyQualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB, 5097218893Sdim DependentNameTypeLoc TL) { 5098218893Sdim const DependentNameType *T = TL.getTypePtr(); 5099198893Srdivacky 5100221345Sdim NestedNameSpecifierLoc QualifierLoc 5101221345Sdim = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); 5102221345Sdim if (!QualifierLoc) 5103198092Srdivacky return QualType(); 5104198092Srdivacky 5105210299Sed QualType Result 5106221345Sdim = getDerived().RebuildDependentNameType(T->getKeyword(), 5107234353Sdim TL.getElaboratedKeywordLoc(), 5108221345Sdim QualifierLoc, 5109210299Sed T->getIdentifier(), 5110210299Sed TL.getNameLoc()); 5111198398Srdivacky if (Result.isNull()) 5112198398Srdivacky return QualType(); 5113198092Srdivacky 5114208600Srdivacky if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) { 5115208600Srdivacky QualType NamedT = ElabT->getNamedType(); 5116210299Sed TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc()); 5117210299Sed 5118208600Srdivacky ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); 5119234353Sdim NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); 5120221345Sdim NewTL.setQualifierLoc(QualifierLoc); 5121210299Sed } else { 5122208600Srdivacky DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result); 5123234353Sdim NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); 5124221345Sdim NewTL.setQualifierLoc(QualifierLoc); 5125208600Srdivacky NewTL.setNameLoc(TL.getNameLoc()); 5126208600Srdivacky } 5127198398Srdivacky return Result; 5128198092Srdivacky} 5129198092Srdivacky 5130198092Srdivackytemplate<typename Derived> 5131210299SedQualType TreeTransform<Derived>:: 5132210299Sed TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, 5133218893Sdim DependentTemplateSpecializationTypeLoc TL) { 5134221345Sdim NestedNameSpecifierLoc QualifierLoc; 5135221345Sdim if (TL.getQualifierLoc()) { 5136221345Sdim QualifierLoc 5137221345Sdim = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc()); 5138221345Sdim if (!QualifierLoc) 5139221345Sdim return QualType(); 5140221345Sdim } 5141239462Sdim 5142218893Sdim return getDerived() 5143221345Sdim .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc); 5144218893Sdim} 5145218893Sdim 5146218893Sdimtemplate<typename Derived> 5147218893SdimQualType TreeTransform<Derived>:: 5148221345SdimTransformDependentTemplateSpecializationType(TypeLocBuilder &TLB, 5149221345Sdim DependentTemplateSpecializationTypeLoc TL, 5150221345Sdim NestedNameSpecifierLoc QualifierLoc) { 5151218893Sdim const DependentTemplateSpecializationType *T = TL.getTypePtr(); 5152239462Sdim 5153210299Sed TemplateArgumentListInfo NewTemplateArgs; 5154210299Sed NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc()); 5155210299Sed NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc()); 5156239462Sdim 5157218893Sdim typedef TemplateArgumentLocContainerIterator< 5158221345Sdim DependentTemplateSpecializationTypeLoc> ArgIterator; 5159218893Sdim if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0), 5160218893Sdim ArgIterator(TL, TL.getNumArgs()), 5161218893Sdim NewTemplateArgs)) 5162218893Sdim return QualType(); 5163239462Sdim 5164218893Sdim QualType Result 5165218893Sdim = getDerived().RebuildDependentTemplateSpecializationType(T->getKeyword(), 5166221345Sdim QualifierLoc, 5167218893Sdim T->getIdentifier(), 5168234353Sdim TL.getTemplateNameLoc(), 5169221345Sdim NewTemplateArgs); 5170210299Sed if (Result.isNull()) 5171210299Sed return QualType(); 5172239462Sdim 5173210299Sed if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) { 5174210299Sed QualType NamedT = ElabT->getNamedType(); 5175239462Sdim 5176210299Sed // Copy information relevant to the template specialization. 5177210299Sed TemplateSpecializationTypeLoc NamedTL 5178210299Sed = TLB.push<TemplateSpecializationTypeLoc>(NamedT); 5179234353Sdim NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); 5180234353Sdim NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc()); 5181210299Sed NamedTL.setLAngleLoc(TL.getLAngleLoc()); 5182210299Sed NamedTL.setRAngleLoc(TL.getRAngleLoc()); 5183221345Sdim for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I) 5184221345Sdim NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo()); 5185239462Sdim 5186210299Sed // Copy information relevant to the elaborated type. 5187210299Sed ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result); 5188234353Sdim NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); 5189221345Sdim NewTL.setQualifierLoc(QualifierLoc); 5190221345Sdim } else if (isa<DependentTemplateSpecializationType>(Result)) { 5191221345Sdim DependentTemplateSpecializationTypeLoc SpecTL 5192221345Sdim = TLB.push<DependentTemplateSpecializationTypeLoc>(Result); 5193234353Sdim SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc()); 5194221345Sdim SpecTL.setQualifierLoc(QualifierLoc); 5195234353Sdim SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); 5196234353Sdim SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc()); 5197221345Sdim SpecTL.setLAngleLoc(TL.getLAngleLoc()); 5198221345Sdim SpecTL.setRAngleLoc(TL.getRAngleLoc()); 5199221345Sdim for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I) 5200221345Sdim SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo()); 5201210299Sed } else { 5202221345Sdim TemplateSpecializationTypeLoc SpecTL 5203221345Sdim = TLB.push<TemplateSpecializationTypeLoc>(Result); 5204234353Sdim SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc()); 5205234353Sdim SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc()); 5206221345Sdim SpecTL.setLAngleLoc(TL.getLAngleLoc()); 5207221345Sdim SpecTL.setRAngleLoc(TL.getRAngleLoc()); 5208221345Sdim for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I) 5209221345Sdim SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo()); 5210210299Sed } 5211210299Sed return Result; 5212210299Sed} 5213210299Sed 5214210299Sedtemplate<typename Derived> 5215218893SdimQualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB, 5216218893Sdim PackExpansionTypeLoc TL) { 5217239462Sdim QualType Pattern 5218239462Sdim = getDerived().TransformType(TLB, TL.getPatternLoc()); 5219218893Sdim if (Pattern.isNull()) 5220218893Sdim return QualType(); 5221239462Sdim 5222239462Sdim QualType Result = TL.getType(); 5223218893Sdim if (getDerived().AlwaysRebuild() || 5224218893Sdim Pattern != TL.getPatternLoc().getType()) { 5225239462Sdim Result = getDerived().RebuildPackExpansionType(Pattern, 5226218893Sdim TL.getPatternLoc().getSourceRange(), 5227218893Sdim TL.getEllipsisLoc(), 5228218893Sdim TL.getTypePtr()->getNumExpansions()); 5229218893Sdim if (Result.isNull()) 5230218893Sdim return QualType(); 5231218893Sdim } 5232239462Sdim 5233218893Sdim PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result); 5234218893Sdim NewT.setEllipsisLoc(TL.getEllipsisLoc()); 5235218893Sdim return Result; 5236218893Sdim} 5237218893Sdim 5238218893Sdimtemplate<typename Derived> 5239198398SrdivackyQualType 5240198398SrdivackyTreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB, 5241218893Sdim ObjCInterfaceTypeLoc TL) { 5242207619Srdivacky // ObjCInterfaceType is never dependent. 5243208600Srdivacky TLB.pushFullCopy(TL); 5244207619Srdivacky return TL.getType(); 5245198092Srdivacky} 5246198092Srdivacky 5247198092Srdivackytemplate<typename Derived> 5248198398SrdivackyQualType 5249208600SrdivackyTreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB, 5250218893Sdim ObjCObjectTypeLoc TL) { 5251208600Srdivacky // ObjCObjectType is never dependent. 5252208600Srdivacky TLB.pushFullCopy(TL); 5253208600Srdivacky return TL.getType(); 5254208600Srdivacky} 5255208600Srdivacky 5256208600Srdivackytemplate<typename Derived> 5257208600SrdivackyQualType 5258198398SrdivackyTreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB, 5259218893Sdim ObjCObjectPointerTypeLoc TL) { 5260207619Srdivacky // ObjCObjectPointerType is never dependent. 5261208600Srdivacky TLB.pushFullCopy(TL); 5262207619Srdivacky return TL.getType(); 5263198092Srdivacky} 5264198092Srdivacky 5265198092Srdivacky//===----------------------------------------------------------------------===// 5266198092Srdivacky// Statement transformation 5267198092Srdivacky//===----------------------------------------------------------------------===// 5268198092Srdivackytemplate<typename Derived> 5269212904SdimStmtResult 5270198092SrdivackyTreeTransform<Derived>::TransformNullStmt(NullStmt *S) { 5271218893Sdim return SemaRef.Owned(S); 5272198092Srdivacky} 5273198092Srdivacky 5274198092Srdivackytemplate<typename Derived> 5275212904SdimStmtResult 5276198092SrdivackyTreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) { 5277198092Srdivacky return getDerived().TransformCompoundStmt(S, false); 5278198092Srdivacky} 5279198092Srdivacky 5280198092Srdivackytemplate<typename Derived> 5281212904SdimStmtResult 5282198092SrdivackyTreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S, 5283198092Srdivacky bool IsStmtExpr) { 5284234353Sdim Sema::CompoundScopeRAII CompoundScope(getSema()); 5285234353Sdim 5286212904Sdim bool SubStmtInvalid = false; 5287198092Srdivacky bool SubStmtChanged = false; 5288243830Sdim SmallVector<Stmt*, 8> Statements; 5289198092Srdivacky for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end(); 5290198092Srdivacky B != BEnd; ++B) { 5291212904Sdim StmtResult Result = getDerived().TransformStmt(*B); 5292212904Sdim if (Result.isInvalid()) { 5293212904Sdim // Immediately fail if this was a DeclStmt, since it's very 5294212904Sdim // likely that this will cause problems for future statements. 5295212904Sdim if (isa<DeclStmt>(*B)) 5296212904Sdim return StmtError(); 5297198092Srdivacky 5298212904Sdim // Otherwise, just keep processing substatements and fail later. 5299212904Sdim SubStmtInvalid = true; 5300212904Sdim continue; 5301212904Sdim } 5302212904Sdim 5303198092Srdivacky SubStmtChanged = SubStmtChanged || Result.get() != *B; 5304198092Srdivacky Statements.push_back(Result.takeAs<Stmt>()); 5305198092Srdivacky } 5306198092Srdivacky 5307212904Sdim if (SubStmtInvalid) 5308212904Sdim return StmtError(); 5309212904Sdim 5310198092Srdivacky if (!getDerived().AlwaysRebuild() && 5311198092Srdivacky !SubStmtChanged) 5312218893Sdim return SemaRef.Owned(S); 5313198092Srdivacky 5314198092Srdivacky return getDerived().RebuildCompoundStmt(S->getLBracLoc(), 5315243830Sdim Statements, 5316198092Srdivacky S->getRBracLoc(), 5317198092Srdivacky IsStmtExpr); 5318198092Srdivacky} 5319198092Srdivacky 5320198092Srdivackytemplate<typename Derived> 5321212904SdimStmtResult 5322198092SrdivackyTreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) { 5323212904Sdim ExprResult LHS, RHS; 5324199512Srdivacky { 5325234353Sdim EnterExpressionEvaluationContext Unevaluated(SemaRef, 5326234353Sdim Sema::ConstantEvaluated); 5327198092Srdivacky 5328199512Srdivacky // Transform the left-hand case value. 5329199512Srdivacky LHS = getDerived().TransformExpr(S->getLHS()); 5330234353Sdim LHS = SemaRef.ActOnConstantExpression(LHS); 5331199512Srdivacky if (LHS.isInvalid()) 5332212904Sdim return StmtError(); 5333198092Srdivacky 5334199512Srdivacky // Transform the right-hand case value (for the GNU case-range extension). 5335199512Srdivacky RHS = getDerived().TransformExpr(S->getRHS()); 5336234353Sdim RHS = SemaRef.ActOnConstantExpression(RHS); 5337199512Srdivacky if (RHS.isInvalid()) 5338212904Sdim return StmtError(); 5339199512Srdivacky } 5340198092Srdivacky 5341198092Srdivacky // Build the case statement. 5342198092Srdivacky // Case statements are always rebuilt so that they will attached to their 5343198092Srdivacky // transformed switch statement. 5344212904Sdim StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(), 5345212904Sdim LHS.get(), 5346198092Srdivacky S->getEllipsisLoc(), 5347212904Sdim RHS.get(), 5348198092Srdivacky S->getColonLoc()); 5349198092Srdivacky if (Case.isInvalid()) 5350212904Sdim return StmtError(); 5351198092Srdivacky 5352198092Srdivacky // Transform the statement following the case 5353212904Sdim StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt()); 5354198092Srdivacky if (SubStmt.isInvalid()) 5355212904Sdim return StmtError(); 5356198092Srdivacky 5357198092Srdivacky // Attach the body to the case statement 5358212904Sdim return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get()); 5359198092Srdivacky} 5360198092Srdivacky 5361198092Srdivackytemplate<typename Derived> 5362212904SdimStmtResult 5363198092SrdivackyTreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) { 5364198092Srdivacky // Transform the statement following the default case 5365212904Sdim StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt()); 5366198092Srdivacky if (SubStmt.isInvalid()) 5367212904Sdim return StmtError(); 5368198092Srdivacky 5369198092Srdivacky // Default statements are always rebuilt 5370198092Srdivacky return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(), 5371212904Sdim SubStmt.get()); 5372198092Srdivacky} 5373198092Srdivacky 5374198092Srdivackytemplate<typename Derived> 5375212904SdimStmtResult 5376198092SrdivackyTreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) { 5377212904Sdim StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt()); 5378198092Srdivacky if (SubStmt.isInvalid()) 5379212904Sdim return StmtError(); 5380198092Srdivacky 5381218893Sdim Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(), 5382218893Sdim S->getDecl()); 5383218893Sdim if (!LD) 5384218893Sdim return StmtError(); 5385234982Sdim 5386234982Sdim 5387198092Srdivacky // FIXME: Pass the real colon location in. 5388218893Sdim return getDerived().RebuildLabelStmt(S->getIdentLoc(), 5389218893Sdim cast<LabelDecl>(LD), SourceLocation(), 5390212904Sdim SubStmt.get()); 5391198092Srdivacky} 5392198092Srdivacky 5393198092Srdivackytemplate<typename Derived> 5394212904SdimStmtResult 5395234982SdimTreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S) { 5396234982Sdim StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt()); 5397234982Sdim if (SubStmt.isInvalid()) 5398234982Sdim return StmtError(); 5399234982Sdim 5400234982Sdim // TODO: transform attributes 5401234982Sdim if (SubStmt.get() == S->getSubStmt() /* && attrs are the same */) 5402234982Sdim return S; 5403234982Sdim 5404234982Sdim return getDerived().RebuildAttributedStmt(S->getAttrLoc(), 5405234982Sdim S->getAttrs(), 5406234982Sdim SubStmt.get()); 5407234982Sdim} 5408234982Sdim 5409234982Sdimtemplate<typename Derived> 5410234982SdimStmtResult 5411198092SrdivackyTreeTransform<Derived>::TransformIfStmt(IfStmt *S) { 5412198092Srdivacky // Transform the condition 5413212904Sdim ExprResult Cond; 5414199990Srdivacky VarDecl *ConditionVar = 0; 5415199990Srdivacky if (S->getConditionVariable()) { 5416239462Sdim ConditionVar 5417199990Srdivacky = cast_or_null<VarDecl>( 5418204643Srdivacky getDerived().TransformDefinition( 5419204643Srdivacky S->getConditionVariable()->getLocation(), 5420204643Srdivacky S->getConditionVariable())); 5421199990Srdivacky if (!ConditionVar) 5422212904Sdim return StmtError(); 5423199990Srdivacky } else { 5424199990Srdivacky Cond = getDerived().TransformExpr(S->getCond()); 5425239462Sdim 5426199990Srdivacky if (Cond.isInvalid()) 5427212904Sdim return StmtError(); 5428239462Sdim 5429208600Srdivacky // Convert the condition to a boolean value. 5430208600Srdivacky if (S->getCond()) { 5431239462Sdim ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getIfLoc(), 5432218893Sdim Cond.get()); 5433208600Srdivacky if (CondE.isInvalid()) 5434212904Sdim return StmtError(); 5435239462Sdim 5436212904Sdim Cond = CondE.get(); 5437208600Srdivacky } 5438199990Srdivacky } 5439239462Sdim 5440212904Sdim Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take())); 5441212904Sdim if (!S->getConditionVariable() && S->getCond() && !FullCond.get()) 5442212904Sdim return StmtError(); 5443239462Sdim 5444198092Srdivacky // Transform the "then" branch. 5445212904Sdim StmtResult Then = getDerived().TransformStmt(S->getThen()); 5446198092Srdivacky if (Then.isInvalid()) 5447212904Sdim return StmtError(); 5448198092Srdivacky 5449198092Srdivacky // Transform the "else" branch. 5450212904Sdim StmtResult Else = getDerived().TransformStmt(S->getElse()); 5451198092Srdivacky if (Else.isInvalid()) 5452212904Sdim return StmtError(); 5453198092Srdivacky 5454198092Srdivacky if (!getDerived().AlwaysRebuild() && 5455212904Sdim FullCond.get() == S->getCond() && 5456199990Srdivacky ConditionVar == S->getConditionVariable() && 5457198092Srdivacky Then.get() == S->getThen() && 5458198092Srdivacky Else.get() == S->getElse()) 5459218893Sdim return SemaRef.Owned(S); 5460198092Srdivacky 5461199990Srdivacky return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar, 5462212904Sdim Then.get(), 5463212904Sdim S->getElseLoc(), Else.get()); 5464198092Srdivacky} 5465198092Srdivacky 5466198092Srdivackytemplate<typename Derived> 5467212904SdimStmtResult 5468198092SrdivackyTreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) { 5469198092Srdivacky // Transform the condition. 5470212904Sdim ExprResult Cond; 5471199990Srdivacky VarDecl *ConditionVar = 0; 5472199990Srdivacky if (S->getConditionVariable()) { 5473239462Sdim ConditionVar 5474199990Srdivacky = cast_or_null<VarDecl>( 5475204643Srdivacky getDerived().TransformDefinition( 5476204643Srdivacky S->getConditionVariable()->getLocation(), 5477204643Srdivacky S->getConditionVariable())); 5478199990Srdivacky if (!ConditionVar) 5479212904Sdim return StmtError(); 5480199990Srdivacky } else { 5481199990Srdivacky Cond = getDerived().TransformExpr(S->getCond()); 5482239462Sdim 5483199990Srdivacky if (Cond.isInvalid()) 5484212904Sdim return StmtError(); 5485199990Srdivacky } 5486198092Srdivacky 5487198092Srdivacky // Rebuild the switch statement. 5488212904Sdim StmtResult Switch 5489212904Sdim = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Cond.get(), 5490208600Srdivacky ConditionVar); 5491198092Srdivacky if (Switch.isInvalid()) 5492212904Sdim return StmtError(); 5493198092Srdivacky 5494198092Srdivacky // Transform the body of the switch statement. 5495212904Sdim StmtResult Body = getDerived().TransformStmt(S->getBody()); 5496198092Srdivacky if (Body.isInvalid()) 5497212904Sdim return StmtError(); 5498198092Srdivacky 5499198092Srdivacky // Complete the switch statement. 5500212904Sdim return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(), 5501212904Sdim Body.get()); 5502198092Srdivacky} 5503198092Srdivacky 5504198092Srdivackytemplate<typename Derived> 5505212904SdimStmtResult 5506198092SrdivackyTreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) { 5507198092Srdivacky // Transform the condition 5508212904Sdim ExprResult Cond; 5509199990Srdivacky VarDecl *ConditionVar = 0; 5510199990Srdivacky if (S->getConditionVariable()) { 5511239462Sdim ConditionVar 5512199990Srdivacky = cast_or_null<VarDecl>( 5513204643Srdivacky getDerived().TransformDefinition( 5514204643Srdivacky S->getConditionVariable()->getLocation(), 5515204643Srdivacky S->getConditionVariable())); 5516199990Srdivacky if (!ConditionVar) 5517212904Sdim return StmtError(); 5518199990Srdivacky } else { 5519199990Srdivacky Cond = getDerived().TransformExpr(S->getCond()); 5520239462Sdim 5521199990Srdivacky if (Cond.isInvalid()) 5522212904Sdim return StmtError(); 5523208600Srdivacky 5524208600Srdivacky if (S->getCond()) { 5525208600Srdivacky // Convert the condition to a boolean value. 5526239462Sdim ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getWhileLoc(), 5527218893Sdim Cond.get()); 5528208600Srdivacky if (CondE.isInvalid()) 5529212904Sdim return StmtError(); 5530212904Sdim Cond = CondE; 5531208600Srdivacky } 5532199990Srdivacky } 5533198092Srdivacky 5534212904Sdim Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take())); 5535212904Sdim if (!S->getConditionVariable() && S->getCond() && !FullCond.get()) 5536212904Sdim return StmtError(); 5537198092Srdivacky 5538198092Srdivacky // Transform the body 5539212904Sdim StmtResult Body = getDerived().TransformStmt(S->getBody()); 5540198092Srdivacky if (Body.isInvalid()) 5541212904Sdim return StmtError(); 5542198092Srdivacky 5543198092Srdivacky if (!getDerived().AlwaysRebuild() && 5544212904Sdim FullCond.get() == S->getCond() && 5545199990Srdivacky ConditionVar == S->getConditionVariable() && 5546198092Srdivacky Body.get() == S->getBody()) 5547212904Sdim return Owned(S); 5548198092Srdivacky 5549208600Srdivacky return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, 5550212904Sdim ConditionVar, Body.get()); 5551198092Srdivacky} 5552198092Srdivacky 5553198092Srdivackytemplate<typename Derived> 5554212904SdimStmtResult 5555198092SrdivackyTreeTransform<Derived>::TransformDoStmt(DoStmt *S) { 5556198092Srdivacky // Transform the body 5557212904Sdim StmtResult Body = getDerived().TransformStmt(S->getBody()); 5558198092Srdivacky if (Body.isInvalid()) 5559212904Sdim return StmtError(); 5560198092Srdivacky 5561208600Srdivacky // Transform the condition 5562212904Sdim ExprResult Cond = getDerived().TransformExpr(S->getCond()); 5563208600Srdivacky if (Cond.isInvalid()) 5564212904Sdim return StmtError(); 5565239462Sdim 5566198092Srdivacky if (!getDerived().AlwaysRebuild() && 5567198092Srdivacky Cond.get() == S->getCond() && 5568198092Srdivacky Body.get() == S->getBody()) 5569218893Sdim return SemaRef.Owned(S); 5570198092Srdivacky 5571212904Sdim return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(), 5572212904Sdim /*FIXME:*/S->getWhileLoc(), Cond.get(), 5573198092Srdivacky S->getRParenLoc()); 5574198092Srdivacky} 5575198092Srdivacky 5576198092Srdivackytemplate<typename Derived> 5577212904SdimStmtResult 5578198092SrdivackyTreeTransform<Derived>::TransformForStmt(ForStmt *S) { 5579198092Srdivacky // Transform the initialization statement 5580212904Sdim StmtResult Init = getDerived().TransformStmt(S->getInit()); 5581198092Srdivacky if (Init.isInvalid()) 5582212904Sdim return StmtError(); 5583198092Srdivacky 5584198092Srdivacky // Transform the condition 5585212904Sdim ExprResult Cond; 5586199990Srdivacky VarDecl *ConditionVar = 0; 5587199990Srdivacky if (S->getConditionVariable()) { 5588239462Sdim ConditionVar 5589199990Srdivacky = cast_or_null<VarDecl>( 5590204643Srdivacky getDerived().TransformDefinition( 5591204643Srdivacky S->getConditionVariable()->getLocation(), 5592204643Srdivacky S->getConditionVariable())); 5593199990Srdivacky if (!ConditionVar) 5594212904Sdim return StmtError(); 5595199990Srdivacky } else { 5596199990Srdivacky Cond = getDerived().TransformExpr(S->getCond()); 5597239462Sdim 5598199990Srdivacky if (Cond.isInvalid()) 5599212904Sdim return StmtError(); 5600208600Srdivacky 5601208600Srdivacky if (S->getCond()) { 5602208600Srdivacky // Convert the condition to a boolean value. 5603239462Sdim ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getForLoc(), 5604218893Sdim Cond.get()); 5605208600Srdivacky if (CondE.isInvalid()) 5606212904Sdim return StmtError(); 5607208600Srdivacky 5608212904Sdim Cond = CondE.get(); 5609208600Srdivacky } 5610199990Srdivacky } 5611198092Srdivacky 5612239462Sdim Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take())); 5613212904Sdim if (!S->getConditionVariable() && S->getCond() && !FullCond.get()) 5614212904Sdim return StmtError(); 5615208600Srdivacky 5616198092Srdivacky // Transform the increment 5617212904Sdim ExprResult Inc = getDerived().TransformExpr(S->getInc()); 5618198092Srdivacky if (Inc.isInvalid()) 5619212904Sdim return StmtError(); 5620198092Srdivacky 5621249423Sdim Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get())); 5622212904Sdim if (S->getInc() && !FullInc.get()) 5623212904Sdim return StmtError(); 5624208600Srdivacky 5625198092Srdivacky // Transform the body 5626212904Sdim StmtResult Body = getDerived().TransformStmt(S->getBody()); 5627198092Srdivacky if (Body.isInvalid()) 5628212904Sdim return StmtError(); 5629198092Srdivacky 5630198092Srdivacky if (!getDerived().AlwaysRebuild() && 5631198092Srdivacky Init.get() == S->getInit() && 5632212904Sdim FullCond.get() == S->getCond() && 5633198092Srdivacky Inc.get() == S->getInc() && 5634198092Srdivacky Body.get() == S->getBody()) 5635218893Sdim return SemaRef.Owned(S); 5636198092Srdivacky 5637198092Srdivacky return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(), 5638212904Sdim Init.get(), FullCond, ConditionVar, 5639212904Sdim FullInc, S->getRParenLoc(), Body.get()); 5640198092Srdivacky} 5641198092Srdivacky 5642198092Srdivackytemplate<typename Derived> 5643212904SdimStmtResult 5644198092SrdivackyTreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) { 5645218893Sdim Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(), 5646218893Sdim S->getLabel()); 5647218893Sdim if (!LD) 5648218893Sdim return StmtError(); 5649239462Sdim 5650198092Srdivacky // Goto statements must always be rebuilt, to resolve the label. 5651198092Srdivacky return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(), 5652218893Sdim cast<LabelDecl>(LD)); 5653198092Srdivacky} 5654198092Srdivacky 5655198092Srdivackytemplate<typename Derived> 5656212904SdimStmtResult 5657198092SrdivackyTreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) { 5658212904Sdim ExprResult Target = getDerived().TransformExpr(S->getTarget()); 5659198092Srdivacky if (Target.isInvalid()) 5660212904Sdim return StmtError(); 5661234353Sdim Target = SemaRef.MaybeCreateExprWithCleanups(Target.take()); 5662198092Srdivacky 5663198092Srdivacky if (!getDerived().AlwaysRebuild() && 5664198092Srdivacky Target.get() == S->getTarget()) 5665218893Sdim return SemaRef.Owned(S); 5666198092Srdivacky 5667198092Srdivacky return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(), 5668212904Sdim Target.get()); 5669198092Srdivacky} 5670198092Srdivacky 5671198092Srdivackytemplate<typename Derived> 5672212904SdimStmtResult 5673198092SrdivackyTreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) { 5674218893Sdim return SemaRef.Owned(S); 5675198092Srdivacky} 5676198092Srdivacky 5677198092Srdivackytemplate<typename Derived> 5678212904SdimStmtResult 5679198092SrdivackyTreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) { 5680218893Sdim return SemaRef.Owned(S); 5681198092Srdivacky} 5682198092Srdivacky 5683198092Srdivackytemplate<typename Derived> 5684212904SdimStmtResult 5685198092SrdivackyTreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) { 5686212904Sdim ExprResult Result = getDerived().TransformExpr(S->getRetValue()); 5687198092Srdivacky if (Result.isInvalid()) 5688212904Sdim return StmtError(); 5689198092Srdivacky 5690198092Srdivacky // FIXME: We always rebuild the return statement because there is no way 5691198092Srdivacky // to tell whether the return type of the function has changed. 5692212904Sdim return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get()); 5693198092Srdivacky} 5694198092Srdivacky 5695198092Srdivackytemplate<typename Derived> 5696212904SdimStmtResult 5697198092SrdivackyTreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) { 5698198092Srdivacky bool DeclChanged = false; 5699226633Sdim SmallVector<Decl *, 4> Decls; 5700198092Srdivacky for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end(); 5701198092Srdivacky D != DEnd; ++D) { 5702204643Srdivacky Decl *Transformed = getDerived().TransformDefinition((*D)->getLocation(), 5703204643Srdivacky *D); 5704198092Srdivacky if (!Transformed) 5705212904Sdim return StmtError(); 5706198092Srdivacky 5707198092Srdivacky if (Transformed != *D) 5708198092Srdivacky DeclChanged = true; 5709198092Srdivacky 5710198092Srdivacky Decls.push_back(Transformed); 5711198092Srdivacky } 5712198092Srdivacky 5713198092Srdivacky if (!getDerived().AlwaysRebuild() && !DeclChanged) 5714218893Sdim return SemaRef.Owned(S); 5715198092Srdivacky 5716263508Sdim return getDerived().RebuildDeclStmt(Decls, S->getStartLoc(), S->getEndLoc()); 5717198092Srdivacky} 5718198092Srdivacky 5719198092Srdivackytemplate<typename Derived> 5720212904SdimStmtResult 5721243830SdimTreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) { 5722239462Sdim 5723243830Sdim SmallVector<Expr*, 8> Constraints; 5724243830Sdim SmallVector<Expr*, 8> Exprs; 5725226633Sdim SmallVector<IdentifierInfo *, 4> Names; 5726203955Srdivacky 5727212904Sdim ExprResult AsmString; 5728243830Sdim SmallVector<Expr*, 8> Clobbers; 5729203955Srdivacky 5730203955Srdivacky bool ExprsChanged = false; 5731239462Sdim 5732203955Srdivacky // Go through the outputs. 5733203955Srdivacky for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) { 5734203955Srdivacky Names.push_back(S->getOutputIdentifier(I)); 5735239462Sdim 5736203955Srdivacky // No need to transform the constraint literal. 5737218893Sdim Constraints.push_back(S->getOutputConstraintLiteral(I)); 5738239462Sdim 5739203955Srdivacky // Transform the output expr. 5740203955Srdivacky Expr *OutputExpr = S->getOutputExpr(I); 5741212904Sdim ExprResult Result = getDerived().TransformExpr(OutputExpr); 5742203955Srdivacky if (Result.isInvalid()) 5743212904Sdim return StmtError(); 5744239462Sdim 5745203955Srdivacky ExprsChanged |= Result.get() != OutputExpr; 5746239462Sdim 5747212904Sdim Exprs.push_back(Result.get()); 5748203955Srdivacky } 5749239462Sdim 5750203955Srdivacky // Go through the inputs. 5751203955Srdivacky for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) { 5752203955Srdivacky Names.push_back(S->getInputIdentifier(I)); 5753239462Sdim 5754203955Srdivacky // No need to transform the constraint literal. 5755218893Sdim Constraints.push_back(S->getInputConstraintLiteral(I)); 5756239462Sdim 5757203955Srdivacky // Transform the input expr. 5758203955Srdivacky Expr *InputExpr = S->getInputExpr(I); 5759212904Sdim ExprResult Result = getDerived().TransformExpr(InputExpr); 5760203955Srdivacky if (Result.isInvalid()) 5761212904Sdim return StmtError(); 5762239462Sdim 5763203955Srdivacky ExprsChanged |= Result.get() != InputExpr; 5764239462Sdim 5765212904Sdim Exprs.push_back(Result.get()); 5766203955Srdivacky } 5767239462Sdim 5768203955Srdivacky if (!getDerived().AlwaysRebuild() && !ExprsChanged) 5769218893Sdim return SemaRef.Owned(S); 5770203955Srdivacky 5771203955Srdivacky // Go through the clobbers. 5772203955Srdivacky for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) 5773243830Sdim Clobbers.push_back(S->getClobberStringLiteral(I)); 5774203955Srdivacky 5775203955Srdivacky // No need to transform the asm string literal. 5776203955Srdivacky AsmString = SemaRef.Owned(S->getAsmString()); 5777243830Sdim return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(), 5778243830Sdim S->isVolatile(), S->getNumOutputs(), 5779243830Sdim S->getNumInputs(), Names.data(), 5780243830Sdim Constraints, Exprs, AsmString.get(), 5781243830Sdim Clobbers, S->getRParenLoc()); 5782198092Srdivacky} 5783198092Srdivacky 5784239462Sdimtemplate<typename Derived> 5785239462SdimStmtResult 5786239462SdimTreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) { 5787239462Sdim ArrayRef<Token> AsmToks = 5788239462Sdim llvm::makeArrayRef(S->getAsmToks(), S->getNumAsmToks()); 5789198092Srdivacky 5790251662Sdim bool HadError = false, HadChange = false; 5791251662Sdim 5792251662Sdim ArrayRef<Expr*> SrcExprs = S->getAllExprs(); 5793251662Sdim SmallVector<Expr*, 8> TransformedExprs; 5794251662Sdim TransformedExprs.reserve(SrcExprs.size()); 5795251662Sdim for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) { 5796251662Sdim ExprResult Result = getDerived().TransformExpr(SrcExprs[i]); 5797251662Sdim if (!Result.isUsable()) { 5798251662Sdim HadError = true; 5799251662Sdim } else { 5800251662Sdim HadChange |= (Result.get() != SrcExprs[i]); 5801251662Sdim TransformedExprs.push_back(Result.take()); 5802251662Sdim } 5803251662Sdim } 5804251662Sdim 5805251662Sdim if (HadError) return StmtError(); 5806251662Sdim if (!HadChange && !getDerived().AlwaysRebuild()) 5807251662Sdim return Owned(S); 5808251662Sdim 5809239462Sdim return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(), 5810251662Sdim AsmToks, S->getAsmString(), 5811251662Sdim S->getNumOutputs(), S->getNumInputs(), 5812251662Sdim S->getAllConstraints(), S->getClobbers(), 5813251662Sdim TransformedExprs, S->getEndLoc()); 5814239462Sdim} 5815239462Sdim 5816198092Srdivackytemplate<typename Derived> 5817212904SdimStmtResult 5818198092SrdivackyTreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) { 5819207619Srdivacky // Transform the body of the @try. 5820212904Sdim StmtResult TryBody = getDerived().TransformStmt(S->getTryBody()); 5821207619Srdivacky if (TryBody.isInvalid()) 5822212904Sdim return StmtError(); 5823239462Sdim 5824207619Srdivacky // Transform the @catch statements (if present). 5825207619Srdivacky bool AnyCatchChanged = false; 5826243830Sdim SmallVector<Stmt*, 8> CatchStmts; 5827207619Srdivacky for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) { 5828212904Sdim StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I)); 5829207619Srdivacky if (Catch.isInvalid()) 5830212904Sdim return StmtError(); 5831207619Srdivacky if (Catch.get() != S->getCatchStmt(I)) 5832207619Srdivacky AnyCatchChanged = true; 5833207619Srdivacky CatchStmts.push_back(Catch.release()); 5834207619Srdivacky } 5835239462Sdim 5836207619Srdivacky // Transform the @finally statement (if present). 5837212904Sdim StmtResult Finally; 5838207619Srdivacky if (S->getFinallyStmt()) { 5839207619Srdivacky Finally = getDerived().TransformStmt(S->getFinallyStmt()); 5840207619Srdivacky if (Finally.isInvalid()) 5841212904Sdim return StmtError(); 5842207619Srdivacky } 5843207619Srdivacky 5844207619Srdivacky // If nothing changed, just retain this statement. 5845207619Srdivacky if (!getDerived().AlwaysRebuild() && 5846207619Srdivacky TryBody.get() == S->getTryBody() && 5847207619Srdivacky !AnyCatchChanged && 5848207619Srdivacky Finally.get() == S->getFinallyStmt()) 5849218893Sdim return SemaRef.Owned(S); 5850239462Sdim 5851207619Srdivacky // Build a new statement. 5852212904Sdim return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(), 5853243830Sdim CatchStmts, Finally.get()); 5854198092Srdivacky} 5855198092Srdivacky 5856198092Srdivackytemplate<typename Derived> 5857212904SdimStmtResult 5858198092SrdivackyTreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) { 5859207619Srdivacky // Transform the @catch parameter, if there is one. 5860207619Srdivacky VarDecl *Var = 0; 5861207619Srdivacky if (VarDecl *FromVar = S->getCatchParamDecl()) { 5862207619Srdivacky TypeSourceInfo *TSInfo = 0; 5863207619Srdivacky if (FromVar->getTypeSourceInfo()) { 5864207619Srdivacky TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo()); 5865207619Srdivacky if (!TSInfo) 5866212904Sdim return StmtError(); 5867207619Srdivacky } 5868239462Sdim 5869207619Srdivacky QualType T; 5870207619Srdivacky if (TSInfo) 5871207619Srdivacky T = TSInfo->getType(); 5872207619Srdivacky else { 5873207619Srdivacky T = getDerived().TransformType(FromVar->getType()); 5874207619Srdivacky if (T.isNull()) 5875239462Sdim return StmtError(); 5876207619Srdivacky } 5877239462Sdim 5878207619Srdivacky Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T); 5879207619Srdivacky if (!Var) 5880212904Sdim return StmtError(); 5881207619Srdivacky } 5882239462Sdim 5883212904Sdim StmtResult Body = getDerived().TransformStmt(S->getCatchBody()); 5884207619Srdivacky if (Body.isInvalid()) 5885212904Sdim return StmtError(); 5886239462Sdim 5887239462Sdim return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(), 5888207619Srdivacky S->getRParenLoc(), 5889212904Sdim Var, Body.get()); 5890198092Srdivacky} 5891198092Srdivacky 5892198092Srdivackytemplate<typename Derived> 5893212904SdimStmtResult 5894198092SrdivackyTreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) { 5895207619Srdivacky // Transform the body. 5896212904Sdim StmtResult Body = getDerived().TransformStmt(S->getFinallyBody()); 5897207619Srdivacky if (Body.isInvalid()) 5898212904Sdim return StmtError(); 5899239462Sdim 5900207619Srdivacky // If nothing changed, just retain this statement. 5901207619Srdivacky if (!getDerived().AlwaysRebuild() && 5902207619Srdivacky Body.get() == S->getFinallyBody()) 5903218893Sdim return SemaRef.Owned(S); 5904207619Srdivacky 5905207619Srdivacky // Build a new statement. 5906207619Srdivacky return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(), 5907212904Sdim Body.get()); 5908198092Srdivacky} 5909198092Srdivacky 5910198092Srdivackytemplate<typename Derived> 5911212904SdimStmtResult 5912198092SrdivackyTreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) { 5913212904Sdim ExprResult Operand; 5914207619Srdivacky if (S->getThrowExpr()) { 5915207619Srdivacky Operand = getDerived().TransformExpr(S->getThrowExpr()); 5916207619Srdivacky if (Operand.isInvalid()) 5917212904Sdim return StmtError(); 5918207619Srdivacky } 5919239462Sdim 5920207619Srdivacky if (!getDerived().AlwaysRebuild() && 5921207619Srdivacky Operand.get() == S->getThrowExpr()) 5922218893Sdim return getSema().Owned(S); 5923239462Sdim 5924212904Sdim return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get()); 5925198092Srdivacky} 5926198092Srdivacky 5927198092Srdivackytemplate<typename Derived> 5928212904SdimStmtResult 5929198092SrdivackyTreeTransform<Derived>::TransformObjCAtSynchronizedStmt( 5930198092Srdivacky ObjCAtSynchronizedStmt *S) { 5931207619Srdivacky // Transform the object we are locking. 5932212904Sdim ExprResult Object = getDerived().TransformExpr(S->getSynchExpr()); 5933207619Srdivacky if (Object.isInvalid()) 5934212904Sdim return StmtError(); 5935226633Sdim Object = 5936226633Sdim getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(), 5937226633Sdim Object.get()); 5938226633Sdim if (Object.isInvalid()) 5939226633Sdim return StmtError(); 5940239462Sdim 5941207619Srdivacky // Transform the body. 5942212904Sdim StmtResult Body = getDerived().TransformStmt(S->getSynchBody()); 5943207619Srdivacky if (Body.isInvalid()) 5944212904Sdim return StmtError(); 5945239462Sdim 5946207619Srdivacky // If nothing change, just retain the current statement. 5947207619Srdivacky if (!getDerived().AlwaysRebuild() && 5948207619Srdivacky Object.get() == S->getSynchExpr() && 5949207619Srdivacky Body.get() == S->getSynchBody()) 5950218893Sdim return SemaRef.Owned(S); 5951207619Srdivacky 5952207619Srdivacky // Build a new statement. 5953207619Srdivacky return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(), 5954212904Sdim Object.get(), Body.get()); 5955198092Srdivacky} 5956198092Srdivacky 5957198092Srdivackytemplate<typename Derived> 5958212904SdimStmtResult 5959224145SdimTreeTransform<Derived>::TransformObjCAutoreleasePoolStmt( 5960224145Sdim ObjCAutoreleasePoolStmt *S) { 5961224145Sdim // Transform the body. 5962224145Sdim StmtResult Body = getDerived().TransformStmt(S->getSubStmt()); 5963224145Sdim if (Body.isInvalid()) 5964224145Sdim return StmtError(); 5965239462Sdim 5966224145Sdim // If nothing changed, just retain this statement. 5967224145Sdim if (!getDerived().AlwaysRebuild() && 5968224145Sdim Body.get() == S->getSubStmt()) 5969224145Sdim return SemaRef.Owned(S); 5970224145Sdim 5971224145Sdim // Build a new statement. 5972224145Sdim return getDerived().RebuildObjCAutoreleasePoolStmt( 5973224145Sdim S->getAtLoc(), Body.get()); 5974224145Sdim} 5975224145Sdim 5976224145Sdimtemplate<typename Derived> 5977224145SdimStmtResult 5978198092SrdivackyTreeTransform<Derived>::TransformObjCForCollectionStmt( 5979198092Srdivacky ObjCForCollectionStmt *S) { 5980207619Srdivacky // Transform the element statement. 5981212904Sdim StmtResult Element = getDerived().TransformStmt(S->getElement()); 5982207619Srdivacky if (Element.isInvalid()) 5983212904Sdim return StmtError(); 5984239462Sdim 5985207619Srdivacky // Transform the collection expression. 5986212904Sdim ExprResult Collection = getDerived().TransformExpr(S->getCollection()); 5987207619Srdivacky if (Collection.isInvalid()) 5988212904Sdim return StmtError(); 5989239462Sdim 5990207619Srdivacky // Transform the body. 5991212904Sdim StmtResult Body = getDerived().TransformStmt(S->getBody()); 5992207619Srdivacky if (Body.isInvalid()) 5993212904Sdim return StmtError(); 5994239462Sdim 5995207619Srdivacky // If nothing changed, just retain this statement. 5996207619Srdivacky if (!getDerived().AlwaysRebuild() && 5997207619Srdivacky Element.get() == S->getElement() && 5998207619Srdivacky Collection.get() == S->getCollection() && 5999207619Srdivacky Body.get() == S->getBody()) 6000218893Sdim return SemaRef.Owned(S); 6001239462Sdim 6002207619Srdivacky // Build a new statement. 6003207619Srdivacky return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(), 6004212904Sdim Element.get(), 6005212904Sdim Collection.get(), 6006207619Srdivacky S->getRParenLoc(), 6007212904Sdim Body.get()); 6008198092Srdivacky} 6009198092Srdivacky 6010263508Sdimtemplate <typename Derived> 6011263508SdimStmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) { 6012198092Srdivacky // Transform the exception declaration, if any. 6013198092Srdivacky VarDecl *Var = 0; 6014263508Sdim if (VarDecl *ExceptionDecl = S->getExceptionDecl()) { 6015263508Sdim TypeSourceInfo *T = 6016263508Sdim getDerived().TransformType(ExceptionDecl->getTypeSourceInfo()); 6017218893Sdim if (!T) 6018212904Sdim return StmtError(); 6019198092Srdivacky 6020263508Sdim Var = getDerived().RebuildExceptionDecl( 6021263508Sdim ExceptionDecl, T, ExceptionDecl->getInnerLocStart(), 6022263508Sdim ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier()); 6023212904Sdim if (!Var || Var->isInvalidDecl()) 6024212904Sdim return StmtError(); 6025198092Srdivacky } 6026198092Srdivacky 6027198092Srdivacky // Transform the actual exception handler. 6028212904Sdim StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock()); 6029212904Sdim if (Handler.isInvalid()) 6030212904Sdim return StmtError(); 6031198092Srdivacky 6032263508Sdim if (!getDerived().AlwaysRebuild() && !Var && 6033198092Srdivacky Handler.get() == S->getHandlerBlock()) 6034218893Sdim return SemaRef.Owned(S); 6035198092Srdivacky 6036263508Sdim return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get()); 6037198092Srdivacky} 6038198092Srdivacky 6039263508Sdimtemplate <typename Derived> 6040263508SdimStmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) { 6041198092Srdivacky // Transform the try block itself. 6042263508Sdim StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock()); 6043198092Srdivacky if (TryBlock.isInvalid()) 6044212904Sdim return StmtError(); 6045198092Srdivacky 6046198092Srdivacky // Transform the handlers. 6047198092Srdivacky bool HandlerChanged = false; 6048263508Sdim SmallVector<Stmt *, 8> Handlers; 6049198092Srdivacky for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) { 6050263508Sdim StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(I)); 6051198092Srdivacky if (Handler.isInvalid()) 6052212904Sdim return StmtError(); 6053198092Srdivacky 6054198092Srdivacky HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I); 6055198092Srdivacky Handlers.push_back(Handler.takeAs<Stmt>()); 6056198092Srdivacky } 6057198092Srdivacky 6058263508Sdim if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() && 6059198092Srdivacky !HandlerChanged) 6060218893Sdim return SemaRef.Owned(S); 6061198092Srdivacky 6062212904Sdim return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(), 6063243830Sdim Handlers); 6064198092Srdivacky} 6065198092Srdivacky 6066221345Sdimtemplate<typename Derived> 6067221345SdimStmtResult 6068221345SdimTreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) { 6069221345Sdim StmtResult Range = getDerived().TransformStmt(S->getRangeStmt()); 6070221345Sdim if (Range.isInvalid()) 6071221345Sdim return StmtError(); 6072221345Sdim 6073221345Sdim StmtResult BeginEnd = getDerived().TransformStmt(S->getBeginEndStmt()); 6074221345Sdim if (BeginEnd.isInvalid()) 6075221345Sdim return StmtError(); 6076221345Sdim 6077221345Sdim ExprResult Cond = getDerived().TransformExpr(S->getCond()); 6078221345Sdim if (Cond.isInvalid()) 6079221345Sdim return StmtError(); 6080234353Sdim if (Cond.get()) 6081234353Sdim Cond = SemaRef.CheckBooleanCondition(Cond.take(), S->getColonLoc()); 6082234353Sdim if (Cond.isInvalid()) 6083234353Sdim return StmtError(); 6084234353Sdim if (Cond.get()) 6085234353Sdim Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.take()); 6086221345Sdim 6087221345Sdim ExprResult Inc = getDerived().TransformExpr(S->getInc()); 6088221345Sdim if (Inc.isInvalid()) 6089221345Sdim return StmtError(); 6090234353Sdim if (Inc.get()) 6091234353Sdim Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.take()); 6092221345Sdim 6093221345Sdim StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt()); 6094221345Sdim if (LoopVar.isInvalid()) 6095221345Sdim return StmtError(); 6096221345Sdim 6097221345Sdim StmtResult NewStmt = S; 6098221345Sdim if (getDerived().AlwaysRebuild() || 6099221345Sdim Range.get() != S->getRangeStmt() || 6100221345Sdim BeginEnd.get() != S->getBeginEndStmt() || 6101221345Sdim Cond.get() != S->getCond() || 6102221345Sdim Inc.get() != S->getInc() || 6103251662Sdim LoopVar.get() != S->getLoopVarStmt()) { 6104221345Sdim NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(), 6105221345Sdim S->getColonLoc(), Range.get(), 6106221345Sdim BeginEnd.get(), Cond.get(), 6107221345Sdim Inc.get(), LoopVar.get(), 6108221345Sdim S->getRParenLoc()); 6109251662Sdim if (NewStmt.isInvalid()) 6110251662Sdim return StmtError(); 6111251662Sdim } 6112221345Sdim 6113221345Sdim StmtResult Body = getDerived().TransformStmt(S->getBody()); 6114221345Sdim if (Body.isInvalid()) 6115221345Sdim return StmtError(); 6116221345Sdim 6117221345Sdim // Body has changed but we didn't rebuild the for-range statement. Rebuild 6118221345Sdim // it now so we have a new statement to attach the body to. 6119251662Sdim if (Body.get() != S->getBody() && NewStmt.get() == S) { 6120221345Sdim NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(), 6121221345Sdim S->getColonLoc(), Range.get(), 6122221345Sdim BeginEnd.get(), Cond.get(), 6123221345Sdim Inc.get(), LoopVar.get(), 6124221345Sdim S->getRParenLoc()); 6125251662Sdim if (NewStmt.isInvalid()) 6126251662Sdim return StmtError(); 6127251662Sdim } 6128221345Sdim 6129221345Sdim if (NewStmt.get() == S) 6130221345Sdim return SemaRef.Owned(S); 6131221345Sdim 6132221345Sdim return FinishCXXForRangeStmt(NewStmt.get(), Body.get()); 6133221345Sdim} 6134221345Sdim 6135221345Sdimtemplate<typename Derived> 6136221345SdimStmtResult 6137234353SdimTreeTransform<Derived>::TransformMSDependentExistsStmt( 6138234353Sdim MSDependentExistsStmt *S) { 6139234353Sdim // Transform the nested-name-specifier, if any. 6140234353Sdim NestedNameSpecifierLoc QualifierLoc; 6141234353Sdim if (S->getQualifierLoc()) { 6142239462Sdim QualifierLoc 6143234353Sdim = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc()); 6144234353Sdim if (!QualifierLoc) 6145234353Sdim return StmtError(); 6146234353Sdim } 6147234353Sdim 6148234353Sdim // Transform the declaration name. 6149234353Sdim DeclarationNameInfo NameInfo = S->getNameInfo(); 6150234353Sdim if (NameInfo.getName()) { 6151234353Sdim NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); 6152234353Sdim if (!NameInfo.getName()) 6153234353Sdim return StmtError(); 6154234353Sdim } 6155234353Sdim 6156234353Sdim // Check whether anything changed. 6157234353Sdim if (!getDerived().AlwaysRebuild() && 6158234353Sdim QualifierLoc == S->getQualifierLoc() && 6159234353Sdim NameInfo.getName() == S->getNameInfo().getName()) 6160234353Sdim return S; 6161239462Sdim 6162234353Sdim // Determine whether this name exists, if we can. 6163234353Sdim CXXScopeSpec SS; 6164234353Sdim SS.Adopt(QualifierLoc); 6165234353Sdim bool Dependent = false; 6166234353Sdim switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/0, SS, NameInfo)) { 6167234353Sdim case Sema::IER_Exists: 6168234353Sdim if (S->isIfExists()) 6169234353Sdim break; 6170239462Sdim 6171234353Sdim return new (getSema().Context) NullStmt(S->getKeywordLoc()); 6172234353Sdim 6173234353Sdim case Sema::IER_DoesNotExist: 6174234353Sdim if (S->isIfNotExists()) 6175234353Sdim break; 6176239462Sdim 6177234353Sdim return new (getSema().Context) NullStmt(S->getKeywordLoc()); 6178239462Sdim 6179234353Sdim case Sema::IER_Dependent: 6180234353Sdim Dependent = true; 6181234353Sdim break; 6182239462Sdim 6183234353Sdim case Sema::IER_Error: 6184234353Sdim return StmtError(); 6185234353Sdim } 6186239462Sdim 6187234353Sdim // We need to continue with the instantiation, so do so now. 6188234353Sdim StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt()); 6189234353Sdim if (SubStmt.isInvalid()) 6190234353Sdim return StmtError(); 6191239462Sdim 6192234353Sdim // If we have resolved the name, just transform to the substatement. 6193234353Sdim if (!Dependent) 6194234353Sdim return SubStmt; 6195239462Sdim 6196234353Sdim // The name is still dependent, so build a dependent expression again. 6197234353Sdim return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(), 6198234353Sdim S->isIfExists(), 6199234353Sdim QualifierLoc, 6200234353Sdim NameInfo, 6201234353Sdim SubStmt.get()); 6202234353Sdim} 6203234353Sdim 6204234353Sdimtemplate<typename Derived> 6205251662SdimExprResult 6206251662SdimTreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) { 6207251662Sdim NestedNameSpecifierLoc QualifierLoc; 6208251662Sdim if (E->getQualifierLoc()) { 6209251662Sdim QualifierLoc 6210251662Sdim = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); 6211251662Sdim if (!QualifierLoc) 6212251662Sdim return ExprError(); 6213251662Sdim } 6214251662Sdim 6215251662Sdim MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>( 6216251662Sdim getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl())); 6217251662Sdim if (!PD) 6218251662Sdim return ExprError(); 6219251662Sdim 6220251662Sdim ExprResult Base = getDerived().TransformExpr(E->getBaseExpr()); 6221251662Sdim if (Base.isInvalid()) 6222251662Sdim return ExprError(); 6223251662Sdim 6224251662Sdim return new (SemaRef.getASTContext()) 6225251662Sdim MSPropertyRefExpr(Base.get(), PD, E->isArrow(), 6226251662Sdim SemaRef.getASTContext().PseudoObjectTy, VK_LValue, 6227251662Sdim QualifierLoc, E->getMemberLoc()); 6228251662Sdim} 6229251662Sdim 6230263508Sdimtemplate <typename Derived> 6231263508SdimStmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) { 6232263508Sdim StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock()); 6233263508Sdim if (TryBlock.isInvalid()) 6234263508Sdim return StmtError(); 6235221345Sdim 6236221345Sdim StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler()); 6237263508Sdim if (Handler.isInvalid()) 6238263508Sdim return StmtError(); 6239263508Sdim 6240263508Sdim if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() && 6241263508Sdim Handler.get() == S->getHandler()) 6242221345Sdim return SemaRef.Owned(S); 6243221345Sdim 6244263508Sdim return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(), 6245263508Sdim TryBlock.take(), Handler.take()); 6246221345Sdim} 6247221345Sdim 6248263508Sdimtemplate <typename Derived> 6249263508SdimStmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) { 6250263508Sdim StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock()); 6251263508Sdim if (Block.isInvalid()) 6252263508Sdim return StmtError(); 6253221345Sdim 6254263508Sdim return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.take()); 6255221345Sdim} 6256221345Sdim 6257263508Sdimtemplate <typename Derived> 6258263508SdimStmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) { 6259221345Sdim ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr()); 6260263508Sdim if (FilterExpr.isInvalid()) 6261263508Sdim return StmtError(); 6262221345Sdim 6263263508Sdim StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock()); 6264263508Sdim if (Block.isInvalid()) 6265263508Sdim return StmtError(); 6266221345Sdim 6267263508Sdim return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.take(), 6268221345Sdim Block.take()); 6269221345Sdim} 6270221345Sdim 6271263508Sdimtemplate <typename Derived> 6272263508SdimStmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) { 6273263508Sdim if (isa<SEHFinallyStmt>(Handler)) 6274221345Sdim return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler)); 6275221345Sdim else 6276221345Sdim return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler)); 6277221345Sdim} 6278221345Sdim 6279263508Sdimtemplate<typename Derived> 6280263508SdimStmtResult 6281263508SdimTreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) { 6282263508Sdim DeclarationNameInfo DirName; 6283263508Sdim getSema().StartOpenMPDSABlock(OMPD_parallel, DirName, 0); 6284263508Sdim 6285263508Sdim // Transform the clauses 6286263508Sdim llvm::SmallVector<OMPClause *, 16> TClauses; 6287263508Sdim ArrayRef<OMPClause *> Clauses = D->clauses(); 6288263508Sdim TClauses.reserve(Clauses.size()); 6289263508Sdim for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); 6290263508Sdim I != E; ++I) { 6291263508Sdim if (*I) { 6292263508Sdim OMPClause *Clause = getDerived().TransformOMPClause(*I); 6293263508Sdim if (!Clause) { 6294263508Sdim getSema().EndOpenMPDSABlock(0); 6295263508Sdim return StmtError(); 6296263508Sdim } 6297263508Sdim TClauses.push_back(Clause); 6298263508Sdim } 6299263508Sdim else { 6300263508Sdim TClauses.push_back(0); 6301263508Sdim } 6302263508Sdim } 6303263508Sdim if (!D->getAssociatedStmt()) { 6304263508Sdim getSema().EndOpenMPDSABlock(0); 6305263508Sdim return StmtError(); 6306263508Sdim } 6307263508Sdim StmtResult AssociatedStmt = 6308263508Sdim getDerived().TransformStmt(D->getAssociatedStmt()); 6309263508Sdim if (AssociatedStmt.isInvalid()) { 6310263508Sdim getSema().EndOpenMPDSABlock(0); 6311263508Sdim return StmtError(); 6312263508Sdim } 6313263508Sdim 6314263508Sdim StmtResult Res = getDerived().RebuildOMPParallelDirective(TClauses, 6315263508Sdim AssociatedStmt.take(), 6316263508Sdim D->getLocStart(), 6317263508Sdim D->getLocEnd()); 6318263508Sdim getSema().EndOpenMPDSABlock(Res.get()); 6319263508Sdim return Res; 6320263508Sdim} 6321263508Sdim 6322263508Sdimtemplate<typename Derived> 6323263508SdimOMPClause * 6324263508SdimTreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) { 6325263508Sdim return getDerived().RebuildOMPDefaultClause(C->getDefaultKind(), 6326263508Sdim C->getDefaultKindKwLoc(), 6327263508Sdim C->getLocStart(), 6328263508Sdim C->getLParenLoc(), 6329263508Sdim C->getLocEnd()); 6330263508Sdim} 6331263508Sdim 6332263508Sdimtemplate<typename Derived> 6333263508SdimOMPClause * 6334263508SdimTreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) { 6335263508Sdim llvm::SmallVector<Expr *, 16> Vars; 6336263508Sdim Vars.reserve(C->varlist_size()); 6337263508Sdim for (OMPPrivateClause::varlist_iterator I = C->varlist_begin(), 6338263508Sdim E = C->varlist_end(); 6339263508Sdim I != E; ++I) { 6340263508Sdim ExprResult EVar = getDerived().TransformExpr(cast<Expr>(*I)); 6341263508Sdim if (EVar.isInvalid()) 6342263508Sdim return 0; 6343263508Sdim Vars.push_back(EVar.take()); 6344263508Sdim } 6345263508Sdim return getDerived().RebuildOMPPrivateClause(Vars, 6346263508Sdim C->getLocStart(), 6347263508Sdim C->getLParenLoc(), 6348263508Sdim C->getLocEnd()); 6349263508Sdim} 6350263508Sdim 6351263508Sdimtemplate<typename Derived> 6352263508SdimOMPClause * 6353263508SdimTreeTransform<Derived>::TransformOMPFirstprivateClause( 6354263508Sdim OMPFirstprivateClause *C) { 6355263508Sdim llvm::SmallVector<Expr *, 16> Vars; 6356263508Sdim Vars.reserve(C->varlist_size()); 6357263508Sdim for (OMPFirstprivateClause::varlist_iterator I = C->varlist_begin(), 6358263508Sdim E = C->varlist_end(); 6359263508Sdim I != E; ++I) { 6360263508Sdim ExprResult EVar = getDerived().TransformExpr(cast<Expr>(*I)); 6361263508Sdim if (EVar.isInvalid()) 6362263508Sdim return 0; 6363263508Sdim Vars.push_back(EVar.take()); 6364263508Sdim } 6365263508Sdim return getDerived().RebuildOMPFirstprivateClause(Vars, 6366263508Sdim C->getLocStart(), 6367263508Sdim C->getLParenLoc(), 6368263508Sdim C->getLocEnd()); 6369263508Sdim} 6370263508Sdim 6371263508Sdimtemplate<typename Derived> 6372263508SdimOMPClause * 6373263508SdimTreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) { 6374263508Sdim llvm::SmallVector<Expr *, 16> Vars; 6375263508Sdim Vars.reserve(C->varlist_size()); 6376263508Sdim for (OMPSharedClause::varlist_iterator I = C->varlist_begin(), 6377263508Sdim E = C->varlist_end(); 6378263508Sdim I != E; ++I) { 6379263508Sdim ExprResult EVar = getDerived().TransformExpr(cast<Expr>(*I)); 6380263508Sdim if (EVar.isInvalid()) 6381263508Sdim return 0; 6382263508Sdim Vars.push_back(EVar.take()); 6383263508Sdim } 6384263508Sdim return getDerived().RebuildOMPSharedClause(Vars, 6385263508Sdim C->getLocStart(), 6386263508Sdim C->getLParenLoc(), 6387263508Sdim C->getLocEnd()); 6388263508Sdim} 6389263508Sdim 6390198092Srdivacky//===----------------------------------------------------------------------===// 6391198092Srdivacky// Expression transformation 6392198092Srdivacky//===----------------------------------------------------------------------===// 6393198092Srdivackytemplate<typename Derived> 6394212904SdimExprResult 6395200583SrdivackyTreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) { 6396218893Sdim return SemaRef.Owned(E); 6397198092Srdivacky} 6398198092Srdivacky 6399198092Srdivackytemplate<typename Derived> 6400212904SdimExprResult 6401200583SrdivackyTreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) { 6402221345Sdim NestedNameSpecifierLoc QualifierLoc; 6403221345Sdim if (E->getQualifierLoc()) { 6404221345Sdim QualifierLoc 6405221345Sdim = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); 6406221345Sdim if (!QualifierLoc) 6407212904Sdim return ExprError(); 6408198893Srdivacky } 6409200583Srdivacky 6410200583Srdivacky ValueDecl *ND 6411204643Srdivacky = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(), 6412204643Srdivacky E->getDecl())); 6413198092Srdivacky if (!ND) 6414212904Sdim return ExprError(); 6415198092Srdivacky 6416212904Sdim DeclarationNameInfo NameInfo = E->getNameInfo(); 6417212904Sdim if (NameInfo.getName()) { 6418212904Sdim NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo); 6419212904Sdim if (!NameInfo.getName()) 6420212904Sdim return ExprError(); 6421212904Sdim } 6422212904Sdim 6423212904Sdim if (!getDerived().AlwaysRebuild() && 6424221345Sdim QualifierLoc == E->getQualifierLoc() && 6425198893Srdivacky ND == E->getDecl() && 6426212904Sdim NameInfo.getName() == E->getDecl()->getDeclName() && 6427212904Sdim !E->hasExplicitTemplateArgs()) { 6428200583Srdivacky 6429200583Srdivacky // Mark it referenced in the new context regardless. 6430200583Srdivacky // FIXME: this is a bit instantiation-specific. 6431234353Sdim SemaRef.MarkDeclRefReferenced(E); 6432200583Srdivacky 6433218893Sdim return SemaRef.Owned(E); 6434200583Srdivacky } 6435198092Srdivacky 6436200583Srdivacky TemplateArgumentListInfo TransArgs, *TemplateArgs = 0; 6437212904Sdim if (E->hasExplicitTemplateArgs()) { 6438200583Srdivacky TemplateArgs = &TransArgs; 6439200583Srdivacky TransArgs.setLAngleLoc(E->getLAngleLoc()); 6440200583Srdivacky TransArgs.setRAngleLoc(E->getRAngleLoc()); 6441218893Sdim if (getDerived().TransformTemplateArguments(E->getTemplateArgs(), 6442218893Sdim E->getNumTemplateArgs(), 6443218893Sdim TransArgs)) 6444218893Sdim return ExprError(); 6445200583Srdivacky } 6446198893Srdivacky 6447239462Sdim return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo, 6448221345Sdim TemplateArgs); 6449198092Srdivacky} 6450198092Srdivacky 6451198092Srdivackytemplate<typename Derived> 6452212904SdimExprResult 6453200583SrdivackyTreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) { 6454218893Sdim return SemaRef.Owned(E); 6455198092Srdivacky} 6456198092Srdivacky 6457198092Srdivackytemplate<typename Derived> 6458212904SdimExprResult 6459200583SrdivackyTreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) { 6460218893Sdim return SemaRef.Owned(E); 6461198092Srdivacky} 6462198092Srdivacky 6463198092Srdivackytemplate<typename Derived> 6464212904SdimExprResult 6465200583SrdivackyTreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) { 6466218893Sdim return SemaRef.Owned(E); 6467198092Srdivacky} 6468198092Srdivacky 6469198092Srdivackytemplate<typename Derived> 6470212904SdimExprResult 6471200583SrdivackyTreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) { 6472218893Sdim return SemaRef.Owned(E); 6473198092Srdivacky} 6474198092Srdivacky 6475198092Srdivackytemplate<typename Derived> 6476212904SdimExprResult 6477200583SrdivackyTreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) { 6478218893Sdim return SemaRef.Owned(E); 6479198092Srdivacky} 6480198092Srdivacky 6481198092Srdivackytemplate<typename Derived> 6482212904SdimExprResult 6483234353SdimTreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) { 6484251662Sdim if (FunctionDecl *FD = E->getDirectCallee()) 6485251662Sdim SemaRef.MarkFunctionReferenced(E->getLocStart(), FD); 6486234353Sdim return SemaRef.MaybeBindToTemporary(E); 6487234353Sdim} 6488234353Sdim 6489234353Sdimtemplate<typename Derived> 6490234353SdimExprResult 6491221345SdimTreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) { 6492221345Sdim ExprResult ControllingExpr = 6493221345Sdim getDerived().TransformExpr(E->getControllingExpr()); 6494221345Sdim if (ControllingExpr.isInvalid()) 6495221345Sdim return ExprError(); 6496221345Sdim 6497226633Sdim SmallVector<Expr *, 4> AssocExprs; 6498226633Sdim SmallVector<TypeSourceInfo *, 4> AssocTypes; 6499221345Sdim for (unsigned i = 0; i != E->getNumAssocs(); ++i) { 6500221345Sdim TypeSourceInfo *TS = E->getAssocTypeSourceInfo(i); 6501221345Sdim if (TS) { 6502221345Sdim TypeSourceInfo *AssocType = getDerived().TransformType(TS); 6503221345Sdim if (!AssocType) 6504221345Sdim return ExprError(); 6505221345Sdim AssocTypes.push_back(AssocType); 6506221345Sdim } else { 6507221345Sdim AssocTypes.push_back(0); 6508221345Sdim } 6509221345Sdim 6510221345Sdim ExprResult AssocExpr = getDerived().TransformExpr(E->getAssocExpr(i)); 6511221345Sdim if (AssocExpr.isInvalid()) 6512221345Sdim return ExprError(); 6513221345Sdim AssocExprs.push_back(AssocExpr.release()); 6514221345Sdim } 6515221345Sdim 6516221345Sdim return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(), 6517221345Sdim E->getDefaultLoc(), 6518221345Sdim E->getRParenLoc(), 6519221345Sdim ControllingExpr.release(), 6520263508Sdim AssocTypes, 6521263508Sdim AssocExprs); 6522221345Sdim} 6523221345Sdim 6524221345Sdimtemplate<typename Derived> 6525221345SdimExprResult 6526200583SrdivackyTreeTransform<Derived>::TransformParenExpr(ParenExpr *E) { 6527212904Sdim ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); 6528198092Srdivacky if (SubExpr.isInvalid()) 6529212904Sdim return ExprError(); 6530198092Srdivacky 6531198092Srdivacky if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr()) 6532218893Sdim return SemaRef.Owned(E); 6533198092Srdivacky 6534212904Sdim return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(), 6535198092Srdivacky E->getRParen()); 6536198092Srdivacky} 6537198092Srdivacky 6538243830Sdim/// \brief The operand of a unary address-of operator has special rules: it's 6539243830Sdim/// allowed to refer to a non-static member of a class even if there's no 'this' 6540243830Sdim/// object available. 6541198092Srdivackytemplate<typename Derived> 6542212904SdimExprResult 6543243830SdimTreeTransform<Derived>::TransformAddressOfOperand(Expr *E) { 6544243830Sdim if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E)) 6545243830Sdim return getDerived().TransformDependentScopeDeclRefExpr(DRE, true); 6546243830Sdim else 6547243830Sdim return getDerived().TransformExpr(E); 6548243830Sdim} 6549243830Sdim 6550243830Sdimtemplate<typename Derived> 6551243830SdimExprResult 6552200583SrdivackyTreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) { 6553263508Sdim ExprResult SubExpr; 6554263508Sdim if (E->getOpcode() == UO_AddrOf) 6555263508Sdim SubExpr = TransformAddressOfOperand(E->getSubExpr()); 6556263508Sdim else 6557263508Sdim SubExpr = TransformExpr(E->getSubExpr()); 6558198092Srdivacky if (SubExpr.isInvalid()) 6559212904Sdim return ExprError(); 6560198092Srdivacky 6561198092Srdivacky if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr()) 6562218893Sdim return SemaRef.Owned(E); 6563198092Srdivacky 6564198092Srdivacky return getDerived().RebuildUnaryOperator(E->getOperatorLoc(), 6565198092Srdivacky E->getOpcode(), 6566212904Sdim SubExpr.get()); 6567198092Srdivacky} 6568198092Srdivacky 6569198092Srdivackytemplate<typename Derived> 6570212904SdimExprResult 6571207619SrdivackyTreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) { 6572207619Srdivacky // Transform the type. 6573207619Srdivacky TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo()); 6574207619Srdivacky if (!Type) 6575212904Sdim return ExprError(); 6576239462Sdim 6577207619Srdivacky // Transform all of the components into components similar to what the 6578207619Srdivacky // parser uses. 6579239462Sdim // FIXME: It would be slightly more efficient in the non-dependent case to 6580239462Sdim // just map FieldDecls, rather than requiring the rebuilder to look for 6581239462Sdim // the fields again. However, __builtin_offsetof is rare enough in 6582207619Srdivacky // template code that we don't care. 6583207619Srdivacky bool ExprChanged = false; 6584212904Sdim typedef Sema::OffsetOfComponent Component; 6585207619Srdivacky typedef OffsetOfExpr::OffsetOfNode Node; 6586226633Sdim SmallVector<Component, 4> Components; 6587207619Srdivacky for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) { 6588207619Srdivacky const Node &ON = E->getComponent(I); 6589207619Srdivacky Component Comp; 6590207619Srdivacky Comp.isBrackets = true; 6591221345Sdim Comp.LocStart = ON.getSourceRange().getBegin(); 6592221345Sdim Comp.LocEnd = ON.getSourceRange().getEnd(); 6593207619Srdivacky switch (ON.getKind()) { 6594207619Srdivacky case Node::Array: { 6595207619Srdivacky Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex()); 6596212904Sdim ExprResult Index = getDerived().TransformExpr(FromIndex); 6597207619Srdivacky if (Index.isInvalid()) 6598212904Sdim return ExprError(); 6599239462Sdim 6600207619Srdivacky ExprChanged = ExprChanged || Index.get() != FromIndex; 6601207619Srdivacky Comp.isBrackets = true; 6602212904Sdim Comp.U.E = Index.get(); 6603207619Srdivacky break; 6604207619Srdivacky } 6605239462Sdim 6606207619Srdivacky case Node::Field: 6607207619Srdivacky case Node::Identifier: 6608207619Srdivacky Comp.isBrackets = false; 6609207619Srdivacky Comp.U.IdentInfo = ON.getFieldName(); 6610207619Srdivacky if (!Comp.U.IdentInfo) 6611207619Srdivacky continue; 6612239462Sdim 6613207619Srdivacky break; 6614239462Sdim 6615207619Srdivacky case Node::Base: 6616207619Srdivacky // Will be recomputed during the rebuild. 6617207619Srdivacky continue; 6618207619Srdivacky } 6619239462Sdim 6620207619Srdivacky Components.push_back(Comp); 6621207619Srdivacky } 6622239462Sdim 6623207619Srdivacky // If nothing changed, retain the existing expression. 6624207619Srdivacky if (!getDerived().AlwaysRebuild() && 6625207619Srdivacky Type == E->getTypeSourceInfo() && 6626207619Srdivacky !ExprChanged) 6627218893Sdim return SemaRef.Owned(E); 6628239462Sdim 6629207619Srdivacky // Build a new offsetof expression. 6630207619Srdivacky return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type, 6631207619Srdivacky Components.data(), Components.size(), 6632207619Srdivacky E->getRParenLoc()); 6633207619Srdivacky} 6634207619Srdivacky 6635207619Srdivackytemplate<typename Derived> 6636212904SdimExprResult 6637218893SdimTreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) { 6638218893Sdim assert(getDerived().AlreadyTransformed(E->getType()) && 6639218893Sdim "opaque value expression requires transformation"); 6640218893Sdim return SemaRef.Owned(E); 6641218893Sdim} 6642218893Sdim 6643218893Sdimtemplate<typename Derived> 6644218893SdimExprResult 6645234353SdimTreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) { 6646234353Sdim // Rebuild the syntactic form. The original syntactic form has 6647234353Sdim // opaque-value expressions in it, so strip those away and rebuild 6648234353Sdim // the result. This is a really awful way of doing this, but the 6649234353Sdim // better solution (rebuilding the semantic expressions and 6650234353Sdim // rebinding OVEs as necessary) doesn't work; we'd need 6651234353Sdim // TreeTransform to not strip away implicit conversions. 6652234353Sdim Expr *newSyntacticForm = SemaRef.recreateSyntacticForm(E); 6653234353Sdim ExprResult result = getDerived().TransformExpr(newSyntacticForm); 6654234353Sdim if (result.isInvalid()) return ExprError(); 6655234353Sdim 6656234353Sdim // If that gives us a pseudo-object result back, the pseudo-object 6657234353Sdim // expression must have been an lvalue-to-rvalue conversion which we 6658234353Sdim // should reapply. 6659234353Sdim if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject)) 6660234353Sdim result = SemaRef.checkPseudoObjectRValue(result.take()); 6661234353Sdim 6662234353Sdim return result; 6663234353Sdim} 6664234353Sdim 6665234353Sdimtemplate<typename Derived> 6666234353SdimExprResult 6667221345SdimTreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr( 6668221345Sdim UnaryExprOrTypeTraitExpr *E) { 6669198092Srdivacky if (E->isArgumentType()) { 6670200583Srdivacky TypeSourceInfo *OldT = E->getArgumentTypeInfo(); 6671198893Srdivacky 6672200583Srdivacky TypeSourceInfo *NewT = getDerived().TransformType(OldT); 6673198893Srdivacky if (!NewT) 6674212904Sdim return ExprError(); 6675198092Srdivacky 6676198893Srdivacky if (!getDerived().AlwaysRebuild() && OldT == NewT) 6677218893Sdim return SemaRef.Owned(E); 6678198092Srdivacky 6679221345Sdim return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(), 6680221345Sdim E->getKind(), 6681221345Sdim E->getSourceRange()); 6682198092Srdivacky } 6683198092Srdivacky 6684234353Sdim // C++0x [expr.sizeof]p1: 6685234353Sdim // The operand is either an expression, which is an unevaluated operand 6686234353Sdim // [...] 6687243830Sdim EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated, 6688243830Sdim Sema::ReuseLambdaContextDecl); 6689198092Srdivacky 6690234353Sdim ExprResult SubExpr = getDerived().TransformExpr(E->getArgumentExpr()); 6691234353Sdim if (SubExpr.isInvalid()) 6692234353Sdim return ExprError(); 6693198092Srdivacky 6694234353Sdim if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr()) 6695234353Sdim return SemaRef.Owned(E); 6696198092Srdivacky 6697221345Sdim return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(), 6698221345Sdim E->getOperatorLoc(), 6699221345Sdim E->getKind(), 6700221345Sdim E->getSourceRange()); 6701198092Srdivacky} 6702198092Srdivacky 6703198092Srdivackytemplate<typename Derived> 6704212904SdimExprResult 6705200583SrdivackyTreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) { 6706212904Sdim ExprResult LHS = getDerived().TransformExpr(E->getLHS()); 6707198092Srdivacky if (LHS.isInvalid()) 6708212904Sdim return ExprError(); 6709198092Srdivacky 6710212904Sdim ExprResult RHS = getDerived().TransformExpr(E->getRHS()); 6711198092Srdivacky if (RHS.isInvalid()) 6712212904Sdim return ExprError(); 6713198092Srdivacky 6714198092Srdivacky 6715198092Srdivacky if (!getDerived().AlwaysRebuild() && 6716198092Srdivacky LHS.get() == E->getLHS() && 6717198092Srdivacky RHS.get() == E->getRHS()) 6718218893Sdim return SemaRef.Owned(E); 6719198092Srdivacky 6720212904Sdim return getDerived().RebuildArraySubscriptExpr(LHS.get(), 6721198092Srdivacky /*FIXME:*/E->getLHS()->getLocStart(), 6722212904Sdim RHS.get(), 6723198092Srdivacky E->getRBracketLoc()); 6724198092Srdivacky} 6725198092Srdivacky 6726198092Srdivackytemplate<typename Derived> 6727212904SdimExprResult 6728200583SrdivackyTreeTransform<Derived>::TransformCallExpr(CallExpr *E) { 6729198092Srdivacky // Transform the callee. 6730212904Sdim ExprResult Callee = getDerived().TransformExpr(E->getCallee()); 6731198092Srdivacky if (Callee.isInvalid()) 6732212904Sdim return ExprError(); 6733198092Srdivacky 6734198092Srdivacky // Transform arguments. 6735198092Srdivacky bool ArgChanged = false; 6736243830Sdim SmallVector<Expr*, 8> Args; 6737239462Sdim if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, 6738218893Sdim &ArgChanged)) 6739218893Sdim return ExprError(); 6740239462Sdim 6741198092Srdivacky if (!getDerived().AlwaysRebuild() && 6742198092Srdivacky Callee.get() == E->getCallee() && 6743198092Srdivacky !ArgChanged) 6744243830Sdim return SemaRef.MaybeBindToTemporary(E); 6745198092Srdivacky 6746198092Srdivacky // FIXME: Wrong source location information for the '('. 6747198092Srdivacky SourceLocation FakeLParenLoc 6748198092Srdivacky = ((Expr *)Callee.get())->getSourceRange().getBegin(); 6749212904Sdim return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc, 6750243830Sdim Args, 6751198092Srdivacky E->getRParenLoc()); 6752198092Srdivacky} 6753198092Srdivacky 6754198092Srdivackytemplate<typename Derived> 6755212904SdimExprResult 6756200583SrdivackyTreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) { 6757212904Sdim ExprResult Base = getDerived().TransformExpr(E->getBase()); 6758198092Srdivacky if (Base.isInvalid()) 6759212904Sdim return ExprError(); 6760198092Srdivacky 6761221345Sdim NestedNameSpecifierLoc QualifierLoc; 6762198092Srdivacky if (E->hasQualifier()) { 6763221345Sdim QualifierLoc 6764221345Sdim = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); 6765239462Sdim 6766221345Sdim if (!QualifierLoc) 6767212904Sdim return ExprError(); 6768198092Srdivacky } 6769234353Sdim SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); 6770198092Srdivacky 6771200583Srdivacky ValueDecl *Member 6772204643Srdivacky = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(), 6773204643Srdivacky E->getMemberDecl())); 6774198092Srdivacky if (!Member) 6775212904Sdim return ExprError(); 6776198092Srdivacky 6777206084Srdivacky NamedDecl *FoundDecl = E->getFoundDecl(); 6778206084Srdivacky if (FoundDecl == E->getMemberDecl()) { 6779206084Srdivacky FoundDecl = Member; 6780206084Srdivacky } else { 6781206084Srdivacky FoundDecl = cast_or_null<NamedDecl>( 6782206084Srdivacky getDerived().TransformDecl(E->getMemberLoc(), FoundDecl)); 6783206084Srdivacky if (!FoundDecl) 6784212904Sdim return ExprError(); 6785206084Srdivacky } 6786206084Srdivacky 6787198092Srdivacky if (!getDerived().AlwaysRebuild() && 6788198092Srdivacky Base.get() == E->getBase() && 6789221345Sdim QualifierLoc == E->getQualifierLoc() && 6790198954Srdivacky Member == E->getMemberDecl() && 6791206084Srdivacky FoundDecl == E->getFoundDecl() && 6792212904Sdim !E->hasExplicitTemplateArgs()) { 6793239462Sdim 6794201361Srdivacky // Mark it referenced in the new context regardless. 6795201361Srdivacky // FIXME: this is a bit instantiation-specific. 6796234353Sdim SemaRef.MarkMemberReferenced(E); 6797234353Sdim 6798218893Sdim return SemaRef.Owned(E); 6799201361Srdivacky } 6800198092Srdivacky 6801199990Srdivacky TemplateArgumentListInfo TransArgs; 6802212904Sdim if (E->hasExplicitTemplateArgs()) { 6803199990Srdivacky TransArgs.setLAngleLoc(E->getLAngleLoc()); 6804199990Srdivacky TransArgs.setRAngleLoc(E->getRAngleLoc()); 6805218893Sdim if (getDerived().TransformTemplateArguments(E->getTemplateArgs(), 6806218893Sdim E->getNumTemplateArgs(), 6807218893Sdim TransArgs)) 6808218893Sdim return ExprError(); 6809198954Srdivacky } 6810239462Sdim 6811198092Srdivacky // FIXME: Bogus source location for the operator 6812198092Srdivacky SourceLocation FakeOperatorLoc 6813198092Srdivacky = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd()); 6814198092Srdivacky 6815202379Srdivacky // FIXME: to do this check properly, we will need to preserve the 6816202379Srdivacky // first-qualifier-in-scope here, just in case we had a dependent 6817202379Srdivacky // base (and therefore couldn't do the check) and a 6818202379Srdivacky // nested-name-qualifier (and therefore could do the lookup). 6819202379Srdivacky NamedDecl *FirstQualifierInScope = 0; 6820202379Srdivacky 6821212904Sdim return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc, 6822198092Srdivacky E->isArrow(), 6823221345Sdim QualifierLoc, 6824234353Sdim TemplateKWLoc, 6825212904Sdim E->getMemberNameInfo(), 6826198954Srdivacky Member, 6827206084Srdivacky FoundDecl, 6828212904Sdim (E->hasExplicitTemplateArgs() 6829199990Srdivacky ? &TransArgs : 0), 6830202379Srdivacky FirstQualifierInScope); 6831198092Srdivacky} 6832198092Srdivacky 6833198092Srdivackytemplate<typename Derived> 6834212904SdimExprResult 6835200583SrdivackyTreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) { 6836212904Sdim ExprResult LHS = getDerived().TransformExpr(E->getLHS()); 6837198092Srdivacky if (LHS.isInvalid()) 6838212904Sdim return ExprError(); 6839198092Srdivacky 6840212904Sdim ExprResult RHS = getDerived().TransformExpr(E->getRHS()); 6841198092Srdivacky if (RHS.isInvalid()) 6842212904Sdim return ExprError(); 6843198092Srdivacky 6844198092Srdivacky if (!getDerived().AlwaysRebuild() && 6845198092Srdivacky LHS.get() == E->getLHS() && 6846198092Srdivacky RHS.get() == E->getRHS()) 6847218893Sdim return SemaRef.Owned(E); 6848198092Srdivacky 6849243830Sdim Sema::FPContractStateRAII FPContractState(getSema()); 6850243830Sdim getSema().FPFeatures.fp_contract = E->isFPContractable(); 6851243830Sdim 6852198092Srdivacky return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(), 6853212904Sdim LHS.get(), RHS.get()); 6854198092Srdivacky} 6855198092Srdivacky 6856198092Srdivackytemplate<typename Derived> 6857212904SdimExprResult 6858198092SrdivackyTreeTransform<Derived>::TransformCompoundAssignOperator( 6859200583Srdivacky CompoundAssignOperator *E) { 6860200583Srdivacky return getDerived().TransformBinaryOperator(E); 6861198092Srdivacky} 6862198092Srdivacky 6863198092Srdivackytemplate<typename Derived> 6864218893SdimExprResult TreeTransform<Derived>:: 6865218893SdimTransformBinaryConditionalOperator(BinaryConditionalOperator *e) { 6866218893Sdim // Just rebuild the common and RHS expressions and see whether we 6867218893Sdim // get any changes. 6868218893Sdim 6869218893Sdim ExprResult commonExpr = getDerived().TransformExpr(e->getCommon()); 6870218893Sdim if (commonExpr.isInvalid()) 6871218893Sdim return ExprError(); 6872218893Sdim 6873218893Sdim ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr()); 6874218893Sdim if (rhs.isInvalid()) 6875218893Sdim return ExprError(); 6876218893Sdim 6877218893Sdim if (!getDerived().AlwaysRebuild() && 6878218893Sdim commonExpr.get() == e->getCommon() && 6879218893Sdim rhs.get() == e->getFalseExpr()) 6880218893Sdim return SemaRef.Owned(e); 6881218893Sdim 6882218893Sdim return getDerived().RebuildConditionalOperator(commonExpr.take(), 6883218893Sdim e->getQuestionLoc(), 6884218893Sdim 0, 6885218893Sdim e->getColonLoc(), 6886218893Sdim rhs.get()); 6887218893Sdim} 6888218893Sdim 6889218893Sdimtemplate<typename Derived> 6890212904SdimExprResult 6891200583SrdivackyTreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) { 6892212904Sdim ExprResult Cond = getDerived().TransformExpr(E->getCond()); 6893198092Srdivacky if (Cond.isInvalid()) 6894212904Sdim return ExprError(); 6895198092Srdivacky 6896212904Sdim ExprResult LHS = getDerived().TransformExpr(E->getLHS()); 6897198092Srdivacky if (LHS.isInvalid()) 6898212904Sdim return ExprError(); 6899198092Srdivacky 6900212904Sdim ExprResult RHS = getDerived().TransformExpr(E->getRHS()); 6901198092Srdivacky if (RHS.isInvalid()) 6902212904Sdim return ExprError(); 6903198092Srdivacky 6904198092Srdivacky if (!getDerived().AlwaysRebuild() && 6905198092Srdivacky Cond.get() == E->getCond() && 6906198092Srdivacky LHS.get() == E->getLHS() && 6907198092Srdivacky RHS.get() == E->getRHS()) 6908218893Sdim return SemaRef.Owned(E); 6909198092Srdivacky 6910212904Sdim return getDerived().RebuildConditionalOperator(Cond.get(), 6911198092Srdivacky E->getQuestionLoc(), 6912212904Sdim LHS.get(), 6913198092Srdivacky E->getColonLoc(), 6914212904Sdim RHS.get()); 6915198092Srdivacky} 6916198092Srdivacky 6917198092Srdivackytemplate<typename Derived> 6918212904SdimExprResult 6919200583SrdivackyTreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) { 6920200583Srdivacky // Implicit casts are eliminated during transformation, since they 6921200583Srdivacky // will be recomputed by semantic analysis after transformation. 6922200583Srdivacky return getDerived().TransformExpr(E->getSubExprAsWritten()); 6923198092Srdivacky} 6924198092Srdivacky 6925198092Srdivackytemplate<typename Derived> 6926212904SdimExprResult 6927200583SrdivackyTreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) { 6928218893Sdim TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten()); 6929218893Sdim if (!Type) 6930218893Sdim return ExprError(); 6931239462Sdim 6932212904Sdim ExprResult SubExpr 6933200583Srdivacky = getDerived().TransformExpr(E->getSubExprAsWritten()); 6934198092Srdivacky if (SubExpr.isInvalid()) 6935212904Sdim return ExprError(); 6936198092Srdivacky 6937198092Srdivacky if (!getDerived().AlwaysRebuild() && 6938218893Sdim Type == E->getTypeInfoAsWritten() && 6939198092Srdivacky SubExpr.get() == E->getSubExpr()) 6940218893Sdim return SemaRef.Owned(E); 6941198092Srdivacky 6942202879Srdivacky return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(), 6943218893Sdim Type, 6944198092Srdivacky E->getRParenLoc(), 6945212904Sdim SubExpr.get()); 6946198092Srdivacky} 6947198092Srdivacky 6948198092Srdivackytemplate<typename Derived> 6949212904SdimExprResult 6950200583SrdivackyTreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) { 6951202879Srdivacky TypeSourceInfo *OldT = E->getTypeSourceInfo(); 6952202879Srdivacky TypeSourceInfo *NewT = getDerived().TransformType(OldT); 6953202879Srdivacky if (!NewT) 6954212904Sdim return ExprError(); 6955198092Srdivacky 6956212904Sdim ExprResult Init = getDerived().TransformExpr(E->getInitializer()); 6957198092Srdivacky if (Init.isInvalid()) 6958212904Sdim return ExprError(); 6959198092Srdivacky 6960198092Srdivacky if (!getDerived().AlwaysRebuild() && 6961202879Srdivacky OldT == NewT && 6962198092Srdivacky Init.get() == E->getInitializer()) 6963234353Sdim return SemaRef.MaybeBindToTemporary(E); 6964198092Srdivacky 6965202879Srdivacky // Note: the expression type doesn't necessarily match the 6966202879Srdivacky // type-as-written, but that's okay, because it should always be 6967202879Srdivacky // derivable from the initializer. 6968202879Srdivacky 6969202879Srdivacky return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), NewT, 6970198092Srdivacky /*FIXME:*/E->getInitializer()->getLocEnd(), 6971212904Sdim Init.get()); 6972198092Srdivacky} 6973198092Srdivacky 6974198092Srdivackytemplate<typename Derived> 6975212904SdimExprResult 6976200583SrdivackyTreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) { 6977212904Sdim ExprResult Base = getDerived().TransformExpr(E->getBase()); 6978198092Srdivacky if (Base.isInvalid()) 6979212904Sdim return ExprError(); 6980198092Srdivacky 6981198092Srdivacky if (!getDerived().AlwaysRebuild() && 6982198092Srdivacky Base.get() == E->getBase()) 6983218893Sdim return SemaRef.Owned(E); 6984198092Srdivacky 6985198092Srdivacky // FIXME: Bad source location 6986198092Srdivacky SourceLocation FakeOperatorLoc 6987198092Srdivacky = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd()); 6988212904Sdim return getDerived().RebuildExtVectorElementExpr(Base.get(), FakeOperatorLoc, 6989198092Srdivacky E->getAccessorLoc(), 6990198092Srdivacky E->getAccessor()); 6991198092Srdivacky} 6992198092Srdivacky 6993198092Srdivackytemplate<typename Derived> 6994212904SdimExprResult 6995200583SrdivackyTreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) { 6996198092Srdivacky bool InitChanged = false; 6997198092Srdivacky 6998243830Sdim SmallVector<Expr*, 4> Inits; 6999239462Sdim if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false, 7000218893Sdim Inits, &InitChanged)) 7001218893Sdim return ExprError(); 7002239462Sdim 7003198092Srdivacky if (!getDerived().AlwaysRebuild() && !InitChanged) 7004218893Sdim return SemaRef.Owned(E); 7005198092Srdivacky 7006243830Sdim return getDerived().RebuildInitList(E->getLBraceLoc(), Inits, 7007199482Srdivacky E->getRBraceLoc(), E->getType()); 7008198092Srdivacky} 7009198092Srdivacky 7010198092Srdivackytemplate<typename Derived> 7011212904SdimExprResult 7012200583SrdivackyTreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) { 7013198092Srdivacky Designation Desig; 7014198092Srdivacky 7015198092Srdivacky // transform the initializer value 7016212904Sdim ExprResult Init = getDerived().TransformExpr(E->getInit()); 7017198092Srdivacky if (Init.isInvalid()) 7018212904Sdim return ExprError(); 7019198092Srdivacky 7020198092Srdivacky // transform the designators. 7021243830Sdim SmallVector<Expr*, 4> ArrayExprs; 7022198092Srdivacky bool ExprChanged = false; 7023198092Srdivacky for (DesignatedInitExpr::designators_iterator D = E->designators_begin(), 7024198092Srdivacky DEnd = E->designators_end(); 7025198092Srdivacky D != DEnd; ++D) { 7026198092Srdivacky if (D->isFieldDesignator()) { 7027198092Srdivacky Desig.AddDesignator(Designator::getField(D->getFieldName(), 7028198092Srdivacky D->getDotLoc(), 7029198092Srdivacky D->getFieldLoc())); 7030198092Srdivacky continue; 7031198092Srdivacky } 7032198092Srdivacky 7033198092Srdivacky if (D->isArrayDesignator()) { 7034212904Sdim ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D)); 7035198092Srdivacky if (Index.isInvalid()) 7036212904Sdim return ExprError(); 7037198092Srdivacky 7038198092Srdivacky Desig.AddDesignator(Designator::getArray(Index.get(), 7039198092Srdivacky D->getLBracketLoc())); 7040198092Srdivacky 7041198092Srdivacky ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D); 7042198092Srdivacky ArrayExprs.push_back(Index.release()); 7043198092Srdivacky continue; 7044198092Srdivacky } 7045198092Srdivacky 7046198092Srdivacky assert(D->isArrayRangeDesignator() && "New kind of designator?"); 7047212904Sdim ExprResult Start 7048198092Srdivacky = getDerived().TransformExpr(E->getArrayRangeStart(*D)); 7049198092Srdivacky if (Start.isInvalid()) 7050212904Sdim return ExprError(); 7051198092Srdivacky 7052212904Sdim ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D)); 7053198092Srdivacky if (End.isInvalid()) 7054212904Sdim return ExprError(); 7055198092Srdivacky 7056198092Srdivacky Desig.AddDesignator(Designator::getArrayRange(Start.get(), 7057198092Srdivacky End.get(), 7058198092Srdivacky D->getLBracketLoc(), 7059198092Srdivacky D->getEllipsisLoc())); 7060198092Srdivacky 7061198092Srdivacky ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) || 7062198092Srdivacky End.get() != E->getArrayRangeEnd(*D); 7063198092Srdivacky 7064198092Srdivacky ArrayExprs.push_back(Start.release()); 7065198092Srdivacky ArrayExprs.push_back(End.release()); 7066198092Srdivacky } 7067198092Srdivacky 7068198092Srdivacky if (!getDerived().AlwaysRebuild() && 7069198092Srdivacky Init.get() == E->getInit() && 7070198092Srdivacky !ExprChanged) 7071218893Sdim return SemaRef.Owned(E); 7072198092Srdivacky 7073243830Sdim return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs, 7074198092Srdivacky E->getEqualOrColonLoc(), 7075212904Sdim E->usesGNUSyntax(), Init.get()); 7076198092Srdivacky} 7077198092Srdivacky 7078198092Srdivackytemplate<typename Derived> 7079212904SdimExprResult 7080198092SrdivackyTreeTransform<Derived>::TransformImplicitValueInitExpr( 7081200583Srdivacky ImplicitValueInitExpr *E) { 7082198893Srdivacky TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName()); 7083239462Sdim 7084198893Srdivacky // FIXME: Will we ever have proper type location here? Will we actually 7085198893Srdivacky // need to transform the type? 7086198092Srdivacky QualType T = getDerived().TransformType(E->getType()); 7087198092Srdivacky if (T.isNull()) 7088212904Sdim return ExprError(); 7089198092Srdivacky 7090198092Srdivacky if (!getDerived().AlwaysRebuild() && 7091198092Srdivacky T == E->getType()) 7092218893Sdim return SemaRef.Owned(E); 7093198092Srdivacky 7094198092Srdivacky return getDerived().RebuildImplicitValueInitExpr(T); 7095198092Srdivacky} 7096198092Srdivacky 7097198092Srdivackytemplate<typename Derived> 7098212904SdimExprResult 7099200583SrdivackyTreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) { 7100212904Sdim TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo()); 7101212904Sdim if (!TInfo) 7102212904Sdim return ExprError(); 7103198092Srdivacky 7104212904Sdim ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); 7105198092Srdivacky if (SubExpr.isInvalid()) 7106212904Sdim return ExprError(); 7107198092Srdivacky 7108198092Srdivacky if (!getDerived().AlwaysRebuild() && 7109212904Sdim TInfo == E->getWrittenTypeInfo() && 7110198092Srdivacky SubExpr.get() == E->getSubExpr()) 7111218893Sdim return SemaRef.Owned(E); 7112198092Srdivacky 7113212904Sdim return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(), 7114212904Sdim TInfo, E->getRParenLoc()); 7115198092Srdivacky} 7116198092Srdivacky 7117198092Srdivackytemplate<typename Derived> 7118212904SdimExprResult 7119200583SrdivackyTreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) { 7120198092Srdivacky bool ArgumentChanged = false; 7121243830Sdim SmallVector<Expr*, 4> Inits; 7122218893Sdim if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits, 7123218893Sdim &ArgumentChanged)) 7124218893Sdim return ExprError(); 7125239462Sdim 7126198092Srdivacky return getDerived().RebuildParenListExpr(E->getLParenLoc(), 7127243830Sdim Inits, 7128198092Srdivacky E->getRParenLoc()); 7129198092Srdivacky} 7130198092Srdivacky 7131198092Srdivacky/// \brief Transform an address-of-label expression. 7132198092Srdivacky/// 7133198092Srdivacky/// By default, the transformation of an address-of-label expression always 7134198092Srdivacky/// rebuilds the expression, so that the label identifier can be resolved to 7135198092Srdivacky/// the corresponding label statement by semantic analysis. 7136198092Srdivackytemplate<typename Derived> 7137212904SdimExprResult 7138200583SrdivackyTreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) { 7139218893Sdim Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(), 7140218893Sdim E->getLabel()); 7141218893Sdim if (!LD) 7142218893Sdim return ExprError(); 7143239462Sdim 7144198092Srdivacky return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(), 7145218893Sdim cast<LabelDecl>(LD)); 7146198092Srdivacky} 7147198092Srdivacky 7148198092Srdivackytemplate<typename Derived> 7149239462SdimExprResult 7150200583SrdivackyTreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) { 7151234353Sdim SemaRef.ActOnStartStmtExpr(); 7152212904Sdim StmtResult SubStmt 7153198092Srdivacky = getDerived().TransformCompoundStmt(E->getSubStmt(), true); 7154234353Sdim if (SubStmt.isInvalid()) { 7155234353Sdim SemaRef.ActOnStmtExprError(); 7156212904Sdim return ExprError(); 7157234353Sdim } 7158198092Srdivacky 7159198092Srdivacky if (!getDerived().AlwaysRebuild() && 7160234353Sdim SubStmt.get() == E->getSubStmt()) { 7161234353Sdim // Calling this an 'error' is unintuitive, but it does the right thing. 7162234353Sdim SemaRef.ActOnStmtExprError(); 7163234353Sdim return SemaRef.MaybeBindToTemporary(E); 7164234353Sdim } 7165198092Srdivacky 7166198092Srdivacky return getDerived().RebuildStmtExpr(E->getLParenLoc(), 7167212904Sdim SubStmt.get(), 7168198092Srdivacky E->getRParenLoc()); 7169198092Srdivacky} 7170198092Srdivacky 7171198092Srdivackytemplate<typename Derived> 7172212904SdimExprResult 7173200583SrdivackyTreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) { 7174212904Sdim ExprResult Cond = getDerived().TransformExpr(E->getCond()); 7175198092Srdivacky if (Cond.isInvalid()) 7176212904Sdim return ExprError(); 7177198092Srdivacky 7178212904Sdim ExprResult LHS = getDerived().TransformExpr(E->getLHS()); 7179198092Srdivacky if (LHS.isInvalid()) 7180212904Sdim return ExprError(); 7181198092Srdivacky 7182212904Sdim ExprResult RHS = getDerived().TransformExpr(E->getRHS()); 7183198092Srdivacky if (RHS.isInvalid()) 7184212904Sdim return ExprError(); 7185198092Srdivacky 7186198092Srdivacky if (!getDerived().AlwaysRebuild() && 7187198092Srdivacky Cond.get() == E->getCond() && 7188198092Srdivacky LHS.get() == E->getLHS() && 7189198092Srdivacky RHS.get() == E->getRHS()) 7190218893Sdim return SemaRef.Owned(E); 7191198092Srdivacky 7192198092Srdivacky return getDerived().RebuildChooseExpr(E->getBuiltinLoc(), 7193212904Sdim Cond.get(), LHS.get(), RHS.get(), 7194198092Srdivacky E->getRParenLoc()); 7195198092Srdivacky} 7196198092Srdivacky 7197198092Srdivackytemplate<typename Derived> 7198212904SdimExprResult 7199200583SrdivackyTreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) { 7200218893Sdim return SemaRef.Owned(E); 7201198092Srdivacky} 7202198092Srdivacky 7203198092Srdivackytemplate<typename Derived> 7204212904SdimExprResult 7205200583SrdivackyTreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) { 7206200583Srdivacky switch (E->getOperator()) { 7207200583Srdivacky case OO_New: 7208200583Srdivacky case OO_Delete: 7209200583Srdivacky case OO_Array_New: 7210200583Srdivacky case OO_Array_Delete: 7211200583Srdivacky llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr"); 7212239462Sdim 7213200583Srdivacky case OO_Call: { 7214200583Srdivacky // This is a call to an object's operator(). 7215200583Srdivacky assert(E->getNumArgs() >= 1 && "Object call is missing arguments"); 7216200583Srdivacky 7217200583Srdivacky // Transform the object itself. 7218212904Sdim ExprResult Object = getDerived().TransformExpr(E->getArg(0)); 7219200583Srdivacky if (Object.isInvalid()) 7220212904Sdim return ExprError(); 7221200583Srdivacky 7222200583Srdivacky // FIXME: Poor location information 7223200583Srdivacky SourceLocation FakeLParenLoc 7224200583Srdivacky = SemaRef.PP.getLocForEndOfToken( 7225200583Srdivacky static_cast<Expr *>(Object.get())->getLocEnd()); 7226200583Srdivacky 7227200583Srdivacky // Transform the call arguments. 7228243830Sdim SmallVector<Expr*, 8> Args; 7229239462Sdim if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true, 7230218893Sdim Args)) 7231218893Sdim return ExprError(); 7232200583Srdivacky 7233212904Sdim return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, 7234243830Sdim Args, 7235200583Srdivacky E->getLocEnd()); 7236200583Srdivacky } 7237200583Srdivacky 7238200583Srdivacky#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 7239200583Srdivacky case OO_##Name: 7240200583Srdivacky#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly) 7241200583Srdivacky#include "clang/Basic/OperatorKinds.def" 7242200583Srdivacky case OO_Subscript: 7243200583Srdivacky // Handled below. 7244200583Srdivacky break; 7245200583Srdivacky 7246200583Srdivacky case OO_Conditional: 7247200583Srdivacky llvm_unreachable("conditional operator is not actually overloadable"); 7248200583Srdivacky 7249200583Srdivacky case OO_None: 7250200583Srdivacky case NUM_OVERLOADED_OPERATORS: 7251200583Srdivacky llvm_unreachable("not an overloaded operator?"); 7252200583Srdivacky } 7253200583Srdivacky 7254212904Sdim ExprResult Callee = getDerived().TransformExpr(E->getCallee()); 7255198092Srdivacky if (Callee.isInvalid()) 7256212904Sdim return ExprError(); 7257198092Srdivacky 7258243830Sdim ExprResult First; 7259243830Sdim if (E->getOperator() == OO_Amp) 7260243830Sdim First = getDerived().TransformAddressOfOperand(E->getArg(0)); 7261243830Sdim else 7262243830Sdim First = getDerived().TransformExpr(E->getArg(0)); 7263198092Srdivacky if (First.isInvalid()) 7264212904Sdim return ExprError(); 7265198092Srdivacky 7266212904Sdim ExprResult Second; 7267198092Srdivacky if (E->getNumArgs() == 2) { 7268198092Srdivacky Second = getDerived().TransformExpr(E->getArg(1)); 7269198092Srdivacky if (Second.isInvalid()) 7270212904Sdim return ExprError(); 7271198092Srdivacky } 7272198092Srdivacky 7273198092Srdivacky if (!getDerived().AlwaysRebuild() && 7274198092Srdivacky Callee.get() == E->getCallee() && 7275198092Srdivacky First.get() == E->getArg(0) && 7276198092Srdivacky (E->getNumArgs() != 2 || Second.get() == E->getArg(1))) 7277234353Sdim return SemaRef.MaybeBindToTemporary(E); 7278198092Srdivacky 7279243830Sdim Sema::FPContractStateRAII FPContractState(getSema()); 7280243830Sdim getSema().FPFeatures.fp_contract = E->isFPContractable(); 7281243830Sdim 7282198092Srdivacky return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(), 7283198092Srdivacky E->getOperatorLoc(), 7284212904Sdim Callee.get(), 7285212904Sdim First.get(), 7286212904Sdim Second.get()); 7287198092Srdivacky} 7288198092Srdivacky 7289198092Srdivackytemplate<typename Derived> 7290212904SdimExprResult 7291200583SrdivackyTreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) { 7292200583Srdivacky return getDerived().TransformCallExpr(E); 7293198092Srdivacky} 7294198092Srdivacky 7295198092Srdivackytemplate<typename Derived> 7296212904SdimExprResult 7297218893SdimTreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) { 7298218893Sdim // Transform the callee. 7299218893Sdim ExprResult Callee = getDerived().TransformExpr(E->getCallee()); 7300218893Sdim if (Callee.isInvalid()) 7301218893Sdim return ExprError(); 7302198092Srdivacky 7303218893Sdim // Transform exec config. 7304218893Sdim ExprResult EC = getDerived().TransformCallExpr(E->getConfig()); 7305218893Sdim if (EC.isInvalid()) 7306218893Sdim return ExprError(); 7307198092Srdivacky 7308218893Sdim // Transform arguments. 7309218893Sdim bool ArgChanged = false; 7310243830Sdim SmallVector<Expr*, 8> Args; 7311239462Sdim if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, 7312218893Sdim &ArgChanged)) 7313218893Sdim return ExprError(); 7314218893Sdim 7315218893Sdim if (!getDerived().AlwaysRebuild() && 7316218893Sdim Callee.get() == E->getCallee() && 7317218893Sdim !ArgChanged) 7318234353Sdim return SemaRef.MaybeBindToTemporary(E); 7319218893Sdim 7320218893Sdim // FIXME: Wrong source location information for the '('. 7321218893Sdim SourceLocation FakeLParenLoc 7322218893Sdim = ((Expr *)Callee.get())->getSourceRange().getBegin(); 7323218893Sdim return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc, 7324243830Sdim Args, 7325218893Sdim E->getRParenLoc(), EC.get()); 7326218893Sdim} 7327218893Sdim 7328218893Sdimtemplate<typename Derived> 7329218893SdimExprResult 7330218893SdimTreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) { 7331218893Sdim TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten()); 7332218893Sdim if (!Type) 7333218893Sdim return ExprError(); 7334239462Sdim 7335212904Sdim ExprResult SubExpr 7336200583Srdivacky = getDerived().TransformExpr(E->getSubExprAsWritten()); 7337198092Srdivacky if (SubExpr.isInvalid()) 7338212904Sdim return ExprError(); 7339198092Srdivacky 7340198092Srdivacky if (!getDerived().AlwaysRebuild() && 7341218893Sdim Type == E->getTypeInfoAsWritten() && 7342198092Srdivacky SubExpr.get() == E->getSubExpr()) 7343218893Sdim return SemaRef.Owned(E); 7344198092Srdivacky return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(), 7345198092Srdivacky E->getStmtClass(), 7346249423Sdim E->getAngleBrackets().getBegin(), 7347218893Sdim Type, 7348249423Sdim E->getAngleBrackets().getEnd(), 7349249423Sdim // FIXME. this should be '(' location 7350249423Sdim E->getAngleBrackets().getEnd(), 7351212904Sdim SubExpr.get(), 7352243830Sdim E->getRParenLoc()); 7353198092Srdivacky} 7354198092Srdivacky 7355198092Srdivackytemplate<typename Derived> 7356212904SdimExprResult 7357200583SrdivackyTreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) { 7358200583Srdivacky return getDerived().TransformCXXNamedCastExpr(E); 7359198092Srdivacky} 7360198092Srdivacky 7361198092Srdivackytemplate<typename Derived> 7362212904SdimExprResult 7363200583SrdivackyTreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) { 7364200583Srdivacky return getDerived().TransformCXXNamedCastExpr(E); 7365198092Srdivacky} 7366198092Srdivacky 7367198092Srdivackytemplate<typename Derived> 7368212904SdimExprResult 7369198092SrdivackyTreeTransform<Derived>::TransformCXXReinterpretCastExpr( 7370200583Srdivacky CXXReinterpretCastExpr *E) { 7371200583Srdivacky return getDerived().TransformCXXNamedCastExpr(E); 7372198092Srdivacky} 7373198092Srdivacky 7374198092Srdivackytemplate<typename Derived> 7375212904SdimExprResult 7376200583SrdivackyTreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) { 7377200583Srdivacky return getDerived().TransformCXXNamedCastExpr(E); 7378198092Srdivacky} 7379198092Srdivacky 7380198092Srdivackytemplate<typename Derived> 7381212904SdimExprResult 7382198092SrdivackyTreeTransform<Derived>::TransformCXXFunctionalCastExpr( 7383200583Srdivacky CXXFunctionalCastExpr *E) { 7384218893Sdim TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten()); 7385218893Sdim if (!Type) 7386218893Sdim return ExprError(); 7387198092Srdivacky 7388212904Sdim ExprResult SubExpr 7389200583Srdivacky = getDerived().TransformExpr(E->getSubExprAsWritten()); 7390198092Srdivacky if (SubExpr.isInvalid()) 7391212904Sdim return ExprError(); 7392198092Srdivacky 7393198092Srdivacky if (!getDerived().AlwaysRebuild() && 7394218893Sdim Type == E->getTypeInfoAsWritten() && 7395198092Srdivacky SubExpr.get() == E->getSubExpr()) 7396218893Sdim return SemaRef.Owned(E); 7397198092Srdivacky 7398218893Sdim return getDerived().RebuildCXXFunctionalCastExpr(Type, 7399263508Sdim E->getLParenLoc(), 7400212904Sdim SubExpr.get(), 7401198092Srdivacky E->getRParenLoc()); 7402198092Srdivacky} 7403198092Srdivacky 7404198092Srdivackytemplate<typename Derived> 7405212904SdimExprResult 7406200583SrdivackyTreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) { 7407198092Srdivacky if (E->isTypeOperand()) { 7408207619Srdivacky TypeSourceInfo *TInfo 7409207619Srdivacky = getDerived().TransformType(E->getTypeOperandSourceInfo()); 7410207619Srdivacky if (!TInfo) 7411212904Sdim return ExprError(); 7412198092Srdivacky 7413198092Srdivacky if (!getDerived().AlwaysRebuild() && 7414207619Srdivacky TInfo == E->getTypeOperandSourceInfo()) 7415218893Sdim return SemaRef.Owned(E); 7416198092Srdivacky 7417207619Srdivacky return getDerived().RebuildCXXTypeidExpr(E->getType(), 7418207619Srdivacky E->getLocStart(), 7419207619Srdivacky TInfo, 7420198092Srdivacky E->getLocEnd()); 7421198092Srdivacky } 7422198092Srdivacky 7423234353Sdim // We don't know whether the subexpression is potentially evaluated until 7424234353Sdim // after we perform semantic analysis. We speculatively assume it is 7425234353Sdim // unevaluated; it will get fixed later if the subexpression is in fact 7426198092Srdivacky // potentially evaluated. 7427243830Sdim EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated, 7428243830Sdim Sema::ReuseLambdaContextDecl); 7429198092Srdivacky 7430212904Sdim ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand()); 7431198092Srdivacky if (SubExpr.isInvalid()) 7432212904Sdim return ExprError(); 7433198092Srdivacky 7434198092Srdivacky if (!getDerived().AlwaysRebuild() && 7435198092Srdivacky SubExpr.get() == E->getExprOperand()) 7436218893Sdim return SemaRef.Owned(E); 7437198092Srdivacky 7438207619Srdivacky return getDerived().RebuildCXXTypeidExpr(E->getType(), 7439207619Srdivacky E->getLocStart(), 7440212904Sdim SubExpr.get(), 7441198092Srdivacky E->getLocEnd()); 7442198092Srdivacky} 7443198092Srdivacky 7444198092Srdivackytemplate<typename Derived> 7445212904SdimExprResult 7446218893SdimTreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) { 7447218893Sdim if (E->isTypeOperand()) { 7448218893Sdim TypeSourceInfo *TInfo 7449218893Sdim = getDerived().TransformType(E->getTypeOperandSourceInfo()); 7450218893Sdim if (!TInfo) 7451218893Sdim return ExprError(); 7452218893Sdim 7453218893Sdim if (!getDerived().AlwaysRebuild() && 7454218893Sdim TInfo == E->getTypeOperandSourceInfo()) 7455218893Sdim return SemaRef.Owned(E); 7456218893Sdim 7457221345Sdim return getDerived().RebuildCXXUuidofExpr(E->getType(), 7458218893Sdim E->getLocStart(), 7459218893Sdim TInfo, 7460218893Sdim E->getLocEnd()); 7461218893Sdim } 7462218893Sdim 7463218893Sdim EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); 7464218893Sdim 7465218893Sdim ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand()); 7466218893Sdim if (SubExpr.isInvalid()) 7467218893Sdim return ExprError(); 7468218893Sdim 7469218893Sdim if (!getDerived().AlwaysRebuild() && 7470218893Sdim SubExpr.get() == E->getExprOperand()) 7471218893Sdim return SemaRef.Owned(E); 7472218893Sdim 7473218893Sdim return getDerived().RebuildCXXUuidofExpr(E->getType(), 7474218893Sdim E->getLocStart(), 7475218893Sdim SubExpr.get(), 7476218893Sdim E->getLocEnd()); 7477218893Sdim} 7478218893Sdim 7479218893Sdimtemplate<typename Derived> 7480218893SdimExprResult 7481200583SrdivackyTreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { 7482218893Sdim return SemaRef.Owned(E); 7483198092Srdivacky} 7484198092Srdivacky 7485198092Srdivackytemplate<typename Derived> 7486212904SdimExprResult 7487198092SrdivackyTreeTransform<Derived>::TransformCXXNullPtrLiteralExpr( 7488200583Srdivacky CXXNullPtrLiteralExpr *E) { 7489218893Sdim return SemaRef.Owned(E); 7490198092Srdivacky} 7491198092Srdivacky 7492198092Srdivackytemplate<typename Derived> 7493212904SdimExprResult 7494200583SrdivackyTreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) { 7495263508Sdim QualType T = getSema().getCurrentThisType(); 7496198092Srdivacky 7497234353Sdim if (!getDerived().AlwaysRebuild() && T == E->getType()) { 7498234353Sdim // Make sure that we capture 'this'. 7499234353Sdim getSema().CheckCXXThisCapture(E->getLocStart()); 7500218893Sdim return SemaRef.Owned(E); 7501234353Sdim } 7502239462Sdim 7503202379Srdivacky return getDerived().RebuildCXXThisExpr(E->getLocStart(), T, E->isImplicit()); 7504198092Srdivacky} 7505198092Srdivacky 7506198092Srdivackytemplate<typename Derived> 7507212904SdimExprResult 7508200583SrdivackyTreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) { 7509212904Sdim ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); 7510198092Srdivacky if (SubExpr.isInvalid()) 7511212904Sdim return ExprError(); 7512198092Srdivacky 7513198092Srdivacky if (!getDerived().AlwaysRebuild() && 7514198092Srdivacky SubExpr.get() == E->getSubExpr()) 7515218893Sdim return SemaRef.Owned(E); 7516198092Srdivacky 7517224145Sdim return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(), 7518224145Sdim E->isThrownVariableInScope()); 7519198092Srdivacky} 7520198092Srdivacky 7521198092Srdivackytemplate<typename Derived> 7522212904SdimExprResult 7523200583SrdivackyTreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) { 7524198092Srdivacky ParmVarDecl *Param 7525204643Srdivacky = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getLocStart(), 7526204643Srdivacky E->getParam())); 7527198092Srdivacky if (!Param) 7528212904Sdim return ExprError(); 7529198092Srdivacky 7530203955Srdivacky if (!getDerived().AlwaysRebuild() && 7531198092Srdivacky Param == E->getParam()) 7532218893Sdim return SemaRef.Owned(E); 7533198092Srdivacky 7534201361Srdivacky return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param); 7535198092Srdivacky} 7536198092Srdivacky 7537198092Srdivackytemplate<typename Derived> 7538212904SdimExprResult 7539251662SdimTreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) { 7540251662Sdim FieldDecl *Field 7541251662Sdim = cast_or_null<FieldDecl>(getDerived().TransformDecl(E->getLocStart(), 7542251662Sdim E->getField())); 7543251662Sdim if (!Field) 7544251662Sdim return ExprError(); 7545251662Sdim 7546251662Sdim if (!getDerived().AlwaysRebuild() && Field == E->getField()) 7547251662Sdim return SemaRef.Owned(E); 7548251662Sdim 7549251662Sdim return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field); 7550251662Sdim} 7551251662Sdim 7552251662Sdimtemplate<typename Derived> 7553251662SdimExprResult 7554218893SdimTreeTransform<Derived>::TransformCXXScalarValueInitExpr( 7555218893Sdim CXXScalarValueInitExpr *E) { 7556218893Sdim TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo()); 7557218893Sdim if (!T) 7558212904Sdim return ExprError(); 7559239462Sdim 7560198092Srdivacky if (!getDerived().AlwaysRebuild() && 7561218893Sdim T == E->getTypeSourceInfo()) 7562218893Sdim return SemaRef.Owned(E); 7563198092Srdivacky 7564239462Sdim return getDerived().RebuildCXXScalarValueInitExpr(T, 7565218893Sdim /*FIXME:*/T->getTypeLoc().getEndLoc(), 7566210299Sed E->getRParenLoc()); 7567198092Srdivacky} 7568198092Srdivacky 7569198092Srdivackytemplate<typename Derived> 7570212904SdimExprResult 7571200583SrdivackyTreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) { 7572198092Srdivacky // Transform the type that we're allocating 7573218893Sdim TypeSourceInfo *AllocTypeInfo 7574218893Sdim = getDerived().TransformType(E->getAllocatedTypeSourceInfo()); 7575218893Sdim if (!AllocTypeInfo) 7576212904Sdim return ExprError(); 7577198092Srdivacky 7578198092Srdivacky // Transform the size of the array we're allocating (if any). 7579212904Sdim ExprResult ArraySize = getDerived().TransformExpr(E->getArraySize()); 7580198092Srdivacky if (ArraySize.isInvalid()) 7581212904Sdim return ExprError(); 7582198092Srdivacky 7583198092Srdivacky // Transform the placement arguments (if any). 7584198092Srdivacky bool ArgumentChanged = false; 7585243830Sdim SmallVector<Expr*, 8> PlacementArgs; 7586239462Sdim if (getDerived().TransformExprs(E->getPlacementArgs(), 7587218893Sdim E->getNumPlacementArgs(), true, 7588218893Sdim PlacementArgs, &ArgumentChanged)) 7589234353Sdim return ExprError(); 7590198092Srdivacky 7591234353Sdim // Transform the initializer (if any). 7592234353Sdim Expr *OldInit = E->getInitializer(); 7593234353Sdim ExprResult NewInit; 7594234353Sdim if (OldInit) 7595234353Sdim NewInit = getDerived().TransformExpr(OldInit); 7596234353Sdim if (NewInit.isInvalid()) 7597234353Sdim return ExprError(); 7598198092Srdivacky 7599234353Sdim // Transform new operator and delete operator. 7600204643Srdivacky FunctionDecl *OperatorNew = 0; 7601204643Srdivacky if (E->getOperatorNew()) { 7602204643Srdivacky OperatorNew = cast_or_null<FunctionDecl>( 7603204643Srdivacky getDerived().TransformDecl(E->getLocStart(), 7604204643Srdivacky E->getOperatorNew())); 7605204643Srdivacky if (!OperatorNew) 7606212904Sdim return ExprError(); 7607204643Srdivacky } 7608204643Srdivacky 7609204643Srdivacky FunctionDecl *OperatorDelete = 0; 7610204643Srdivacky if (E->getOperatorDelete()) { 7611204643Srdivacky OperatorDelete = cast_or_null<FunctionDecl>( 7612204643Srdivacky getDerived().TransformDecl(E->getLocStart(), 7613204643Srdivacky E->getOperatorDelete())); 7614204643Srdivacky if (!OperatorDelete) 7615212904Sdim return ExprError(); 7616204643Srdivacky } 7617239462Sdim 7618198092Srdivacky if (!getDerived().AlwaysRebuild() && 7619218893Sdim AllocTypeInfo == E->getAllocatedTypeSourceInfo() && 7620198092Srdivacky ArraySize.get() == E->getArraySize() && 7621234353Sdim NewInit.get() == OldInit && 7622204643Srdivacky OperatorNew == E->getOperatorNew() && 7623204643Srdivacky OperatorDelete == E->getOperatorDelete() && 7624204643Srdivacky !ArgumentChanged) { 7625204643Srdivacky // Mark any declarations we need as referenced. 7626204643Srdivacky // FIXME: instantiation-specific. 7627204643Srdivacky if (OperatorNew) 7628234353Sdim SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorNew); 7629204643Srdivacky if (OperatorDelete) 7630234353Sdim SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorDelete); 7631239462Sdim 7632234353Sdim if (E->isArray() && !E->getAllocatedType()->isDependentType()) { 7633226633Sdim QualType ElementType 7634226633Sdim = SemaRef.Context.getBaseElementType(E->getAllocatedType()); 7635226633Sdim if (const RecordType *RecordT = ElementType->getAs<RecordType>()) { 7636226633Sdim CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl()); 7637226633Sdim if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) { 7638234353Sdim SemaRef.MarkFunctionReferenced(E->getLocStart(), Destructor); 7639226633Sdim } 7640226633Sdim } 7641226633Sdim } 7642234353Sdim 7643218893Sdim return SemaRef.Owned(E); 7644204643Srdivacky } 7645198092Srdivacky 7646218893Sdim QualType AllocType = AllocTypeInfo->getType(); 7647201361Srdivacky if (!ArraySize.get()) { 7648201361Srdivacky // If no array size was specified, but the new expression was 7649201361Srdivacky // instantiated with an array type (e.g., "new T" where T is 7650201361Srdivacky // instantiated with "int[4]"), extract the outer bound from the 7651201361Srdivacky // array type as our array size. We do this with constant and 7652201361Srdivacky // dependently-sized array types. 7653201361Srdivacky const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType); 7654201361Srdivacky if (!ArrayT) { 7655201361Srdivacky // Do nothing 7656201361Srdivacky } else if (const ConstantArrayType *ConsArrayT 7657201361Srdivacky = dyn_cast<ConstantArrayType>(ArrayT)) { 7658239462Sdim ArraySize 7659212904Sdim = SemaRef.Owned(IntegerLiteral::Create(SemaRef.Context, 7660239462Sdim ConsArrayT->getSize(), 7661212904Sdim SemaRef.Context.getSizeType(), 7662212904Sdim /*FIXME:*/E->getLocStart())); 7663201361Srdivacky AllocType = ConsArrayT->getElementType(); 7664201361Srdivacky } else if (const DependentSizedArrayType *DepArrayT 7665201361Srdivacky = dyn_cast<DependentSizedArrayType>(ArrayT)) { 7666201361Srdivacky if (DepArrayT->getSizeExpr()) { 7667218893Sdim ArraySize = SemaRef.Owned(DepArrayT->getSizeExpr()); 7668201361Srdivacky AllocType = DepArrayT->getElementType(); 7669201361Srdivacky } 7670201361Srdivacky } 7671201361Srdivacky } 7672234353Sdim 7673198092Srdivacky return getDerived().RebuildCXXNewExpr(E->getLocStart(), 7674198092Srdivacky E->isGlobalNew(), 7675198092Srdivacky /*FIXME:*/E->getLocStart(), 7676243830Sdim PlacementArgs, 7677198092Srdivacky /*FIXME:*/E->getLocStart(), 7678210299Sed E->getTypeIdParens(), 7679198092Srdivacky AllocType, 7680218893Sdim AllocTypeInfo, 7681212904Sdim ArraySize.get(), 7682234353Sdim E->getDirectInitRange(), 7683234353Sdim NewInit.take()); 7684198092Srdivacky} 7685198092Srdivacky 7686198092Srdivackytemplate<typename Derived> 7687212904SdimExprResult 7688200583SrdivackyTreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) { 7689212904Sdim ExprResult Operand = getDerived().TransformExpr(E->getArgument()); 7690198092Srdivacky if (Operand.isInvalid()) 7691212904Sdim return ExprError(); 7692198092Srdivacky 7693204643Srdivacky // Transform the delete operator, if known. 7694204643Srdivacky FunctionDecl *OperatorDelete = 0; 7695204643Srdivacky if (E->getOperatorDelete()) { 7696204643Srdivacky OperatorDelete = cast_or_null<FunctionDecl>( 7697204643Srdivacky getDerived().TransformDecl(E->getLocStart(), 7698204643Srdivacky E->getOperatorDelete())); 7699204643Srdivacky if (!OperatorDelete) 7700212904Sdim return ExprError(); 7701204643Srdivacky } 7702239462Sdim 7703198092Srdivacky if (!getDerived().AlwaysRebuild() && 7704204643Srdivacky Operand.get() == E->getArgument() && 7705204643Srdivacky OperatorDelete == E->getOperatorDelete()) { 7706204643Srdivacky // Mark any declarations we need as referenced. 7707204643Srdivacky // FIXME: instantiation-specific. 7708204643Srdivacky if (OperatorDelete) 7709234353Sdim SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorDelete); 7710239462Sdim 7711218893Sdim if (!E->getArgument()->isTypeDependent()) { 7712218893Sdim QualType Destroyed = SemaRef.Context.getBaseElementType( 7713218893Sdim E->getDestroyedType()); 7714218893Sdim if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) { 7715218893Sdim CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl()); 7716239462Sdim SemaRef.MarkFunctionReferenced(E->getLocStart(), 7717234353Sdim SemaRef.LookupDestructor(Record)); 7718218893Sdim } 7719218893Sdim } 7720239462Sdim 7721218893Sdim return SemaRef.Owned(E); 7722204643Srdivacky } 7723198092Srdivacky 7724198092Srdivacky return getDerived().RebuildCXXDeleteExpr(E->getLocStart(), 7725198092Srdivacky E->isGlobalDelete(), 7726198092Srdivacky E->isArrayForm(), 7727212904Sdim Operand.get()); 7728198092Srdivacky} 7729198092Srdivacky 7730198092Srdivackytemplate<typename Derived> 7731212904SdimExprResult 7732198092SrdivackyTreeTransform<Derived>::TransformCXXPseudoDestructorExpr( 7733200583Srdivacky CXXPseudoDestructorExpr *E) { 7734212904Sdim ExprResult Base = getDerived().TransformExpr(E->getBase()); 7735198092Srdivacky if (Base.isInvalid()) 7736212904Sdim return ExprError(); 7737198092Srdivacky 7738212904Sdim ParsedType ObjectTypePtr; 7739204643Srdivacky bool MayBePseudoDestructor = false; 7740239462Sdim Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(), 7741204643Srdivacky E->getOperatorLoc(), 7742204643Srdivacky E->isArrow()? tok::arrow : tok::period, 7743204643Srdivacky ObjectTypePtr, 7744204643Srdivacky MayBePseudoDestructor); 7745204643Srdivacky if (Base.isInvalid()) 7746212904Sdim return ExprError(); 7747239462Sdim 7748212904Sdim QualType ObjectType = ObjectTypePtr.get(); 7749219077Sdim NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc(); 7750219077Sdim if (QualifierLoc) { 7751219077Sdim QualifierLoc 7752219077Sdim = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType); 7753219077Sdim if (!QualifierLoc) 7754218893Sdim return ExprError(); 7755218893Sdim } 7756219077Sdim CXXScopeSpec SS; 7757219077Sdim SS.Adopt(QualifierLoc); 7758198092Srdivacky 7759204643Srdivacky PseudoDestructorTypeStorage Destroyed; 7760204643Srdivacky if (E->getDestroyedTypeInfo()) { 7761204643Srdivacky TypeSourceInfo *DestroyedTypeInfo 7762218893Sdim = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(), 7763221345Sdim ObjectType, 0, SS); 7764204643Srdivacky if (!DestroyedTypeInfo) 7765212904Sdim return ExprError(); 7766204643Srdivacky Destroyed = DestroyedTypeInfo; 7767234353Sdim } else if (!ObjectType.isNull() && ObjectType->isDependentType()) { 7768204643Srdivacky // We aren't likely to be able to resolve the identifier down to a type 7769204643Srdivacky // now anyway, so just retain the identifier. 7770204643Srdivacky Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(), 7771204643Srdivacky E->getDestroyedTypeLoc()); 7772204643Srdivacky } else { 7773204643Srdivacky // Look for a destructor known with the given name. 7774212904Sdim ParsedType T = SemaRef.getDestructorName(E->getTildeLoc(), 7775204643Srdivacky *E->getDestroyedTypeIdentifier(), 7776204643Srdivacky E->getDestroyedTypeLoc(), 7777204643Srdivacky /*Scope=*/0, 7778204643Srdivacky SS, ObjectTypePtr, 7779204643Srdivacky false); 7780204643Srdivacky if (!T) 7781212904Sdim return ExprError(); 7782239462Sdim 7783204643Srdivacky Destroyed 7784204643Srdivacky = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T), 7785204643Srdivacky E->getDestroyedTypeLoc()); 7786198092Srdivacky } 7787198092Srdivacky 7788204643Srdivacky TypeSourceInfo *ScopeTypeInfo = 0; 7789204643Srdivacky if (E->getScopeTypeInfo()) { 7790249423Sdim CXXScopeSpec EmptySS; 7791249423Sdim ScopeTypeInfo = getDerived().TransformTypeInObjectScope( 7792249423Sdim E->getScopeTypeInfo(), ObjectType, 0, EmptySS); 7793204643Srdivacky if (!ScopeTypeInfo) 7794212904Sdim return ExprError(); 7795204643Srdivacky } 7796239462Sdim 7797212904Sdim return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(), 7798198092Srdivacky E->getOperatorLoc(), 7799198092Srdivacky E->isArrow(), 7800219077Sdim SS, 7801204643Srdivacky ScopeTypeInfo, 7802204643Srdivacky E->getColonColonLoc(), 7803204643Srdivacky E->getTildeLoc(), 7804204643Srdivacky Destroyed); 7805198092Srdivacky} 7806198092Srdivacky 7807198092Srdivackytemplate<typename Derived> 7808212904SdimExprResult 7809199990SrdivackyTreeTransform<Derived>::TransformUnresolvedLookupExpr( 7810200583Srdivacky UnresolvedLookupExpr *Old) { 7811199990Srdivacky LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(), 7812199990Srdivacky Sema::LookupOrdinaryName); 7813199990Srdivacky 7814199990Srdivacky // Transform all the decls. 7815199990Srdivacky for (UnresolvedLookupExpr::decls_iterator I = Old->decls_begin(), 7816199990Srdivacky E = Old->decls_end(); I != E; ++I) { 7817204643Srdivacky NamedDecl *InstD = static_cast<NamedDecl*>( 7818204643Srdivacky getDerived().TransformDecl(Old->getNameLoc(), 7819204643Srdivacky *I)); 7820200583Srdivacky if (!InstD) { 7821200583Srdivacky // Silently ignore these if a UsingShadowDecl instantiated to nothing. 7822200583Srdivacky // This can happen because of dependent hiding. 7823200583Srdivacky if (isa<UsingShadowDecl>(*I)) 7824200583Srdivacky continue; 7825263508Sdim else { 7826263508Sdim R.clear(); 7827212904Sdim return ExprError(); 7828263508Sdim } 7829200583Srdivacky } 7830199990Srdivacky 7831199990Srdivacky // Expand using declarations. 7832199990Srdivacky if (isa<UsingDecl>(InstD)) { 7833199990Srdivacky UsingDecl *UD = cast<UsingDecl>(InstD); 7834199990Srdivacky for (UsingDecl::shadow_iterator I = UD->shadow_begin(), 7835199990Srdivacky E = UD->shadow_end(); I != E; ++I) 7836199990Srdivacky R.addDecl(*I); 7837199990Srdivacky continue; 7838199990Srdivacky } 7839199990Srdivacky 7840199990Srdivacky R.addDecl(InstD); 7841199990Srdivacky } 7842199990Srdivacky 7843199990Srdivacky // Resolve a kind, but don't do any further analysis. If it's 7844199990Srdivacky // ambiguous, the callee needs to deal with it. 7845199990Srdivacky R.resolveKind(); 7846199990Srdivacky 7847199990Srdivacky // Rebuild the nested-name qualifier, if present. 7848199990Srdivacky CXXScopeSpec SS; 7849221345Sdim if (Old->getQualifierLoc()) { 7850221345Sdim NestedNameSpecifierLoc QualifierLoc 7851221345Sdim = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc()); 7852221345Sdim if (!QualifierLoc) 7853212904Sdim return ExprError(); 7854239462Sdim 7855221345Sdim SS.Adopt(QualifierLoc); 7856239462Sdim } 7857239462Sdim 7858207619Srdivacky if (Old->getNamingClass()) { 7859207619Srdivacky CXXRecordDecl *NamingClass 7860207619Srdivacky = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl( 7861207619Srdivacky Old->getNameLoc(), 7862207619Srdivacky Old->getNamingClass())); 7863263508Sdim if (!NamingClass) { 7864263508Sdim R.clear(); 7865212904Sdim return ExprError(); 7866263508Sdim } 7867239462Sdim 7868207619Srdivacky R.setNamingClass(NamingClass); 7869199990Srdivacky } 7870199990Srdivacky 7871234353Sdim SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc(); 7872234353Sdim 7873234353Sdim // If we have neither explicit template arguments, nor the template keyword, 7874234353Sdim // it's a normal declaration name. 7875234353Sdim if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid()) 7876199990Srdivacky return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL()); 7877199990Srdivacky 7878199990Srdivacky // If we have template arguments, rebuild them, then rebuild the 7879199990Srdivacky // templateid expression. 7880199990Srdivacky TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc()); 7881243830Sdim if (Old->hasExplicitTemplateArgs() && 7882243830Sdim getDerived().TransformTemplateArguments(Old->getTemplateArgs(), 7883218893Sdim Old->getNumTemplateArgs(), 7884263508Sdim TransArgs)) { 7885263508Sdim R.clear(); 7886218893Sdim return ExprError(); 7887263508Sdim } 7888199990Srdivacky 7889234353Sdim return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R, 7890234353Sdim Old->requiresADL(), &TransArgs); 7891198092Srdivacky} 7892198092Srdivacky 7893198092Srdivackytemplate<typename Derived> 7894212904SdimExprResult 7895200583SrdivackyTreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) { 7896218893Sdim TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo()); 7897218893Sdim if (!T) 7898212904Sdim return ExprError(); 7899198092Srdivacky 7900198092Srdivacky if (!getDerived().AlwaysRebuild() && 7901218893Sdim T == E->getQueriedTypeSourceInfo()) 7902218893Sdim return SemaRef.Owned(E); 7903198092Srdivacky 7904198092Srdivacky return getDerived().RebuildUnaryTypeTrait(E->getTrait(), 7905198092Srdivacky E->getLocStart(), 7906198092Srdivacky T, 7907198092Srdivacky E->getLocEnd()); 7908198092Srdivacky} 7909198092Srdivacky 7910198092Srdivackytemplate<typename Derived> 7911212904SdimExprResult 7912218893SdimTreeTransform<Derived>::TransformBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) { 7913218893Sdim TypeSourceInfo *LhsT = getDerived().TransformType(E->getLhsTypeSourceInfo()); 7914218893Sdim if (!LhsT) 7915218893Sdim return ExprError(); 7916218893Sdim 7917218893Sdim TypeSourceInfo *RhsT = getDerived().TransformType(E->getRhsTypeSourceInfo()); 7918218893Sdim if (!RhsT) 7919218893Sdim return ExprError(); 7920218893Sdim 7921218893Sdim if (!getDerived().AlwaysRebuild() && 7922218893Sdim LhsT == E->getLhsTypeSourceInfo() && RhsT == E->getRhsTypeSourceInfo()) 7923218893Sdim return SemaRef.Owned(E); 7924218893Sdim 7925218893Sdim return getDerived().RebuildBinaryTypeTrait(E->getTrait(), 7926218893Sdim E->getLocStart(), 7927218893Sdim LhsT, RhsT, 7928218893Sdim E->getLocEnd()); 7929218893Sdim} 7930218893Sdim 7931218893Sdimtemplate<typename Derived> 7932218893SdimExprResult 7933234353SdimTreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) { 7934234353Sdim bool ArgChanged = false; 7935249423Sdim SmallVector<TypeSourceInfo *, 4> Args; 7936234353Sdim for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) { 7937234353Sdim TypeSourceInfo *From = E->getArg(I); 7938234353Sdim TypeLoc FromTL = From->getTypeLoc(); 7939249423Sdim if (!FromTL.getAs<PackExpansionTypeLoc>()) { 7940234353Sdim TypeLocBuilder TLB; 7941234353Sdim TLB.reserve(FromTL.getFullDataSize()); 7942234353Sdim QualType To = getDerived().TransformType(TLB, FromTL); 7943234353Sdim if (To.isNull()) 7944234353Sdim return ExprError(); 7945239462Sdim 7946234353Sdim if (To == From->getType()) 7947234353Sdim Args.push_back(From); 7948234353Sdim else { 7949234353Sdim Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); 7950234353Sdim ArgChanged = true; 7951234353Sdim } 7952234353Sdim continue; 7953234353Sdim } 7954239462Sdim 7955234353Sdim ArgChanged = true; 7956239462Sdim 7957234353Sdim // We have a pack expansion. Instantiate it. 7958249423Sdim PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>(); 7959234353Sdim TypeLoc PatternTL = ExpansionTL.getPatternLoc(); 7960234353Sdim SmallVector<UnexpandedParameterPack, 2> Unexpanded; 7961234353Sdim SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded); 7962239462Sdim 7963234353Sdim // Determine whether the set of unexpanded parameter packs can and should 7964234353Sdim // be expanded. 7965234353Sdim bool Expand = true; 7966234353Sdim bool RetainExpansion = false; 7967249423Sdim Optional<unsigned> OrigNumExpansions = 7968249423Sdim ExpansionTL.getTypePtr()->getNumExpansions(); 7969249423Sdim Optional<unsigned> NumExpansions = OrigNumExpansions; 7970234353Sdim if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(), 7971234353Sdim PatternTL.getSourceRange(), 7972234353Sdim Unexpanded, 7973234353Sdim Expand, RetainExpansion, 7974234353Sdim NumExpansions)) 7975234353Sdim return ExprError(); 7976239462Sdim 7977234353Sdim if (!Expand) { 7978234353Sdim // The transform has determined that we should perform a simple 7979239462Sdim // transformation on the pack expansion, producing another pack 7980234353Sdim // expansion. 7981234353Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); 7982239462Sdim 7983234353Sdim TypeLocBuilder TLB; 7984234353Sdim TLB.reserve(From->getTypeLoc().getFullDataSize()); 7985234353Sdim 7986234353Sdim QualType To = getDerived().TransformType(TLB, PatternTL); 7987234353Sdim if (To.isNull()) 7988234353Sdim return ExprError(); 7989234353Sdim 7990239462Sdim To = getDerived().RebuildPackExpansionType(To, 7991234353Sdim PatternTL.getSourceRange(), 7992234353Sdim ExpansionTL.getEllipsisLoc(), 7993234353Sdim NumExpansions); 7994234353Sdim if (To.isNull()) 7995234353Sdim return ExprError(); 7996239462Sdim 7997234353Sdim PackExpansionTypeLoc ToExpansionTL 7998234353Sdim = TLB.push<PackExpansionTypeLoc>(To); 7999234353Sdim ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc()); 8000234353Sdim Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); 8001234353Sdim continue; 8002234353Sdim } 8003234353Sdim 8004234353Sdim // Expand the pack expansion by substituting for each argument in the 8005234353Sdim // pack(s). 8006234353Sdim for (unsigned I = 0; I != *NumExpansions; ++I) { 8007234353Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I); 8008234353Sdim TypeLocBuilder TLB; 8009234353Sdim TLB.reserve(PatternTL.getFullDataSize()); 8010234353Sdim QualType To = getDerived().TransformType(TLB, PatternTL); 8011234353Sdim if (To.isNull()) 8012234353Sdim return ExprError(); 8013234353Sdim 8014263508Sdim if (To->containsUnexpandedParameterPack()) { 8015263508Sdim To = getDerived().RebuildPackExpansionType(To, 8016263508Sdim PatternTL.getSourceRange(), 8017263508Sdim ExpansionTL.getEllipsisLoc(), 8018263508Sdim NumExpansions); 8019263508Sdim if (To.isNull()) 8020263508Sdim return ExprError(); 8021263508Sdim 8022263508Sdim PackExpansionTypeLoc ToExpansionTL 8023263508Sdim = TLB.push<PackExpansionTypeLoc>(To); 8024263508Sdim ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc()); 8025263508Sdim } 8026263508Sdim 8027234353Sdim Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); 8028234353Sdim } 8029239462Sdim 8030234353Sdim if (!RetainExpansion) 8031234353Sdim continue; 8032239462Sdim 8033234353Sdim // If we're supposed to retain a pack expansion, do so by temporarily 8034234353Sdim // forgetting the partially-substituted parameter pack. 8035234353Sdim ForgetPartiallySubstitutedPackRAII Forget(getDerived()); 8036234353Sdim 8037234353Sdim TypeLocBuilder TLB; 8038234353Sdim TLB.reserve(From->getTypeLoc().getFullDataSize()); 8039239462Sdim 8040234353Sdim QualType To = getDerived().TransformType(TLB, PatternTL); 8041234353Sdim if (To.isNull()) 8042234353Sdim return ExprError(); 8043239462Sdim 8044239462Sdim To = getDerived().RebuildPackExpansionType(To, 8045234353Sdim PatternTL.getSourceRange(), 8046234353Sdim ExpansionTL.getEllipsisLoc(), 8047234353Sdim NumExpansions); 8048234353Sdim if (To.isNull()) 8049234353Sdim return ExprError(); 8050239462Sdim 8051234353Sdim PackExpansionTypeLoc ToExpansionTL 8052234353Sdim = TLB.push<PackExpansionTypeLoc>(To); 8053234353Sdim ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc()); 8054234353Sdim Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To)); 8055234353Sdim } 8056239462Sdim 8057234353Sdim if (!getDerived().AlwaysRebuild() && !ArgChanged) 8058234353Sdim return SemaRef.Owned(E); 8059234353Sdim 8060234353Sdim return getDerived().RebuildTypeTrait(E->getTrait(), 8061234353Sdim E->getLocStart(), 8062234353Sdim Args, 8063234353Sdim E->getLocEnd()); 8064234353Sdim} 8065234353Sdim 8066234353Sdimtemplate<typename Derived> 8067234353SdimExprResult 8068221345SdimTreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) { 8069221345Sdim TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo()); 8070221345Sdim if (!T) 8071221345Sdim return ExprError(); 8072221345Sdim 8073221345Sdim if (!getDerived().AlwaysRebuild() && 8074221345Sdim T == E->getQueriedTypeSourceInfo()) 8075221345Sdim return SemaRef.Owned(E); 8076221345Sdim 8077221345Sdim ExprResult SubExpr; 8078221345Sdim { 8079221345Sdim EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); 8080221345Sdim SubExpr = getDerived().TransformExpr(E->getDimensionExpression()); 8081221345Sdim if (SubExpr.isInvalid()) 8082221345Sdim return ExprError(); 8083221345Sdim 8084221345Sdim if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression()) 8085221345Sdim return SemaRef.Owned(E); 8086221345Sdim } 8087221345Sdim 8088221345Sdim return getDerived().RebuildArrayTypeTrait(E->getTrait(), 8089221345Sdim E->getLocStart(), 8090221345Sdim T, 8091221345Sdim SubExpr.get(), 8092221345Sdim E->getLocEnd()); 8093221345Sdim} 8094221345Sdim 8095221345Sdimtemplate<typename Derived> 8096221345SdimExprResult 8097221345SdimTreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) { 8098221345Sdim ExprResult SubExpr; 8099221345Sdim { 8100221345Sdim EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); 8101221345Sdim SubExpr = getDerived().TransformExpr(E->getQueriedExpression()); 8102221345Sdim if (SubExpr.isInvalid()) 8103221345Sdim return ExprError(); 8104221345Sdim 8105221345Sdim if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression()) 8106221345Sdim return SemaRef.Owned(E); 8107221345Sdim } 8108221345Sdim 8109221345Sdim return getDerived().RebuildExpressionTrait( 8110221345Sdim E->getTrait(), E->getLocStart(), SubExpr.get(), E->getLocEnd()); 8111221345Sdim} 8112221345Sdim 8113221345Sdimtemplate<typename Derived> 8114221345SdimExprResult 8115199990SrdivackyTreeTransform<Derived>::TransformDependentScopeDeclRefExpr( 8116212904Sdim DependentScopeDeclRefExpr *E) { 8117243830Sdim return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand*/false); 8118243830Sdim} 8119243830Sdim 8120243830Sdimtemplate<typename Derived> 8121243830SdimExprResult 8122243830SdimTreeTransform<Derived>::TransformDependentScopeDeclRefExpr( 8123243830Sdim DependentScopeDeclRefExpr *E, 8124243830Sdim bool IsAddressOfOperand) { 8125263508Sdim assert(E->getQualifierLoc()); 8126219077Sdim NestedNameSpecifierLoc QualifierLoc 8127219077Sdim = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc()); 8128219077Sdim if (!QualifierLoc) 8129212904Sdim return ExprError(); 8130234353Sdim SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); 8131198092Srdivacky 8132218893Sdim // TODO: If this is a conversion-function-id, verify that the 8133218893Sdim // destination type name (if present) resolves the same way after 8134218893Sdim // instantiation as it did in the local scope. 8135218893Sdim 8136212904Sdim DeclarationNameInfo NameInfo 8137212904Sdim = getDerived().TransformDeclarationNameInfo(E->getNameInfo()); 8138212904Sdim if (!NameInfo.getName()) 8139212904Sdim return ExprError(); 8140198092Srdivacky 8141199990Srdivacky if (!E->hasExplicitTemplateArgs()) { 8142199990Srdivacky if (!getDerived().AlwaysRebuild() && 8143219077Sdim QualifierLoc == E->getQualifierLoc() && 8144212904Sdim // Note: it is sufficient to compare the Name component of NameInfo: 8145212904Sdim // if name has not changed, DNLoc has not changed either. 8146212904Sdim NameInfo.getName() == E->getDeclName()) 8147218893Sdim return SemaRef.Owned(E); 8148198092Srdivacky 8149219077Sdim return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc, 8150234353Sdim TemplateKWLoc, 8151212904Sdim NameInfo, 8152243830Sdim /*TemplateArgs*/ 0, 8153243830Sdim IsAddressOfOperand); 8154199990Srdivacky } 8155198092Srdivacky 8156199990Srdivacky TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc()); 8157218893Sdim if (getDerived().TransformTemplateArguments(E->getTemplateArgs(), 8158218893Sdim E->getNumTemplateArgs(), 8159218893Sdim TransArgs)) 8160218893Sdim return ExprError(); 8161198092Srdivacky 8162219077Sdim return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc, 8163234353Sdim TemplateKWLoc, 8164212904Sdim NameInfo, 8165243830Sdim &TransArgs, 8166243830Sdim IsAddressOfOperand); 8167198092Srdivacky} 8168198092Srdivacky 8169198092Srdivackytemplate<typename Derived> 8170212904SdimExprResult 8171200583SrdivackyTreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) { 8172249423Sdim // CXXConstructExprs other than for list-initialization and 8173249423Sdim // CXXTemporaryObjectExpr are always implicit, so when we have 8174249423Sdim // a 1-argument construction we just transform that argument. 8175249423Sdim if ((E->getNumArgs() == 1 || 8176249423Sdim (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) && 8177249423Sdim (!getDerived().DropCallArgument(E->getArg(0))) && 8178249423Sdim !E->isListInitialization()) 8179203955Srdivacky return getDerived().TransformExpr(E->getArg(0)); 8180203955Srdivacky 8181198092Srdivacky TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName()); 8182198092Srdivacky 8183198092Srdivacky QualType T = getDerived().TransformType(E->getType()); 8184198092Srdivacky if (T.isNull()) 8185212904Sdim return ExprError(); 8186198092Srdivacky 8187198092Srdivacky CXXConstructorDecl *Constructor 8188198092Srdivacky = cast_or_null<CXXConstructorDecl>( 8189204643Srdivacky getDerived().TransformDecl(E->getLocStart(), 8190204643Srdivacky E->getConstructor())); 8191198092Srdivacky if (!Constructor) 8192212904Sdim return ExprError(); 8193198092Srdivacky 8194198092Srdivacky bool ArgumentChanged = false; 8195243830Sdim SmallVector<Expr*, 8> Args; 8196239462Sdim if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, 8197218893Sdim &ArgumentChanged)) 8198218893Sdim return ExprError(); 8199239462Sdim 8200198092Srdivacky if (!getDerived().AlwaysRebuild() && 8201198092Srdivacky T == E->getType() && 8202198092Srdivacky Constructor == E->getConstructor() && 8203204643Srdivacky !ArgumentChanged) { 8204204643Srdivacky // Mark the constructor as referenced. 8205204643Srdivacky // FIXME: Instantiation-specific 8206234353Sdim SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor); 8207218893Sdim return SemaRef.Owned(E); 8208204643Srdivacky } 8209198092Srdivacky 8210200583Srdivacky return getDerived().RebuildCXXConstructExpr(T, /*FIXME:*/E->getLocStart(), 8211200583Srdivacky Constructor, E->isElidable(), 8212243830Sdim Args, 8213226633Sdim E->hadMultipleCandidates(), 8214249423Sdim E->isListInitialization(), 8215212904Sdim E->requiresZeroInitialization(), 8216218893Sdim E->getConstructionKind(), 8217263508Sdim E->getParenOrBraceRange()); 8218198092Srdivacky} 8219198092Srdivacky 8220198092Srdivacky/// \brief Transform a C++ temporary-binding expression. 8221198092Srdivacky/// 8222201361Srdivacky/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just 8223201361Srdivacky/// transform the subexpression and return that. 8224198092Srdivackytemplate<typename Derived> 8225212904SdimExprResult 8226200583SrdivackyTreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) { 8227201361Srdivacky return getDerived().TransformExpr(E->getSubExpr()); 8228198092Srdivacky} 8229198092Srdivacky 8230218893Sdim/// \brief Transform a C++ expression that contains cleanups that should 8231218893Sdim/// be run after the expression is evaluated. 8232198092Srdivacky/// 8233218893Sdim/// Since ExprWithCleanups nodes are implicitly generated, we 8234201361Srdivacky/// just transform the subexpression and return that. 8235198092Srdivackytemplate<typename Derived> 8236212904SdimExprResult 8237218893SdimTreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) { 8238201361Srdivacky return getDerived().TransformExpr(E->getSubExpr()); 8239198092Srdivacky} 8240198092Srdivacky 8241198092Srdivackytemplate<typename Derived> 8242212904SdimExprResult 8243198092SrdivackyTreeTransform<Derived>::TransformCXXTemporaryObjectExpr( 8244218893Sdim CXXTemporaryObjectExpr *E) { 8245218893Sdim TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo()); 8246218893Sdim if (!T) 8247212904Sdim return ExprError(); 8248198092Srdivacky 8249198092Srdivacky CXXConstructorDecl *Constructor 8250198092Srdivacky = cast_or_null<CXXConstructorDecl>( 8251239462Sdim getDerived().TransformDecl(E->getLocStart(), 8252204643Srdivacky E->getConstructor())); 8253198092Srdivacky if (!Constructor) 8254212904Sdim return ExprError(); 8255198092Srdivacky 8256198092Srdivacky bool ArgumentChanged = false; 8257243830Sdim SmallVector<Expr*, 8> Args; 8258198092Srdivacky Args.reserve(E->getNumArgs()); 8259239462Sdim if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args, 8260218893Sdim &ArgumentChanged)) 8261218893Sdim return ExprError(); 8262204643Srdivacky 8263198092Srdivacky if (!getDerived().AlwaysRebuild() && 8264218893Sdim T == E->getTypeSourceInfo() && 8265198092Srdivacky Constructor == E->getConstructor() && 8266204643Srdivacky !ArgumentChanged) { 8267204643Srdivacky // FIXME: Instantiation-specific 8268234353Sdim SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor); 8269218893Sdim return SemaRef.MaybeBindToTemporary(E); 8270204643Srdivacky } 8271239462Sdim 8272249423Sdim // FIXME: Pass in E->isListInitialization(). 8273218893Sdim return getDerived().RebuildCXXTemporaryObjectExpr(T, 8274218893Sdim /*FIXME:*/T->getTypeLoc().getEndLoc(), 8275243830Sdim Args, 8276198092Srdivacky E->getLocEnd()); 8277198092Srdivacky} 8278198092Srdivacky 8279198092Srdivackytemplate<typename Derived> 8280212904SdimExprResult 8281234353SdimTreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { 8282263508Sdim 8283263508Sdim // Transform any init-capture expressions before entering the scope of the 8284263508Sdim // lambda body, because they are not semantically within that scope. 8285263508Sdim SmallVector<InitCaptureInfoTy, 8> InitCaptureExprsAndTypes; 8286263508Sdim InitCaptureExprsAndTypes.resize(E->explicit_capture_end() - 8287263508Sdim E->explicit_capture_begin()); 8288263508Sdim 8289263508Sdim for (LambdaExpr::capture_iterator C = E->capture_begin(), 8290263508Sdim CEnd = E->capture_end(); 8291263508Sdim C != CEnd; ++C) { 8292263508Sdim if (!C->isInitCapture()) 8293263508Sdim continue; 8294263508Sdim EnterExpressionEvaluationContext EEEC(getSema(), 8295263508Sdim Sema::PotentiallyEvaluated); 8296263508Sdim ExprResult NewExprInitResult = getDerived().TransformInitializer( 8297263508Sdim C->getCapturedVar()->getInit(), 8298263508Sdim C->getCapturedVar()->getInitStyle() == VarDecl::CallInit); 8299263508Sdim 8300263508Sdim if (NewExprInitResult.isInvalid()) 8301263508Sdim return ExprError(); 8302263508Sdim Expr *NewExprInit = NewExprInitResult.get(); 8303263508Sdim 8304263508Sdim VarDecl *OldVD = C->getCapturedVar(); 8305263508Sdim QualType NewInitCaptureType = 8306263508Sdim getSema().performLambdaInitCaptureInitialization(C->getLocation(), 8307263508Sdim OldVD->getType()->isReferenceType(), OldVD->getIdentifier(), 8308263508Sdim NewExprInit); 8309263508Sdim NewExprInitResult = NewExprInit; 8310263508Sdim InitCaptureExprsAndTypes[C - E->capture_begin()] = 8311263508Sdim std::make_pair(NewExprInitResult, NewInitCaptureType); 8312263508Sdim 8313263508Sdim } 8314263508Sdim 8315263508Sdim LambdaScopeInfo *LSI = getSema().PushLambdaScope(); 8316263508Sdim // Transform the template parameters, and add them to the current 8317263508Sdim // instantiation scope. The null case is handled correctly. 8318263508Sdim LSI->GLTemplateParameterList = getDerived().TransformTemplateParameterList( 8319263508Sdim E->getTemplateParameterList()); 8320263508Sdim 8321263508Sdim // Check to see if the TypeSourceInfo of the call operator needs to 8322263508Sdim // be transformed, and if so do the transformation in the 8323263508Sdim // CurrentInstantiationScope. 8324263508Sdim 8325263508Sdim TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo(); 8326263508Sdim FunctionProtoTypeLoc OldCallOpFPTL = 8327263508Sdim OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>(); 8328263508Sdim TypeSourceInfo *NewCallOpTSI = 0; 8329263508Sdim 8330263508Sdim const bool CallOpWasAlreadyTransformed = 8331263508Sdim getDerived().AlreadyTransformed(OldCallOpTSI->getType()); 8332263508Sdim 8333263508Sdim // Use the Old Call Operator's TypeSourceInfo if it is already transformed. 8334263508Sdim if (CallOpWasAlreadyTransformed) 8335263508Sdim NewCallOpTSI = OldCallOpTSI; 8336263508Sdim else { 8337263508Sdim // Transform the TypeSourceInfo of the Original Lambda's Call Operator. 8338263508Sdim // The transformation MUST be done in the CurrentInstantiationScope since 8339263508Sdim // it introduces a mapping of the original to the newly created 8340263508Sdim // transformed parameters. 8341263508Sdim 8342263508Sdim TypeLocBuilder NewCallOpTLBuilder; 8343263508Sdim QualType NewCallOpType = TransformFunctionProtoType(NewCallOpTLBuilder, 8344263508Sdim OldCallOpFPTL, 8345263508Sdim 0, 0); 8346263508Sdim NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, 8347263508Sdim NewCallOpType); 8348263508Sdim } 8349263508Sdim // Extract the ParmVarDecls from the NewCallOpTSI and add them to 8350263508Sdim // the vector below - this will be used to synthesize the 8351263508Sdim // NewCallOperator. Additionally, add the parameters of the untransformed 8352263508Sdim // lambda call operator to the CurrentInstantiationScope. 8353263508Sdim SmallVector<ParmVarDecl *, 4> Params; 8354263508Sdim { 8355263508Sdim FunctionProtoTypeLoc NewCallOpFPTL = 8356263508Sdim NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>(); 8357263508Sdim ParmVarDecl **NewParamDeclArray = NewCallOpFPTL.getParmArray(); 8358263508Sdim const unsigned NewNumArgs = NewCallOpFPTL.getNumArgs(); 8359263508Sdim 8360263508Sdim for (unsigned I = 0; I < NewNumArgs; ++I) { 8361263508Sdim // If this call operator's type does not require transformation, 8362263508Sdim // the parameters do not get added to the current instantiation scope, 8363263508Sdim // - so ADD them! This allows the following to compile when the enclosing 8364263508Sdim // template is specialized and the entire lambda expression has to be 8365263508Sdim // transformed. 8366263508Sdim // template<class T> void foo(T t) { 8367263508Sdim // auto L = [](auto a) { 8368263508Sdim // auto M = [](char b) { <-- note: non-generic lambda 8369263508Sdim // auto N = [](auto c) { 8370263508Sdim // int x = sizeof(a); 8371263508Sdim // x = sizeof(b); <-- specifically this line 8372263508Sdim // x = sizeof(c); 8373263508Sdim // }; 8374263508Sdim // }; 8375263508Sdim // }; 8376263508Sdim // } 8377263508Sdim // foo('a') 8378263508Sdim if (CallOpWasAlreadyTransformed) 8379263508Sdim getDerived().transformedLocalDecl(NewParamDeclArray[I], 8380263508Sdim NewParamDeclArray[I]); 8381263508Sdim // Add to Params array, so these parameters can be used to create 8382263508Sdim // the newly transformed call operator. 8383263508Sdim Params.push_back(NewParamDeclArray[I]); 8384263508Sdim } 8385263508Sdim } 8386263508Sdim 8387263508Sdim if (!NewCallOpTSI) 8388234353Sdim return ExprError(); 8389234353Sdim 8390243830Sdim // Create the local class that will describe the lambda. 8391243830Sdim CXXRecordDecl *Class 8392243830Sdim = getSema().createLambdaClosureType(E->getIntroducerRange(), 8393263508Sdim NewCallOpTSI, 8394263508Sdim /*KnownDependent=*/false, 8395263508Sdim E->getCaptureDefault()); 8396263508Sdim 8397243830Sdim getDerived().transformedLocalDecl(E->getLambdaClass(), Class); 8398243830Sdim 8399234353Sdim // Build the call operator. 8400263508Sdim CXXMethodDecl *NewCallOperator 8401234353Sdim = getSema().startLambdaDefinition(Class, E->getIntroducerRange(), 8402263508Sdim NewCallOpTSI, 8403234353Sdim E->getCallOperator()->getLocEnd(), 8404239462Sdim Params); 8405263508Sdim LSI->CallOperator = NewCallOperator; 8406234353Sdim 8407263508Sdim getDerived().transformAttrs(E->getCallOperator(), NewCallOperator); 8408263508Sdim 8409263508Sdim return getDerived().TransformLambdaScope(E, NewCallOperator, 8410263508Sdim InitCaptureExprsAndTypes); 8411239462Sdim} 8412239462Sdim 8413239462Sdimtemplate<typename Derived> 8414239462SdimExprResult 8415239462SdimTreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E, 8416263508Sdim CXXMethodDecl *CallOperator, 8417263508Sdim ArrayRef<InitCaptureInfoTy> InitCaptureExprsAndTypes) { 8418263508Sdim bool Invalid = false; 8419263508Sdim 8420234353Sdim // Introduce the context of the call operator. 8421234353Sdim Sema::ContextRAII SavedContext(getSema(), CallOperator); 8422234353Sdim 8423263508Sdim LambdaScopeInfo *const LSI = getSema().getCurLambda(); 8424234353Sdim // Enter the scope of the lambda. 8425263508Sdim getSema().buildLambdaScope(LSI, CallOperator, E->getIntroducerRange(), 8426234353Sdim E->getCaptureDefault(), 8427263508Sdim E->getCaptureDefaultLoc(), 8428234353Sdim E->hasExplicitParameters(), 8429234353Sdim E->hasExplicitResultType(), 8430234353Sdim E->isMutable()); 8431239462Sdim 8432234353Sdim // Transform captures. 8433234353Sdim bool FinishedExplicitCaptures = false; 8434239462Sdim for (LambdaExpr::capture_iterator C = E->capture_begin(), 8435234353Sdim CEnd = E->capture_end(); 8436234353Sdim C != CEnd; ++C) { 8437234353Sdim // When we hit the first implicit capture, tell Sema that we've finished 8438234353Sdim // the list of explicit captures. 8439234353Sdim if (!FinishedExplicitCaptures && C->isImplicit()) { 8440234353Sdim getSema().finishLambdaExplicitCaptures(LSI); 8441234353Sdim FinishedExplicitCaptures = true; 8442234353Sdim } 8443239462Sdim 8444234353Sdim // Capturing 'this' is trivial. 8445234353Sdim if (C->capturesThis()) { 8446234353Sdim getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit()); 8447234353Sdim continue; 8448234353Sdim } 8449239462Sdim 8450263508Sdim // Rebuild init-captures, including the implied field declaration. 8451263508Sdim if (C->isInitCapture()) { 8452263508Sdim 8453263508Sdim InitCaptureInfoTy InitExprTypePair = 8454263508Sdim InitCaptureExprsAndTypes[C - E->capture_begin()]; 8455263508Sdim ExprResult Init = InitExprTypePair.first; 8456263508Sdim QualType InitQualType = InitExprTypePair.second; 8457263508Sdim if (Init.isInvalid() || InitQualType.isNull()) { 8458263508Sdim Invalid = true; 8459263508Sdim continue; 8460263508Sdim } 8461263508Sdim VarDecl *OldVD = C->getCapturedVar(); 8462263508Sdim VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl( 8463263508Sdim OldVD->getLocation(), InitExprTypePair.second, 8464263508Sdim OldVD->getIdentifier(), Init.get()); 8465263508Sdim if (!NewVD) 8466263508Sdim Invalid = true; 8467263508Sdim else { 8468263508Sdim getDerived().transformedLocalDecl(OldVD, NewVD); 8469263508Sdim } 8470263508Sdim getSema().buildInitCaptureField(LSI, NewVD); 8471263508Sdim continue; 8472263508Sdim } 8473263508Sdim 8474263508Sdim assert(C->capturesVariable() && "unexpected kind of lambda capture"); 8475263508Sdim 8476234353Sdim // Determine the capture kind for Sema. 8477234353Sdim Sema::TryCaptureKind Kind 8478234353Sdim = C->isImplicit()? Sema::TryCapture_Implicit 8479234353Sdim : C->getCaptureKind() == LCK_ByCopy 8480234353Sdim ? Sema::TryCapture_ExplicitByVal 8481234353Sdim : Sema::TryCapture_ExplicitByRef; 8482234353Sdim SourceLocation EllipsisLoc; 8483234353Sdim if (C->isPackExpansion()) { 8484234353Sdim UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation()); 8485234353Sdim bool ShouldExpand = false; 8486234353Sdim bool RetainExpansion = false; 8487249423Sdim Optional<unsigned> NumExpansions; 8488239462Sdim if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(), 8489239462Sdim C->getLocation(), 8490234353Sdim Unexpanded, 8491234353Sdim ShouldExpand, RetainExpansion, 8492263508Sdim NumExpansions)) { 8493263508Sdim Invalid = true; 8494263508Sdim continue; 8495263508Sdim } 8496239462Sdim 8497234353Sdim if (ShouldExpand) { 8498234353Sdim // The transform has determined that we should perform an expansion; 8499234353Sdim // transform and capture each of the arguments. 8500234353Sdim // expansion of the pattern. Do so. 8501234353Sdim VarDecl *Pack = C->getCapturedVar(); 8502234353Sdim for (unsigned I = 0; I != *NumExpansions; ++I) { 8503234353Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); 8504234353Sdim VarDecl *CapturedVar 8505239462Sdim = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(), 8506234353Sdim Pack)); 8507234353Sdim if (!CapturedVar) { 8508234353Sdim Invalid = true; 8509234353Sdim continue; 8510234353Sdim } 8511239462Sdim 8512234353Sdim // Capture the transformed variable. 8513239462Sdim getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind); 8514239462Sdim } 8515234353Sdim continue; 8516234353Sdim } 8517239462Sdim 8518234353Sdim EllipsisLoc = C->getEllipsisLoc(); 8519234353Sdim } 8520239462Sdim 8521234353Sdim // Transform the captured variable. 8522234353Sdim VarDecl *CapturedVar 8523239462Sdim = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(), 8524234353Sdim C->getCapturedVar())); 8525234353Sdim if (!CapturedVar) { 8526234353Sdim Invalid = true; 8527234353Sdim continue; 8528234353Sdim } 8529239462Sdim 8530234353Sdim // Capture the transformed variable. 8531234353Sdim getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind); 8532234353Sdim } 8533234353Sdim if (!FinishedExplicitCaptures) 8534234353Sdim getSema().finishLambdaExplicitCaptures(LSI); 8535234353Sdim 8536234353Sdim 8537234353Sdim // Enter a new evaluation context to insulate the lambda from any 8538234353Sdim // cleanups from the enclosing full-expression. 8539239462Sdim getSema().PushExpressionEvaluationContext(Sema::PotentiallyEvaluated); 8540234353Sdim 8541234353Sdim if (Invalid) { 8542239462Sdim getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0, 8543234353Sdim /*IsInstantiation=*/true); 8544234353Sdim return ExprError(); 8545234353Sdim } 8546234353Sdim 8547234353Sdim // Instantiate the body of the lambda expression. 8548234353Sdim StmtResult Body = getDerived().TransformStmt(E->getBody()); 8549234353Sdim if (Body.isInvalid()) { 8550239462Sdim getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0, 8551234353Sdim /*IsInstantiation=*/true); 8552239462Sdim return ExprError(); 8553234353Sdim } 8554234353Sdim 8555239462Sdim return getSema().ActOnLambdaExpr(E->getLocStart(), Body.take(), 8556234353Sdim /*CurScope=*/0, /*IsInstantiation=*/true); 8557234353Sdim} 8558234353Sdim 8559234353Sdimtemplate<typename Derived> 8560234353SdimExprResult 8561198092SrdivackyTreeTransform<Derived>::TransformCXXUnresolvedConstructExpr( 8562200583Srdivacky CXXUnresolvedConstructExpr *E) { 8563218893Sdim TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo()); 8564218893Sdim if (!T) 8565212904Sdim return ExprError(); 8566198092Srdivacky 8567198092Srdivacky bool ArgumentChanged = false; 8568243830Sdim SmallVector<Expr*, 8> Args; 8569218893Sdim Args.reserve(E->arg_size()); 8570239462Sdim if (getDerived().TransformExprs(E->arg_begin(), E->arg_size(), true, Args, 8571218893Sdim &ArgumentChanged)) 8572218893Sdim return ExprError(); 8573239462Sdim 8574198092Srdivacky if (!getDerived().AlwaysRebuild() && 8575218893Sdim T == E->getTypeSourceInfo() && 8576198092Srdivacky !ArgumentChanged) 8577218893Sdim return SemaRef.Owned(E); 8578198092Srdivacky 8579198092Srdivacky // FIXME: we're faking the locations of the commas 8580218893Sdim return getDerived().RebuildCXXUnresolvedConstructExpr(T, 8581198092Srdivacky E->getLParenLoc(), 8582243830Sdim Args, 8583198092Srdivacky E->getRParenLoc()); 8584198092Srdivacky} 8585198092Srdivacky 8586198092Srdivackytemplate<typename Derived> 8587212904SdimExprResult 8588199990SrdivackyTreeTransform<Derived>::TransformCXXDependentScopeMemberExpr( 8589212904Sdim CXXDependentScopeMemberExpr *E) { 8590198092Srdivacky // Transform the base of the expression. 8591212904Sdim ExprResult Base((Expr*) 0); 8592200583Srdivacky Expr *OldBase; 8593200583Srdivacky QualType BaseType; 8594200583Srdivacky QualType ObjectType; 8595200583Srdivacky if (!E->isImplicitAccess()) { 8596200583Srdivacky OldBase = E->getBase(); 8597200583Srdivacky Base = getDerived().TransformExpr(OldBase); 8598200583Srdivacky if (Base.isInvalid()) 8599212904Sdim return ExprError(); 8600198092Srdivacky 8601200583Srdivacky // Start the member reference and compute the object's type. 8602212904Sdim ParsedType ObjectTy; 8603204643Srdivacky bool MayBePseudoDestructor = false; 8604212904Sdim Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(), 8605200583Srdivacky E->getOperatorLoc(), 8606198092Srdivacky E->isArrow()? tok::arrow : tok::period, 8607204643Srdivacky ObjectTy, 8608204643Srdivacky MayBePseudoDestructor); 8609200583Srdivacky if (Base.isInvalid()) 8610212904Sdim return ExprError(); 8611198092Srdivacky 8612212904Sdim ObjectType = ObjectTy.get(); 8613200583Srdivacky BaseType = ((Expr*) Base.get())->getType(); 8614200583Srdivacky } else { 8615200583Srdivacky OldBase = 0; 8616200583Srdivacky BaseType = getDerived().TransformType(E->getBaseType()); 8617200583Srdivacky ObjectType = BaseType->getAs<PointerType>()->getPointeeType(); 8618200583Srdivacky } 8619200583Srdivacky 8620198398Srdivacky // Transform the first part of the nested-name-specifier that qualifies 8621198398Srdivacky // the member name. 8622198092Srdivacky NamedDecl *FirstQualifierInScope 8623198398Srdivacky = getDerived().TransformFirstQualifierInScope( 8624221345Sdim E->getFirstQualifierFoundInScope(), 8625221345Sdim E->getQualifierLoc().getBeginLoc()); 8626198092Srdivacky 8627221345Sdim NestedNameSpecifierLoc QualifierLoc; 8628198092Srdivacky if (E->getQualifier()) { 8629221345Sdim QualifierLoc 8630221345Sdim = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(), 8631221345Sdim ObjectType, 8632221345Sdim FirstQualifierInScope); 8633221345Sdim if (!QualifierLoc) 8634212904Sdim return ExprError(); 8635198092Srdivacky } 8636198092Srdivacky 8637234353Sdim SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc(); 8638234353Sdim 8639218893Sdim // TODO: If this is a conversion-function-id, verify that the 8640218893Sdim // destination type name (if present) resolves the same way after 8641218893Sdim // instantiation as it did in the local scope. 8642218893Sdim 8643212904Sdim DeclarationNameInfo NameInfo 8644218893Sdim = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo()); 8645212904Sdim if (!NameInfo.getName()) 8646212904Sdim return ExprError(); 8647198092Srdivacky 8648200583Srdivacky if (!E->hasExplicitTemplateArgs()) { 8649198092Srdivacky // This is a reference to a member without an explicitly-specified 8650198092Srdivacky // template argument list. Optimize for this common case. 8651198092Srdivacky if (!getDerived().AlwaysRebuild() && 8652200583Srdivacky Base.get() == OldBase && 8653200583Srdivacky BaseType == E->getBaseType() && 8654221345Sdim QualifierLoc == E->getQualifierLoc() && 8655212904Sdim NameInfo.getName() == E->getMember() && 8656198092Srdivacky FirstQualifierInScope == E->getFirstQualifierFoundInScope()) 8657218893Sdim return SemaRef.Owned(E); 8658198092Srdivacky 8659212904Sdim return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(), 8660200583Srdivacky BaseType, 8661198092Srdivacky E->isArrow(), 8662198092Srdivacky E->getOperatorLoc(), 8663221345Sdim QualifierLoc, 8664234353Sdim TemplateKWLoc, 8665199990Srdivacky FirstQualifierInScope, 8666212904Sdim NameInfo, 8667199990Srdivacky /*TemplateArgs*/ 0); 8668198092Srdivacky } 8669198092Srdivacky 8670199990Srdivacky TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc()); 8671218893Sdim if (getDerived().TransformTemplateArguments(E->getTemplateArgs(), 8672218893Sdim E->getNumTemplateArgs(), 8673218893Sdim TransArgs)) 8674218893Sdim return ExprError(); 8675198092Srdivacky 8676212904Sdim return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(), 8677200583Srdivacky BaseType, 8678198092Srdivacky E->isArrow(), 8679198092Srdivacky E->getOperatorLoc(), 8680221345Sdim QualifierLoc, 8681234353Sdim TemplateKWLoc, 8682199990Srdivacky FirstQualifierInScope, 8683212904Sdim NameInfo, 8684199990Srdivacky &TransArgs); 8685198092Srdivacky} 8686198092Srdivacky 8687198092Srdivackytemplate<typename Derived> 8688212904SdimExprResult 8689200583SrdivackyTreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) { 8690199990Srdivacky // Transform the base of the expression. 8691212904Sdim ExprResult Base((Expr*) 0); 8692200583Srdivacky QualType BaseType; 8693200583Srdivacky if (!Old->isImplicitAccess()) { 8694200583Srdivacky Base = getDerived().TransformExpr(Old->getBase()); 8695200583Srdivacky if (Base.isInvalid()) 8696212904Sdim return ExprError(); 8697234353Sdim Base = getSema().PerformMemberExprBaseConversion(Base.take(), 8698234353Sdim Old->isArrow()); 8699234353Sdim if (Base.isInvalid()) 8700234353Sdim return ExprError(); 8701234353Sdim BaseType = Base.get()->getType(); 8702200583Srdivacky } else { 8703200583Srdivacky BaseType = getDerived().TransformType(Old->getBaseType()); 8704200583Srdivacky } 8705199990Srdivacky 8706221345Sdim NestedNameSpecifierLoc QualifierLoc; 8707221345Sdim if (Old->getQualifierLoc()) { 8708221345Sdim QualifierLoc 8709221345Sdim = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc()); 8710221345Sdim if (!QualifierLoc) 8711212904Sdim return ExprError(); 8712199990Srdivacky } 8713199990Srdivacky 8714234353Sdim SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc(); 8715234353Sdim 8716212904Sdim LookupResult R(SemaRef, Old->getMemberNameInfo(), 8717199990Srdivacky Sema::LookupOrdinaryName); 8718199990Srdivacky 8719199990Srdivacky // Transform all the decls. 8720199990Srdivacky for (UnresolvedMemberExpr::decls_iterator I = Old->decls_begin(), 8721199990Srdivacky E = Old->decls_end(); I != E; ++I) { 8722204643Srdivacky NamedDecl *InstD = static_cast<NamedDecl*>( 8723204643Srdivacky getDerived().TransformDecl(Old->getMemberLoc(), 8724204643Srdivacky *I)); 8725200583Srdivacky if (!InstD) { 8726200583Srdivacky // Silently ignore these if a UsingShadowDecl instantiated to nothing. 8727200583Srdivacky // This can happen because of dependent hiding. 8728200583Srdivacky if (isa<UsingShadowDecl>(*I)) 8729200583Srdivacky continue; 8730221345Sdim else { 8731221345Sdim R.clear(); 8732212904Sdim return ExprError(); 8733221345Sdim } 8734200583Srdivacky } 8735199990Srdivacky 8736199990Srdivacky // Expand using declarations. 8737199990Srdivacky if (isa<UsingDecl>(InstD)) { 8738199990Srdivacky UsingDecl *UD = cast<UsingDecl>(InstD); 8739199990Srdivacky for (UsingDecl::shadow_iterator I = UD->shadow_begin(), 8740199990Srdivacky E = UD->shadow_end(); I != E; ++I) 8741199990Srdivacky R.addDecl(*I); 8742199990Srdivacky continue; 8743199990Srdivacky } 8744199990Srdivacky 8745199990Srdivacky R.addDecl(InstD); 8746199990Srdivacky } 8747199990Srdivacky 8748199990Srdivacky R.resolveKind(); 8749199990Srdivacky 8750207619Srdivacky // Determine the naming class. 8751208600Srdivacky if (Old->getNamingClass()) { 8752239462Sdim CXXRecordDecl *NamingClass 8753207619Srdivacky = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl( 8754207619Srdivacky Old->getMemberLoc(), 8755207619Srdivacky Old->getNamingClass())); 8756207619Srdivacky if (!NamingClass) 8757212904Sdim return ExprError(); 8758239462Sdim 8759207619Srdivacky R.setNamingClass(NamingClass); 8760207619Srdivacky } 8761239462Sdim 8762199990Srdivacky TemplateArgumentListInfo TransArgs; 8763199990Srdivacky if (Old->hasExplicitTemplateArgs()) { 8764199990Srdivacky TransArgs.setLAngleLoc(Old->getLAngleLoc()); 8765199990Srdivacky TransArgs.setRAngleLoc(Old->getRAngleLoc()); 8766218893Sdim if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(), 8767218893Sdim Old->getNumTemplateArgs(), 8768218893Sdim TransArgs)) 8769218893Sdim return ExprError(); 8770199990Srdivacky } 8771202379Srdivacky 8772202379Srdivacky // FIXME: to do this check properly, we will need to preserve the 8773202379Srdivacky // first-qualifier-in-scope here, just in case we had a dependent 8774202379Srdivacky // base (and therefore couldn't do the check) and a 8775202379Srdivacky // nested-name-qualifier (and therefore could do the lookup). 8776202379Srdivacky NamedDecl *FirstQualifierInScope = 0; 8777239462Sdim 8778212904Sdim return getDerived().RebuildUnresolvedMemberExpr(Base.get(), 8779200583Srdivacky BaseType, 8780199990Srdivacky Old->getOperatorLoc(), 8781199990Srdivacky Old->isArrow(), 8782221345Sdim QualifierLoc, 8783234353Sdim TemplateKWLoc, 8784202379Srdivacky FirstQualifierInScope, 8785199990Srdivacky R, 8786199990Srdivacky (Old->hasExplicitTemplateArgs() 8787199990Srdivacky ? &TransArgs : 0)); 8788199990Srdivacky} 8789199990Srdivacky 8790199990Srdivackytemplate<typename Derived> 8791212904SdimExprResult 8792218893SdimTreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) { 8793223017Sdim EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); 8794218893Sdim ExprResult SubExpr = getDerived().TransformExpr(E->getOperand()); 8795218893Sdim if (SubExpr.isInvalid()) 8796218893Sdim return ExprError(); 8797218893Sdim 8798218893Sdim if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand()) 8799218893Sdim return SemaRef.Owned(E); 8800218893Sdim 8801218893Sdim return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get()); 8802218893Sdim} 8803218893Sdim 8804218893Sdimtemplate<typename Derived> 8805218893SdimExprResult 8806218893SdimTreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) { 8807218893Sdim ExprResult Pattern = getDerived().TransformExpr(E->getPattern()); 8808218893Sdim if (Pattern.isInvalid()) 8809218893Sdim return ExprError(); 8810239462Sdim 8811218893Sdim if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern()) 8812218893Sdim return SemaRef.Owned(E); 8813218893Sdim 8814218893Sdim return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(), 8815218893Sdim E->getNumExpansions()); 8816218893Sdim} 8817218893Sdim 8818218893Sdimtemplate<typename Derived> 8819218893SdimExprResult 8820218893SdimTreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) { 8821218893Sdim // If E is not value-dependent, then nothing will change when we transform it. 8822218893Sdim // Note: This is an instantiation-centric view. 8823218893Sdim if (!E->isValueDependent()) 8824218893Sdim return SemaRef.Owned(E); 8825218893Sdim 8826218893Sdim // Note: None of the implementations of TryExpandParameterPacks can ever 8827218893Sdim // produce a diagnostic when given only a single unexpanded parameter pack, 8828239462Sdim // so 8829218893Sdim UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc()); 8830218893Sdim bool ShouldExpand = false; 8831218893Sdim bool RetainExpansion = false; 8832249423Sdim Optional<unsigned> NumExpansions; 8833239462Sdim if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(), 8834226633Sdim Unexpanded, 8835218893Sdim ShouldExpand, RetainExpansion, 8836218893Sdim NumExpansions)) 8837218893Sdim return ExprError(); 8838239462Sdim 8839226633Sdim if (RetainExpansion) 8840218893Sdim return SemaRef.Owned(E); 8841239462Sdim 8842226633Sdim NamedDecl *Pack = E->getPack(); 8843226633Sdim if (!ShouldExpand) { 8844239462Sdim Pack = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getPackLoc(), 8845226633Sdim Pack)); 8846226633Sdim if (!Pack) 8847226633Sdim return ExprError(); 8848226633Sdim } 8849226633Sdim 8850239462Sdim 8851218893Sdim // We now know the length of the parameter pack, so build a new expression 8852218893Sdim // that stores that length. 8853239462Sdim return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), Pack, 8854239462Sdim E->getPackLoc(), E->getRParenLoc(), 8855226633Sdim NumExpansions); 8856218893Sdim} 8857218893Sdim 8858218893Sdimtemplate<typename Derived> 8859218893SdimExprResult 8860218893SdimTreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr( 8861218893Sdim SubstNonTypeTemplateParmPackExpr *E) { 8862218893Sdim // Default behavior is to do nothing with this transformation. 8863218893Sdim return SemaRef.Owned(E); 8864218893Sdim} 8865218893Sdim 8866218893Sdimtemplate<typename Derived> 8867218893SdimExprResult 8868224145SdimTreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr( 8869224145Sdim SubstNonTypeTemplateParmExpr *E) { 8870224145Sdim // Default behavior is to do nothing with this transformation. 8871224145Sdim return SemaRef.Owned(E); 8872224145Sdim} 8873224145Sdim 8874224145Sdimtemplate<typename Derived> 8875224145SdimExprResult 8876243830SdimTreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) { 8877243830Sdim // Default behavior is to do nothing with this transformation. 8878243830Sdim return SemaRef.Owned(E); 8879243830Sdim} 8880243830Sdim 8881243830Sdimtemplate<typename Derived> 8882243830SdimExprResult 8883224145SdimTreeTransform<Derived>::TransformMaterializeTemporaryExpr( 8884224145Sdim MaterializeTemporaryExpr *E) { 8885224145Sdim return getDerived().TransformExpr(E->GetTemporaryExpr()); 8886224145Sdim} 8887239462Sdim 8888224145Sdimtemplate<typename Derived> 8889224145SdimExprResult 8890263508SdimTreeTransform<Derived>::TransformCXXStdInitializerListExpr( 8891263508Sdim CXXStdInitializerListExpr *E) { 8892263508Sdim return getDerived().TransformExpr(E->getSubExpr()); 8893263508Sdim} 8894263508Sdim 8895263508Sdimtemplate<typename Derived> 8896263508SdimExprResult 8897200583SrdivackyTreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) { 8898234353Sdim return SemaRef.MaybeBindToTemporary(E); 8899234353Sdim} 8900234353Sdim 8901234353Sdimtemplate<typename Derived> 8902234353SdimExprResult 8903234353SdimTreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) { 8904218893Sdim return SemaRef.Owned(E); 8905198092Srdivacky} 8906198092Srdivacky 8907198092Srdivackytemplate<typename Derived> 8908212904SdimExprResult 8909239462SdimTreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) { 8910239462Sdim ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr()); 8911239462Sdim if (SubExpr.isInvalid()) 8912239462Sdim return ExprError(); 8913239462Sdim 8914239462Sdim if (!getDerived().AlwaysRebuild() && 8915239462Sdim SubExpr.get() == E->getSubExpr()) 8916239462Sdim return SemaRef.Owned(E); 8917239462Sdim 8918239462Sdim return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get()); 8919234353Sdim} 8920234353Sdim 8921234353Sdimtemplate<typename Derived> 8922234353SdimExprResult 8923234353SdimTreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) { 8924234353Sdim // Transform each of the elements. 8925249423Sdim SmallVector<Expr *, 8> Elements; 8926234353Sdim bool ArgChanged = false; 8927239462Sdim if (getDerived().TransformExprs(E->getElements(), E->getNumElements(), 8928234353Sdim /*IsCall=*/false, Elements, &ArgChanged)) 8929234353Sdim return ExprError(); 8930239462Sdim 8931234353Sdim if (!getDerived().AlwaysRebuild() && !ArgChanged) 8932234353Sdim return SemaRef.MaybeBindToTemporary(E); 8933239462Sdim 8934234353Sdim return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(), 8935234353Sdim Elements.data(), 8936234353Sdim Elements.size()); 8937234353Sdim} 8938234353Sdim 8939234353Sdimtemplate<typename Derived> 8940234353SdimExprResult 8941234353SdimTreeTransform<Derived>::TransformObjCDictionaryLiteral( 8942239462Sdim ObjCDictionaryLiteral *E) { 8943234353Sdim // Transform each of the elements. 8944249423Sdim SmallVector<ObjCDictionaryElement, 8> Elements; 8945234353Sdim bool ArgChanged = false; 8946234353Sdim for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) { 8947234353Sdim ObjCDictionaryElement OrigElement = E->getKeyValueElement(I); 8948239462Sdim 8949234353Sdim if (OrigElement.isPackExpansion()) { 8950234353Sdim // This key/value element is a pack expansion. 8951234353Sdim SmallVector<UnexpandedParameterPack, 2> Unexpanded; 8952234353Sdim getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded); 8953234353Sdim getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded); 8954234353Sdim assert(!Unexpanded.empty() && "Pack expansion without parameter packs?"); 8955234353Sdim 8956234353Sdim // Determine whether the set of unexpanded parameter packs can 8957234353Sdim // and should be expanded. 8958234353Sdim bool Expand = true; 8959234353Sdim bool RetainExpansion = false; 8960249423Sdim Optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions; 8961249423Sdim Optional<unsigned> NumExpansions = OrigNumExpansions; 8962234353Sdim SourceRange PatternRange(OrigElement.Key->getLocStart(), 8963234353Sdim OrigElement.Value->getLocEnd()); 8964234353Sdim if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc, 8965234353Sdim PatternRange, 8966234353Sdim Unexpanded, 8967234353Sdim Expand, RetainExpansion, 8968234353Sdim NumExpansions)) 8969234353Sdim return ExprError(); 8970234353Sdim 8971234353Sdim if (!Expand) { 8972234353Sdim // The transform has determined that we should perform a simple 8973239462Sdim // transformation on the pack expansion, producing another pack 8974234353Sdim // expansion. 8975234353Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1); 8976234353Sdim ExprResult Key = getDerived().TransformExpr(OrigElement.Key); 8977234353Sdim if (Key.isInvalid()) 8978234353Sdim return ExprError(); 8979234353Sdim 8980234353Sdim if (Key.get() != OrigElement.Key) 8981234353Sdim ArgChanged = true; 8982234353Sdim 8983234353Sdim ExprResult Value = getDerived().TransformExpr(OrigElement.Value); 8984234353Sdim if (Value.isInvalid()) 8985234353Sdim return ExprError(); 8986239462Sdim 8987234353Sdim if (Value.get() != OrigElement.Value) 8988234353Sdim ArgChanged = true; 8989234353Sdim 8990239462Sdim ObjCDictionaryElement Expansion = { 8991234353Sdim Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions 8992234353Sdim }; 8993234353Sdim Elements.push_back(Expansion); 8994234353Sdim continue; 8995234353Sdim } 8996234353Sdim 8997234353Sdim // Record right away that the argument was changed. This needs 8998234353Sdim // to happen even if the array expands to nothing. 8999234353Sdim ArgChanged = true; 9000239462Sdim 9001234353Sdim // The transform has determined that we should perform an elementwise 9002234353Sdim // expansion of the pattern. Do so. 9003234353Sdim for (unsigned I = 0; I != *NumExpansions; ++I) { 9004234353Sdim Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I); 9005234353Sdim ExprResult Key = getDerived().TransformExpr(OrigElement.Key); 9006234353Sdim if (Key.isInvalid()) 9007234353Sdim return ExprError(); 9008234353Sdim 9009234353Sdim ExprResult Value = getDerived().TransformExpr(OrigElement.Value); 9010234353Sdim if (Value.isInvalid()) 9011234353Sdim return ExprError(); 9012234353Sdim 9013239462Sdim ObjCDictionaryElement Element = { 9014234353Sdim Key.get(), Value.get(), SourceLocation(), NumExpansions 9015234353Sdim }; 9016234353Sdim 9017234353Sdim // If any unexpanded parameter packs remain, we still have a 9018234353Sdim // pack expansion. 9019234353Sdim if (Key.get()->containsUnexpandedParameterPack() || 9020234353Sdim Value.get()->containsUnexpandedParameterPack()) 9021234353Sdim Element.EllipsisLoc = OrigElement.EllipsisLoc; 9022239462Sdim 9023234353Sdim Elements.push_back(Element); 9024234353Sdim } 9025234353Sdim 9026234353Sdim // We've finished with this pack expansion. 9027234353Sdim continue; 9028234353Sdim } 9029234353Sdim 9030234353Sdim // Transform and check key. 9031234353Sdim ExprResult Key = getDerived().TransformExpr(OrigElement.Key); 9032234353Sdim if (Key.isInvalid()) 9033234353Sdim return ExprError(); 9034239462Sdim 9035234353Sdim if (Key.get() != OrigElement.Key) 9036234353Sdim ArgChanged = true; 9037239462Sdim 9038234353Sdim // Transform and check value. 9039234353Sdim ExprResult Value 9040234353Sdim = getDerived().TransformExpr(OrigElement.Value); 9041234353Sdim if (Value.isInvalid()) 9042234353Sdim return ExprError(); 9043239462Sdim 9044234353Sdim if (Value.get() != OrigElement.Value) 9045234353Sdim ArgChanged = true; 9046239462Sdim 9047239462Sdim ObjCDictionaryElement Element = { 9048249423Sdim Key.get(), Value.get(), SourceLocation(), None 9049234353Sdim }; 9050234353Sdim Elements.push_back(Element); 9051234353Sdim } 9052239462Sdim 9053234353Sdim if (!getDerived().AlwaysRebuild() && !ArgChanged) 9054234353Sdim return SemaRef.MaybeBindToTemporary(E); 9055234353Sdim 9056234353Sdim return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(), 9057234353Sdim Elements.data(), 9058234353Sdim Elements.size()); 9059234353Sdim} 9060234353Sdim 9061234353Sdimtemplate<typename Derived> 9062234353SdimExprResult 9063200583SrdivackyTreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) { 9064207619Srdivacky TypeSourceInfo *EncodedTypeInfo 9065207619Srdivacky = getDerived().TransformType(E->getEncodedTypeSourceInfo()); 9066207619Srdivacky if (!EncodedTypeInfo) 9067212904Sdim return ExprError(); 9068198092Srdivacky 9069198092Srdivacky if (!getDerived().AlwaysRebuild() && 9070207619Srdivacky EncodedTypeInfo == E->getEncodedTypeSourceInfo()) 9071218893Sdim return SemaRef.Owned(E); 9072198092Srdivacky 9073198092Srdivacky return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(), 9074207619Srdivacky EncodedTypeInfo, 9075198092Srdivacky E->getRParenLoc()); 9076198092Srdivacky} 9077198092Srdivacky 9078198092Srdivackytemplate<typename Derived> 9079224145SdimExprResult TreeTransform<Derived>:: 9080224145SdimTransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) { 9081251662Sdim // This is a kind of implicit conversion, and it needs to get dropped 9082251662Sdim // and recomputed for the same general reasons that ImplicitCastExprs 9083251662Sdim // do, as well a more specific one: this expression is only valid when 9084251662Sdim // it appears *immediately* as an argument expression. 9085251662Sdim return getDerived().TransformExpr(E->getSubExpr()); 9086224145Sdim} 9087224145Sdim 9088224145Sdimtemplate<typename Derived> 9089224145SdimExprResult TreeTransform<Derived>:: 9090224145SdimTransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) { 9091239462Sdim TypeSourceInfo *TSInfo 9092224145Sdim = getDerived().TransformType(E->getTypeInfoAsWritten()); 9093224145Sdim if (!TSInfo) 9094224145Sdim return ExprError(); 9095239462Sdim 9096224145Sdim ExprResult Result = getDerived().TransformExpr(E->getSubExpr()); 9097239462Sdim if (Result.isInvalid()) 9098224145Sdim return ExprError(); 9099239462Sdim 9100224145Sdim if (!getDerived().AlwaysRebuild() && 9101224145Sdim TSInfo == E->getTypeInfoAsWritten() && 9102224145Sdim Result.get() == E->getSubExpr()) 9103224145Sdim return SemaRef.Owned(E); 9104239462Sdim 9105224145Sdim return SemaRef.BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(), 9106239462Sdim E->getBridgeKeywordLoc(), TSInfo, 9107224145Sdim Result.get()); 9108224145Sdim} 9109224145Sdim 9110224145Sdimtemplate<typename Derived> 9111212904SdimExprResult 9112200583SrdivackyTreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) { 9113207619Srdivacky // Transform arguments. 9114207619Srdivacky bool ArgChanged = false; 9115243830Sdim SmallVector<Expr*, 8> Args; 9116218893Sdim Args.reserve(E->getNumArgs()); 9117239462Sdim if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args, 9118218893Sdim &ArgChanged)) 9119218893Sdim return ExprError(); 9120239462Sdim 9121207619Srdivacky if (E->getReceiverKind() == ObjCMessageExpr::Class) { 9122207619Srdivacky // Class message: transform the receiver type. 9123207619Srdivacky TypeSourceInfo *ReceiverTypeInfo 9124207619Srdivacky = getDerived().TransformType(E->getClassReceiverTypeInfo()); 9125207619Srdivacky if (!ReceiverTypeInfo) 9126212904Sdim return ExprError(); 9127239462Sdim 9128207619Srdivacky // If nothing changed, just retain the existing message send. 9129207619Srdivacky if (!getDerived().AlwaysRebuild() && 9130207619Srdivacky ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged) 9131234353Sdim return SemaRef.MaybeBindToTemporary(E); 9132207619Srdivacky 9133207619Srdivacky // Build a new class message send. 9134226633Sdim SmallVector<SourceLocation, 16> SelLocs; 9135226633Sdim E->getSelectorLocs(SelLocs); 9136207619Srdivacky return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo, 9137207619Srdivacky E->getSelector(), 9138226633Sdim SelLocs, 9139207619Srdivacky E->getMethodDecl(), 9140207619Srdivacky E->getLeftLoc(), 9141243830Sdim Args, 9142207619Srdivacky E->getRightLoc()); 9143207619Srdivacky } 9144207619Srdivacky 9145207619Srdivacky // Instance message: transform the receiver 9146207619Srdivacky assert(E->getReceiverKind() == ObjCMessageExpr::Instance && 9147207619Srdivacky "Only class and instance messages may be instantiated"); 9148212904Sdim ExprResult Receiver 9149207619Srdivacky = getDerived().TransformExpr(E->getInstanceReceiver()); 9150207619Srdivacky if (Receiver.isInvalid()) 9151212904Sdim return ExprError(); 9152207619Srdivacky 9153207619Srdivacky // If nothing changed, just retain the existing message send. 9154207619Srdivacky if (!getDerived().AlwaysRebuild() && 9155207619Srdivacky Receiver.get() == E->getInstanceReceiver() && !ArgChanged) 9156234353Sdim return SemaRef.MaybeBindToTemporary(E); 9157239462Sdim 9158207619Srdivacky // Build a new instance message send. 9159226633Sdim SmallVector<SourceLocation, 16> SelLocs; 9160226633Sdim E->getSelectorLocs(SelLocs); 9161212904Sdim return getDerived().RebuildObjCMessageExpr(Receiver.get(), 9162207619Srdivacky E->getSelector(), 9163226633Sdim SelLocs, 9164207619Srdivacky E->getMethodDecl(), 9165207619Srdivacky E->getLeftLoc(), 9166243830Sdim Args, 9167207619Srdivacky E->getRightLoc()); 9168198092Srdivacky} 9169198092Srdivacky 9170198092Srdivackytemplate<typename Derived> 9171212904SdimExprResult 9172200583SrdivackyTreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) { 9173218893Sdim return SemaRef.Owned(E); 9174198092Srdivacky} 9175198092Srdivacky 9176198092Srdivackytemplate<typename Derived> 9177212904SdimExprResult 9178200583SrdivackyTreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) { 9179218893Sdim return SemaRef.Owned(E); 9180198092Srdivacky} 9181198092Srdivacky 9182198092Srdivackytemplate<typename Derived> 9183212904SdimExprResult 9184200583SrdivackyTreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) { 9185207619Srdivacky // Transform the base expression. 9186212904Sdim ExprResult Base = getDerived().TransformExpr(E->getBase()); 9187207619Srdivacky if (Base.isInvalid()) 9188212904Sdim return ExprError(); 9189207619Srdivacky 9190207619Srdivacky // We don't need to transform the ivar; it will never change. 9191239462Sdim 9192207619Srdivacky // If nothing changed, just retain the existing expression. 9193207619Srdivacky if (!getDerived().AlwaysRebuild() && 9194207619Srdivacky Base.get() == E->getBase()) 9195218893Sdim return SemaRef.Owned(E); 9196239462Sdim 9197212904Sdim return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(), 9198207619Srdivacky E->getLocation(), 9199207619Srdivacky E->isArrow(), E->isFreeIvar()); 9200198092Srdivacky} 9201198092Srdivacky 9202198092Srdivackytemplate<typename Derived> 9203212904SdimExprResult 9204200583SrdivackyTreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) { 9205218893Sdim // 'super' and types never change. Property never changes. Just 9206218893Sdim // retain the existing expression. 9207218893Sdim if (!E->isObjectReceiver()) 9208218893Sdim return SemaRef.Owned(E); 9209239462Sdim 9210207619Srdivacky // Transform the base expression. 9211212904Sdim ExprResult Base = getDerived().TransformExpr(E->getBase()); 9212207619Srdivacky if (Base.isInvalid()) 9213212904Sdim return ExprError(); 9214239462Sdim 9215207619Srdivacky // We don't need to transform the property; it will never change. 9216239462Sdim 9217207619Srdivacky // If nothing changed, just retain the existing expression. 9218207619Srdivacky if (!getDerived().AlwaysRebuild() && 9219207619Srdivacky Base.get() == E->getBase()) 9220218893Sdim return SemaRef.Owned(E); 9221198092Srdivacky 9222218893Sdim if (E->isExplicitProperty()) 9223218893Sdim return getDerived().RebuildObjCPropertyRefExpr(Base.get(), 9224218893Sdim E->getExplicitProperty(), 9225218893Sdim E->getLocation()); 9226198092Srdivacky 9227218893Sdim return getDerived().RebuildObjCPropertyRefExpr(Base.get(), 9228234353Sdim SemaRef.Context.PseudoObjectTy, 9229218893Sdim E->getImplicitPropertyGetter(), 9230218893Sdim E->getImplicitPropertySetter(), 9231218893Sdim E->getLocation()); 9232198092Srdivacky} 9233198092Srdivacky 9234198092Srdivackytemplate<typename Derived> 9235212904SdimExprResult 9236234353SdimTreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) { 9237234353Sdim // Transform the base expression. 9238234353Sdim ExprResult Base = getDerived().TransformExpr(E->getBaseExpr()); 9239234353Sdim if (Base.isInvalid()) 9240234353Sdim return ExprError(); 9241234353Sdim 9242234353Sdim // Transform the key expression. 9243234353Sdim ExprResult Key = getDerived().TransformExpr(E->getKeyExpr()); 9244234353Sdim if (Key.isInvalid()) 9245234353Sdim return ExprError(); 9246234353Sdim 9247234353Sdim // If nothing changed, just retain the existing expression. 9248234353Sdim if (!getDerived().AlwaysRebuild() && 9249234353Sdim Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr()) 9250234353Sdim return SemaRef.Owned(E); 9251234353Sdim 9252239462Sdim return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(), 9253234353Sdim Base.get(), Key.get(), 9254234353Sdim E->getAtIndexMethodDecl(), 9255234353Sdim E->setAtIndexMethodDecl()); 9256234353Sdim} 9257234353Sdim 9258234353Sdimtemplate<typename Derived> 9259234353SdimExprResult 9260200583SrdivackyTreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) { 9261207619Srdivacky // Transform the base expression. 9262212904Sdim ExprResult Base = getDerived().TransformExpr(E->getBase()); 9263207619Srdivacky if (Base.isInvalid()) 9264212904Sdim return ExprError(); 9265239462Sdim 9266207619Srdivacky // If nothing changed, just retain the existing expression. 9267207619Srdivacky if (!getDerived().AlwaysRebuild() && 9268207619Srdivacky Base.get() == E->getBase()) 9269218893Sdim return SemaRef.Owned(E); 9270239462Sdim 9271212904Sdim return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(), 9272249423Sdim E->getOpLoc(), 9273207619Srdivacky E->isArrow()); 9274198092Srdivacky} 9275198092Srdivacky 9276198092Srdivackytemplate<typename Derived> 9277212904SdimExprResult 9278200583SrdivackyTreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) { 9279198092Srdivacky bool ArgumentChanged = false; 9280243830Sdim SmallVector<Expr*, 8> SubExprs; 9281218893Sdim SubExprs.reserve(E->getNumSubExprs()); 9282239462Sdim if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false, 9283218893Sdim SubExprs, &ArgumentChanged)) 9284218893Sdim return ExprError(); 9285198092Srdivacky 9286198092Srdivacky if (!getDerived().AlwaysRebuild() && 9287198092Srdivacky !ArgumentChanged) 9288218893Sdim return SemaRef.Owned(E); 9289198092Srdivacky 9290198092Srdivacky return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(), 9291243830Sdim SubExprs, 9292198092Srdivacky E->getRParenLoc()); 9293198092Srdivacky} 9294198092Srdivacky 9295198092Srdivackytemplate<typename Derived> 9296212904SdimExprResult 9297263508SdimTreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) { 9298263508Sdim ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr()); 9299263508Sdim if (SrcExpr.isInvalid()) 9300263508Sdim return ExprError(); 9301263508Sdim 9302263508Sdim TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo()); 9303263508Sdim if (!Type) 9304263508Sdim return ExprError(); 9305263508Sdim 9306263508Sdim if (!getDerived().AlwaysRebuild() && 9307263508Sdim Type == E->getTypeSourceInfo() && 9308263508Sdim SrcExpr.get() == E->getSrcExpr()) 9309263508Sdim return SemaRef.Owned(E); 9310263508Sdim 9311263508Sdim return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(), 9312263508Sdim SrcExpr.get(), Type, 9313263508Sdim E->getRParenLoc()); 9314263508Sdim} 9315263508Sdim 9316263508Sdimtemplate<typename Derived> 9317263508SdimExprResult 9318200583SrdivackyTreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) { 9319218893Sdim BlockDecl *oldBlock = E->getBlockDecl(); 9320239462Sdim 9321218893Sdim SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/0); 9322218893Sdim BlockScopeInfo *blockScope = SemaRef.getCurBlock(); 9323218893Sdim 9324218893Sdim blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic()); 9325234353Sdim blockScope->TheDecl->setBlockMissingReturnType( 9326234353Sdim oldBlock->blockMissingReturnType()); 9327239462Sdim 9328226633Sdim SmallVector<ParmVarDecl*, 4> params; 9329226633Sdim SmallVector<QualType, 4> paramTypes; 9330239462Sdim 9331210299Sed // Parameter substitution. 9332218893Sdim if (getDerived().TransformFunctionTypeParams(E->getCaretLocation(), 9333218893Sdim oldBlock->param_begin(), 9334218893Sdim oldBlock->param_size(), 9335234353Sdim 0, paramTypes, ¶ms)) { 9336234353Sdim getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/0); 9337234353Sdim return ExprError(); 9338234353Sdim } 9339218893Sdim 9340249423Sdim const FunctionProtoType *exprFunctionType = E->getFunctionType(); 9341234353Sdim QualType exprResultType = 9342234353Sdim getDerived().TransformType(exprFunctionType->getResultType()); 9343218893Sdim 9344249423Sdim QualType functionType = 9345249423Sdim getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, 9346249423Sdim exprFunctionType->getExtProtoInfo()); 9347218893Sdim blockScope->FunctionType = functionType; 9348218893Sdim 9349218893Sdim // Set the parameters on the block decl. 9350218893Sdim if (!params.empty()) 9351226633Sdim blockScope->TheDecl->setParams(params); 9352234353Sdim 9353234353Sdim if (!oldBlock->blockMissingReturnType()) { 9354234353Sdim blockScope->HasImplicitReturnType = false; 9355234353Sdim blockScope->ReturnType = exprResultType; 9356234353Sdim } 9357239462Sdim 9358210299Sed // Transform the body 9359218893Sdim StmtResult body = getDerived().TransformStmt(E->getBody()); 9360234353Sdim if (body.isInvalid()) { 9361234353Sdim getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/0); 9362212904Sdim return ExprError(); 9363234353Sdim } 9364218893Sdim 9365218893Sdim#ifndef NDEBUG 9366218893Sdim // In builds with assertions, make sure that we captured everything we 9367218893Sdim // captured before. 9368223017Sdim if (!SemaRef.getDiagnostics().hasErrorOccurred()) { 9369223017Sdim for (BlockDecl::capture_iterator i = oldBlock->capture_begin(), 9370223017Sdim e = oldBlock->capture_end(); i != e; ++i) { 9371223017Sdim VarDecl *oldCapture = i->getVariable(); 9372218893Sdim 9373223017Sdim // Ignore parameter packs. 9374223017Sdim if (isa<ParmVarDecl>(oldCapture) && 9375223017Sdim cast<ParmVarDecl>(oldCapture)->isParameterPack()) 9376223017Sdim continue; 9377218893Sdim 9378223017Sdim VarDecl *newCapture = 9379223017Sdim cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(), 9380223017Sdim oldCapture)); 9381223017Sdim assert(blockScope->CaptureMap.count(newCapture)); 9382223017Sdim } 9383234353Sdim assert(oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured()); 9384218893Sdim } 9385218893Sdim#endif 9386218893Sdim 9387218893Sdim return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(), 9388218893Sdim /*Scope=*/0); 9389198092Srdivacky} 9390198092Srdivacky 9391198092Srdivackytemplate<typename Derived> 9392212904SdimExprResult 9393223017SdimTreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) { 9394226633Sdim llvm_unreachable("Cannot transform asType expressions yet"); 9395223017Sdim} 9396226633Sdim 9397226633Sdimtemplate<typename Derived> 9398226633SdimExprResult 9399226633SdimTreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) { 9400226633Sdim QualType RetTy = getDerived().TransformType(E->getType()); 9401226633Sdim bool ArgumentChanged = false; 9402243830Sdim SmallVector<Expr*, 8> SubExprs; 9403226633Sdim SubExprs.reserve(E->getNumSubExprs()); 9404226633Sdim if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false, 9405226633Sdim SubExprs, &ArgumentChanged)) 9406226633Sdim return ExprError(); 9407226633Sdim 9408226633Sdim if (!getDerived().AlwaysRebuild() && 9409226633Sdim !ArgumentChanged) 9410226633Sdim return SemaRef.Owned(E); 9411226633Sdim 9412243830Sdim return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs, 9413226633Sdim RetTy, E->getOp(), E->getRParenLoc()); 9414226633Sdim} 9415239462Sdim 9416198092Srdivacky//===----------------------------------------------------------------------===// 9417198092Srdivacky// Type reconstruction 9418198092Srdivacky//===----------------------------------------------------------------------===// 9419198092Srdivacky 9420198092Srdivackytemplate<typename Derived> 9421198893SrdivackyQualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType, 9422198893Srdivacky SourceLocation Star) { 9423210299Sed return SemaRef.BuildPointerType(PointeeType, Star, 9424198092Srdivacky getDerived().getBaseEntity()); 9425198092Srdivacky} 9426198092Srdivacky 9427198092Srdivackytemplate<typename Derived> 9428198893SrdivackyQualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType, 9429198893Srdivacky SourceLocation Star) { 9430210299Sed return SemaRef.BuildBlockPointerType(PointeeType, Star, 9431198092Srdivacky getDerived().getBaseEntity()); 9432198092Srdivacky} 9433198092Srdivacky 9434198092Srdivackytemplate<typename Derived> 9435198092SrdivackyQualType 9436198893SrdivackyTreeTransform<Derived>::RebuildReferenceType(QualType ReferentType, 9437198893Srdivacky bool WrittenAsLValue, 9438198893Srdivacky SourceLocation Sigil) { 9439210299Sed return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue, 9440198893Srdivacky Sigil, getDerived().getBaseEntity()); 9441198092Srdivacky} 9442198092Srdivacky 9443198092Srdivackytemplate<typename Derived> 9444198092SrdivackyQualType 9445198893SrdivackyTreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType, 9446198893Srdivacky QualType ClassType, 9447198893Srdivacky SourceLocation Sigil) { 9448210299Sed return SemaRef.BuildMemberPointerType(PointeeType, ClassType, 9449198893Srdivacky Sigil, getDerived().getBaseEntity()); 9450198092Srdivacky} 9451198092Srdivacky 9452198092Srdivackytemplate<typename Derived> 9453198092SrdivackyQualType 9454198092SrdivackyTreeTransform<Derived>::RebuildArrayType(QualType ElementType, 9455198092Srdivacky ArrayType::ArraySizeModifier SizeMod, 9456198092Srdivacky const llvm::APInt *Size, 9457198092Srdivacky Expr *SizeExpr, 9458198092Srdivacky unsigned IndexTypeQuals, 9459198092Srdivacky SourceRange BracketsRange) { 9460198092Srdivacky if (SizeExpr || !Size) 9461198092Srdivacky return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr, 9462198092Srdivacky IndexTypeQuals, BracketsRange, 9463198092Srdivacky getDerived().getBaseEntity()); 9464198092Srdivacky 9465198092Srdivacky QualType Types[] = { 9466198092Srdivacky SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy, 9467198092Srdivacky SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy, 9468198092Srdivacky SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty 9469198092Srdivacky }; 9470263508Sdim const unsigned NumTypes = llvm::array_lengthof(Types); 9471198092Srdivacky QualType SizeType; 9472198092Srdivacky for (unsigned I = 0; I != NumTypes; ++I) 9473198092Srdivacky if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) { 9474198092Srdivacky SizeType = Types[I]; 9475198092Srdivacky break; 9476198092Srdivacky } 9477198092Srdivacky 9478234353Sdim // Note that we can return a VariableArrayType here in the case where 9479234353Sdim // the element type was a dependent VariableArrayType. 9480234353Sdim IntegerLiteral *ArraySize 9481234353Sdim = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType, 9482234353Sdim /*FIXME*/BracketsRange.getBegin()); 9483234353Sdim return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize, 9484198092Srdivacky IndexTypeQuals, BracketsRange, 9485198092Srdivacky getDerived().getBaseEntity()); 9486198092Srdivacky} 9487198092Srdivacky 9488198092Srdivackytemplate<typename Derived> 9489198092SrdivackyQualType 9490198092SrdivackyTreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType, 9491198092Srdivacky ArrayType::ArraySizeModifier SizeMod, 9492198092Srdivacky const llvm::APInt &Size, 9493198893Srdivacky unsigned IndexTypeQuals, 9494198893Srdivacky SourceRange BracketsRange) { 9495198092Srdivacky return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0, 9496198893Srdivacky IndexTypeQuals, BracketsRange); 9497198092Srdivacky} 9498198092Srdivacky 9499198092Srdivackytemplate<typename Derived> 9500198092SrdivackyQualType 9501198092SrdivackyTreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType, 9502198092Srdivacky ArrayType::ArraySizeModifier SizeMod, 9503198893Srdivacky unsigned IndexTypeQuals, 9504198893Srdivacky SourceRange BracketsRange) { 9505198092Srdivacky return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0, 9506198893Srdivacky IndexTypeQuals, BracketsRange); 9507198092Srdivacky} 9508198092Srdivacky 9509198092Srdivackytemplate<typename Derived> 9510198092SrdivackyQualType 9511198092SrdivackyTreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType, 9512198092Srdivacky ArrayType::ArraySizeModifier SizeMod, 9513212904Sdim Expr *SizeExpr, 9514198092Srdivacky unsigned IndexTypeQuals, 9515198092Srdivacky SourceRange BracketsRange) { 9516198092Srdivacky return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 9517212904Sdim SizeExpr, 9518198092Srdivacky IndexTypeQuals, BracketsRange); 9519198092Srdivacky} 9520198092Srdivacky 9521198092Srdivackytemplate<typename Derived> 9522198092SrdivackyQualType 9523198092SrdivackyTreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType, 9524198092Srdivacky ArrayType::ArraySizeModifier SizeMod, 9525212904Sdim Expr *SizeExpr, 9526198092Srdivacky unsigned IndexTypeQuals, 9527198092Srdivacky SourceRange BracketsRange) { 9528198092Srdivacky return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 9529212904Sdim SizeExpr, 9530198092Srdivacky IndexTypeQuals, BracketsRange); 9531198092Srdivacky} 9532198092Srdivacky 9533198092Srdivackytemplate<typename Derived> 9534198092SrdivackyQualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType, 9535218893Sdim unsigned NumElements, 9536218893Sdim VectorType::VectorKind VecKind) { 9537198092Srdivacky // FIXME: semantic checking! 9538218893Sdim return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind); 9539198092Srdivacky} 9540198092Srdivacky 9541198092Srdivackytemplate<typename Derived> 9542198092SrdivackyQualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType, 9543198092Srdivacky unsigned NumElements, 9544198092Srdivacky SourceLocation AttributeLoc) { 9545198092Srdivacky llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy), 9546198092Srdivacky NumElements, true); 9547198092Srdivacky IntegerLiteral *VectorSize 9548212904Sdim = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy, 9549212904Sdim AttributeLoc); 9550212904Sdim return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc); 9551198092Srdivacky} 9552198092Srdivacky 9553198092Srdivackytemplate<typename Derived> 9554198092SrdivackyQualType 9555198092SrdivackyTreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType, 9556212904Sdim Expr *SizeExpr, 9557198092Srdivacky SourceLocation AttributeLoc) { 9558212904Sdim return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc); 9559198092Srdivacky} 9560198092Srdivacky 9561198092Srdivackytemplate<typename Derived> 9562249423SdimQualType TreeTransform<Derived>::RebuildFunctionProtoType( 9563249423Sdim QualType T, 9564249423Sdim llvm::MutableArrayRef<QualType> ParamTypes, 9565249423Sdim const FunctionProtoType::ExtProtoInfo &EPI) { 9566249423Sdim return SemaRef.BuildFunctionType(T, ParamTypes, 9567198092Srdivacky getDerived().getBaseLocation(), 9568212904Sdim getDerived().getBaseEntity(), 9569249423Sdim EPI); 9570198092Srdivacky} 9571198092Srdivacky 9572198092Srdivackytemplate<typename Derived> 9573198398SrdivackyQualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) { 9574198398Srdivacky return SemaRef.Context.getFunctionNoProtoType(T); 9575198398Srdivacky} 9576198398Srdivacky 9577198398Srdivackytemplate<typename Derived> 9578200583SrdivackyQualType TreeTransform<Derived>::RebuildUnresolvedUsingType(Decl *D) { 9579200583Srdivacky assert(D && "no decl found"); 9580200583Srdivacky if (D->isInvalidDecl()) return QualType(); 9581200583Srdivacky 9582207619Srdivacky // FIXME: Doesn't account for ObjCInterfaceDecl! 9583200583Srdivacky TypeDecl *Ty; 9584200583Srdivacky if (isa<UsingDecl>(D)) { 9585200583Srdivacky UsingDecl *Using = cast<UsingDecl>(D); 9586263508Sdim assert(Using->hasTypename() && 9587200583Srdivacky "UnresolvedUsingTypenameDecl transformed to non-typename using"); 9588200583Srdivacky 9589200583Srdivacky // A valid resolved using typename decl points to exactly one type decl. 9590200583Srdivacky assert(++Using->shadow_begin() == Using->shadow_end()); 9591200583Srdivacky Ty = cast<TypeDecl>((*Using->shadow_begin())->getTargetDecl()); 9592239462Sdim 9593200583Srdivacky } else { 9594200583Srdivacky assert(isa<UnresolvedUsingTypenameDecl>(D) && 9595200583Srdivacky "UnresolvedUsingTypenameDecl transformed to non-using decl"); 9596200583Srdivacky Ty = cast<UnresolvedUsingTypenameDecl>(D); 9597200583Srdivacky } 9598200583Srdivacky 9599200583Srdivacky return SemaRef.Context.getTypeDeclType(Ty); 9600200583Srdivacky} 9601200583Srdivacky 9602200583Srdivackytemplate<typename Derived> 9603218893SdimQualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, 9604218893Sdim SourceLocation Loc) { 9605218893Sdim return SemaRef.BuildTypeofExprType(E, Loc); 9606198092Srdivacky} 9607198092Srdivacky 9608198092Srdivackytemplate<typename Derived> 9609198092SrdivackyQualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) { 9610198092Srdivacky return SemaRef.Context.getTypeOfType(Underlying); 9611198092Srdivacky} 9612198092Srdivacky 9613198092Srdivackytemplate<typename Derived> 9614218893SdimQualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, 9615218893Sdim SourceLocation Loc) { 9616218893Sdim return SemaRef.BuildDecltypeType(E, Loc); 9617198092Srdivacky} 9618198092Srdivacky 9619198092Srdivackytemplate<typename Derived> 9620223017SdimQualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType, 9621223017Sdim UnaryTransformType::UTTKind UKind, 9622223017Sdim SourceLocation Loc) { 9623223017Sdim return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc); 9624223017Sdim} 9625223017Sdim 9626223017Sdimtemplate<typename Derived> 9627198092SrdivackyQualType TreeTransform<Derived>::RebuildTemplateSpecializationType( 9628198893Srdivacky TemplateName Template, 9629198893Srdivacky SourceLocation TemplateNameLoc, 9630221345Sdim TemplateArgumentListInfo &TemplateArgs) { 9631199990Srdivacky return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs); 9632198092Srdivacky} 9633198092Srdivacky 9634198092Srdivackytemplate<typename Derived> 9635226633SdimQualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType, 9636226633Sdim SourceLocation KWLoc) { 9637226633Sdim return SemaRef.BuildAtomicType(ValueType, KWLoc); 9638226633Sdim} 9639226633Sdim 9640226633Sdimtemplate<typename Derived> 9641198092SrdivackyTemplateName 9642221345SdimTreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, 9643198092Srdivacky bool TemplateKW, 9644198092Srdivacky TemplateDecl *Template) { 9645221345Sdim return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW, 9646198092Srdivacky Template); 9647198092Srdivacky} 9648198092Srdivacky 9649198092Srdivackytemplate<typename Derived> 9650198092SrdivackyTemplateName 9651221345SdimTreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, 9652221345Sdim const IdentifierInfo &Name, 9653221345Sdim SourceLocation NameLoc, 9654218893Sdim QualType ObjectType, 9655218893Sdim NamedDecl *FirstQualifierInScope) { 9656221345Sdim UnqualifiedId TemplateName; 9657221345Sdim TemplateName.setIdentifier(&Name, NameLoc); 9658210299Sed Sema::TemplateTy Template; 9659234353Sdim SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller. 9660210299Sed getSema().ActOnDependentTemplateName(/*Scope=*/0, 9661234353Sdim SS, TemplateKWLoc, TemplateName, 9662212904Sdim ParsedType::make(ObjectType), 9663210299Sed /*EnteringContext=*/false, 9664210299Sed Template); 9665218893Sdim return Template.get(); 9666198092Srdivacky} 9667198092Srdivacky 9668198092Srdivackytemplate<typename Derived> 9669198893SrdivackyTemplateName 9670221345SdimTreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS, 9671198893Srdivacky OverloadedOperatorKind Operator, 9672221345Sdim SourceLocation NameLoc, 9673198893Srdivacky QualType ObjectType) { 9674198893Srdivacky UnqualifiedId Name; 9675221345Sdim // FIXME: Bogus location information. 9676234353Sdim SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc }; 9677221345Sdim Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations); 9678234353Sdim SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller. 9679210299Sed Sema::TemplateTy Template; 9680210299Sed getSema().ActOnDependentTemplateName(/*Scope=*/0, 9681234353Sdim SS, TemplateKWLoc, Name, 9682212904Sdim ParsedType::make(ObjectType), 9683210299Sed /*EnteringContext=*/false, 9684210299Sed Template); 9685263508Sdim return Template.get(); 9686198893Srdivacky} 9687239462Sdim 9688198893Srdivackytemplate<typename Derived> 9689212904SdimExprResult 9690198092SrdivackyTreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op, 9691198092Srdivacky SourceLocation OpLoc, 9692212904Sdim Expr *OrigCallee, 9693212904Sdim Expr *First, 9694212904Sdim Expr *Second) { 9695212904Sdim Expr *Callee = OrigCallee->IgnoreParenCasts(); 9696212904Sdim bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus); 9697198092Srdivacky 9698198092Srdivacky // Determine whether this should be a builtin operation. 9699198893Srdivacky if (Op == OO_Subscript) { 9700212904Sdim if (!First->getType()->isOverloadableType() && 9701212904Sdim !Second->getType()->isOverloadableType()) 9702212904Sdim return getSema().CreateBuiltinArraySubscriptExpr(First, 9703212904Sdim Callee->getLocStart(), 9704212904Sdim Second, OpLoc); 9705199482Srdivacky } else if (Op == OO_Arrow) { 9706199482Srdivacky // -> is never a builtin operation. 9707212904Sdim return SemaRef.BuildOverloadedArrowExpr(0, First, OpLoc); 9708212904Sdim } else if (Second == 0 || isPostIncDec) { 9709212904Sdim if (!First->getType()->isOverloadableType()) { 9710198092Srdivacky // The argument is not of overloadable type, so try to create a 9711198092Srdivacky // built-in unary operation. 9712212904Sdim UnaryOperatorKind Opc 9713198092Srdivacky = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec); 9714198092Srdivacky 9715212904Sdim return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First); 9716198092Srdivacky } 9717198092Srdivacky } else { 9718212904Sdim if (!First->getType()->isOverloadableType() && 9719212904Sdim !Second->getType()->isOverloadableType()) { 9720198092Srdivacky // Neither of the arguments is an overloadable type, so try to 9721198092Srdivacky // create a built-in binary operation. 9722212904Sdim BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op); 9723212904Sdim ExprResult Result 9724212904Sdim = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second); 9725198092Srdivacky if (Result.isInvalid()) 9726212904Sdim return ExprError(); 9727198092Srdivacky 9728243830Sdim return Result; 9729198092Srdivacky } 9730198092Srdivacky } 9731198092Srdivacky 9732198092Srdivacky // Compute the transformed set of functions (and function templates) to be 9733198092Srdivacky // used during overload resolution. 9734203955Srdivacky UnresolvedSet<16> Functions; 9735198092Srdivacky 9736212904Sdim if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) { 9737199990Srdivacky assert(ULE->requiresADL()); 9738198092Srdivacky 9739199990Srdivacky // FIXME: Do we have to check 9740199990Srdivacky // IsAcceptableNonMemberOperatorCandidate for each of these? 9741203955Srdivacky Functions.append(ULE->decls_begin(), ULE->decls_end()); 9742199990Srdivacky } else { 9743243830Sdim // If we've resolved this to a particular non-member function, just call 9744243830Sdim // that function. If we resolved it to a member function, 9745243830Sdim // CreateOverloaded* will find that function for us. 9746243830Sdim NamedDecl *ND = cast<DeclRefExpr>(Callee)->getDecl(); 9747243830Sdim if (!isa<CXXMethodDecl>(ND)) 9748243830Sdim Functions.addDecl(ND); 9749199990Srdivacky } 9750199990Srdivacky 9751198092Srdivacky // Add any functions found via argument-dependent lookup. 9752212904Sdim Expr *Args[2] = { First, Second }; 9753212904Sdim unsigned NumArgs = 1 + (Second != 0); 9754198092Srdivacky 9755198092Srdivacky // Create the overloaded operator invocation for unary operators. 9756198092Srdivacky if (NumArgs == 1 || isPostIncDec) { 9757212904Sdim UnaryOperatorKind Opc 9758198092Srdivacky = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec); 9759212904Sdim return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First); 9760198092Srdivacky } 9761198092Srdivacky 9762224145Sdim if (Op == OO_Subscript) { 9763224145Sdim SourceLocation LBrace; 9764224145Sdim SourceLocation RBrace; 9765198893Srdivacky 9766224145Sdim if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee)) { 9767224145Sdim DeclarationNameLoc &NameLoc = DRE->getNameInfo().getInfo(); 9768224145Sdim LBrace = SourceLocation::getFromRawEncoding( 9769224145Sdim NameLoc.CXXOperatorName.BeginOpNameLoc); 9770224145Sdim RBrace = SourceLocation::getFromRawEncoding( 9771224145Sdim NameLoc.CXXOperatorName.EndOpNameLoc); 9772224145Sdim } else { 9773224145Sdim LBrace = Callee->getLocStart(); 9774224145Sdim RBrace = OpLoc; 9775224145Sdim } 9776224145Sdim 9777224145Sdim return SemaRef.CreateOverloadedArraySubscriptExpr(LBrace, RBrace, 9778224145Sdim First, Second); 9779224145Sdim } 9780224145Sdim 9781198092Srdivacky // Create the overloaded operator invocation for binary operators. 9782212904Sdim BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op); 9783212904Sdim ExprResult Result 9784198092Srdivacky = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]); 9785198092Srdivacky if (Result.isInvalid()) 9786212904Sdim return ExprError(); 9787198092Srdivacky 9788243830Sdim return Result; 9789198092Srdivacky} 9790198092Srdivacky 9791204643Srdivackytemplate<typename Derived> 9792239462SdimExprResult 9793212904SdimTreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base, 9794204643Srdivacky SourceLocation OperatorLoc, 9795204643Srdivacky bool isArrow, 9796219077Sdim CXXScopeSpec &SS, 9797204643Srdivacky TypeSourceInfo *ScopeType, 9798204643Srdivacky SourceLocation CCLoc, 9799204643Srdivacky SourceLocation TildeLoc, 9800204643Srdivacky PseudoDestructorTypeStorage Destroyed) { 9801212904Sdim QualType BaseType = Base->getType(); 9802212904Sdim if (Base->isTypeDependent() || Destroyed.getIdentifier() || 9803204643Srdivacky (!isArrow && !BaseType->getAs<RecordType>()) || 9804239462Sdim (isArrow && BaseType->getAs<PointerType>() && 9805204643Srdivacky !BaseType->getAs<PointerType>()->getPointeeType() 9806204643Srdivacky ->template getAs<RecordType>())){ 9807204643Srdivacky // This pseudo-destructor expression is still a pseudo-destructor. 9808212904Sdim return SemaRef.BuildPseudoDestructorExpr(Base, OperatorLoc, 9809204643Srdivacky isArrow? tok::arrow : tok::period, 9810204643Srdivacky SS, ScopeType, CCLoc, TildeLoc, 9811204643Srdivacky Destroyed, 9812204643Srdivacky /*FIXME?*/true); 9813204643Srdivacky } 9814212904Sdim 9815204643Srdivacky TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo(); 9816212904Sdim DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName( 9817212904Sdim SemaRef.Context.getCanonicalType(DestroyedType->getType()))); 9818212904Sdim DeclarationNameInfo NameInfo(Name, Destroyed.getLocation()); 9819212904Sdim NameInfo.setNamedTypeInfo(DestroyedType); 9820212904Sdim 9821239462Sdim // The scope type is now known to be a valid nested name specifier 9822239462Sdim // component. Tack it on to the end of the nested name specifier. 9823239462Sdim if (ScopeType) 9824239462Sdim SS.Extend(SemaRef.Context, SourceLocation(), 9825239462Sdim ScopeType->getTypeLoc(), CCLoc); 9826212904Sdim 9827234353Sdim SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller. 9828212904Sdim return getSema().BuildMemberReferenceExpr(Base, BaseType, 9829204643Srdivacky OperatorLoc, isArrow, 9830234353Sdim SS, TemplateKWLoc, 9831234353Sdim /*FIXME: FirstQualifier*/ 0, 9832212904Sdim NameInfo, 9833204643Srdivacky /*TemplateArgs*/ 0); 9834204643Srdivacky} 9835204643Srdivacky 9836251662Sdimtemplate<typename Derived> 9837251662SdimStmtResult 9838251662SdimTreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) { 9839251662Sdim SourceLocation Loc = S->getLocStart(); 9840251662Sdim unsigned NumParams = S->getCapturedDecl()->getNumParams(); 9841251662Sdim getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/0, 9842251662Sdim S->getCapturedRegionKind(), NumParams); 9843251662Sdim StmtResult Body = getDerived().TransformStmt(S->getCapturedStmt()); 9844251662Sdim 9845251662Sdim if (Body.isInvalid()) { 9846251662Sdim getSema().ActOnCapturedRegionError(); 9847251662Sdim return StmtError(); 9848251662Sdim } 9849251662Sdim 9850251662Sdim return getSema().ActOnCapturedRegionEnd(Body.take()); 9851251662Sdim} 9852251662Sdim 9853198092Srdivacky} // end namespace clang 9854198092Srdivacky 9855198092Srdivacky#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H 9856