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"
27249423Sdim#include "clang/Lex/Preprocessor.h"
28249423Sdim#include "clang/Sema/Designator.h"
29249423Sdim#include "clang/Sema/Lookup.h"
30212904Sdim#include "clang/Sema/Ownership.h"
31249423Sdim#include "clang/Sema/ParsedTemplate.h"
32249423Sdim#include "clang/Sema/ScopeInfo.h"
33249423Sdim#include "clang/Sema/SemaDiagnostic.h"
34249423Sdim#include "clang/Sema/SemaInternal.h"
35226633Sdim#include "llvm/ADT/ArrayRef.h"
36198398Srdivacky#include "llvm/Support/ErrorHandling.h"
37198092Srdivacky#include <algorithm>
38198092Srdivacky
39198092Srdivackynamespace clang {
40212904Sdimusing namespace sema;
41198092Srdivacky
42198092Srdivacky/// \brief A semantic tree transformation that allows one to transform one
43198092Srdivacky/// abstract syntax tree into another.
44198092Srdivacky///
45198092Srdivacky/// A new tree transformation is defined by creating a new subclass \c X of
46198092Srdivacky/// \c TreeTransform<X> and then overriding certain operations to provide
47198092Srdivacky/// behavior specific to that transformation. For example, template
48198092Srdivacky/// instantiation is implemented as a tree transformation where the
49198092Srdivacky/// transformation of TemplateTypeParmType nodes involves substituting the
50198092Srdivacky/// template arguments for their corresponding template parameters; a similar
51198092Srdivacky/// transformation is performed for non-type template parameters and
52198092Srdivacky/// template template parameters.
53198092Srdivacky///
54198092Srdivacky/// This tree-transformation template uses static polymorphism to allow
55198092Srdivacky/// subclasses to customize any of its operations. Thus, a subclass can
56198092Srdivacky/// override any of the transformation or rebuild operators by providing an
57198092Srdivacky/// operation with the same signature as the default implementation. The
58198092Srdivacky/// overridding function should not be virtual.
59198092Srdivacky///
60198092Srdivacky/// Semantic tree transformations are split into two stages, either of which
61198092Srdivacky/// can be replaced by a subclass. The "transform" step transforms an AST node
62198092Srdivacky/// or the parts of an AST node using the various transformation functions,
63198092Srdivacky/// then passes the pieces on to the "rebuild" step, which constructs a new AST
64198092Srdivacky/// node of the appropriate kind from the pieces. The default transformation
65198092Srdivacky/// routines recursively transform the operands to composite AST nodes (e.g.,
66198092Srdivacky/// the pointee type of a PointerType node) and, if any of those operand nodes
67198092Srdivacky/// were changed by the transformation, invokes the rebuild operation to create
68198092Srdivacky/// a new AST node.
69198092Srdivacky///
70198092Srdivacky/// Subclasses can customize the transformation at various levels. The
71198092Srdivacky/// most coarse-grained transformations involve replacing TransformType(),
72221345Sdim/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
73198092Srdivacky/// TransformTemplateName(), or TransformTemplateArgument() with entirely
74198092Srdivacky/// new implementations.
75198092Srdivacky///
76198092Srdivacky/// For more fine-grained transformations, subclasses can replace any of the
77198092Srdivacky/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
78198092Srdivacky/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
79198092Srdivacky/// replacing TransformTemplateTypeParmType() allows template instantiation
80198092Srdivacky/// to substitute template arguments for their corresponding template
81198092Srdivacky/// parameters. Additionally, subclasses can override the \c RebuildXXX
82198092Srdivacky/// functions to control how AST nodes are rebuilt when their operands change.
83198092Srdivacky/// By default, \c TreeTransform will invoke semantic analysis to rebuild
84198092Srdivacky/// AST nodes. However, certain other tree transformations (e.g, cloning) may
85198092Srdivacky/// be able to use more efficient rebuild steps.
86198092Srdivacky///
87198092Srdivacky/// There are a handful of other functions that can be overridden, allowing one
88198092Srdivacky/// to avoid traversing nodes that don't need any transformation
89198092Srdivacky/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
90198092Srdivacky/// operands have not changed (\c AlwaysRebuild()), and customize the
91198092Srdivacky/// default locations and entity names used for type-checking
92198092Srdivacky/// (\c getBaseLocation(), \c getBaseEntity()).
93198092Srdivackytemplate<typename Derived>
94198092Srdivackyclass TreeTransform {
95218893Sdim  /// \brief Private RAII object that helps us forget and then re-remember
96218893Sdim  /// the template argument corresponding to a partially-substituted parameter
97218893Sdim  /// pack.
98218893Sdim  class ForgetPartiallySubstitutedPackRAII {
99218893Sdim    Derived &Self;
100218893Sdim    TemplateArgument Old;
101239462Sdim
102218893Sdim  public:
103218893Sdim    ForgetPartiallySubstitutedPackRAII(Derived &Self) : Self(Self) {
104218893Sdim      Old = Self.ForgetPartiallySubstitutedPack();
105218893Sdim    }
106239462Sdim
107218893Sdim    ~ForgetPartiallySubstitutedPackRAII() {
108218893Sdim      Self.RememberPartiallySubstitutedPack(Old);
109218893Sdim    }
110218893Sdim  };
111239462Sdim
112198092Srdivackyprotected:
113198092Srdivacky  Sema &SemaRef;
114239462Sdim
115234353Sdim  /// \brief The set of local declarations that have been transformed, for
116234353Sdim  /// cases where we are forced to build new declarations within the transformer
117234353Sdim  /// rather than in the subclass (e.g., lambda closure types).
118234353Sdim  llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
119239462Sdim
120198092Srdivackypublic:
121198092Srdivacky  /// \brief Initializes a new tree transformer.
122198092Srdivacky  TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
123198092Srdivacky
124198092Srdivacky  /// \brief Retrieves a reference to the derived class.
125198092Srdivacky  Derived &getDerived() { return static_cast<Derived&>(*this); }
126198092Srdivacky
127198092Srdivacky  /// \brief Retrieves a reference to the derived class.
128198092Srdivacky  const Derived &getDerived() const {
129198092Srdivacky    return static_cast<const Derived&>(*this);
130198092Srdivacky  }
131198092Srdivacky
132212904Sdim  static inline ExprResult Owned(Expr *E) { return E; }
133212904Sdim  static inline StmtResult Owned(Stmt *S) { return S; }
134212904Sdim
135198092Srdivacky  /// \brief Retrieves a reference to the semantic analysis object used for
136198092Srdivacky  /// this tree transform.
137198092Srdivacky  Sema &getSema() const { return SemaRef; }
138198092Srdivacky
139198092Srdivacky  /// \brief Whether the transformation should always rebuild AST nodes, even
140198092Srdivacky  /// if none of the children have changed.
141198092Srdivacky  ///
142198092Srdivacky  /// Subclasses may override this function to specify when the transformation
143198092Srdivacky  /// should rebuild all AST nodes.
144198092Srdivacky  bool AlwaysRebuild() { return false; }
145198092Srdivacky
146198092Srdivacky  /// \brief Returns the location of the entity being transformed, if that
147198092Srdivacky  /// information was not available elsewhere in the AST.
148198092Srdivacky  ///
149198092Srdivacky  /// By default, returns no source-location information. Subclasses can
150198092Srdivacky  /// provide an alternative implementation that provides better location
151198092Srdivacky  /// information.
152198092Srdivacky  SourceLocation getBaseLocation() { return SourceLocation(); }
153198092Srdivacky
154198092Srdivacky  /// \brief Returns the name of the entity being transformed, if that
155198092Srdivacky  /// information was not available elsewhere in the AST.
156198092Srdivacky  ///
157198092Srdivacky  /// By default, returns an empty name. Subclasses can provide an alternative
158198092Srdivacky  /// implementation with a more precise name.
159198092Srdivacky  DeclarationName getBaseEntity() { return DeclarationName(); }
160198092Srdivacky
161198092Srdivacky  /// \brief Sets the "base" location and entity when that
162198092Srdivacky  /// information is known based on another transformation.
163198092Srdivacky  ///
164198092Srdivacky  /// By default, the source location and entity are ignored. Subclasses can
165198092Srdivacky  /// override this function to provide a customized implementation.
166198092Srdivacky  void setBase(SourceLocation Loc, DeclarationName Entity) { }
167198092Srdivacky
168198092Srdivacky  /// \brief RAII object that temporarily sets the base location and entity
169198092Srdivacky  /// used for reporting diagnostics in types.
170198092Srdivacky  class TemporaryBase {
171198092Srdivacky    TreeTransform &Self;
172198092Srdivacky    SourceLocation OldLocation;
173198092Srdivacky    DeclarationName OldEntity;
174198092Srdivacky
175198092Srdivacky  public:
176198092Srdivacky    TemporaryBase(TreeTransform &Self, SourceLocation Location,
177198092Srdivacky                  DeclarationName Entity) : Self(Self) {
178198092Srdivacky      OldLocation = Self.getDerived().getBaseLocation();
179198092Srdivacky      OldEntity = Self.getDerived().getBaseEntity();
180239462Sdim
181218893Sdim      if (Location.isValid())
182218893Sdim        Self.getDerived().setBase(Location, Entity);
183198092Srdivacky    }
184198092Srdivacky
185198092Srdivacky    ~TemporaryBase() {
186198092Srdivacky      Self.getDerived().setBase(OldLocation, OldEntity);
187198092Srdivacky    }
188198092Srdivacky  };
189198092Srdivacky
190198092Srdivacky  /// \brief Determine whether the given type \p T has already been
191198092Srdivacky  /// transformed.
192198092Srdivacky  ///
193198092Srdivacky  /// Subclasses can provide an alternative implementation of this routine
194198092Srdivacky  /// to short-circuit evaluation when it is known that a given type will
195198092Srdivacky  /// not change. For example, template instantiation need not traverse
196198092Srdivacky  /// non-dependent types.
197198092Srdivacky  bool AlreadyTransformed(QualType T) {
198198092Srdivacky    return T.isNull();
199198092Srdivacky  }
200198092Srdivacky
201200583Srdivacky  /// \brief Determine whether the given call argument should be dropped, e.g.,
202200583Srdivacky  /// because it is a default argument.
203200583Srdivacky  ///
204200583Srdivacky  /// Subclasses can provide an alternative implementation of this routine to
205200583Srdivacky  /// determine which kinds of call arguments get dropped. By default,
206200583Srdivacky  /// CXXDefaultArgument nodes are dropped (prior to transformation).
207200583Srdivacky  bool DropCallArgument(Expr *E) {
208200583Srdivacky    return E->isDefaultArgument();
209200583Srdivacky  }
210239462Sdim
211218893Sdim  /// \brief Determine whether we should expand a pack expansion with the
212218893Sdim  /// given set of parameter packs into separate arguments by repeatedly
213218893Sdim  /// transforming the pattern.
214218893Sdim  ///
215218893Sdim  /// By default, the transformer never tries to expand pack expansions.
216218893Sdim  /// Subclasses can override this routine to provide different behavior.
217218893Sdim  ///
218218893Sdim  /// \param EllipsisLoc The location of the ellipsis that identifies the
219218893Sdim  /// pack expansion.
220218893Sdim  ///
221218893Sdim  /// \param PatternRange The source range that covers the entire pattern of
222218893Sdim  /// the pack expansion.
223218893Sdim  ///
224239462Sdim  /// \param Unexpanded The set of unexpanded parameter packs within the
225218893Sdim  /// pattern.
226218893Sdim  ///
227218893Sdim  /// \param ShouldExpand Will be set to \c true if the transformer should
228218893Sdim  /// expand the corresponding pack expansions into separate arguments. When
229218893Sdim  /// set, \c NumExpansions must also be set.
230218893Sdim  ///
231218893Sdim  /// \param RetainExpansion Whether the caller should add an unexpanded
232218893Sdim  /// pack expansion after all of the expanded arguments. This is used
233218893Sdim  /// when extending explicitly-specified template argument packs per
234218893Sdim  /// C++0x [temp.arg.explicit]p9.
235218893Sdim  ///
236218893Sdim  /// \param NumExpansions The number of separate arguments that will be in
237218893Sdim  /// the expanded form of the corresponding pack expansion. This is both an
238218893Sdim  /// input and an output parameter, which can be set by the caller if the
239218893Sdim  /// number of expansions is known a priori (e.g., due to a prior substitution)
240218893Sdim  /// and will be set by the callee when the number of expansions is known.
241218893Sdim  /// The callee must set this value when \c ShouldExpand is \c true; it may
242218893Sdim  /// set this value in other cases.
243218893Sdim  ///
244239462Sdim  /// \returns true if an error occurred (e.g., because the parameter packs
245239462Sdim  /// are to be instantiated with arguments of different lengths), false
246239462Sdim  /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
247218893Sdim  /// must be set.
248218893Sdim  bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
249218893Sdim                               SourceRange PatternRange,
250249423Sdim                               ArrayRef<UnexpandedParameterPack> Unexpanded,
251218893Sdim                               bool &ShouldExpand,
252218893Sdim                               bool &RetainExpansion,
253249423Sdim                               Optional<unsigned> &NumExpansions) {
254218893Sdim    ShouldExpand = false;
255218893Sdim    return false;
256218893Sdim  }
257239462Sdim
258218893Sdim  /// \brief "Forget" about the partially-substituted pack template argument,
259218893Sdim  /// when performing an instantiation that must preserve the parameter pack
260218893Sdim  /// use.
261218893Sdim  ///
262218893Sdim  /// This routine is meant to be overridden by the template instantiator.
263218893Sdim  TemplateArgument ForgetPartiallySubstitutedPack() {
264218893Sdim    return TemplateArgument();
265218893Sdim  }
266239462Sdim
267218893Sdim  /// \brief "Remember" the partially-substituted pack template argument
268218893Sdim  /// after performing an instantiation that must preserve the parameter pack
269218893Sdim  /// use.
270218893Sdim  ///
271218893Sdim  /// This routine is meant to be overridden by the template instantiator.
272218893Sdim  void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
273239462Sdim
274218893Sdim  /// \brief Note to the derived class when a function parameter pack is
275218893Sdim  /// being expanded.
276218893Sdim  void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
277239462Sdim
278198092Srdivacky  /// \brief Transforms the given type into another type.
279198092Srdivacky  ///
280198398Srdivacky  /// By default, this routine transforms a type by creating a
281200583Srdivacky  /// TypeSourceInfo for it and delegating to the appropriate
282198398Srdivacky  /// function.  This is expensive, but we don't mind, because
283198398Srdivacky  /// this method is deprecated anyway;  all users should be
284200583Srdivacky  /// switched to storing TypeSourceInfos.
285198092Srdivacky  ///
286198092Srdivacky  /// \returns the transformed type.
287218893Sdim  QualType TransformType(QualType T);
288198092Srdivacky
289198398Srdivacky  /// \brief Transforms the given type-with-location into a new
290198398Srdivacky  /// type-with-location.
291198092Srdivacky  ///
292198398Srdivacky  /// By default, this routine transforms a type by delegating to the
293198398Srdivacky  /// appropriate TransformXXXType to build a new type.  Subclasses
294198398Srdivacky  /// may override this function (to take over all type
295198398Srdivacky  /// transformations) or some set of the TransformXXXType functions
296198398Srdivacky  /// to alter the transformation.
297218893Sdim  TypeSourceInfo *TransformType(TypeSourceInfo *DI);
298198092Srdivacky
299198398Srdivacky  /// \brief Transform the given type-with-location into a new
300198398Srdivacky  /// type, collecting location information in the given builder
301198398Srdivacky  /// as necessary.
302198398Srdivacky  ///
303218893Sdim  QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
304198398Srdivacky
305198092Srdivacky  /// \brief Transform the given statement.
306198092Srdivacky  ///
307198092Srdivacky  /// By default, this routine transforms a statement by delegating to the
308198092Srdivacky  /// appropriate TransformXXXStmt function to transform a specific kind of
309198092Srdivacky  /// statement or the TransformExpr() function to transform an expression.
310198092Srdivacky  /// Subclasses may override this function to transform statements using some
311198092Srdivacky  /// other mechanism.
312198092Srdivacky  ///
313198092Srdivacky  /// \returns the transformed statement.
314212904Sdim  StmtResult TransformStmt(Stmt *S);
315198092Srdivacky
316198092Srdivacky  /// \brief Transform the given expression.
317198092Srdivacky  ///
318198092Srdivacky  /// By default, this routine transforms an expression by delegating to the
319198092Srdivacky  /// appropriate TransformXXXExpr function to build a new expression.
320198092Srdivacky  /// Subclasses may override this function to transform expressions using some
321198092Srdivacky  /// other mechanism.
322198092Srdivacky  ///
323198092Srdivacky  /// \returns the transformed expression.
324212904Sdim  ExprResult TransformExpr(Expr *E);
325198092Srdivacky
326249423Sdim  /// \brief Transform the given initializer.
327249423Sdim  ///
328249423Sdim  /// By default, this routine transforms an initializer by stripping off the
329249423Sdim  /// semantic nodes added by initialization, then passing the result to
330249423Sdim  /// TransformExpr or TransformExprs.
331249423Sdim  ///
332249423Sdim  /// \returns the transformed initializer.
333249423Sdim  ExprResult TransformInitializer(Expr *Init, bool CXXDirectInit);
334249423Sdim
335218893Sdim  /// \brief Transform the given list of expressions.
336218893Sdim  ///
337239462Sdim  /// This routine transforms a list of expressions by invoking
338239462Sdim  /// \c TransformExpr() for each subexpression. However, it also provides
339218893Sdim  /// support for variadic templates by expanding any pack expansions (if the
340218893Sdim  /// derived class permits such expansion) along the way. When pack expansions
341218893Sdim  /// are present, the number of outputs may not equal the number of inputs.
342218893Sdim  ///
343218893Sdim  /// \param Inputs The set of expressions to be transformed.
344218893Sdim  ///
345218893Sdim  /// \param NumInputs The number of expressions in \c Inputs.
346218893Sdim  ///
347218893Sdim  /// \param IsCall If \c true, then this transform is being performed on
348239462Sdim  /// function-call arguments, and any arguments that should be dropped, will
349218893Sdim  /// be.
350218893Sdim  ///
351218893Sdim  /// \param Outputs The transformed input expressions will be added to this
352218893Sdim  /// vector.
353218893Sdim  ///
354218893Sdim  /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
355218893Sdim  /// due to transformation.
356218893Sdim  ///
357218893Sdim  /// \returns true if an error occurred, false otherwise.
358218893Sdim  bool TransformExprs(Expr **Inputs, unsigned NumInputs, bool IsCall,
359226633Sdim                      SmallVectorImpl<Expr *> &Outputs,
360218893Sdim                      bool *ArgChanged = 0);
361239462Sdim
362198092Srdivacky  /// \brief Transform the given declaration, which is referenced from a type
363198092Srdivacky  /// or expression.
364198092Srdivacky  ///
365234353Sdim  /// By default, acts as the identity function on declarations, unless the
366234353Sdim  /// transformer has had to transform the declaration itself. Subclasses
367198092Srdivacky  /// may override this function to provide alternate behavior.
368239462Sdim  Decl *TransformDecl(SourceLocation Loc, Decl *D) {
369234353Sdim    llvm::DenseMap<Decl *, Decl *>::iterator Known
370234353Sdim      = TransformedLocalDecls.find(D);
371234353Sdim    if (Known != TransformedLocalDecls.end())
372234353Sdim      return Known->second;
373239462Sdim
374239462Sdim    return D;
375234353Sdim  }
376198092Srdivacky
377239462Sdim  /// \brief Transform the attributes associated with the given declaration and
378234353Sdim  /// place them on the new declaration.
379234353Sdim  ///
380234353Sdim  /// By default, this operation does nothing. Subclasses may override this
381234353Sdim  /// behavior to transform attributes.
382234353Sdim  void transformAttrs(Decl *Old, Decl *New) { }
383239462Sdim
384234353Sdim  /// \brief Note that a local declaration has been transformed by this
385234353Sdim  /// transformer.
386234353Sdim  ///
387239462Sdim  /// Local declarations are typically transformed via a call to
388234353Sdim  /// TransformDefinition. However, in some cases (e.g., lambda expressions),
389234353Sdim  /// the transformer itself has to transform the declarations. This routine
390234353Sdim  /// can be overridden by a subclass that keeps track of such mappings.
391234353Sdim  void transformedLocalDecl(Decl *Old, Decl *New) {
392234353Sdim    TransformedLocalDecls[Old] = New;
393234353Sdim  }
394239462Sdim
395198092Srdivacky  /// \brief Transform the definition of the given declaration.
396198092Srdivacky  ///
397198092Srdivacky  /// By default, invokes TransformDecl() to transform the declaration.
398198092Srdivacky  /// Subclasses may override this function to provide alternate behavior.
399239462Sdim  Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
400239462Sdim    return getDerived().TransformDecl(Loc, D);
401204643Srdivacky  }
402198092Srdivacky
403198398Srdivacky  /// \brief Transform the given declaration, which was the first part of a
404198398Srdivacky  /// nested-name-specifier in a member access expression.
405198398Srdivacky  ///
406239462Sdim  /// This specific declaration transformation only applies to the first
407198398Srdivacky  /// identifier in a nested-name-specifier of a member access expression, e.g.,
408198398Srdivacky  /// the \c T in \c x->T::member
409198398Srdivacky  ///
410198398Srdivacky  /// By default, invokes TransformDecl() to transform the declaration.
411198398Srdivacky  /// Subclasses may override this function to provide alternate behavior.
412239462Sdim  NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
413239462Sdim    return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
414198398Srdivacky  }
415239462Sdim
416219077Sdim  /// \brief Transform the given nested-name-specifier with source-location
417219077Sdim  /// information.
418219077Sdim  ///
419219077Sdim  /// By default, transforms all of the types and declarations within the
420219077Sdim  /// nested-name-specifier. Subclasses may override this function to provide
421219077Sdim  /// alternate behavior.
422219077Sdim  NestedNameSpecifierLoc TransformNestedNameSpecifierLoc(
423219077Sdim                                                    NestedNameSpecifierLoc NNS,
424219077Sdim                                          QualType ObjectType = QualType(),
425219077Sdim                                          NamedDecl *FirstQualifierInScope = 0);
426219077Sdim
427198092Srdivacky  /// \brief Transform the given declaration name.
428198092Srdivacky  ///
429198092Srdivacky  /// By default, transforms the types of conversion function, constructor,
430198092Srdivacky  /// and destructor names and then (if needed) rebuilds the declaration name.
431198092Srdivacky  /// Identifiers and selectors are returned unmodified. Sublcasses may
432198092Srdivacky  /// override this function to provide alternate behavior.
433212904Sdim  DeclarationNameInfo
434218893Sdim  TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
435198092Srdivacky
436198092Srdivacky  /// \brief Transform the given template name.
437198092Srdivacky  ///
438221345Sdim  /// \param SS The nested-name-specifier that qualifies the template
439221345Sdim  /// name. This nested-name-specifier must already have been transformed.
440221345Sdim  ///
441221345Sdim  /// \param Name The template name to transform.
442221345Sdim  ///
443221345Sdim  /// \param NameLoc The source location of the template name.
444221345Sdim  ///
445239462Sdim  /// \param ObjectType If we're translating a template name within a member
446221345Sdim  /// access expression, this is the type of the object whose member template
447221345Sdim  /// is being referenced.
448221345Sdim  ///
449221345Sdim  /// \param FirstQualifierInScope If the first part of a nested-name-specifier
450221345Sdim  /// also refers to a name within the current (lexical) scope, this is the
451221345Sdim  /// declaration it refers to.
452221345Sdim  ///
453198092Srdivacky  /// By default, transforms the template name by transforming the declarations
454198092Srdivacky  /// and nested-name-specifiers that occur within the template name.
455198092Srdivacky  /// Subclasses may override this function to provide alternate behavior.
456221345Sdim  TemplateName TransformTemplateName(CXXScopeSpec &SS,
457221345Sdim                                     TemplateName Name,
458234353Sdim                                     SourceLocation NameLoc,
459218893Sdim                                     QualType ObjectType = QualType(),
460218893Sdim                                     NamedDecl *FirstQualifierInScope = 0);
461198092Srdivacky
462198092Srdivacky  /// \brief Transform the given template argument.
463198092Srdivacky  ///
464198092Srdivacky  /// By default, this operation transforms the type, expression, or
465198092Srdivacky  /// declaration stored within the template argument and constructs a
466198092Srdivacky  /// new template argument from the transformed result. Subclasses may
467198092Srdivacky  /// override this function to provide alternate behavior.
468198893Srdivacky  ///
469198893Srdivacky  /// Returns true if there was an error.
470198893Srdivacky  bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
471198893Srdivacky                                 TemplateArgumentLoc &Output);
472198092Srdivacky
473218893Sdim  /// \brief Transform the given set of template arguments.
474218893Sdim  ///
475239462Sdim  /// By default, this operation transforms all of the template arguments
476218893Sdim  /// in the input set using \c TransformTemplateArgument(), and appends
477218893Sdim  /// the transformed arguments to the output list.
478218893Sdim  ///
479218893Sdim  /// Note that this overload of \c TransformTemplateArguments() is merely
480218893Sdim  /// a convenience function. Subclasses that wish to override this behavior
481218893Sdim  /// should override the iterator-based member template version.
482218893Sdim  ///
483218893Sdim  /// \param Inputs The set of template arguments to be transformed.
484218893Sdim  ///
485218893Sdim  /// \param NumInputs The number of template arguments in \p Inputs.
486218893Sdim  ///
487218893Sdim  /// \param Outputs The set of transformed template arguments output by this
488218893Sdim  /// routine.
489218893Sdim  ///
490218893Sdim  /// Returns true if an error occurred.
491218893Sdim  bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
492218893Sdim                                  unsigned NumInputs,
493218893Sdim                                  TemplateArgumentListInfo &Outputs) {
494218893Sdim    return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs);
495218893Sdim  }
496218893Sdim
497218893Sdim  /// \brief Transform the given set of template arguments.
498218893Sdim  ///
499239462Sdim  /// By default, this operation transforms all of the template arguments
500218893Sdim  /// in the input set using \c TransformTemplateArgument(), and appends
501239462Sdim  /// the transformed arguments to the output list.
502218893Sdim  ///
503218893Sdim  /// \param First An iterator to the first template argument.
504218893Sdim  ///
505218893Sdim  /// \param Last An iterator one step past the last template argument.
506218893Sdim  ///
507218893Sdim  /// \param Outputs The set of transformed template arguments output by this
508218893Sdim  /// routine.
509218893Sdim  ///
510218893Sdim  /// Returns true if an error occurred.
511218893Sdim  template<typename InputIterator>
512218893Sdim  bool TransformTemplateArguments(InputIterator First,
513218893Sdim                                  InputIterator Last,
514218893Sdim                                  TemplateArgumentListInfo &Outputs);
515218893Sdim
516198893Srdivacky  /// \brief Fakes up a TemplateArgumentLoc for a given TemplateArgument.
517198893Srdivacky  void InventTemplateArgumentLoc(const TemplateArgument &Arg,
518198893Srdivacky                                 TemplateArgumentLoc &ArgLoc);
519198893Srdivacky
520200583Srdivacky  /// \brief Fakes up a TypeSourceInfo for a type.
521200583Srdivacky  TypeSourceInfo *InventTypeSourceInfo(QualType T) {
522200583Srdivacky    return SemaRef.Context.getTrivialTypeSourceInfo(T,
523198893Srdivacky                       getDerived().getBaseLocation());
524198893Srdivacky  }
525198893Srdivacky
526198398Srdivacky#define ABSTRACT_TYPELOC(CLASS, PARENT)
527198398Srdivacky#define TYPELOC(CLASS, PARENT)                                   \
528218893Sdim  QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
529198398Srdivacky#include "clang/AST/TypeLocNodes.def"
530198092Srdivacky
531234982Sdim  QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
532234982Sdim                                      FunctionProtoTypeLoc TL,
533234982Sdim                                      CXXRecordDecl *ThisContext,
534234982Sdim                                      unsigned ThisTypeQuals);
535234982Sdim
536221345Sdim  StmtResult
537221345Sdim  TransformSEHHandler(Stmt *Handler);
538221345Sdim
539239462Sdim  QualType
540218893Sdim  TransformTemplateSpecializationType(TypeLocBuilder &TLB,
541218893Sdim                                      TemplateSpecializationTypeLoc TL,
542218893Sdim                                      TemplateName Template);
543218893Sdim
544239462Sdim  QualType
545218893Sdim  TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
546218893Sdim                                      DependentTemplateSpecializationTypeLoc TL,
547221345Sdim                                               TemplateName Template,
548221345Sdim                                               CXXScopeSpec &SS);
549218893Sdim
550239462Sdim  QualType
551221345Sdim  TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
552221345Sdim                                               DependentTemplateSpecializationTypeLoc TL,
553221345Sdim                                         NestedNameSpecifierLoc QualifierLoc);
554221345Sdim
555205219Srdivacky  /// \brief Transforms the parameters of a function type into the
556205219Srdivacky  /// given vectors.
557205219Srdivacky  ///
558205219Srdivacky  /// The result vectors should be kept in sync; null entries in the
559205219Srdivacky  /// variables vector are acceptable.
560205219Srdivacky  ///
561205219Srdivacky  /// Return true on error.
562218893Sdim  bool TransformFunctionTypeParams(SourceLocation Loc,
563218893Sdim                                   ParmVarDecl **Params, unsigned NumParams,
564218893Sdim                                   const QualType *ParamTypes,
565226633Sdim                                   SmallVectorImpl<QualType> &PTypes,
566226633Sdim                                   SmallVectorImpl<ParmVarDecl*> *PVars);
567205219Srdivacky
568205219Srdivacky  /// \brief Transforms a single function-type parameter.  Return null
569205219Srdivacky  /// on error.
570221345Sdim  ///
571221345Sdim  /// \param indexAdjustment - A number to add to the parameter's
572221345Sdim  ///   scope index;  can be negative
573218893Sdim  ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
574221345Sdim                                          int indexAdjustment,
575249423Sdim                                          Optional<unsigned> NumExpansions,
576234353Sdim                                          bool ExpectParameterPack);
577205219Srdivacky
578218893Sdim  QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
579198893Srdivacky
580212904Sdim  StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
581212904Sdim  ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
582198092Srdivacky
583239462Sdim  /// \brief Transform the captures and body of a lambda expression.
584239462Sdim  ExprResult TransformLambdaScope(LambdaExpr *E, CXXMethodDecl *CallOperator);
585239462Sdim
586243830Sdim  ExprResult TransformAddressOfOperand(Expr *E);
587243830Sdim  ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
588243830Sdim                                                bool IsAddressOfOperand);
589243830Sdim
590198092Srdivacky#define STMT(Node, Parent)                        \
591212904Sdim  StmtResult Transform##Node(Node *S);
592198092Srdivacky#define EXPR(Node, Parent)                        \
593212904Sdim  ExprResult Transform##Node(Node *E);
594208600Srdivacky#define ABSTRACT_STMT(Stmt)
595208600Srdivacky#include "clang/AST/StmtNodes.inc"
596198092Srdivacky
597198092Srdivacky  /// \brief Build a new pointer type given its pointee type.
598198092Srdivacky  ///
599198092Srdivacky  /// By default, performs semantic analysis when building the pointer type.
600198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
601198893Srdivacky  QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
602198092Srdivacky
603198092Srdivacky  /// \brief Build a new block pointer type given its pointee type.
604198092Srdivacky  ///
605198092Srdivacky  /// By default, performs semantic analysis when building the block pointer
606198092Srdivacky  /// type. Subclasses may override this routine to provide different behavior.
607198893Srdivacky  QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
608198092Srdivacky
609198893Srdivacky  /// \brief Build a new reference type given the type it references.
610198092Srdivacky  ///
611198893Srdivacky  /// By default, performs semantic analysis when building the
612198893Srdivacky  /// reference type. Subclasses may override this routine to provide
613198893Srdivacky  /// different behavior.
614198092Srdivacky  ///
615198893Srdivacky  /// \param LValue whether the type was written with an lvalue sigil
616198893Srdivacky  /// or an rvalue sigil.
617198893Srdivacky  QualType RebuildReferenceType(QualType ReferentType,
618198893Srdivacky                                bool LValue,
619198893Srdivacky                                SourceLocation Sigil);
620198092Srdivacky
621198092Srdivacky  /// \brief Build a new member pointer type given the pointee type and the
622198092Srdivacky  /// class type it refers into.
623198092Srdivacky  ///
624198092Srdivacky  /// By default, performs semantic analysis when building the member pointer
625198092Srdivacky  /// type. Subclasses may override this routine to provide different behavior.
626198893Srdivacky  QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
627198893Srdivacky                                    SourceLocation Sigil);
628198092Srdivacky
629198092Srdivacky  /// \brief Build a new array type given the element type, size
630198092Srdivacky  /// modifier, size of the array (if known), size expression, and index type
631198092Srdivacky  /// qualifiers.
632198092Srdivacky  ///
633198092Srdivacky  /// By default, performs semantic analysis when building the array type.
634198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
635198092Srdivacky  /// Also by default, all of the other Rebuild*Array
636198092Srdivacky  QualType RebuildArrayType(QualType ElementType,
637198092Srdivacky                            ArrayType::ArraySizeModifier SizeMod,
638198092Srdivacky                            const llvm::APInt *Size,
639198092Srdivacky                            Expr *SizeExpr,
640198092Srdivacky                            unsigned IndexTypeQuals,
641198092Srdivacky                            SourceRange BracketsRange);
642198092Srdivacky
643198092Srdivacky  /// \brief Build a new constant array type given the element type, size
644198092Srdivacky  /// modifier, (known) size of the array, and index type qualifiers.
645198092Srdivacky  ///
646198092Srdivacky  /// By default, performs semantic analysis when building the array type.
647198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
648198092Srdivacky  QualType RebuildConstantArrayType(QualType ElementType,
649198092Srdivacky                                    ArrayType::ArraySizeModifier SizeMod,
650198092Srdivacky                                    const llvm::APInt &Size,
651198893Srdivacky                                    unsigned IndexTypeQuals,
652198893Srdivacky                                    SourceRange BracketsRange);
653198092Srdivacky
654198092Srdivacky  /// \brief Build a new incomplete array type given the element type, size
655198092Srdivacky  /// modifier, and index type qualifiers.
656198092Srdivacky  ///
657198092Srdivacky  /// By default, performs semantic analysis when building the array type.
658198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
659198092Srdivacky  QualType RebuildIncompleteArrayType(QualType ElementType,
660198092Srdivacky                                      ArrayType::ArraySizeModifier SizeMod,
661198893Srdivacky                                      unsigned IndexTypeQuals,
662198893Srdivacky                                      SourceRange BracketsRange);
663198092Srdivacky
664198092Srdivacky  /// \brief Build a new variable-length array type given the element type,
665198092Srdivacky  /// size modifier, size expression, and index type qualifiers.
666198092Srdivacky  ///
667198092Srdivacky  /// By default, performs semantic analysis when building the array type.
668198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
669198092Srdivacky  QualType RebuildVariableArrayType(QualType ElementType,
670198092Srdivacky                                    ArrayType::ArraySizeModifier SizeMod,
671212904Sdim                                    Expr *SizeExpr,
672198092Srdivacky                                    unsigned IndexTypeQuals,
673198092Srdivacky                                    SourceRange BracketsRange);
674198092Srdivacky
675198092Srdivacky  /// \brief Build a new dependent-sized array type given the element type,
676198092Srdivacky  /// size modifier, size expression, and index type qualifiers.
677198092Srdivacky  ///
678198092Srdivacky  /// By default, performs semantic analysis when building the array type.
679198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
680198092Srdivacky  QualType RebuildDependentSizedArrayType(QualType ElementType,
681198092Srdivacky                                          ArrayType::ArraySizeModifier SizeMod,
682212904Sdim                                          Expr *SizeExpr,
683198092Srdivacky                                          unsigned IndexTypeQuals,
684198092Srdivacky                                          SourceRange BracketsRange);
685198092Srdivacky
686198092Srdivacky  /// \brief Build a new vector type given the element type and
687198092Srdivacky  /// number of elements.
688198092Srdivacky  ///
689198092Srdivacky  /// By default, performs semantic analysis when building the vector type.
690198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
691203955Srdivacky  QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
692218893Sdim                             VectorType::VectorKind VecKind);
693198092Srdivacky
694198092Srdivacky  /// \brief Build a new extended vector type given the element type and
695198092Srdivacky  /// number of elements.
696198092Srdivacky  ///
697198092Srdivacky  /// By default, performs semantic analysis when building the vector type.
698198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
699198092Srdivacky  QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
700198092Srdivacky                                SourceLocation AttributeLoc);
701198092Srdivacky
702198092Srdivacky  /// \brief Build a new potentially dependently-sized extended vector type
703198092Srdivacky  /// given the element type and number of elements.
704198092Srdivacky  ///
705198092Srdivacky  /// By default, performs semantic analysis when building the vector type.
706198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
707198092Srdivacky  QualType RebuildDependentSizedExtVectorType(QualType ElementType,
708212904Sdim                                              Expr *SizeExpr,
709198092Srdivacky                                              SourceLocation AttributeLoc);
710198092Srdivacky
711198092Srdivacky  /// \brief Build a new function type.
712198092Srdivacky  ///
713198092Srdivacky  /// By default, performs semantic analysis when building the function type.
714198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
715198092Srdivacky  QualType RebuildFunctionProtoType(QualType T,
716249423Sdim                                    llvm::MutableArrayRef<QualType> ParamTypes,
717249423Sdim                                    const FunctionProtoType::ExtProtoInfo &EPI);
718198092Srdivacky
719198398Srdivacky  /// \brief Build a new unprototyped function type.
720198398Srdivacky  QualType RebuildFunctionNoProtoType(QualType ResultType);
721198398Srdivacky
722200583Srdivacky  /// \brief Rebuild an unresolved typename type, given the decl that
723200583Srdivacky  /// the UnresolvedUsingTypenameDecl was transformed to.
724200583Srdivacky  QualType RebuildUnresolvedUsingType(Decl *D);
725200583Srdivacky
726198092Srdivacky  /// \brief Build a new typedef type.
727221345Sdim  QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
728198092Srdivacky    return SemaRef.Context.getTypeDeclType(Typedef);
729198092Srdivacky  }
730198092Srdivacky
731198092Srdivacky  /// \brief Build a new class/struct/union type.
732198092Srdivacky  QualType RebuildRecordType(RecordDecl *Record) {
733198092Srdivacky    return SemaRef.Context.getTypeDeclType(Record);
734198092Srdivacky  }
735198092Srdivacky
736198092Srdivacky  /// \brief Build a new Enum type.
737198092Srdivacky  QualType RebuildEnumType(EnumDecl *Enum) {
738198092Srdivacky    return SemaRef.Context.getTypeDeclType(Enum);
739198092Srdivacky  }
740198092Srdivacky
741198092Srdivacky  /// \brief Build a new typeof(expr) type.
742198092Srdivacky  ///
743198092Srdivacky  /// By default, performs semantic analysis when building the typeof type.
744198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
745218893Sdim  QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc);
746198092Srdivacky
747198092Srdivacky  /// \brief Build a new typeof(type) type.
748198092Srdivacky  ///
749198092Srdivacky  /// By default, builds a new TypeOfType with the given underlying type.
750198092Srdivacky  QualType RebuildTypeOfType(QualType Underlying);
751198092Srdivacky
752223017Sdim  /// \brief Build a new unary transform type.
753223017Sdim  QualType RebuildUnaryTransformType(QualType BaseType,
754223017Sdim                                     UnaryTransformType::UTTKind UKind,
755223017Sdim                                     SourceLocation Loc);
756223017Sdim
757251662Sdim  /// \brief Build a new C++11 decltype type.
758198092Srdivacky  ///
759198092Srdivacky  /// By default, performs semantic analysis when building the decltype type.
760198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
761218893Sdim  QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
762198092Srdivacky
763251662Sdim  /// \brief Build a new C++11 auto type.
764218893Sdim  ///
765218893Sdim  /// By default, builds a new AutoType with the given deduced type.
766251662Sdim  QualType RebuildAutoType(QualType Deduced, bool IsDecltypeAuto) {
767251662Sdim    // Note, IsDependent is always false here: we implicitly convert an 'auto'
768251662Sdim    // which has been deduced to a dependent type into an undeduced 'auto', so
769251662Sdim    // that we'll retry deduction after the transformation.
770251662Sdim    return SemaRef.Context.getAutoType(Deduced, IsDecltypeAuto);
771218893Sdim  }
772218893Sdim
773198092Srdivacky  /// \brief Build a new template specialization type.
774198092Srdivacky  ///
775198092Srdivacky  /// By default, performs semantic analysis when building the template
776198092Srdivacky  /// specialization type. Subclasses may override this routine to provide
777198092Srdivacky  /// different behavior.
778198092Srdivacky  QualType RebuildTemplateSpecializationType(TemplateName Template,
779198893Srdivacky                                             SourceLocation TemplateLoc,
780221345Sdim                                             TemplateArgumentListInfo &Args);
781198092Srdivacky
782218893Sdim  /// \brief Build a new parenthesized type.
783218893Sdim  ///
784218893Sdim  /// By default, builds a new ParenType type from the inner type.
785218893Sdim  /// Subclasses may override this routine to provide different behavior.
786218893Sdim  QualType RebuildParenType(QualType InnerType) {
787218893Sdim    return SemaRef.Context.getParenType(InnerType);
788218893Sdim  }
789218893Sdim
790198092Srdivacky  /// \brief Build a new qualified name type.
791198092Srdivacky  ///
792208600Srdivacky  /// By default, builds a new ElaboratedType type from the keyword,
793208600Srdivacky  /// the nested-name-specifier and the named type.
794208600Srdivacky  /// Subclasses may override this routine to provide different behavior.
795218893Sdim  QualType RebuildElaboratedType(SourceLocation KeywordLoc,
796218893Sdim                                 ElaboratedTypeKeyword Keyword,
797221345Sdim                                 NestedNameSpecifierLoc QualifierLoc,
798221345Sdim                                 QualType Named) {
799239462Sdim    return SemaRef.Context.getElaboratedType(Keyword,
800239462Sdim                                         QualifierLoc.getNestedNameSpecifier(),
801221345Sdim                                             Named);
802198092Srdivacky  }
803198092Srdivacky
804198092Srdivacky  /// \brief Build a new typename type that refers to a template-id.
805198092Srdivacky  ///
806208600Srdivacky  /// By default, builds a new DependentNameType type from the
807208600Srdivacky  /// nested-name-specifier and the given type. Subclasses may override
808208600Srdivacky  /// this routine to provide different behavior.
809210299Sed  QualType RebuildDependentTemplateSpecializationType(
810221345Sdim                                          ElaboratedTypeKeyword Keyword,
811221345Sdim                                          NestedNameSpecifierLoc QualifierLoc,
812221345Sdim                                          const IdentifierInfo *Name,
813221345Sdim                                          SourceLocation NameLoc,
814221345Sdim                                          TemplateArgumentListInfo &Args) {
815210299Sed    // Rebuild the template name.
816210299Sed    // TODO: avoid TemplateName abstraction
817221345Sdim    CXXScopeSpec SS;
818221345Sdim    SS.Adopt(QualifierLoc);
819239462Sdim    TemplateName InstName
820221345Sdim      = getDerived().RebuildTemplateName(SS, *Name, NameLoc, QualType(), 0);
821239462Sdim
822210299Sed    if (InstName.isNull())
823210299Sed      return QualType();
824239462Sdim
825210299Sed    // If it's still dependent, make a dependent specialization.
826210299Sed    if (InstName.getAsDependentTemplateName())
827239462Sdim      return SemaRef.Context.getDependentTemplateSpecializationType(Keyword,
828239462Sdim                                          QualifierLoc.getNestedNameSpecifier(),
829239462Sdim                                                                    Name,
830221345Sdim                                                                    Args);
831239462Sdim
832210299Sed    // Otherwise, make an elaborated type wrapping a non-dependent
833210299Sed    // specialization.
834210299Sed    QualType T =
835221345Sdim    getDerived().RebuildTemplateSpecializationType(InstName, NameLoc, Args);
836210299Sed    if (T.isNull()) return QualType();
837239462Sdim
838221345Sdim    if (Keyword == ETK_None && QualifierLoc.getNestedNameSpecifier() == 0)
839221345Sdim      return T;
840239462Sdim
841239462Sdim    return SemaRef.Context.getElaboratedType(Keyword,
842239462Sdim                                       QualifierLoc.getNestedNameSpecifier(),
843221345Sdim                                             T);
844198092Srdivacky  }
845198092Srdivacky
846198092Srdivacky  /// \brief Build a new typename type that refers to an identifier.
847198092Srdivacky  ///
848198092Srdivacky  /// By default, performs semantic analysis when building the typename type
849208600Srdivacky  /// (or elaborated type). Subclasses may override this routine to provide
850198092Srdivacky  /// different behavior.
851208600Srdivacky  QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
852221345Sdim                                    SourceLocation KeywordLoc,
853221345Sdim                                    NestedNameSpecifierLoc QualifierLoc,
854206084Srdivacky                                    const IdentifierInfo *Id,
855208600Srdivacky                                    SourceLocation IdLoc) {
856206084Srdivacky    CXXScopeSpec SS;
857221345Sdim    SS.Adopt(QualifierLoc);
858208600Srdivacky
859221345Sdim    if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
860206084Srdivacky      // If the name is still dependent, just build a new dependent name type.
861206084Srdivacky      if (!SemaRef.computeDeclContext(SS))
862239462Sdim        return SemaRef.Context.getDependentNameType(Keyword,
863239462Sdim                                          QualifierLoc.getNestedNameSpecifier(),
864221345Sdim                                                    Id);
865206084Srdivacky    }
866206084Srdivacky
867208600Srdivacky    if (Keyword == ETK_None || Keyword == ETK_Typename)
868221345Sdim      return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
869221345Sdim                                       *Id, IdLoc);
870208600Srdivacky
871208600Srdivacky    TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
872208600Srdivacky
873208600Srdivacky    // We had a dependent elaborated-type-specifier that has been transformed
874206084Srdivacky    // into a non-dependent elaborated-type-specifier. Find the tag we're
875206084Srdivacky    // referring to.
876208600Srdivacky    LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
877206084Srdivacky    DeclContext *DC = SemaRef.computeDeclContext(SS, false);
878206084Srdivacky    if (!DC)
879206084Srdivacky      return QualType();
880206084Srdivacky
881208600Srdivacky    if (SemaRef.RequireCompleteDeclContext(SS, DC))
882208600Srdivacky      return QualType();
883208600Srdivacky
884206084Srdivacky    TagDecl *Tag = 0;
885206084Srdivacky    SemaRef.LookupQualifiedName(Result, DC);
886206084Srdivacky    switch (Result.getResultKind()) {
887206084Srdivacky      case LookupResult::NotFound:
888206084Srdivacky      case LookupResult::NotFoundInCurrentInstantiation:
889206084Srdivacky        break;
890239462Sdim
891206084Srdivacky      case LookupResult::Found:
892206084Srdivacky        Tag = Result.getAsSingle<TagDecl>();
893206084Srdivacky        break;
894239462Sdim
895206084Srdivacky      case LookupResult::FoundOverloaded:
896206084Srdivacky      case LookupResult::FoundUnresolvedValue:
897206084Srdivacky        llvm_unreachable("Tag lookup cannot find non-tags");
898239462Sdim
899206084Srdivacky      case LookupResult::Ambiguous:
900206084Srdivacky        // Let the LookupResult structure handle ambiguities.
901206084Srdivacky        return QualType();
902206084Srdivacky    }
903206084Srdivacky
904206084Srdivacky    if (!Tag) {
905218893Sdim      // Check where the name exists but isn't a tag type and use that to emit
906218893Sdim      // better diagnostics.
907218893Sdim      LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
908218893Sdim      SemaRef.LookupQualifiedName(Result, DC);
909218893Sdim      switch (Result.getResultKind()) {
910218893Sdim        case LookupResult::Found:
911218893Sdim        case LookupResult::FoundOverloaded:
912218893Sdim        case LookupResult::FoundUnresolvedValue: {
913223017Sdim          NamedDecl *SomeDecl = Result.getRepresentativeDecl();
914218893Sdim          unsigned Kind = 0;
915218893Sdim          if (isa<TypedefDecl>(SomeDecl)) Kind = 1;
916221345Sdim          else if (isa<TypeAliasDecl>(SomeDecl)) Kind = 2;
917221345Sdim          else if (isa<ClassTemplateDecl>(SomeDecl)) Kind = 3;
918218893Sdim          SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag) << Kind;
919218893Sdim          SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
920218893Sdim          break;
921223017Sdim        }
922218893Sdim        default:
923218893Sdim          // FIXME: Would be nice to highlight just the source range.
924218893Sdim          SemaRef.Diag(IdLoc, diag::err_not_tag_in_scope)
925218893Sdim            << Kind << Id << DC;
926218893Sdim          break;
927218893Sdim      }
928206084Srdivacky      return QualType();
929206084Srdivacky    }
930208600Srdivacky
931223017Sdim    if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false,
932223017Sdim                                              IdLoc, *Id)) {
933208600Srdivacky      SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
934206084Srdivacky      SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
935206084Srdivacky      return QualType();
936206084Srdivacky    }
937206084Srdivacky
938206084Srdivacky    // Build the elaborated-type-specifier type.
939206084Srdivacky    QualType T = SemaRef.Context.getTypeDeclType(Tag);
940239462Sdim    return SemaRef.Context.getElaboratedType(Keyword,
941239462Sdim                                         QualifierLoc.getNestedNameSpecifier(),
942221345Sdim                                             T);
943198092Srdivacky  }
944198092Srdivacky
945218893Sdim  /// \brief Build a new pack expansion type.
946218893Sdim  ///
947218893Sdim  /// By default, builds a new PackExpansionType type from the given pattern.
948218893Sdim  /// Subclasses may override this routine to provide different behavior.
949239462Sdim  QualType RebuildPackExpansionType(QualType Pattern,
950218893Sdim                                    SourceRange PatternRange,
951218893Sdim                                    SourceLocation EllipsisLoc,
952249423Sdim                                    Optional<unsigned> NumExpansions) {
953218893Sdim    return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
954218893Sdim                                        NumExpansions);
955218893Sdim  }
956218893Sdim
957226633Sdim  /// \brief Build a new atomic type given its value type.
958226633Sdim  ///
959226633Sdim  /// By default, performs semantic analysis when building the atomic type.
960226633Sdim  /// Subclasses may override this routine to provide different behavior.
961226633Sdim  QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
962226633Sdim
963198092Srdivacky  /// \brief Build a new template name given a nested name specifier, a flag
964198092Srdivacky  /// indicating whether the "template" keyword was provided, and the template
965198092Srdivacky  /// that the template name refers to.
966198092Srdivacky  ///
967198092Srdivacky  /// By default, builds the new template name directly. Subclasses may override
968198092Srdivacky  /// this routine to provide different behavior.
969221345Sdim  TemplateName RebuildTemplateName(CXXScopeSpec &SS,
970198092Srdivacky                                   bool TemplateKW,
971198092Srdivacky                                   TemplateDecl *Template);
972198092Srdivacky
973198092Srdivacky  /// \brief Build a new template name given a nested name specifier and the
974198092Srdivacky  /// name that is referred to as a template.
975198092Srdivacky  ///
976198092Srdivacky  /// By default, performs semantic analysis to determine whether the name can
977198092Srdivacky  /// be resolved to a specific template, then builds the appropriate kind of
978198092Srdivacky  /// template name. Subclasses may override this routine to provide different
979198092Srdivacky  /// behavior.
980221345Sdim  TemplateName RebuildTemplateName(CXXScopeSpec &SS,
981221345Sdim                                   const IdentifierInfo &Name,
982221345Sdim                                   SourceLocation NameLoc,
983218893Sdim                                   QualType ObjectType,
984218893Sdim                                   NamedDecl *FirstQualifierInScope);
985198092Srdivacky
986198893Srdivacky  /// \brief Build a new template name given a nested name specifier and the
987198893Srdivacky  /// overloaded operator name that is referred to as a template.
988198893Srdivacky  ///
989198893Srdivacky  /// By default, performs semantic analysis to determine whether the name can
990198893Srdivacky  /// be resolved to a specific template, then builds the appropriate kind of
991198893Srdivacky  /// template name. Subclasses may override this routine to provide different
992198893Srdivacky  /// behavior.
993221345Sdim  TemplateName RebuildTemplateName(CXXScopeSpec &SS,
994198893Srdivacky                                   OverloadedOperatorKind Operator,
995221345Sdim                                   SourceLocation NameLoc,
996198893Srdivacky                                   QualType ObjectType);
997218893Sdim
998218893Sdim  /// \brief Build a new template name given a template template parameter pack
999239462Sdim  /// and the
1000218893Sdim  ///
1001218893Sdim  /// By default, performs semantic analysis to determine whether the name can
1002218893Sdim  /// be resolved to a specific template, then builds the appropriate kind of
1003218893Sdim  /// template name. Subclasses may override this routine to provide different
1004218893Sdim  /// behavior.
1005218893Sdim  TemplateName RebuildTemplateName(TemplateTemplateParmDecl *Param,
1006218893Sdim                                   const TemplateArgument &ArgPack) {
1007218893Sdim    return getSema().Context.getSubstTemplateTemplateParmPack(Param, ArgPack);
1008218893Sdim  }
1009218893Sdim
1010198092Srdivacky  /// \brief Build a new compound statement.
1011198092Srdivacky  ///
1012198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1013198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1014212904Sdim  StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1015198092Srdivacky                                       MultiStmtArg Statements,
1016198092Srdivacky                                       SourceLocation RBraceLoc,
1017198092Srdivacky                                       bool IsStmtExpr) {
1018212904Sdim    return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1019198092Srdivacky                                       IsStmtExpr);
1020198092Srdivacky  }
1021198092Srdivacky
1022198092Srdivacky  /// \brief Build a new case statement.
1023198092Srdivacky  ///
1024198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1025198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1026212904Sdim  StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1027212904Sdim                                   Expr *LHS,
1028198092Srdivacky                                   SourceLocation EllipsisLoc,
1029212904Sdim                                   Expr *RHS,
1030198092Srdivacky                                   SourceLocation ColonLoc) {
1031212904Sdim    return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1032198092Srdivacky                                   ColonLoc);
1033198092Srdivacky  }
1034198092Srdivacky
1035198092Srdivacky  /// \brief Attach the body to a new case statement.
1036198092Srdivacky  ///
1037198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1038198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1039212904Sdim  StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1040212904Sdim    getSema().ActOnCaseStmtBody(S, Body);
1041212904Sdim    return S;
1042198092Srdivacky  }
1043198092Srdivacky
1044198092Srdivacky  /// \brief Build a new default statement.
1045198092Srdivacky  ///
1046198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1047198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1048212904Sdim  StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1049198092Srdivacky                                      SourceLocation ColonLoc,
1050212904Sdim                                      Stmt *SubStmt) {
1051212904Sdim    return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1052198092Srdivacky                                      /*CurScope=*/0);
1053198092Srdivacky  }
1054198092Srdivacky
1055198092Srdivacky  /// \brief Build a new label statement.
1056198092Srdivacky  ///
1057198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1058198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1059218893Sdim  StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1060218893Sdim                              SourceLocation ColonLoc, Stmt *SubStmt) {
1061218893Sdim    return SemaRef.ActOnLabelStmt(IdentLoc, L, ColonLoc, SubStmt);
1062198092Srdivacky  }
1063198092Srdivacky
1064234982Sdim  /// \brief Build a new label statement.
1065234982Sdim  ///
1066234982Sdim  /// By default, performs semantic analysis to build the new statement.
1067234982Sdim  /// Subclasses may override this routine to provide different behavior.
1068239462Sdim  StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1069239462Sdim                                   ArrayRef<const Attr*> Attrs,
1070234982Sdim                                   Stmt *SubStmt) {
1071234982Sdim    return SemaRef.ActOnAttributedStmt(AttrLoc, Attrs, SubStmt);
1072234982Sdim  }
1073234982Sdim
1074198092Srdivacky  /// \brief Build a new "if" statement.
1075198092Srdivacky  ///
1076198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1077198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1078212904Sdim  StmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
1079239462Sdim                           VarDecl *CondVar, Stmt *Then,
1080218893Sdim                           SourceLocation ElseLoc, Stmt *Else) {
1081212904Sdim    return getSema().ActOnIfStmt(IfLoc, Cond, CondVar, Then, ElseLoc, Else);
1082198092Srdivacky  }
1083198092Srdivacky
1084198092Srdivacky  /// \brief Start building a new switch statement.
1085198092Srdivacky  ///
1086198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1087198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1088212904Sdim  StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1089218893Sdim                                    Expr *Cond, VarDecl *CondVar) {
1090239462Sdim    return getSema().ActOnStartOfSwitchStmt(SwitchLoc, Cond,
1091212904Sdim                                            CondVar);
1092198092Srdivacky  }
1093198092Srdivacky
1094198092Srdivacky  /// \brief Attach the body to the switch statement.
1095198092Srdivacky  ///
1096198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1097198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1098212904Sdim  StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1099218893Sdim                                   Stmt *Switch, Stmt *Body) {
1100212904Sdim    return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1101198092Srdivacky  }
1102198092Srdivacky
1103198092Srdivacky  /// \brief Build a new while statement.
1104198092Srdivacky  ///
1105198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1106198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1107218893Sdim  StmtResult RebuildWhileStmt(SourceLocation WhileLoc, Sema::FullExprArg Cond,
1108218893Sdim                              VarDecl *CondVar, Stmt *Body) {
1109212904Sdim    return getSema().ActOnWhileStmt(WhileLoc, Cond, CondVar, Body);
1110198092Srdivacky  }
1111198092Srdivacky
1112198092Srdivacky  /// \brief Build a new do-while statement.
1113198092Srdivacky  ///
1114198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1115198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1116212904Sdim  StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1117218893Sdim                           SourceLocation WhileLoc, SourceLocation LParenLoc,
1118218893Sdim                           Expr *Cond, SourceLocation RParenLoc) {
1119212904Sdim    return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1120212904Sdim                                 Cond, RParenLoc);
1121198092Srdivacky  }
1122198092Srdivacky
1123198092Srdivacky  /// \brief Build a new for statement.
1124198092Srdivacky  ///
1125198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1126198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1127218893Sdim  StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1128239462Sdim                            Stmt *Init, Sema::FullExprArg Cond,
1129218893Sdim                            VarDecl *CondVar, Sema::FullExprArg Inc,
1130218893Sdim                            SourceLocation RParenLoc, Stmt *Body) {
1131239462Sdim    return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1132218893Sdim                                  CondVar, Inc, RParenLoc, Body);
1133198092Srdivacky  }
1134198092Srdivacky
1135198092Srdivacky  /// \brief Build a new goto statement.
1136198092Srdivacky  ///
1137198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1138198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1139218893Sdim  StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1140218893Sdim                             LabelDecl *Label) {
1141218893Sdim    return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1142198092Srdivacky  }
1143198092Srdivacky
1144198092Srdivacky  /// \brief Build a new indirect goto statement.
1145198092Srdivacky  ///
1146198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1147198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1148212904Sdim  StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1149218893Sdim                                     SourceLocation StarLoc,
1150218893Sdim                                     Expr *Target) {
1151212904Sdim    return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1152198092Srdivacky  }
1153198092Srdivacky
1154198092Srdivacky  /// \brief Build a new return 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 RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1159212904Sdim    return getSema().ActOnReturnStmt(ReturnLoc, Result);
1160198092Srdivacky  }
1161198092Srdivacky
1162198092Srdivacky  /// \brief Build a new declaration statement.
1163198092Srdivacky  ///
1164198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1165198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1166212904Sdim  StmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
1167198092Srdivacky                                   SourceLocation StartLoc,
1168198092Srdivacky                                   SourceLocation EndLoc) {
1169219077Sdim    Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls, NumDecls);
1170219077Sdim    return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1171198092Srdivacky  }
1172198092Srdivacky
1173203955Srdivacky  /// \brief Build a new inline asm statement.
1174203955Srdivacky  ///
1175203955Srdivacky  /// By default, performs semantic analysis to build the new statement.
1176203955Srdivacky  /// Subclasses may override this routine to provide different behavior.
1177243830Sdim  StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1178243830Sdim                               bool IsVolatile, unsigned NumOutputs,
1179243830Sdim                               unsigned NumInputs, IdentifierInfo **Names,
1180243830Sdim                               MultiExprArg Constraints, MultiExprArg Exprs,
1181243830Sdim                               Expr *AsmString, MultiExprArg Clobbers,
1182243830Sdim                               SourceLocation RParenLoc) {
1183243830Sdim    return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1184243830Sdim                                     NumInputs, Names, Constraints, Exprs,
1185243830Sdim                                     AsmString, Clobbers, RParenLoc);
1186203955Srdivacky  }
1187207619Srdivacky
1188239462Sdim  /// \brief Build a new MS style inline asm statement.
1189207619Srdivacky  ///
1190207619Srdivacky  /// By default, performs semantic analysis to build the new statement.
1191207619Srdivacky  /// Subclasses may override this routine to provide different behavior.
1192243830Sdim  StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1193251662Sdim                              ArrayRef<Token> AsmToks,
1194251662Sdim                              StringRef AsmString,
1195251662Sdim                              unsigned NumOutputs, unsigned NumInputs,
1196251662Sdim                              ArrayRef<StringRef> Constraints,
1197251662Sdim                              ArrayRef<StringRef> Clobbers,
1198251662Sdim                              ArrayRef<Expr*> Exprs,
1199251662Sdim                              SourceLocation EndLoc) {
1200251662Sdim    return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1201251662Sdim                                    NumOutputs, NumInputs,
1202251662Sdim                                    Constraints, Clobbers, Exprs, EndLoc);
1203239462Sdim  }
1204239462Sdim
1205239462Sdim  /// \brief Build a new Objective-C \@try statement.
1206239462Sdim  ///
1207239462Sdim  /// By default, performs semantic analysis to build the new statement.
1208239462Sdim  /// Subclasses may override this routine to provide different behavior.
1209212904Sdim  StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1210212904Sdim                                        Stmt *TryBody,
1211207619Srdivacky                                        MultiStmtArg CatchStmts,
1212212904Sdim                                        Stmt *Finally) {
1213243830Sdim    return getSema().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1214212904Sdim                                        Finally);
1215207619Srdivacky  }
1216207619Srdivacky
1217207619Srdivacky  /// \brief Rebuild an Objective-C exception declaration.
1218207619Srdivacky  ///
1219207619Srdivacky  /// By default, performs semantic analysis to build the new declaration.
1220207619Srdivacky  /// Subclasses may override this routine to provide different behavior.
1221207619Srdivacky  VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1222207619Srdivacky                                    TypeSourceInfo *TInfo, QualType T) {
1223221345Sdim    return getSema().BuildObjCExceptionDecl(TInfo, T,
1224221345Sdim                                            ExceptionDecl->getInnerLocStart(),
1225221345Sdim                                            ExceptionDecl->getLocation(),
1226221345Sdim                                            ExceptionDecl->getIdentifier());
1227207619Srdivacky  }
1228239462Sdim
1229239462Sdim  /// \brief Build a new Objective-C \@catch statement.
1230207619Srdivacky  ///
1231207619Srdivacky  /// By default, performs semantic analysis to build the new statement.
1232207619Srdivacky  /// Subclasses may override this routine to provide different behavior.
1233212904Sdim  StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1234207619Srdivacky                                          SourceLocation RParenLoc,
1235207619Srdivacky                                          VarDecl *Var,
1236212904Sdim                                          Stmt *Body) {
1237207619Srdivacky    return getSema().ActOnObjCAtCatchStmt(AtLoc, RParenLoc,
1238212904Sdim                                          Var, Body);
1239207619Srdivacky  }
1240239462Sdim
1241239462Sdim  /// \brief Build a new Objective-C \@finally statement.
1242207619Srdivacky  ///
1243207619Srdivacky  /// By default, performs semantic analysis to build the new statement.
1244207619Srdivacky  /// Subclasses may override this routine to provide different behavior.
1245212904Sdim  StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1246212904Sdim                                            Stmt *Body) {
1247212904Sdim    return getSema().ActOnObjCAtFinallyStmt(AtLoc, Body);
1248207619Srdivacky  }
1249239462Sdim
1250239462Sdim  /// \brief Build a new Objective-C \@throw statement.
1251207619Srdivacky  ///
1252207619Srdivacky  /// By default, performs semantic analysis to build the new statement.
1253207619Srdivacky  /// Subclasses may override this routine to provide different behavior.
1254212904Sdim  StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1255212904Sdim                                          Expr *Operand) {
1256212904Sdim    return getSema().BuildObjCAtThrowStmt(AtLoc, Operand);
1257207619Srdivacky  }
1258239462Sdim
1259239462Sdim  /// \brief Rebuild the operand to an Objective-C \@synchronized statement.
1260226633Sdim  ///
1261226633Sdim  /// By default, performs semantic analysis to build the new statement.
1262226633Sdim  /// Subclasses may override this routine to provide different behavior.
1263226633Sdim  ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
1264226633Sdim                                              Expr *object) {
1265226633Sdim    return getSema().ActOnObjCAtSynchronizedOperand(atLoc, object);
1266226633Sdim  }
1267226633Sdim
1268239462Sdim  /// \brief Build a new Objective-C \@synchronized statement.
1269207619Srdivacky  ///
1270207619Srdivacky  /// By default, performs semantic analysis to build the new statement.
1271207619Srdivacky  /// Subclasses may override this routine to provide different behavior.
1272212904Sdim  StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
1273226633Sdim                                           Expr *Object, Stmt *Body) {
1274226633Sdim    return getSema().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
1275207619Srdivacky  }
1276207619Srdivacky
1277239462Sdim  /// \brief Build a new Objective-C \@autoreleasepool statement.
1278224145Sdim  ///
1279224145Sdim  /// By default, performs semantic analysis to build the new statement.
1280224145Sdim  /// Subclasses may override this routine to provide different behavior.
1281224145Sdim  StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
1282224145Sdim                                            Stmt *Body) {
1283224145Sdim    return getSema().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
1284224145Sdim  }
1285224145Sdim
1286207619Srdivacky  /// \brief Build a new Objective-C fast enumeration statement.
1287207619Srdivacky  ///
1288207619Srdivacky  /// By default, performs semantic analysis to build the new statement.
1289207619Srdivacky  /// Subclasses may override this routine to provide different behavior.
1290212904Sdim  StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
1291212904Sdim                                          Stmt *Element,
1292212904Sdim                                          Expr *Collection,
1293212904Sdim                                          SourceLocation RParenLoc,
1294212904Sdim                                          Stmt *Body) {
1295239462Sdim    StmtResult ForEachStmt = getSema().ActOnObjCForCollectionStmt(ForLoc,
1296239462Sdim                                                Element,
1297212904Sdim                                                Collection,
1298239462Sdim                                                RParenLoc);
1299239462Sdim    if (ForEachStmt.isInvalid())
1300239462Sdim      return StmtError();
1301239462Sdim
1302239462Sdim    return getSema().FinishObjCForCollectionStmt(ForEachStmt.take(), Body);
1303207619Srdivacky  }
1304239462Sdim
1305198092Srdivacky  /// \brief Build a new C++ exception declaration.
1306198092Srdivacky  ///
1307198092Srdivacky  /// By default, performs semantic analysis to build the new decaration.
1308198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1309221345Sdim  VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
1310200583Srdivacky                                TypeSourceInfo *Declarator,
1311221345Sdim                                SourceLocation StartLoc,
1312221345Sdim                                SourceLocation IdLoc,
1313221345Sdim                                IdentifierInfo *Id) {
1314221345Sdim    VarDecl *Var = getSema().BuildExceptionDeclaration(0, Declarator,
1315221345Sdim                                                       StartLoc, IdLoc, Id);
1316221345Sdim    if (Var)
1317221345Sdim      getSema().CurContext->addDecl(Var);
1318221345Sdim    return Var;
1319198092Srdivacky  }
1320198092Srdivacky
1321198092Srdivacky  /// \brief Build a new C++ catch statement.
1322198092Srdivacky  ///
1323198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1324198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1325212904Sdim  StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
1326212904Sdim                                 VarDecl *ExceptionDecl,
1327212904Sdim                                 Stmt *Handler) {
1328212904Sdim    return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
1329212904Sdim                                                      Handler));
1330198092Srdivacky  }
1331198092Srdivacky
1332198092Srdivacky  /// \brief Build a new C++ try statement.
1333198092Srdivacky  ///
1334198092Srdivacky  /// By default, performs semantic analysis to build the new statement.
1335198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1336212904Sdim  StmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
1337212904Sdim                               Stmt *TryBlock,
1338212904Sdim                               MultiStmtArg Handlers) {
1339243830Sdim    return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
1340198092Srdivacky  }
1341198092Srdivacky
1342221345Sdim  /// \brief Build a new C++0x range-based for statement.
1343221345Sdim  ///
1344221345Sdim  /// By default, performs semantic analysis to build the new statement.
1345221345Sdim  /// Subclasses may override this routine to provide different behavior.
1346221345Sdim  StmtResult RebuildCXXForRangeStmt(SourceLocation ForLoc,
1347221345Sdim                                    SourceLocation ColonLoc,
1348221345Sdim                                    Stmt *Range, Stmt *BeginEnd,
1349221345Sdim                                    Expr *Cond, Expr *Inc,
1350221345Sdim                                    Stmt *LoopVar,
1351221345Sdim                                    SourceLocation RParenLoc) {
1352251662Sdim    // If we've just learned that the range is actually an Objective-C
1353251662Sdim    // collection, treat this as an Objective-C fast enumeration loop.
1354251662Sdim    if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
1355251662Sdim      if (RangeStmt->isSingleDecl()) {
1356251662Sdim        if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
1357251662Sdim          if (RangeVar->isInvalidDecl())
1358251662Sdim            return StmtError();
1359251662Sdim
1360251662Sdim          Expr *RangeExpr = RangeVar->getInit();
1361251662Sdim          if (!RangeExpr->isTypeDependent() &&
1362251662Sdim              RangeExpr->getType()->isObjCObjectPointerType())
1363251662Sdim            return getSema().ActOnObjCForCollectionStmt(ForLoc, LoopVar, RangeExpr,
1364251662Sdim                                                        RParenLoc);
1365251662Sdim        }
1366251662Sdim      }
1367251662Sdim    }
1368251662Sdim
1369221345Sdim    return getSema().BuildCXXForRangeStmt(ForLoc, ColonLoc, Range, BeginEnd,
1370243830Sdim                                          Cond, Inc, LoopVar, RParenLoc,
1371243830Sdim                                          Sema::BFRK_Rebuild);
1372221345Sdim  }
1373234353Sdim
1374234353Sdim  /// \brief Build a new C++0x range-based for statement.
1375234353Sdim  ///
1376234353Sdim  /// By default, performs semantic analysis to build the new statement.
1377234353Sdim  /// Subclasses may override this routine to provide different behavior.
1378239462Sdim  StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
1379234353Sdim                                          bool IsIfExists,
1380234353Sdim                                          NestedNameSpecifierLoc QualifierLoc,
1381234353Sdim                                          DeclarationNameInfo NameInfo,
1382234353Sdim                                          Stmt *Nested) {
1383234353Sdim    return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
1384234353Sdim                                                QualifierLoc, NameInfo, Nested);
1385234353Sdim  }
1386234353Sdim
1387221345Sdim  /// \brief Attach body to a C++0x range-based for statement.
1388221345Sdim  ///
1389221345Sdim  /// By default, performs semantic analysis to finish the new statement.
1390221345Sdim  /// Subclasses may override this routine to provide different behavior.
1391221345Sdim  StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
1392221345Sdim    return getSema().FinishCXXForRangeStmt(ForRange, Body);
1393221345Sdim  }
1394239462Sdim
1395221345Sdim  StmtResult RebuildSEHTryStmt(bool IsCXXTry,
1396221345Sdim                               SourceLocation TryLoc,
1397221345Sdim                               Stmt *TryBlock,
1398221345Sdim                               Stmt *Handler) {
1399221345Sdim    return getSema().ActOnSEHTryBlock(IsCXXTry,TryLoc,TryBlock,Handler);
1400221345Sdim  }
1401221345Sdim
1402221345Sdim  StmtResult RebuildSEHExceptStmt(SourceLocation Loc,
1403221345Sdim                                  Expr *FilterExpr,
1404221345Sdim                                  Stmt *Block) {
1405221345Sdim    return getSema().ActOnSEHExceptBlock(Loc,FilterExpr,Block);
1406221345Sdim  }
1407221345Sdim
1408221345Sdim  StmtResult RebuildSEHFinallyStmt(SourceLocation Loc,
1409221345Sdim                                   Stmt *Block) {
1410221345Sdim    return getSema().ActOnSEHFinallyBlock(Loc,Block);
1411221345Sdim  }
1412221345Sdim
1413198092Srdivacky  /// \brief Build a new expression that references a declaration.
1414198092Srdivacky  ///
1415198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1416198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1417212904Sdim  ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
1418212904Sdim                                        LookupResult &R,
1419212904Sdim                                        bool RequiresADL) {
1420199990Srdivacky    return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
1421199990Srdivacky  }
1422199990Srdivacky
1423199990Srdivacky
1424199990Srdivacky  /// \brief Build a new expression that references a declaration.
1425199990Srdivacky  ///
1426199990Srdivacky  /// By default, performs semantic analysis to build the new expression.
1427199990Srdivacky  /// Subclasses may override this routine to provide different behavior.
1428221345Sdim  ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
1429212904Sdim                                ValueDecl *VD,
1430212904Sdim                                const DeclarationNameInfo &NameInfo,
1431212904Sdim                                TemplateArgumentListInfo *TemplateArgs) {
1432198893Srdivacky    CXXScopeSpec SS;
1433221345Sdim    SS.Adopt(QualifierLoc);
1434200583Srdivacky
1435200583Srdivacky    // FIXME: loses template args.
1436212904Sdim
1437212904Sdim    return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD);
1438198092Srdivacky  }
1439198092Srdivacky
1440198092Srdivacky  /// \brief Build a new expression in parentheses.
1441198092Srdivacky  ///
1442198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1443198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1444212904Sdim  ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
1445198092Srdivacky                                    SourceLocation RParen) {
1446212904Sdim    return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
1447198092Srdivacky  }
1448198092Srdivacky
1449198092Srdivacky  /// \brief Build a new pseudo-destructor expression.
1450198092Srdivacky  ///
1451198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1452198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1453212904Sdim  ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
1454219077Sdim                                            SourceLocation OperatorLoc,
1455219077Sdim                                            bool isArrow,
1456219077Sdim                                            CXXScopeSpec &SS,
1457219077Sdim                                            TypeSourceInfo *ScopeType,
1458219077Sdim                                            SourceLocation CCLoc,
1459219077Sdim                                            SourceLocation TildeLoc,
1460204643Srdivacky                                        PseudoDestructorTypeStorage Destroyed);
1461198092Srdivacky
1462198092Srdivacky  /// \brief Build a new unary operator expression.
1463198092Srdivacky  ///
1464198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1465198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1466212904Sdim  ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
1467212904Sdim                                        UnaryOperatorKind Opc,
1468212904Sdim                                        Expr *SubExpr) {
1469212904Sdim    return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, SubExpr);
1470198092Srdivacky  }
1471198092Srdivacky
1472207619Srdivacky  /// \brief Build a new builtin offsetof expression.
1473207619Srdivacky  ///
1474207619Srdivacky  /// By default, performs semantic analysis to build the new expression.
1475207619Srdivacky  /// Subclasses may override this routine to provide different behavior.
1476212904Sdim  ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
1477207619Srdivacky                                       TypeSourceInfo *Type,
1478212904Sdim                                       Sema::OffsetOfComponent *Components,
1479207619Srdivacky                                       unsigned NumComponents,
1480207619Srdivacky                                       SourceLocation RParenLoc) {
1481207619Srdivacky    return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
1482207619Srdivacky                                          NumComponents, RParenLoc);
1483207619Srdivacky  }
1484239462Sdim
1485239462Sdim  /// \brief Build a new sizeof, alignof or vec_step expression with a
1486221345Sdim  /// type argument.
1487198092Srdivacky  ///
1488198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1489198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1490221345Sdim  ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
1491221345Sdim                                         SourceLocation OpLoc,
1492221345Sdim                                         UnaryExprOrTypeTrait ExprKind,
1493221345Sdim                                         SourceRange R) {
1494221345Sdim    return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
1495198092Srdivacky  }
1496198092Srdivacky
1497221345Sdim  /// \brief Build a new sizeof, alignof or vec step expression with an
1498221345Sdim  /// expression argument.
1499198092Srdivacky  ///
1500198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1501198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1502221345Sdim  ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
1503221345Sdim                                         UnaryExprOrTypeTrait ExprKind,
1504221345Sdim                                         SourceRange R) {
1505212904Sdim    ExprResult Result
1506223017Sdim      = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
1507198092Srdivacky    if (Result.isInvalid())
1508212904Sdim      return ExprError();
1509198092Srdivacky
1510243830Sdim    return Result;
1511198092Srdivacky  }
1512198092Srdivacky
1513198092Srdivacky  /// \brief Build a new array subscript expression.
1514198092Srdivacky  ///
1515198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1516198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1517212904Sdim  ExprResult RebuildArraySubscriptExpr(Expr *LHS,
1518198092Srdivacky                                             SourceLocation LBracketLoc,
1519212904Sdim                                             Expr *RHS,
1520198092Srdivacky                                             SourceLocation RBracketLoc) {
1521212904Sdim    return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, LHS,
1522212904Sdim                                             LBracketLoc, RHS,
1523198092Srdivacky                                             RBracketLoc);
1524198092Srdivacky  }
1525198092Srdivacky
1526198092Srdivacky  /// \brief Build a new call expression.
1527198092Srdivacky  ///
1528198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1529198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1530212904Sdim  ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
1531198092Srdivacky                                   MultiExprArg Args,
1532218893Sdim                                   SourceLocation RParenLoc,
1533218893Sdim                                   Expr *ExecConfig = 0) {
1534212904Sdim    return getSema().ActOnCallExpr(/*Scope=*/0, Callee, LParenLoc,
1535243830Sdim                                   Args, RParenLoc, ExecConfig);
1536198092Srdivacky  }
1537198092Srdivacky
1538198092Srdivacky  /// \brief Build a new member access expression.
1539198092Srdivacky  ///
1540198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1541198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1542212904Sdim  ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
1543218893Sdim                               bool isArrow,
1544221345Sdim                               NestedNameSpecifierLoc QualifierLoc,
1545234353Sdim                               SourceLocation TemplateKWLoc,
1546218893Sdim                               const DeclarationNameInfo &MemberNameInfo,
1547218893Sdim                               ValueDecl *Member,
1548218893Sdim                               NamedDecl *FoundDecl,
1549199990Srdivacky                        const TemplateArgumentListInfo *ExplicitTemplateArgs,
1550218893Sdim                               NamedDecl *FirstQualifierInScope) {
1551234353Sdim    ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
1552234353Sdim                                                                      isArrow);
1553198092Srdivacky    if (!Member->getDeclName()) {
1554218893Sdim      // We have a reference to an unnamed field.  This is always the
1555218893Sdim      // base of an anonymous struct/union member access, i.e. the
1556218893Sdim      // field is always of record type.
1557221345Sdim      assert(!QualifierLoc && "Can't have an unnamed field with a qualifier!");
1558218893Sdim      assert(Member->getType()->isRecordType() &&
1559218893Sdim             "unnamed member not of record type?");
1560198092Srdivacky
1561234353Sdim      BaseResult =
1562234353Sdim        getSema().PerformObjectMemberConversion(BaseResult.take(),
1563221345Sdim                                                QualifierLoc.getNestedNameSpecifier(),
1564221345Sdim                                                FoundDecl, Member);
1565221345Sdim      if (BaseResult.isInvalid())
1566212904Sdim        return ExprError();
1567221345Sdim      Base = BaseResult.take();
1568218893Sdim      ExprValueKind VK = isArrow ? VK_LValue : Base->getValueKind();
1569198092Srdivacky      MemberExpr *ME =
1570212904Sdim        new (getSema().Context) MemberExpr(Base, isArrow,
1571212904Sdim                                           Member, MemberNameInfo,
1572218893Sdim                                           cast<FieldDecl>(Member)->getType(),
1573218893Sdim                                           VK, OK_Ordinary);
1574198092Srdivacky      return getSema().Owned(ME);
1575198092Srdivacky    }
1576198092Srdivacky
1577198092Srdivacky    CXXScopeSpec SS;
1578221345Sdim    SS.Adopt(QualifierLoc);
1579198092Srdivacky
1580221345Sdim    Base = BaseResult.take();
1581212904Sdim    QualType BaseType = Base->getType();
1582200583Srdivacky
1583206084Srdivacky    // FIXME: this involves duplicating earlier analysis in a lot of
1584206084Srdivacky    // cases; we should avoid this when possible.
1585212904Sdim    LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
1586206084Srdivacky    R.addDecl(FoundDecl);
1587202379Srdivacky    R.resolveKind();
1588202379Srdivacky
1589212904Sdim    return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
1590234353Sdim                                              SS, TemplateKWLoc,
1591234353Sdim                                              FirstQualifierInScope,
1592202379Srdivacky                                              R, ExplicitTemplateArgs);
1593198092Srdivacky  }
1594198092Srdivacky
1595198092Srdivacky  /// \brief Build a new binary operator 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 RebuildBinaryOperator(SourceLocation OpLoc,
1600212904Sdim                                         BinaryOperatorKind Opc,
1601212904Sdim                                         Expr *LHS, Expr *RHS) {
1602212904Sdim    return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc, LHS, RHS);
1603198092Srdivacky  }
1604198092Srdivacky
1605198092Srdivacky  /// \brief Build a new conditional operator expression.
1606198092Srdivacky  ///
1607198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1608198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1609212904Sdim  ExprResult RebuildConditionalOperator(Expr *Cond,
1610218893Sdim                                        SourceLocation QuestionLoc,
1611218893Sdim                                        Expr *LHS,
1612218893Sdim                                        SourceLocation ColonLoc,
1613218893Sdim                                        Expr *RHS) {
1614212904Sdim    return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
1615212904Sdim                                        LHS, RHS);
1616198092Srdivacky  }
1617198092Srdivacky
1618198092Srdivacky  /// \brief Build a new C-style cast expression.
1619198092Srdivacky  ///
1620198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1621198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1622212904Sdim  ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
1623202879Srdivacky                                         TypeSourceInfo *TInfo,
1624198092Srdivacky                                         SourceLocation RParenLoc,
1625212904Sdim                                         Expr *SubExpr) {
1626202879Srdivacky    return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
1627212904Sdim                                         SubExpr);
1628198092Srdivacky  }
1629198092Srdivacky
1630198092Srdivacky  /// \brief Build a new compound literal expression.
1631198092Srdivacky  ///
1632198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1633198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1634212904Sdim  ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
1635202879Srdivacky                                              TypeSourceInfo *TInfo,
1636198092Srdivacky                                              SourceLocation RParenLoc,
1637212904Sdim                                              Expr *Init) {
1638202879Srdivacky    return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
1639212904Sdim                                              Init);
1640198092Srdivacky  }
1641198092Srdivacky
1642198092Srdivacky  /// \brief Build a new extended vector element access expression.
1643198092Srdivacky  ///
1644198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1645198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1646212904Sdim  ExprResult RebuildExtVectorElementExpr(Expr *Base,
1647198092Srdivacky                                               SourceLocation OpLoc,
1648198092Srdivacky                                               SourceLocation AccessorLoc,
1649198092Srdivacky                                               IdentifierInfo &Accessor) {
1650200583Srdivacky
1651199990Srdivacky    CXXScopeSpec SS;
1652212904Sdim    DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
1653212904Sdim    return getSema().BuildMemberReferenceExpr(Base, Base->getType(),
1654199990Srdivacky                                              OpLoc, /*IsArrow*/ false,
1655234353Sdim                                              SS, SourceLocation(),
1656234353Sdim                                              /*FirstQualifierInScope*/ 0,
1657212904Sdim                                              NameInfo,
1658199990Srdivacky                                              /* TemplateArgs */ 0);
1659198092Srdivacky  }
1660198092Srdivacky
1661198092Srdivacky  /// \brief Build a new initializer list expression.
1662198092Srdivacky  ///
1663198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1664198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1665212904Sdim  ExprResult RebuildInitList(SourceLocation LBraceLoc,
1666224145Sdim                             MultiExprArg Inits,
1667224145Sdim                             SourceLocation RBraceLoc,
1668224145Sdim                             QualType ResultTy) {
1669212904Sdim    ExprResult Result
1670243830Sdim      = SemaRef.ActOnInitList(LBraceLoc, Inits, RBraceLoc);
1671199482Srdivacky    if (Result.isInvalid() || ResultTy->isDependentType())
1672243830Sdim      return Result;
1673239462Sdim
1674199482Srdivacky    // Patch in the result type we were given, which may have been computed
1675199482Srdivacky    // when the initial InitListExpr was built.
1676199482Srdivacky    InitListExpr *ILE = cast<InitListExpr>((Expr *)Result.get());
1677199482Srdivacky    ILE->setType(ResultTy);
1678243830Sdim    return Result;
1679198092Srdivacky  }
1680198092Srdivacky
1681198092Srdivacky  /// \brief Build a new designated initializer expression.
1682198092Srdivacky  ///
1683198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1684198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1685212904Sdim  ExprResult RebuildDesignatedInitExpr(Designation &Desig,
1686198092Srdivacky                                             MultiExprArg ArrayExprs,
1687198092Srdivacky                                             SourceLocation EqualOrColonLoc,
1688198092Srdivacky                                             bool GNUSyntax,
1689212904Sdim                                             Expr *Init) {
1690212904Sdim    ExprResult Result
1691198092Srdivacky      = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1692212904Sdim                                           Init);
1693198092Srdivacky    if (Result.isInvalid())
1694212904Sdim      return ExprError();
1695198092Srdivacky
1696243830Sdim    return Result;
1697198092Srdivacky  }
1698198092Srdivacky
1699198092Srdivacky  /// \brief Build a new value-initialized expression.
1700198092Srdivacky  ///
1701198092Srdivacky  /// By default, builds the implicit value initialization without performing
1702198092Srdivacky  /// any semantic analysis. Subclasses may override this routine to provide
1703198092Srdivacky  /// different behavior.
1704212904Sdim  ExprResult RebuildImplicitValueInitExpr(QualType T) {
1705198092Srdivacky    return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1706198092Srdivacky  }
1707198092Srdivacky
1708198092Srdivacky  /// \brief Build a new \c va_arg expression.
1709198092Srdivacky  ///
1710198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1711198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1712212904Sdim  ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
1713212904Sdim                                    Expr *SubExpr, TypeSourceInfo *TInfo,
1714212904Sdim                                    SourceLocation RParenLoc) {
1715212904Sdim    return getSema().BuildVAArgExpr(BuiltinLoc,
1716212904Sdim                                    SubExpr, TInfo,
1717212904Sdim                                    RParenLoc);
1718198092Srdivacky  }
1719198092Srdivacky
1720198092Srdivacky  /// \brief Build a new expression list in parentheses.
1721198092Srdivacky  ///
1722198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1723198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1724212904Sdim  ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1725234353Sdim                                  MultiExprArg SubExprs,
1726234353Sdim                                  SourceLocation RParenLoc) {
1727243830Sdim    return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
1728198092Srdivacky  }
1729198092Srdivacky
1730198092Srdivacky  /// \brief Build a new address-of-label expression.
1731198092Srdivacky  ///
1732198092Srdivacky  /// By default, performs semantic analysis, using the name of the label
1733198092Srdivacky  /// rather than attempting to map the label statement itself.
1734198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1735212904Sdim  ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1736218893Sdim                                  SourceLocation LabelLoc, LabelDecl *Label) {
1737218893Sdim    return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
1738198092Srdivacky  }
1739198092Srdivacky
1740198092Srdivacky  /// \brief Build a new GNU statement expression.
1741198092Srdivacky  ///
1742198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1743198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1744212904Sdim  ExprResult RebuildStmtExpr(SourceLocation LParenLoc,
1745212904Sdim                                   Stmt *SubStmt,
1746198092Srdivacky                                   SourceLocation RParenLoc) {
1747212904Sdim    return getSema().ActOnStmtExpr(LParenLoc, SubStmt, RParenLoc);
1748198092Srdivacky  }
1749198092Srdivacky
1750198092Srdivacky  /// \brief Build a new __builtin_choose_expr expression.
1751198092Srdivacky  ///
1752198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1753198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1754212904Sdim  ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1755212904Sdim                                     Expr *Cond, Expr *LHS, Expr *RHS,
1756198092Srdivacky                                     SourceLocation RParenLoc) {
1757198092Srdivacky    return SemaRef.ActOnChooseExpr(BuiltinLoc,
1758212904Sdim                                   Cond, LHS, RHS,
1759198092Srdivacky                                   RParenLoc);
1760198092Srdivacky  }
1761198092Srdivacky
1762221345Sdim  /// \brief Build a new generic selection expression.
1763221345Sdim  ///
1764221345Sdim  /// By default, performs semantic analysis to build the new expression.
1765221345Sdim  /// Subclasses may override this routine to provide different behavior.
1766221345Sdim  ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
1767221345Sdim                                         SourceLocation DefaultLoc,
1768221345Sdim                                         SourceLocation RParenLoc,
1769221345Sdim                                         Expr *ControllingExpr,
1770221345Sdim                                         TypeSourceInfo **Types,
1771221345Sdim                                         Expr **Exprs,
1772221345Sdim                                         unsigned NumAssocs) {
1773221345Sdim    return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
1774221345Sdim                                                ControllingExpr, Types, Exprs,
1775221345Sdim                                                NumAssocs);
1776221345Sdim  }
1777221345Sdim
1778198092Srdivacky  /// \brief Build a new overloaded operator call expression.
1779198092Srdivacky  ///
1780198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1781198092Srdivacky  /// The semantic analysis provides the behavior of template instantiation,
1782198092Srdivacky  /// copying with transformations that turn what looks like an overloaded
1783198092Srdivacky  /// operator call into a use of a builtin operator, performing
1784198092Srdivacky  /// argument-dependent lookup, etc. Subclasses may override this routine to
1785198092Srdivacky  /// provide different behavior.
1786212904Sdim  ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1787198092Srdivacky                                              SourceLocation OpLoc,
1788212904Sdim                                              Expr *Callee,
1789212904Sdim                                              Expr *First,
1790212904Sdim                                              Expr *Second);
1791198092Srdivacky
1792198092Srdivacky  /// \brief Build a new C++ "named" cast expression, such as static_cast or
1793198092Srdivacky  /// reinterpret_cast.
1794198092Srdivacky  ///
1795198092Srdivacky  /// By default, this routine dispatches to one of the more-specific routines
1796198092Srdivacky  /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
1797198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1798212904Sdim  ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1799198092Srdivacky                                           Stmt::StmtClass Class,
1800198092Srdivacky                                           SourceLocation LAngleLoc,
1801202879Srdivacky                                           TypeSourceInfo *TInfo,
1802198092Srdivacky                                           SourceLocation RAngleLoc,
1803198092Srdivacky                                           SourceLocation LParenLoc,
1804212904Sdim                                           Expr *SubExpr,
1805198092Srdivacky                                           SourceLocation RParenLoc) {
1806198092Srdivacky    switch (Class) {
1807198092Srdivacky    case Stmt::CXXStaticCastExprClass:
1808202879Srdivacky      return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
1809198092Srdivacky                                                   RAngleLoc, LParenLoc,
1810212904Sdim                                                   SubExpr, RParenLoc);
1811198092Srdivacky
1812198092Srdivacky    case Stmt::CXXDynamicCastExprClass:
1813202879Srdivacky      return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
1814198092Srdivacky                                                    RAngleLoc, LParenLoc,
1815212904Sdim                                                    SubExpr, RParenLoc);
1816198092Srdivacky
1817198092Srdivacky    case Stmt::CXXReinterpretCastExprClass:
1818202879Srdivacky      return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
1819198092Srdivacky                                                        RAngleLoc, LParenLoc,
1820212904Sdim                                                        SubExpr,
1821198092Srdivacky                                                        RParenLoc);
1822198092Srdivacky
1823198092Srdivacky    case Stmt::CXXConstCastExprClass:
1824202879Srdivacky      return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
1825198092Srdivacky                                                   RAngleLoc, LParenLoc,
1826212904Sdim                                                   SubExpr, RParenLoc);
1827198092Srdivacky
1828198092Srdivacky    default:
1829226633Sdim      llvm_unreachable("Invalid C++ named cast");
1830198092Srdivacky    }
1831198092Srdivacky  }
1832198092Srdivacky
1833198092Srdivacky  /// \brief Build a new C++ static_cast expression.
1834198092Srdivacky  ///
1835198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1836198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1837212904Sdim  ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1838198092Srdivacky                                            SourceLocation LAngleLoc,
1839202879Srdivacky                                            TypeSourceInfo *TInfo,
1840198092Srdivacky                                            SourceLocation RAngleLoc,
1841198092Srdivacky                                            SourceLocation LParenLoc,
1842212904Sdim                                            Expr *SubExpr,
1843198092Srdivacky                                            SourceLocation RParenLoc) {
1844202879Srdivacky    return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
1845212904Sdim                                       TInfo, SubExpr,
1846202879Srdivacky                                       SourceRange(LAngleLoc, RAngleLoc),
1847202879Srdivacky                                       SourceRange(LParenLoc, RParenLoc));
1848198092Srdivacky  }
1849198092Srdivacky
1850198092Srdivacky  /// \brief Build a new C++ dynamic_cast expression.
1851198092Srdivacky  ///
1852198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1853198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1854212904Sdim  ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1855198092Srdivacky                                             SourceLocation LAngleLoc,
1856202879Srdivacky                                             TypeSourceInfo *TInfo,
1857198092Srdivacky                                             SourceLocation RAngleLoc,
1858198092Srdivacky                                             SourceLocation LParenLoc,
1859212904Sdim                                             Expr *SubExpr,
1860198092Srdivacky                                             SourceLocation RParenLoc) {
1861202879Srdivacky    return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
1862212904Sdim                                       TInfo, SubExpr,
1863202879Srdivacky                                       SourceRange(LAngleLoc, RAngleLoc),
1864202879Srdivacky                                       SourceRange(LParenLoc, RParenLoc));
1865198092Srdivacky  }
1866198092Srdivacky
1867198092Srdivacky  /// \brief Build a new C++ reinterpret_cast expression.
1868198092Srdivacky  ///
1869198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1870198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1871212904Sdim  ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1872198092Srdivacky                                                 SourceLocation LAngleLoc,
1873202879Srdivacky                                                 TypeSourceInfo *TInfo,
1874198092Srdivacky                                                 SourceLocation RAngleLoc,
1875198092Srdivacky                                                 SourceLocation LParenLoc,
1876212904Sdim                                                 Expr *SubExpr,
1877198092Srdivacky                                                 SourceLocation RParenLoc) {
1878202879Srdivacky    return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1879212904Sdim                                       TInfo, SubExpr,
1880202879Srdivacky                                       SourceRange(LAngleLoc, RAngleLoc),
1881202879Srdivacky                                       SourceRange(LParenLoc, RParenLoc));
1882198092Srdivacky  }
1883198092Srdivacky
1884198092Srdivacky  /// \brief Build a new C++ const_cast expression.
1885198092Srdivacky  ///
1886198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1887198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1888212904Sdim  ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1889198092Srdivacky                                           SourceLocation LAngleLoc,
1890202879Srdivacky                                           TypeSourceInfo *TInfo,
1891198092Srdivacky                                           SourceLocation RAngleLoc,
1892198092Srdivacky                                           SourceLocation LParenLoc,
1893212904Sdim                                           Expr *SubExpr,
1894198092Srdivacky                                           SourceLocation RParenLoc) {
1895202879Srdivacky    return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
1896212904Sdim                                       TInfo, SubExpr,
1897202879Srdivacky                                       SourceRange(LAngleLoc, RAngleLoc),
1898202879Srdivacky                                       SourceRange(LParenLoc, RParenLoc));
1899198092Srdivacky  }
1900198092Srdivacky
1901198092Srdivacky  /// \brief Build a new C++ functional-style cast expression.
1902198092Srdivacky  ///
1903198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1904198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1905218893Sdim  ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
1906218893Sdim                                          SourceLocation LParenLoc,
1907218893Sdim                                          Expr *Sub,
1908218893Sdim                                          SourceLocation RParenLoc) {
1909218893Sdim    return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
1910212904Sdim                                               MultiExprArg(&Sub, 1),
1911198092Srdivacky                                               RParenLoc);
1912198092Srdivacky  }
1913198092Srdivacky
1914198092Srdivacky  /// \brief Build a new C++ typeid(type) expression.
1915198092Srdivacky  ///
1916198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1917198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1918212904Sdim  ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
1919207619Srdivacky                                        SourceLocation TypeidLoc,
1920207619Srdivacky                                        TypeSourceInfo *Operand,
1921198092Srdivacky                                        SourceLocation RParenLoc) {
1922239462Sdim    return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
1923207619Srdivacky                                    RParenLoc);
1924198092Srdivacky  }
1925198092Srdivacky
1926218893Sdim
1927198092Srdivacky  /// \brief Build a new C++ typeid(expr) expression.
1928198092Srdivacky  ///
1929198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1930198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1931212904Sdim  ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
1932207619Srdivacky                                        SourceLocation TypeidLoc,
1933212904Sdim                                        Expr *Operand,
1934198092Srdivacky                                        SourceLocation RParenLoc) {
1935212904Sdim    return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
1936207619Srdivacky                                    RParenLoc);
1937198092Srdivacky  }
1938198092Srdivacky
1939218893Sdim  /// \brief Build a new C++ __uuidof(type) expression.
1940218893Sdim  ///
1941218893Sdim  /// By default, performs semantic analysis to build the new expression.
1942218893Sdim  /// Subclasses may override this routine to provide different behavior.
1943218893Sdim  ExprResult RebuildCXXUuidofExpr(QualType TypeInfoType,
1944218893Sdim                                        SourceLocation TypeidLoc,
1945218893Sdim                                        TypeSourceInfo *Operand,
1946218893Sdim                                        SourceLocation RParenLoc) {
1947239462Sdim    return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand,
1948218893Sdim                                    RParenLoc);
1949218893Sdim  }
1950218893Sdim
1951218893Sdim  /// \brief Build a new C++ __uuidof(expr) expression.
1952218893Sdim  ///
1953218893Sdim  /// By default, performs semantic analysis to build the new expression.
1954218893Sdim  /// Subclasses may override this routine to provide different behavior.
1955218893Sdim  ExprResult RebuildCXXUuidofExpr(QualType TypeInfoType,
1956218893Sdim                                        SourceLocation TypeidLoc,
1957218893Sdim                                        Expr *Operand,
1958218893Sdim                                        SourceLocation RParenLoc) {
1959218893Sdim    return getSema().BuildCXXUuidof(TypeInfoType, TypeidLoc, Operand,
1960218893Sdim                                    RParenLoc);
1961218893Sdim  }
1962218893Sdim
1963198092Srdivacky  /// \brief Build a new C++ "this" expression.
1964198092Srdivacky  ///
1965198092Srdivacky  /// By default, builds a new "this" expression without performing any
1966198092Srdivacky  /// semantic analysis. Subclasses may override this routine to provide
1967198092Srdivacky  /// different behavior.
1968212904Sdim  ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
1969218893Sdim                                QualType ThisType,
1970218893Sdim                                bool isImplicit) {
1971234353Sdim    getSema().CheckCXXThisCapture(ThisLoc);
1972198092Srdivacky    return getSema().Owned(
1973202379Srdivacky                      new (getSema().Context) CXXThisExpr(ThisLoc, ThisType,
1974202379Srdivacky                                                          isImplicit));
1975198092Srdivacky  }
1976198092Srdivacky
1977198092Srdivacky  /// \brief Build a new C++ throw expression.
1978198092Srdivacky  ///
1979198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
1980198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
1981224145Sdim  ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
1982224145Sdim                                 bool IsThrownVariableInScope) {
1983224145Sdim    return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
1984198092Srdivacky  }
1985198092Srdivacky
1986198092Srdivacky  /// \brief Build a new C++ default-argument expression.
1987198092Srdivacky  ///
1988198092Srdivacky  /// By default, builds a new default-argument expression, which does not
1989198092Srdivacky  /// require any semantic analysis. Subclasses may override this routine to
1990198092Srdivacky  /// provide different behavior.
1991239462Sdim  ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc,
1992201361Srdivacky                                            ParmVarDecl *Param) {
1993201361Srdivacky    return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Loc,
1994201361Srdivacky                                                     Param));
1995198092Srdivacky  }
1996198092Srdivacky
1997251662Sdim  /// \brief Build a new C++11 default-initialization expression.
1998251662Sdim  ///
1999251662Sdim  /// By default, builds a new default field initialization expression, which
2000251662Sdim  /// does not require any semantic analysis. Subclasses may override this
2001251662Sdim  /// routine to provide different behavior.
2002251662Sdim  ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
2003251662Sdim                                       FieldDecl *Field) {
2004251662Sdim    return getSema().Owned(CXXDefaultInitExpr::Create(getSema().Context, Loc,
2005251662Sdim                                                      Field));
2006251662Sdim  }
2007251662Sdim
2008198092Srdivacky  /// \brief Build a new C++ zero-initialization expression.
2009198092Srdivacky  ///
2010198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2011198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2012218893Sdim  ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
2013218893Sdim                                           SourceLocation LParenLoc,
2014218893Sdim                                           SourceLocation RParenLoc) {
2015218893Sdim    return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc,
2016251662Sdim                                               None, RParenLoc);
2017198092Srdivacky  }
2018198092Srdivacky
2019198092Srdivacky  /// \brief Build a new C++ "new" expression.
2020198092Srdivacky  ///
2021198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2022198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2023212904Sdim  ExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
2024218893Sdim                               bool UseGlobal,
2025218893Sdim                               SourceLocation PlacementLParen,
2026218893Sdim                               MultiExprArg PlacementArgs,
2027218893Sdim                               SourceLocation PlacementRParen,
2028218893Sdim                               SourceRange TypeIdParens,
2029218893Sdim                               QualType AllocatedType,
2030218893Sdim                               TypeSourceInfo *AllocatedTypeInfo,
2031218893Sdim                               Expr *ArraySize,
2032234353Sdim                               SourceRange DirectInitRange,
2033234353Sdim                               Expr *Initializer) {
2034198092Srdivacky    return getSema().BuildCXXNew(StartLoc, UseGlobal,
2035198092Srdivacky                                 PlacementLParen,
2036243830Sdim                                 PlacementArgs,
2037198092Srdivacky                                 PlacementRParen,
2038210299Sed                                 TypeIdParens,
2039218893Sdim                                 AllocatedType,
2040218893Sdim                                 AllocatedTypeInfo,
2041212904Sdim                                 ArraySize,
2042234353Sdim                                 DirectInitRange,
2043234353Sdim                                 Initializer);
2044198092Srdivacky  }
2045198092Srdivacky
2046198092Srdivacky  /// \brief Build a new C++ "delete" expression.
2047198092Srdivacky  ///
2048198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2049198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2050212904Sdim  ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
2051198092Srdivacky                                        bool IsGlobalDelete,
2052198092Srdivacky                                        bool IsArrayForm,
2053212904Sdim                                        Expr *Operand) {
2054198092Srdivacky    return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
2055212904Sdim                                    Operand);
2056198092Srdivacky  }
2057198092Srdivacky
2058198092Srdivacky  /// \brief Build a new unary type trait expression.
2059198092Srdivacky  ///
2060198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2061198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2062212904Sdim  ExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
2063218893Sdim                                   SourceLocation StartLoc,
2064218893Sdim                                   TypeSourceInfo *T,
2065218893Sdim                                   SourceLocation RParenLoc) {
2066218893Sdim    return getSema().BuildUnaryTypeTrait(Trait, StartLoc, T, RParenLoc);
2067198092Srdivacky  }
2068198092Srdivacky
2069218893Sdim  /// \brief Build a new binary type trait expression.
2070218893Sdim  ///
2071218893Sdim  /// By default, performs semantic analysis to build the new expression.
2072218893Sdim  /// Subclasses may override this routine to provide different behavior.
2073218893Sdim  ExprResult RebuildBinaryTypeTrait(BinaryTypeTrait Trait,
2074218893Sdim                                    SourceLocation StartLoc,
2075218893Sdim                                    TypeSourceInfo *LhsT,
2076218893Sdim                                    TypeSourceInfo *RhsT,
2077218893Sdim                                    SourceLocation RParenLoc) {
2078218893Sdim    return getSema().BuildBinaryTypeTrait(Trait, StartLoc, LhsT, RhsT, RParenLoc);
2079218893Sdim  }
2080218893Sdim
2081234353Sdim  /// \brief Build a new type trait expression.
2082234353Sdim  ///
2083234353Sdim  /// By default, performs semantic analysis to build the new expression.
2084234353Sdim  /// Subclasses may override this routine to provide different behavior.
2085234353Sdim  ExprResult RebuildTypeTrait(TypeTrait Trait,
2086234353Sdim                              SourceLocation StartLoc,
2087234353Sdim                              ArrayRef<TypeSourceInfo *> Args,
2088234353Sdim                              SourceLocation RParenLoc) {
2089234353Sdim    return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
2090234353Sdim  }
2091239462Sdim
2092221345Sdim  /// \brief Build a new array type trait expression.
2093221345Sdim  ///
2094221345Sdim  /// By default, performs semantic analysis to build the new expression.
2095221345Sdim  /// Subclasses may override this routine to provide different behavior.
2096221345Sdim  ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
2097221345Sdim                                   SourceLocation StartLoc,
2098221345Sdim                                   TypeSourceInfo *TSInfo,
2099221345Sdim                                   Expr *DimExpr,
2100221345Sdim                                   SourceLocation RParenLoc) {
2101221345Sdim    return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
2102221345Sdim  }
2103221345Sdim
2104221345Sdim  /// \brief Build a new expression trait expression.
2105221345Sdim  ///
2106221345Sdim  /// By default, performs semantic analysis to build the new expression.
2107221345Sdim  /// Subclasses may override this routine to provide different behavior.
2108221345Sdim  ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
2109221345Sdim                                   SourceLocation StartLoc,
2110221345Sdim                                   Expr *Queried,
2111221345Sdim                                   SourceLocation RParenLoc) {
2112221345Sdim    return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
2113221345Sdim  }
2114221345Sdim
2115198092Srdivacky  /// \brief Build a new (previously unresolved) declaration reference
2116198092Srdivacky  /// expression.
2117198092Srdivacky  ///
2118198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2119198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2120219077Sdim  ExprResult RebuildDependentScopeDeclRefExpr(
2121219077Sdim                                          NestedNameSpecifierLoc QualifierLoc,
2122234353Sdim                                          SourceLocation TemplateKWLoc,
2123212904Sdim                                       const DeclarationNameInfo &NameInfo,
2124243830Sdim                              const TemplateArgumentListInfo *TemplateArgs,
2125243830Sdim                                          bool IsAddressOfOperand) {
2126198092Srdivacky    CXXScopeSpec SS;
2127219077Sdim    SS.Adopt(QualifierLoc);
2128199990Srdivacky
2129234353Sdim    if (TemplateArgs || TemplateKWLoc.isValid())
2130234353Sdim      return getSema().BuildQualifiedTemplateIdExpr(SS, TemplateKWLoc,
2131234353Sdim                                                    NameInfo, TemplateArgs);
2132199990Srdivacky
2133243830Sdim    return getSema().BuildQualifiedDeclarationNameExpr(SS, NameInfo,
2134243830Sdim                                                       IsAddressOfOperand);
2135198092Srdivacky  }
2136198092Srdivacky
2137198092Srdivacky  /// \brief Build a new template-id expression.
2138198092Srdivacky  ///
2139198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2140198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2141212904Sdim  ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
2142234353Sdim                                   SourceLocation TemplateKWLoc,
2143234353Sdim                                   LookupResult &R,
2144234353Sdim                                   bool RequiresADL,
2145234353Sdim                              const TemplateArgumentListInfo *TemplateArgs) {
2146234353Sdim    return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
2147234353Sdim                                         TemplateArgs);
2148198092Srdivacky  }
2149198092Srdivacky
2150198092Srdivacky  /// \brief Build a new object-construction expression.
2151198092Srdivacky  ///
2152198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2153198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2154212904Sdim  ExprResult RebuildCXXConstructExpr(QualType T,
2155226633Sdim                                     SourceLocation Loc,
2156226633Sdim                                     CXXConstructorDecl *Constructor,
2157226633Sdim                                     bool IsElidable,
2158226633Sdim                                     MultiExprArg Args,
2159226633Sdim                                     bool HadMultipleCandidates,
2160249423Sdim                                     bool ListInitialization,
2161226633Sdim                                     bool RequiresZeroInit,
2162218893Sdim                             CXXConstructExpr::ConstructionKind ConstructKind,
2163226633Sdim                                     SourceRange ParenRange) {
2164243830Sdim    SmallVector<Expr*, 8> ConvertedArgs;
2165243830Sdim    if (getSema().CompleteConstructorCall(Constructor, Args, Loc,
2166200583Srdivacky                                          ConvertedArgs))
2167212904Sdim      return ExprError();
2168239462Sdim
2169200583Srdivacky    return getSema().BuildCXXConstructExpr(Loc, T, Constructor, IsElidable,
2170243830Sdim                                           ConvertedArgs,
2171226633Sdim                                           HadMultipleCandidates,
2172249423Sdim                                           ListInitialization,
2173218893Sdim                                           RequiresZeroInit, ConstructKind,
2174218893Sdim                                           ParenRange);
2175198092Srdivacky  }
2176198092Srdivacky
2177198092Srdivacky  /// \brief Build a new object-construction expression.
2178198092Srdivacky  ///
2179198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2180198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2181218893Sdim  ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
2182218893Sdim                                           SourceLocation LParenLoc,
2183218893Sdim                                           MultiExprArg Args,
2184218893Sdim                                           SourceLocation RParenLoc) {
2185218893Sdim    return getSema().BuildCXXTypeConstructExpr(TSInfo,
2186198092Srdivacky                                               LParenLoc,
2187243830Sdim                                               Args,
2188198092Srdivacky                                               RParenLoc);
2189198092Srdivacky  }
2190198092Srdivacky
2191198092Srdivacky  /// \brief Build a new object-construction expression.
2192198092Srdivacky  ///
2193198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2194198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2195218893Sdim  ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
2196218893Sdim                                               SourceLocation LParenLoc,
2197218893Sdim                                               MultiExprArg Args,
2198218893Sdim                                               SourceLocation RParenLoc) {
2199218893Sdim    return getSema().BuildCXXTypeConstructExpr(TSInfo,
2200198092Srdivacky                                               LParenLoc,
2201243830Sdim                                               Args,
2202198092Srdivacky                                               RParenLoc);
2203198092Srdivacky  }
2204198092Srdivacky
2205198092Srdivacky  /// \brief Build a new member reference expression.
2206198092Srdivacky  ///
2207198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2208198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2209212904Sdim  ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
2210221345Sdim                                                QualType BaseType,
2211221345Sdim                                                bool IsArrow,
2212221345Sdim                                                SourceLocation OperatorLoc,
2213221345Sdim                                          NestedNameSpecifierLoc QualifierLoc,
2214234353Sdim                                                SourceLocation TemplateKWLoc,
2215199990Srdivacky                                            NamedDecl *FirstQualifierInScope,
2216212904Sdim                                   const DeclarationNameInfo &MemberNameInfo,
2217199990Srdivacky                              const TemplateArgumentListInfo *TemplateArgs) {
2218198092Srdivacky    CXXScopeSpec SS;
2219221345Sdim    SS.Adopt(QualifierLoc);
2220198092Srdivacky
2221212904Sdim    return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
2222200583Srdivacky                                            OperatorLoc, IsArrow,
2223234353Sdim                                            SS, TemplateKWLoc,
2224234353Sdim                                            FirstQualifierInScope,
2225212904Sdim                                            MemberNameInfo,
2226212904Sdim                                            TemplateArgs);
2227198092Srdivacky  }
2228198092Srdivacky
2229199990Srdivacky  /// \brief Build a new member reference expression.
2230198092Srdivacky  ///
2231198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2232198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2233234353Sdim  ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
2234234353Sdim                                         SourceLocation OperatorLoc,
2235234353Sdim                                         bool IsArrow,
2236234353Sdim                                         NestedNameSpecifierLoc QualifierLoc,
2237234353Sdim                                         SourceLocation TemplateKWLoc,
2238234353Sdim                                         NamedDecl *FirstQualifierInScope,
2239234353Sdim                                         LookupResult &R,
2240199990Srdivacky                                const TemplateArgumentListInfo *TemplateArgs) {
2241198092Srdivacky    CXXScopeSpec SS;
2242221345Sdim    SS.Adopt(QualifierLoc);
2243198092Srdivacky
2244212904Sdim    return SemaRef.BuildMemberReferenceExpr(BaseE, BaseType,
2245200583Srdivacky                                            OperatorLoc, IsArrow,
2246234353Sdim                                            SS, TemplateKWLoc,
2247234353Sdim                                            FirstQualifierInScope,
2248202379Srdivacky                                            R, TemplateArgs);
2249198092Srdivacky  }
2250198092Srdivacky
2251218893Sdim  /// \brief Build a new noexcept expression.
2252218893Sdim  ///
2253218893Sdim  /// By default, performs semantic analysis to build the new expression.
2254218893Sdim  /// Subclasses may override this routine to provide different behavior.
2255218893Sdim  ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
2256218893Sdim    return SemaRef.BuildCXXNoexceptExpr(Range.getBegin(), Arg, Range.getEnd());
2257218893Sdim  }
2258218893Sdim
2259218893Sdim  /// \brief Build a new expression to compute the length of a parameter pack.
2260239462Sdim  ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
2261239462Sdim                                   SourceLocation PackLoc,
2262218893Sdim                                   SourceLocation RParenLoc,
2263249423Sdim                                   Optional<unsigned> Length) {
2264226633Sdim    if (Length)
2265239462Sdim      return new (SemaRef.Context) SizeOfPackExpr(SemaRef.Context.getSizeType(),
2266239462Sdim                                                  OperatorLoc, Pack, PackLoc,
2267226633Sdim                                                  RParenLoc, *Length);
2268239462Sdim
2269239462Sdim    return new (SemaRef.Context) SizeOfPackExpr(SemaRef.Context.getSizeType(),
2270239462Sdim                                                OperatorLoc, Pack, PackLoc,
2271226633Sdim                                                RParenLoc);
2272218893Sdim  }
2273234353Sdim
2274239462Sdim  /// \brief Build a new Objective-C boxed expression.
2275239462Sdim  ///
2276239462Sdim  /// By default, performs semantic analysis to build the new expression.
2277239462Sdim  /// Subclasses may override this routine to provide different behavior.
2278239462Sdim  ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
2279239462Sdim    return getSema().BuildObjCBoxedExpr(SR, ValueExpr);
2280239462Sdim  }
2281239462Sdim
2282234353Sdim  /// \brief Build a new Objective-C array literal.
2283234353Sdim  ///
2284234353Sdim  /// By default, performs semantic analysis to build the new expression.
2285234353Sdim  /// Subclasses may override this routine to provide different behavior.
2286234353Sdim  ExprResult RebuildObjCArrayLiteral(SourceRange Range,
2287234353Sdim                                     Expr **Elements, unsigned NumElements) {
2288239462Sdim    return getSema().BuildObjCArrayLiteral(Range,
2289234353Sdim                                           MultiExprArg(Elements, NumElements));
2290234353Sdim  }
2291239462Sdim
2292239462Sdim  ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
2293234353Sdim                                         Expr *Base, Expr *Key,
2294234353Sdim                                         ObjCMethodDecl *getterMethod,
2295234353Sdim                                         ObjCMethodDecl *setterMethod) {
2296234353Sdim    return  getSema().BuildObjCSubscriptExpression(RB, Base, Key,
2297234353Sdim                                                   getterMethod, setterMethod);
2298234353Sdim  }
2299234353Sdim
2300234353Sdim  /// \brief Build a new Objective-C dictionary literal.
2301234353Sdim  ///
2302234353Sdim  /// By default, performs semantic analysis to build the new expression.
2303234353Sdim  /// Subclasses may override this routine to provide different behavior.
2304234353Sdim  ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
2305234353Sdim                                          ObjCDictionaryElement *Elements,
2306234353Sdim                                          unsigned NumElements) {
2307234353Sdim    return getSema().BuildObjCDictionaryLiteral(Range, Elements, NumElements);
2308234353Sdim  }
2309239462Sdim
2310239462Sdim  /// \brief Build a new Objective-C \@encode expression.
2311198092Srdivacky  ///
2312198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2313198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2314212904Sdim  ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
2315207619Srdivacky                                         TypeSourceInfo *EncodeTypeInfo,
2316198092Srdivacky                                         SourceLocation RParenLoc) {
2317207619Srdivacky    return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, EncodeTypeInfo,
2318198092Srdivacky                                                           RParenLoc));
2319198092Srdivacky  }
2320198092Srdivacky
2321207619Srdivacky  /// \brief Build a new Objective-C class message.
2322212904Sdim  ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
2323207619Srdivacky                                          Selector Sel,
2324226633Sdim                                          ArrayRef<SourceLocation> SelectorLocs,
2325207619Srdivacky                                          ObjCMethodDecl *Method,
2326239462Sdim                                          SourceLocation LBracLoc,
2327207619Srdivacky                                          MultiExprArg Args,
2328207619Srdivacky                                          SourceLocation RBracLoc) {
2329207619Srdivacky    return SemaRef.BuildClassMessage(ReceiverTypeInfo,
2330207619Srdivacky                                     ReceiverTypeInfo->getType(),
2331207619Srdivacky                                     /*SuperLoc=*/SourceLocation(),
2332226633Sdim                                     Sel, Method, LBracLoc, SelectorLocs,
2333243830Sdim                                     RBracLoc, Args);
2334207619Srdivacky  }
2335207619Srdivacky
2336207619Srdivacky  /// \brief Build a new Objective-C instance message.
2337212904Sdim  ExprResult RebuildObjCMessageExpr(Expr *Receiver,
2338207619Srdivacky                                          Selector Sel,
2339226633Sdim                                          ArrayRef<SourceLocation> SelectorLocs,
2340207619Srdivacky                                          ObjCMethodDecl *Method,
2341239462Sdim                                          SourceLocation LBracLoc,
2342207619Srdivacky                                          MultiExprArg Args,
2343207619Srdivacky                                          SourceLocation RBracLoc) {
2344212904Sdim    return SemaRef.BuildInstanceMessage(Receiver,
2345212904Sdim                                        Receiver->getType(),
2346207619Srdivacky                                        /*SuperLoc=*/SourceLocation(),
2347226633Sdim                                        Sel, Method, LBracLoc, SelectorLocs,
2348243830Sdim                                        RBracLoc, Args);
2349207619Srdivacky  }
2350207619Srdivacky
2351207619Srdivacky  /// \brief Build a new Objective-C ivar reference expression.
2352198092Srdivacky  ///
2353198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2354198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2355212904Sdim  ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
2356207619Srdivacky                                          SourceLocation IvarLoc,
2357207619Srdivacky                                          bool IsArrow, bool IsFreeIvar) {
2358207619Srdivacky    // FIXME: We lose track of the IsFreeIvar bit.
2359207619Srdivacky    CXXScopeSpec SS;
2360221345Sdim    ExprResult Base = getSema().Owned(BaseArg);
2361207619Srdivacky    LookupResult R(getSema(), Ivar->getDeclName(), IvarLoc,
2362207619Srdivacky                   Sema::LookupMemberName);
2363212904Sdim    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
2364207619Srdivacky                                                         /*FIME:*/IvarLoc,
2365212904Sdim                                                         SS, 0,
2366210299Sed                                                         false);
2367221345Sdim    if (Result.isInvalid() || Base.isInvalid())
2368212904Sdim      return ExprError();
2369239462Sdim
2370207619Srdivacky    if (Result.get())
2371243830Sdim      return Result;
2372239462Sdim
2373221345Sdim    return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
2374234353Sdim                                              /*FIXME:*/IvarLoc, IsArrow,
2375234353Sdim                                              SS, SourceLocation(),
2376207619Srdivacky                                              /*FirstQualifierInScope=*/0,
2377239462Sdim                                              R,
2378207619Srdivacky                                              /*TemplateArgs=*/0);
2379198092Srdivacky  }
2380198092Srdivacky
2381207619Srdivacky  /// \brief Build a new Objective-C property reference expression.
2382207619Srdivacky  ///
2383207619Srdivacky  /// By default, performs semantic analysis to build the new expression.
2384207619Srdivacky  /// Subclasses may override this routine to provide different behavior.
2385239462Sdim  ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
2386234353Sdim                                        ObjCPropertyDecl *Property,
2387234353Sdim                                        SourceLocation PropertyLoc) {
2388207619Srdivacky    CXXScopeSpec SS;
2389221345Sdim    ExprResult Base = getSema().Owned(BaseArg);
2390207619Srdivacky    LookupResult R(getSema(), Property->getDeclName(), PropertyLoc,
2391207619Srdivacky                   Sema::LookupMemberName);
2392207619Srdivacky    bool IsArrow = false;
2393212904Sdim    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
2394207619Srdivacky                                                         /*FIME:*/PropertyLoc,
2395212904Sdim                                                         SS, 0, false);
2396221345Sdim    if (Result.isInvalid() || Base.isInvalid())
2397212904Sdim      return ExprError();
2398239462Sdim
2399207619Srdivacky    if (Result.get())
2400243830Sdim      return Result;
2401239462Sdim
2402221345Sdim    return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
2403239462Sdim                                              /*FIXME:*/PropertyLoc, IsArrow,
2404234353Sdim                                              SS, SourceLocation(),
2405207619Srdivacky                                              /*FirstQualifierInScope=*/0,
2406239462Sdim                                              R,
2407207619Srdivacky                                              /*TemplateArgs=*/0);
2408207619Srdivacky  }
2409239462Sdim
2410218893Sdim  /// \brief Build a new Objective-C property reference expression.
2411207619Srdivacky  ///
2412207619Srdivacky  /// By default, performs semantic analysis to build the new expression.
2413218893Sdim  /// Subclasses may override this routine to provide different behavior.
2414218893Sdim  ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
2415218893Sdim                                        ObjCMethodDecl *Getter,
2416218893Sdim                                        ObjCMethodDecl *Setter,
2417218893Sdim                                        SourceLocation PropertyLoc) {
2418218893Sdim    // Since these expressions can only be value-dependent, we do not
2419218893Sdim    // need to perform semantic analysis again.
2420212904Sdim    return Owned(
2421218893Sdim      new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
2422218893Sdim                                                  VK_LValue, OK_ObjCProperty,
2423218893Sdim                                                  PropertyLoc, Base));
2424207619Srdivacky  }
2425207619Srdivacky
2426207619Srdivacky  /// \brief Build a new Objective-C "isa" expression.
2427207619Srdivacky  ///
2428207619Srdivacky  /// By default, performs semantic analysis to build the new expression.
2429207619Srdivacky  /// Subclasses may override this routine to provide different behavior.
2430212904Sdim  ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
2431249423Sdim                                SourceLocation OpLoc,
2432207619Srdivacky                                      bool IsArrow) {
2433207619Srdivacky    CXXScopeSpec SS;
2434221345Sdim    ExprResult Base = getSema().Owned(BaseArg);
2435207619Srdivacky    LookupResult R(getSema(), &getSema().Context.Idents.get("isa"), IsaLoc,
2436207619Srdivacky                   Sema::LookupMemberName);
2437212904Sdim    ExprResult Result = getSema().LookupMemberExpr(R, Base, IsArrow,
2438249423Sdim                                                         OpLoc,
2439212904Sdim                                                         SS, 0, false);
2440221345Sdim    if (Result.isInvalid() || Base.isInvalid())
2441212904Sdim      return ExprError();
2442239462Sdim
2443207619Srdivacky    if (Result.get())
2444243830Sdim      return Result;
2445239462Sdim
2446221345Sdim    return getSema().BuildMemberReferenceExpr(Base.get(), Base.get()->getType(),
2447249423Sdim                                              OpLoc, IsArrow,
2448234353Sdim                                              SS, SourceLocation(),
2449207619Srdivacky                                              /*FirstQualifierInScope=*/0,
2450239462Sdim                                              R,
2451207619Srdivacky                                              /*TemplateArgs=*/0);
2452207619Srdivacky  }
2453239462Sdim
2454198092Srdivacky  /// \brief Build a new shuffle vector expression.
2455198092Srdivacky  ///
2456198092Srdivacky  /// By default, performs semantic analysis to build the new expression.
2457198092Srdivacky  /// Subclasses may override this routine to provide different behavior.
2458212904Sdim  ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
2459218893Sdim                                      MultiExprArg SubExprs,
2460218893Sdim                                      SourceLocation RParenLoc) {
2461198092Srdivacky    // Find the declaration for __builtin_shufflevector
2462198092Srdivacky    const IdentifierInfo &Name
2463198092Srdivacky      = SemaRef.Context.Idents.get("__builtin_shufflevector");
2464198092Srdivacky    TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
2465198092Srdivacky    DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
2466249423Sdim    assert(!Lookup.empty() && "No __builtin_shufflevector?");
2467198092Srdivacky
2468198092Srdivacky    // Build a reference to the __builtin_shufflevector builtin
2469249423Sdim    FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
2470243830Sdim    Expr *Callee = new (SemaRef.Context) DeclRefExpr(Builtin, false,
2471243830Sdim                                                  SemaRef.Context.BuiltinFnTy,
2472243830Sdim                                                  VK_RValue, BuiltinLoc);
2473243830Sdim    QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
2474243830Sdim    Callee = SemaRef.ImpCastExprToType(Callee, CalleePtrTy,
2475243830Sdim                                       CK_BuiltinFnToFnPtr).take();
2476198092Srdivacky
2477198092Srdivacky    // Build the CallExpr
2478221345Sdim    ExprResult TheCall = SemaRef.Owned(
2479243830Sdim      new (SemaRef.Context) CallExpr(SemaRef.Context, Callee, SubExprs,
2480243830Sdim                                     Builtin->getCallResultType(),
2481218893Sdim                            Expr::getValueKindForType(Builtin->getResultType()),
2482221345Sdim                                     RParenLoc));
2483198092Srdivacky
2484198092Srdivacky    // Type-check the __builtin_shufflevector expression.
2485221345Sdim    return SemaRef.SemaBuiltinShuffleVector(cast<CallExpr>(TheCall.take()));
2486198092Srdivacky  }
2487218893Sdim
2488218893Sdim  /// \brief Build a new template argument pack expansion.
2489218893Sdim  ///
2490218893Sdim  /// By default, performs semantic analysis to build a new pack expansion
2491239462Sdim  /// for a template argument. Subclasses may override this routine to provide
2492218893Sdim  /// different behavior.
2493218893Sdim  TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
2494218893Sdim                                           SourceLocation EllipsisLoc,
2495249423Sdim                                           Optional<unsigned> NumExpansions) {
2496218893Sdim    switch (Pattern.getArgument().getKind()) {
2497218893Sdim    case TemplateArgument::Expression: {
2498218893Sdim      ExprResult Result
2499218893Sdim        = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
2500218893Sdim                                       EllipsisLoc, NumExpansions);
2501218893Sdim      if (Result.isInvalid())
2502218893Sdim        return TemplateArgumentLoc();
2503239462Sdim
2504218893Sdim      return TemplateArgumentLoc(Result.get(), Result.get());
2505218893Sdim    }
2506239462Sdim
2507218893Sdim    case TemplateArgument::Template:
2508218893Sdim      return TemplateArgumentLoc(TemplateArgument(
2509218893Sdim                                          Pattern.getArgument().getAsTemplate(),
2510218893Sdim                                                  NumExpansions),
2511221345Sdim                                 Pattern.getTemplateQualifierLoc(),
2512218893Sdim                                 Pattern.getTemplateNameLoc(),
2513218893Sdim                                 EllipsisLoc);
2514239462Sdim
2515218893Sdim    case TemplateArgument::Null:
2516218893Sdim    case TemplateArgument::Integral:
2517218893Sdim    case TemplateArgument::Declaration:
2518218893Sdim    case TemplateArgument::Pack:
2519218893Sdim    case TemplateArgument::TemplateExpansion:
2520243830Sdim    case TemplateArgument::NullPtr:
2521218893Sdim      llvm_unreachable("Pack expansion pattern has no parameter packs");
2522239462Sdim
2523218893Sdim    case TemplateArgument::Type:
2524239462Sdim      if (TypeSourceInfo *Expansion
2525218893Sdim            = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
2526218893Sdim                                           EllipsisLoc,
2527218893Sdim                                           NumExpansions))
2528218893Sdim        return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
2529218893Sdim                                   Expansion);
2530218893Sdim      break;
2531218893Sdim    }
2532239462Sdim
2533218893Sdim    return TemplateArgumentLoc();
2534218893Sdim  }
2535239462Sdim
2536218893Sdim  /// \brief Build a new expression pack expansion.
2537218893Sdim  ///
2538218893Sdim  /// By default, performs semantic analysis to build a new pack expansion
2539239462Sdim  /// for an expression. Subclasses may override this routine to provide
2540218893Sdim  /// different behavior.
2541218893Sdim  ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
2542249423Sdim                                  Optional<unsigned> NumExpansions) {
2543218893Sdim    return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
2544218893Sdim  }
2545226633Sdim
2546226633Sdim  /// \brief Build a new atomic operation expression.
2547226633Sdim  ///
2548226633Sdim  /// By default, performs semantic analysis to build the new expression.
2549226633Sdim  /// Subclasses may override this routine to provide different behavior.
2550226633Sdim  ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc,
2551226633Sdim                               MultiExprArg SubExprs,
2552226633Sdim                               QualType RetTy,
2553226633Sdim                               AtomicExpr::AtomicOp Op,
2554226633Sdim                               SourceLocation RParenLoc) {
2555226633Sdim    // Just create the expression; there is not any interesting semantic
2556226633Sdim    // analysis here because we can't actually build an AtomicExpr until
2557226633Sdim    // we are sure it is semantically sound.
2558243830Sdim    return new (SemaRef.Context) AtomicExpr(BuiltinLoc, SubExprs, RetTy, Op,
2559226633Sdim                                            RParenLoc);
2560226633Sdim  }
2561226633Sdim
2562218893Sdimprivate:
2563219077Sdim  TypeLoc TransformTypeInObjectScope(TypeLoc TL,
2564219077Sdim                                     QualType ObjectType,
2565219077Sdim                                     NamedDecl *FirstQualifierInScope,
2566219077Sdim                                     CXXScopeSpec &SS);
2567221345Sdim
2568221345Sdim  TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
2569221345Sdim                                             QualType ObjectType,
2570221345Sdim                                             NamedDecl *FirstQualifierInScope,
2571221345Sdim                                             CXXScopeSpec &SS);
2572198092Srdivacky};
2573198092Srdivacky
2574198092Srdivackytemplate<typename Derived>
2575212904SdimStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
2576198092Srdivacky  if (!S)
2577198092Srdivacky    return SemaRef.Owned(S);
2578198092Srdivacky
2579198092Srdivacky  switch (S->getStmtClass()) {
2580198092Srdivacky  case Stmt::NoStmtClass: break;
2581198092Srdivacky
2582198092Srdivacky  // Transform individual statement nodes
2583198092Srdivacky#define STMT(Node, Parent)                                              \
2584198092Srdivacky  case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
2585218893Sdim#define ABSTRACT_STMT(Node)
2586198092Srdivacky#define EXPR(Node, Parent)
2587208600Srdivacky#include "clang/AST/StmtNodes.inc"
2588198092Srdivacky
2589198092Srdivacky  // Transform expressions by calling TransformExpr.
2590198092Srdivacky#define STMT(Node, Parent)
2591208600Srdivacky#define ABSTRACT_STMT(Stmt)
2592198092Srdivacky#define EXPR(Node, Parent) case Stmt::Node##Class:
2593208600Srdivacky#include "clang/AST/StmtNodes.inc"
2594198092Srdivacky    {
2595212904Sdim      ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
2596198092Srdivacky      if (E.isInvalid())
2597212904Sdim        return StmtError();
2598198092Srdivacky
2599249423Sdim      return getSema().ActOnExprStmt(E);
2600198092Srdivacky    }
2601198092Srdivacky  }
2602198092Srdivacky
2603218893Sdim  return SemaRef.Owned(S);
2604198092Srdivacky}
2605198092Srdivacky
2606198092Srdivacky
2607198092Srdivackytemplate<typename Derived>
2608212904SdimExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
2609198092Srdivacky  if (!E)
2610198092Srdivacky    return SemaRef.Owned(E);
2611198092Srdivacky
2612198092Srdivacky  switch (E->getStmtClass()) {
2613198092Srdivacky    case Stmt::NoStmtClass: break;
2614198092Srdivacky#define STMT(Node, Parent) case Stmt::Node##Class: break;
2615208600Srdivacky#define ABSTRACT_STMT(Stmt)
2616198092Srdivacky#define EXPR(Node, Parent)                                              \
2617200583Srdivacky    case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
2618208600Srdivacky#include "clang/AST/StmtNodes.inc"
2619198092Srdivacky  }
2620198092Srdivacky
2621218893Sdim  return SemaRef.Owned(E);
2622198092Srdivacky}
2623198092Srdivacky
2624198092Srdivackytemplate<typename Derived>
2625249423SdimExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
2626249423Sdim                                                        bool CXXDirectInit) {
2627249423Sdim  // Initializers are instantiated like expressions, except that various outer
2628249423Sdim  // layers are stripped.
2629249423Sdim  if (!Init)
2630249423Sdim    return SemaRef.Owned(Init);
2631249423Sdim
2632249423Sdim  if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init))
2633249423Sdim    Init = ExprTemp->getSubExpr();
2634249423Sdim
2635249423Sdim  while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
2636249423Sdim    Init = Binder->getSubExpr();
2637249423Sdim
2638249423Sdim  if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
2639249423Sdim    Init = ICE->getSubExprAsWritten();
2640249423Sdim
2641249423Sdim  // If this is not a direct-initializer, we only need to reconstruct
2642249423Sdim  // InitListExprs. Other forms of copy-initialization will be a no-op if
2643249423Sdim  // the initializer is already the right type.
2644249423Sdim  CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
2645249423Sdim  if (!CXXDirectInit && !(Construct && Construct->isListInitialization()))
2646249423Sdim    return getDerived().TransformExpr(Init);
2647249423Sdim
2648249423Sdim  // Revert value-initialization back to empty parens.
2649249423Sdim  if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
2650249423Sdim    SourceRange Parens = VIE->getSourceRange();
2651251662Sdim    return getDerived().RebuildParenListExpr(Parens.getBegin(), None,
2652249423Sdim                                             Parens.getEnd());
2653249423Sdim  }
2654249423Sdim
2655249423Sdim  // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
2656249423Sdim  if (isa<ImplicitValueInitExpr>(Init))
2657251662Sdim    return getDerived().RebuildParenListExpr(SourceLocation(), None,
2658249423Sdim                                             SourceLocation());
2659249423Sdim
2660249423Sdim  // Revert initialization by constructor back to a parenthesized or braced list
2661249423Sdim  // of expressions. Any other form of initializer can just be reused directly.
2662249423Sdim  if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
2663249423Sdim    return getDerived().TransformExpr(Init);
2664249423Sdim
2665249423Sdim  SmallVector<Expr*, 8> NewArgs;
2666249423Sdim  bool ArgChanged = false;
2667249423Sdim  if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
2668249423Sdim                     /*IsCall*/true, NewArgs, &ArgChanged))
2669249423Sdim    return ExprError();
2670249423Sdim
2671249423Sdim  // If this was list initialization, revert to list form.
2672249423Sdim  if (Construct->isListInitialization())
2673249423Sdim    return getDerived().RebuildInitList(Construct->getLocStart(), NewArgs,
2674249423Sdim                                        Construct->getLocEnd(),
2675249423Sdim                                        Construct->getType());
2676249423Sdim
2677249423Sdim  // Build a ParenListExpr to represent anything else.
2678249423Sdim  SourceRange Parens = Construct->getParenRange();
2679249423Sdim  return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
2680249423Sdim                                           Parens.getEnd());
2681249423Sdim}
2682249423Sdim
2683249423Sdimtemplate<typename Derived>
2684239462Sdimbool TreeTransform<Derived>::TransformExprs(Expr **Inputs,
2685239462Sdim                                            unsigned NumInputs,
2686218893Sdim                                            bool IsCall,
2687226633Sdim                                      SmallVectorImpl<Expr *> &Outputs,
2688218893Sdim                                            bool *ArgChanged) {
2689218893Sdim  for (unsigned I = 0; I != NumInputs; ++I) {
2690218893Sdim    // If requested, drop call arguments that need to be dropped.
2691218893Sdim    if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
2692218893Sdim      if (ArgChanged)
2693218893Sdim        *ArgChanged = true;
2694239462Sdim
2695218893Sdim      break;
2696218893Sdim    }
2697239462Sdim
2698218893Sdim    if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
2699218893Sdim      Expr *Pattern = Expansion->getPattern();
2700239462Sdim
2701226633Sdim      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
2702218893Sdim      getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
2703218893Sdim      assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
2704239462Sdim
2705218893Sdim      // Determine whether the set of unexpanded parameter packs can and should
2706218893Sdim      // be expanded.
2707218893Sdim      bool Expand = true;
2708218893Sdim      bool RetainExpansion = false;
2709249423Sdim      Optional<unsigned> OrigNumExpansions = Expansion->getNumExpansions();
2710249423Sdim      Optional<unsigned> NumExpansions = OrigNumExpansions;
2711218893Sdim      if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
2712218893Sdim                                               Pattern->getSourceRange(),
2713226633Sdim                                               Unexpanded,
2714218893Sdim                                               Expand, RetainExpansion,
2715218893Sdim                                               NumExpansions))
2716218893Sdim        return true;
2717239462Sdim
2718218893Sdim      if (!Expand) {
2719218893Sdim        // The transform has determined that we should perform a simple
2720239462Sdim        // transformation on the pack expansion, producing another pack
2721218893Sdim        // expansion.
2722218893Sdim        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
2723218893Sdim        ExprResult OutPattern = getDerived().TransformExpr(Pattern);
2724218893Sdim        if (OutPattern.isInvalid())
2725218893Sdim          return true;
2726239462Sdim
2727239462Sdim        ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
2728218893Sdim                                                Expansion->getEllipsisLoc(),
2729218893Sdim                                                           NumExpansions);
2730218893Sdim        if (Out.isInvalid())
2731218893Sdim          return true;
2732239462Sdim
2733218893Sdim        if (ArgChanged)
2734218893Sdim          *ArgChanged = true;
2735218893Sdim        Outputs.push_back(Out.get());
2736218893Sdim        continue;
2737218893Sdim      }
2738224145Sdim
2739224145Sdim      // Record right away that the argument was changed.  This needs
2740224145Sdim      // to happen even if the array expands to nothing.
2741224145Sdim      if (ArgChanged) *ArgChanged = true;
2742239462Sdim
2743218893Sdim      // The transform has determined that we should perform an elementwise
2744218893Sdim      // expansion of the pattern. Do so.
2745218893Sdim      for (unsigned I = 0; I != *NumExpansions; ++I) {
2746218893Sdim        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
2747218893Sdim        ExprResult Out = getDerived().TransformExpr(Pattern);
2748218893Sdim        if (Out.isInvalid())
2749218893Sdim          return true;
2750218893Sdim
2751218893Sdim        if (Out.get()->containsUnexpandedParameterPack()) {
2752218893Sdim          Out = RebuildPackExpansion(Out.get(), Expansion->getEllipsisLoc(),
2753218893Sdim                                     OrigNumExpansions);
2754218893Sdim          if (Out.isInvalid())
2755218893Sdim            return true;
2756218893Sdim        }
2757239462Sdim
2758218893Sdim        Outputs.push_back(Out.get());
2759218893Sdim      }
2760239462Sdim
2761218893Sdim      continue;
2762218893Sdim    }
2763239462Sdim
2764249423Sdim    ExprResult Result =
2765249423Sdim      IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
2766249423Sdim             : getDerived().TransformExpr(Inputs[I]);
2767218893Sdim    if (Result.isInvalid())
2768218893Sdim      return true;
2769239462Sdim
2770218893Sdim    if (Result.get() != Inputs[I] && ArgChanged)
2771218893Sdim      *ArgChanged = true;
2772239462Sdim
2773239462Sdim    Outputs.push_back(Result.get());
2774218893Sdim  }
2775239462Sdim
2776218893Sdim  return false;
2777218893Sdim}
2778218893Sdim
2779218893Sdimtemplate<typename Derived>
2780219077SdimNestedNameSpecifierLoc
2781219077SdimTreeTransform<Derived>::TransformNestedNameSpecifierLoc(
2782219077Sdim                                                    NestedNameSpecifierLoc NNS,
2783219077Sdim                                                     QualType ObjectType,
2784219077Sdim                                             NamedDecl *FirstQualifierInScope) {
2785226633Sdim  SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
2786239462Sdim  for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
2787219077Sdim       Qualifier = Qualifier.getPrefix())
2788219077Sdim    Qualifiers.push_back(Qualifier);
2789219077Sdim
2790219077Sdim  CXXScopeSpec SS;
2791219077Sdim  while (!Qualifiers.empty()) {
2792219077Sdim    NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
2793219077Sdim    NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
2794239462Sdim
2795219077Sdim    switch (QNNS->getKind()) {
2796219077Sdim    case NestedNameSpecifier::Identifier:
2797239462Sdim      if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/0,
2798219077Sdim                                              *QNNS->getAsIdentifier(),
2799239462Sdim                                              Q.getLocalBeginLoc(),
2800219077Sdim                                              Q.getLocalEndLoc(),
2801239462Sdim                                              ObjectType, false, SS,
2802219077Sdim                                              FirstQualifierInScope, false))
2803219077Sdim        return NestedNameSpecifierLoc();
2804239462Sdim
2805219077Sdim      break;
2806239462Sdim
2807219077Sdim    case NestedNameSpecifier::Namespace: {
2808219077Sdim      NamespaceDecl *NS
2809219077Sdim        = cast_or_null<NamespaceDecl>(
2810219077Sdim                                    getDerived().TransformDecl(
2811219077Sdim                                                          Q.getLocalBeginLoc(),
2812219077Sdim                                                       QNNS->getAsNamespace()));
2813219077Sdim      SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
2814219077Sdim      break;
2815219077Sdim    }
2816239462Sdim
2817219077Sdim    case NestedNameSpecifier::NamespaceAlias: {
2818219077Sdim      NamespaceAliasDecl *Alias
2819219077Sdim        = cast_or_null<NamespaceAliasDecl>(
2820219077Sdim                      getDerived().TransformDecl(Q.getLocalBeginLoc(),
2821219077Sdim                                                 QNNS->getAsNamespaceAlias()));
2822239462Sdim      SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
2823219077Sdim                Q.getLocalEndLoc());
2824219077Sdim      break;
2825219077Sdim    }
2826239462Sdim
2827219077Sdim    case NestedNameSpecifier::Global:
2828219077Sdim      // There is no meaningful transformation that one could perform on the
2829219077Sdim      // global scope.
2830219077Sdim      SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
2831219077Sdim      break;
2832239462Sdim
2833219077Sdim    case NestedNameSpecifier::TypeSpecWithTemplate:
2834219077Sdim    case NestedNameSpecifier::TypeSpec: {
2835219077Sdim      TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
2836219077Sdim                                              FirstQualifierInScope, SS);
2837239462Sdim
2838219077Sdim      if (!TL)
2839219077Sdim        return NestedNameSpecifierLoc();
2840239462Sdim
2841219077Sdim      if (TL.getType()->isDependentType() || TL.getType()->isRecordType() ||
2842249423Sdim          (SemaRef.getLangOpts().CPlusPlus11 &&
2843219077Sdim           TL.getType()->isEnumeralType())) {
2844239462Sdim        assert(!TL.getType().hasLocalQualifiers() &&
2845219077Sdim               "Can't get cv-qualifiers here");
2846234353Sdim        if (TL.getType()->isEnumeralType())
2847234353Sdim          SemaRef.Diag(TL.getBeginLoc(),
2848234353Sdim                       diag::warn_cxx98_compat_enum_nested_name_spec);
2849219077Sdim        SS.Extend(SemaRef.Context, /*FIXME:*/SourceLocation(), TL,
2850219077Sdim                  Q.getLocalEndLoc());
2851219077Sdim        break;
2852219077Sdim      }
2853223017Sdim      // If the nested-name-specifier is an invalid type def, don't emit an
2854223017Sdim      // error because a previous error should have already been emitted.
2855249423Sdim      TypedefTypeLoc TTL = TL.getAs<TypedefTypeLoc>();
2856249423Sdim      if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
2857239462Sdim        SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
2858223017Sdim          << TL.getType() << SS.getRange();
2859223017Sdim      }
2860219077Sdim      return NestedNameSpecifierLoc();
2861219077Sdim    }
2862221345Sdim    }
2863239462Sdim
2864221345Sdim    // The qualifier-in-scope and object type only apply to the leftmost entity.
2865219077Sdim    FirstQualifierInScope = 0;
2866221345Sdim    ObjectType = QualType();
2867219077Sdim  }
2868239462Sdim
2869219077Sdim  // Don't rebuild the nested-name-specifier if we don't have to.
2870239462Sdim  if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
2871219077Sdim      !getDerived().AlwaysRebuild())
2872219077Sdim    return NNS;
2873239462Sdim
2874239462Sdim  // If we can re-use the source-location data from the original
2875219077Sdim  // nested-name-specifier, do so.
2876219077Sdim  if (SS.location_size() == NNS.getDataLength() &&
2877219077Sdim      memcmp(SS.location_data(), NNS.getOpaqueData(), SS.location_size()) == 0)
2878219077Sdim    return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
2879219077Sdim
2880219077Sdim  // Allocate new nested-name-specifier location information.
2881219077Sdim  return SS.getWithLocInContext(SemaRef.Context);
2882219077Sdim}
2883219077Sdim
2884219077Sdimtemplate<typename Derived>
2885212904SdimDeclarationNameInfo
2886212904SdimTreeTransform<Derived>
2887218893Sdim::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
2888212904Sdim  DeclarationName Name = NameInfo.getName();
2889198092Srdivacky  if (!Name)
2890212904Sdim    return DeclarationNameInfo();
2891198092Srdivacky
2892198092Srdivacky  switch (Name.getNameKind()) {
2893198092Srdivacky  case DeclarationName::Identifier:
2894198092Srdivacky  case DeclarationName::ObjCZeroArgSelector:
2895198092Srdivacky  case DeclarationName::ObjCOneArgSelector:
2896198092Srdivacky  case DeclarationName::ObjCMultiArgSelector:
2897198092Srdivacky  case DeclarationName::CXXOperatorName:
2898199990Srdivacky  case DeclarationName::CXXLiteralOperatorName:
2899198092Srdivacky  case DeclarationName::CXXUsingDirective:
2900212904Sdim    return NameInfo;
2901198092Srdivacky
2902198092Srdivacky  case DeclarationName::CXXConstructorName:
2903198092Srdivacky  case DeclarationName::CXXDestructorName:
2904198092Srdivacky  case DeclarationName::CXXConversionFunctionName: {
2905212904Sdim    TypeSourceInfo *NewTInfo;
2906212904Sdim    CanQualType NewCanTy;
2907212904Sdim    if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
2908218893Sdim      NewTInfo = getDerived().TransformType(OldTInfo);
2909218893Sdim      if (!NewTInfo)
2910218893Sdim        return DeclarationNameInfo();
2911218893Sdim      NewCanTy = SemaRef.Context.getCanonicalType(NewTInfo->getType());
2912212904Sdim    }
2913212904Sdim    else {
2914212904Sdim      NewTInfo = 0;
2915212904Sdim      TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
2916218893Sdim      QualType NewT = getDerived().TransformType(Name.getCXXNameType());
2917212904Sdim      if (NewT.isNull())
2918212904Sdim        return DeclarationNameInfo();
2919212904Sdim      NewCanTy = SemaRef.Context.getCanonicalType(NewT);
2920212904Sdim    }
2921198092Srdivacky
2922212904Sdim    DeclarationName NewName
2923212904Sdim      = SemaRef.Context.DeclarationNames.getCXXSpecialName(Name.getNameKind(),
2924212904Sdim                                                           NewCanTy);
2925212904Sdim    DeclarationNameInfo NewNameInfo(NameInfo);
2926212904Sdim    NewNameInfo.setName(NewName);
2927212904Sdim    NewNameInfo.setNamedTypeInfo(NewTInfo);
2928212904Sdim    return NewNameInfo;
2929198092Srdivacky  }
2930198092Srdivacky  }
2931198092Srdivacky
2932226633Sdim  llvm_unreachable("Unknown name kind.");
2933198092Srdivacky}
2934198092Srdivacky
2935198092Srdivackytemplate<typename Derived>
2936198092SrdivackyTemplateName
2937221345SdimTreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
2938221345Sdim                                              TemplateName Name,
2939221345Sdim                                              SourceLocation NameLoc,
2940218893Sdim                                              QualType ObjectType,
2941218893Sdim                                              NamedDecl *FirstQualifierInScope) {
2942198092Srdivacky  if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
2943221345Sdim    TemplateDecl *Template = QTN->getTemplateDecl();
2944221345Sdim    assert(Template && "qualified template name must refer to a template");
2945239462Sdim
2946221345Sdim    TemplateDecl *TransTemplate
2947239462Sdim      = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
2948221345Sdim                                                              Template));
2949221345Sdim    if (!TransTemplate)
2950198092Srdivacky      return TemplateName();
2951239462Sdim
2952221345Sdim    if (!getDerived().AlwaysRebuild() &&
2953221345Sdim        SS.getScopeRep() == QTN->getQualifier() &&
2954221345Sdim        TransTemplate == Template)
2955221345Sdim      return Name;
2956239462Sdim
2957221345Sdim    return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
2958221345Sdim                                            TransTemplate);
2959198092Srdivacky  }
2960239462Sdim
2961198092Srdivacky  if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
2962221345Sdim    if (SS.getScopeRep()) {
2963218893Sdim      // These apply to the scope specifier, not the template.
2964218893Sdim      ObjectType = QualType();
2965218893Sdim      FirstQualifierInScope = 0;
2966239462Sdim    }
2967239462Sdim
2968198092Srdivacky    if (!getDerived().AlwaysRebuild() &&
2969221345Sdim        SS.getScopeRep() == DTN->getQualifier() &&
2970198398Srdivacky        ObjectType.isNull())
2971198092Srdivacky      return Name;
2972239462Sdim
2973218893Sdim    if (DTN->isIdentifier()) {
2974221345Sdim      return getDerived().RebuildTemplateName(SS,
2975239462Sdim                                              *DTN->getIdentifier(),
2976221345Sdim                                              NameLoc,
2977218893Sdim                                              ObjectType,
2978218893Sdim                                              FirstQualifierInScope);
2979218893Sdim    }
2980239462Sdim
2981221345Sdim    return getDerived().RebuildTemplateName(SS, DTN->getOperator(), NameLoc,
2982198893Srdivacky                                            ObjectType);
2983198092Srdivacky  }
2984239462Sdim
2985198092Srdivacky  if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
2986198092Srdivacky    TemplateDecl *TransTemplate
2987239462Sdim      = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
2988221345Sdim                                                              Template));
2989198092Srdivacky    if (!TransTemplate)
2990198092Srdivacky      return TemplateName();
2991239462Sdim
2992198092Srdivacky    if (!getDerived().AlwaysRebuild() &&
2993198092Srdivacky        TransTemplate == Template)
2994198092Srdivacky      return Name;
2995239462Sdim
2996198092Srdivacky    return TemplateName(TransTemplate);
2997198092Srdivacky  }
2998239462Sdim
2999218893Sdim  if (SubstTemplateTemplateParmPackStorage *SubstPack
3000221345Sdim      = Name.getAsSubstTemplateTemplateParmPack()) {
3001218893Sdim    TemplateTemplateParmDecl *TransParam
3002221345Sdim    = cast_or_null<TemplateTemplateParmDecl>(
3003221345Sdim            getDerived().TransformDecl(NameLoc, SubstPack->getParameterPack()));
3004218893Sdim    if (!TransParam)
3005218893Sdim      return TemplateName();
3006239462Sdim
3007218893Sdim    if (!getDerived().AlwaysRebuild() &&
3008218893Sdim        TransParam == SubstPack->getParameterPack())
3009218893Sdim      return Name;
3010239462Sdim
3011239462Sdim    return getDerived().RebuildTemplateName(TransParam,
3012218893Sdim                                            SubstPack->getArgumentPack());
3013218893Sdim  }
3014239462Sdim
3015199990Srdivacky  // These should be getting filtered out before they reach the AST.
3016218893Sdim  llvm_unreachable("overloaded function decl survived to here");
3017198092Srdivacky}
3018198092Srdivacky
3019198092Srdivackytemplate<typename Derived>
3020198893Srdivackyvoid TreeTransform<Derived>::InventTemplateArgumentLoc(
3021198893Srdivacky                                         const TemplateArgument &Arg,
3022198893Srdivacky                                         TemplateArgumentLoc &Output) {
3023198893Srdivacky  SourceLocation Loc = getDerived().getBaseLocation();
3024198092Srdivacky  switch (Arg.getKind()) {
3025198092Srdivacky  case TemplateArgument::Null:
3026200583Srdivacky    llvm_unreachable("null template argument in TreeTransform");
3027198893Srdivacky    break;
3028198893Srdivacky
3029198893Srdivacky  case TemplateArgument::Type:
3030198893Srdivacky    Output = TemplateArgumentLoc(Arg,
3031200583Srdivacky               SemaRef.Context.getTrivialTypeSourceInfo(Arg.getAsType(), Loc));
3032239462Sdim
3033198893Srdivacky    break;
3034198893Srdivacky
3035199482Srdivacky  case TemplateArgument::Template:
3036221345Sdim  case TemplateArgument::TemplateExpansion: {
3037221345Sdim    NestedNameSpecifierLocBuilder Builder;
3038221345Sdim    TemplateName Template = Arg.getAsTemplate();
3039221345Sdim    if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
3040221345Sdim      Builder.MakeTrivial(SemaRef.Context, DTN->getQualifier(), Loc);
3041221345Sdim    else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
3042221345Sdim      Builder.MakeTrivial(SemaRef.Context, QTN->getQualifier(), Loc);
3043239462Sdim
3044221345Sdim    if (Arg.getKind() == TemplateArgument::Template)
3045239462Sdim      Output = TemplateArgumentLoc(Arg,
3046221345Sdim                                   Builder.getWithLocInContext(SemaRef.Context),
3047221345Sdim                                   Loc);
3048221345Sdim    else
3049239462Sdim      Output = TemplateArgumentLoc(Arg,
3050221345Sdim                                   Builder.getWithLocInContext(SemaRef.Context),
3051221345Sdim                                   Loc, Loc);
3052239462Sdim
3053199482Srdivacky    break;
3054221345Sdim  }
3055218893Sdim
3056198893Srdivacky  case TemplateArgument::Expression:
3057198893Srdivacky    Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
3058198893Srdivacky    break;
3059198893Srdivacky
3060198893Srdivacky  case TemplateArgument::Declaration:
3061198092Srdivacky  case TemplateArgument::Integral:
3062198893Srdivacky  case TemplateArgument::Pack:
3063243830Sdim  case TemplateArgument::NullPtr:
3064198893Srdivacky    Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
3065198893Srdivacky    break;
3066198893Srdivacky  }
3067198893Srdivacky}
3068198092Srdivacky
3069198893Srdivackytemplate<typename Derived>
3070198893Srdivackybool TreeTransform<Derived>::TransformTemplateArgument(
3071198893Srdivacky                                         const TemplateArgumentLoc &Input,
3072198893Srdivacky                                         TemplateArgumentLoc &Output) {
3073198893Srdivacky  const TemplateArgument &Arg = Input.getArgument();
3074198893Srdivacky  switch (Arg.getKind()) {
3075198893Srdivacky  case TemplateArgument::Null:
3076198893Srdivacky  case TemplateArgument::Integral:
3077243830Sdim  case TemplateArgument::Pack:
3078243830Sdim  case TemplateArgument::Declaration:
3079243830Sdim  case TemplateArgument::NullPtr:
3080243830Sdim    llvm_unreachable("Unexpected TemplateArgument");
3081198893Srdivacky
3082198092Srdivacky  case TemplateArgument::Type: {
3083200583Srdivacky    TypeSourceInfo *DI = Input.getTypeSourceInfo();
3084198893Srdivacky    if (DI == NULL)
3085200583Srdivacky      DI = InventTypeSourceInfo(Input.getArgument().getAsType());
3086198893Srdivacky
3087198893Srdivacky    DI = getDerived().TransformType(DI);
3088198893Srdivacky    if (!DI) return true;
3089198893Srdivacky
3090198893Srdivacky    Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
3091198893Srdivacky    return false;
3092198092Srdivacky  }
3093198092Srdivacky
3094199482Srdivacky  case TemplateArgument::Template: {
3095221345Sdim    NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
3096221345Sdim    if (QualifierLoc) {
3097221345Sdim      QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
3098221345Sdim      if (!QualifierLoc)
3099221345Sdim        return true;
3100221345Sdim    }
3101239462Sdim
3102221345Sdim    CXXScopeSpec SS;
3103221345Sdim    SS.Adopt(QualifierLoc);
3104199482Srdivacky    TemplateName Template
3105221345Sdim      = getDerived().TransformTemplateName(SS, Arg.getAsTemplate(),
3106221345Sdim                                           Input.getTemplateNameLoc());
3107199482Srdivacky    if (Template.isNull())
3108199482Srdivacky      return true;
3109239462Sdim
3110221345Sdim    Output = TemplateArgumentLoc(TemplateArgument(Template), QualifierLoc,
3111199482Srdivacky                                 Input.getTemplateNameLoc());
3112199482Srdivacky    return false;
3113199482Srdivacky  }
3114218893Sdim
3115218893Sdim  case TemplateArgument::TemplateExpansion:
3116218893Sdim    llvm_unreachable("Caller should expand pack expansions");
3117218893Sdim
3118198092Srdivacky  case TemplateArgument::Expression: {
3119234353Sdim    // Template argument expressions are constant expressions.
3120198092Srdivacky    EnterExpressionEvaluationContext Unevaluated(getSema(),
3121234353Sdim                                                 Sema::ConstantEvaluated);
3122198092Srdivacky
3123198893Srdivacky    Expr *InputExpr = Input.getSourceExpression();
3124198893Srdivacky    if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
3125198893Srdivacky
3126221345Sdim    ExprResult E = getDerived().TransformExpr(InputExpr);
3127234353Sdim    E = SemaRef.ActOnConstantExpression(E);
3128198893Srdivacky    if (E.isInvalid()) return true;
3129212904Sdim    Output = TemplateArgumentLoc(TemplateArgument(E.take()), E.take());
3130198893Srdivacky    return false;
3131198092Srdivacky  }
3132198092Srdivacky  }
3133198092Srdivacky
3134198092Srdivacky  // Work around bogus GCC warning
3135198893Srdivacky  return true;
3136198092Srdivacky}
3137198092Srdivacky
3138218893Sdim/// \brief Iterator adaptor that invents template argument location information
3139218893Sdim/// for each of the template arguments in its underlying iterator.
3140218893Sdimtemplate<typename Derived, typename InputIterator>
3141218893Sdimclass TemplateArgumentLocInventIterator {
3142218893Sdim  TreeTransform<Derived> &Self;
3143218893Sdim  InputIterator Iter;
3144239462Sdim
3145218893Sdimpublic:
3146218893Sdim  typedef TemplateArgumentLoc value_type;
3147218893Sdim  typedef TemplateArgumentLoc reference;
3148218893Sdim  typedef typename std::iterator_traits<InputIterator>::difference_type
3149218893Sdim    difference_type;
3150218893Sdim  typedef std::input_iterator_tag iterator_category;
3151239462Sdim
3152218893Sdim  class pointer {
3153218893Sdim    TemplateArgumentLoc Arg;
3154239462Sdim
3155218893Sdim  public:
3156218893Sdim    explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
3157239462Sdim
3158218893Sdim    const TemplateArgumentLoc *operator->() const { return &Arg; }
3159218893Sdim  };
3160239462Sdim
3161218893Sdim  TemplateArgumentLocInventIterator() { }
3162239462Sdim
3163218893Sdim  explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
3164218893Sdim                                             InputIterator Iter)
3165218893Sdim    : Self(Self), Iter(Iter) { }
3166239462Sdim
3167218893Sdim  TemplateArgumentLocInventIterator &operator++() {
3168218893Sdim    ++Iter;
3169218893Sdim    return *this;
3170218893Sdim  }
3171239462Sdim
3172218893Sdim  TemplateArgumentLocInventIterator operator++(int) {
3173218893Sdim    TemplateArgumentLocInventIterator Old(*this);
3174218893Sdim    ++(*this);
3175218893Sdim    return Old;
3176218893Sdim  }
3177239462Sdim
3178218893Sdim  reference operator*() const {
3179218893Sdim    TemplateArgumentLoc Result;
3180218893Sdim    Self.InventTemplateArgumentLoc(*Iter, Result);
3181218893Sdim    return Result;
3182218893Sdim  }
3183239462Sdim
3184218893Sdim  pointer operator->() const { return pointer(**this); }
3185239462Sdim
3186218893Sdim  friend bool operator==(const TemplateArgumentLocInventIterator &X,
3187218893Sdim                         const TemplateArgumentLocInventIterator &Y) {
3188218893Sdim    return X.Iter == Y.Iter;
3189218893Sdim  }
3190218893Sdim
3191218893Sdim  friend bool operator!=(const TemplateArgumentLocInventIterator &X,
3192218893Sdim                         const TemplateArgumentLocInventIterator &Y) {
3193218893Sdim    return X.Iter != Y.Iter;
3194218893Sdim  }
3195218893Sdim};
3196239462Sdim
3197218893Sdimtemplate<typename Derived>
3198218893Sdimtemplate<typename InputIterator>
3199218893Sdimbool TreeTransform<Derived>::TransformTemplateArguments(InputIterator First,
3200218893Sdim                                                        InputIterator Last,
3201218893Sdim                                            TemplateArgumentListInfo &Outputs) {
3202218893Sdim  for (; First != Last; ++First) {
3203218893Sdim    TemplateArgumentLoc Out;
3204218893Sdim    TemplateArgumentLoc In = *First;
3205239462Sdim
3206218893Sdim    if (In.getArgument().getKind() == TemplateArgument::Pack) {
3207218893Sdim      // Unpack argument packs, which we translate them into separate
3208218893Sdim      // arguments.
3209218893Sdim      // FIXME: We could do much better if we could guarantee that the
3210218893Sdim      // TemplateArgumentLocInfo for the pack expansion would be usable for
3211218893Sdim      // all of the template arguments in the argument pack.
3212239462Sdim      typedef TemplateArgumentLocInventIterator<Derived,
3213218893Sdim                                                TemplateArgument::pack_iterator>
3214218893Sdim        PackLocIterator;
3215239462Sdim      if (TransformTemplateArguments(PackLocIterator(*this,
3216218893Sdim                                                 In.getArgument().pack_begin()),
3217218893Sdim                                     PackLocIterator(*this,
3218218893Sdim                                                   In.getArgument().pack_end()),
3219218893Sdim                                     Outputs))
3220218893Sdim        return true;
3221239462Sdim
3222218893Sdim      continue;
3223218893Sdim    }
3224239462Sdim
3225218893Sdim    if (In.getArgument().isPackExpansion()) {
3226218893Sdim      // We have a pack expansion, for which we will be substituting into
3227218893Sdim      // the pattern.
3228218893Sdim      SourceLocation Ellipsis;
3229249423Sdim      Optional<unsigned> OrigNumExpansions;
3230218893Sdim      TemplateArgumentLoc Pattern
3231239462Sdim        = In.getPackExpansionPattern(Ellipsis, OrigNumExpansions,
3232218893Sdim                                     getSema().Context);
3233239462Sdim
3234226633Sdim      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
3235218893Sdim      getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
3236218893Sdim      assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
3237239462Sdim
3238218893Sdim      // Determine whether the set of unexpanded parameter packs can and should
3239218893Sdim      // be expanded.
3240218893Sdim      bool Expand = true;
3241218893Sdim      bool RetainExpansion = false;
3242249423Sdim      Optional<unsigned> NumExpansions = OrigNumExpansions;
3243218893Sdim      if (getDerived().TryExpandParameterPacks(Ellipsis,
3244218893Sdim                                               Pattern.getSourceRange(),
3245226633Sdim                                               Unexpanded,
3246239462Sdim                                               Expand,
3247218893Sdim                                               RetainExpansion,
3248218893Sdim                                               NumExpansions))
3249218893Sdim        return true;
3250239462Sdim
3251218893Sdim      if (!Expand) {
3252218893Sdim        // The transform has determined that we should perform a simple
3253239462Sdim        // transformation on the pack expansion, producing another pack
3254218893Sdim        // expansion.
3255218893Sdim        TemplateArgumentLoc OutPattern;
3256218893Sdim        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
3257218893Sdim        if (getDerived().TransformTemplateArgument(Pattern, OutPattern))
3258218893Sdim          return true;
3259239462Sdim
3260218893Sdim        Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
3261218893Sdim                                                NumExpansions);
3262218893Sdim        if (Out.getArgument().isNull())
3263218893Sdim          return true;
3264239462Sdim
3265218893Sdim        Outputs.addArgument(Out);
3266218893Sdim        continue;
3267218893Sdim      }
3268239462Sdim
3269218893Sdim      // The transform has determined that we should perform an elementwise
3270218893Sdim      // expansion of the pattern. Do so.
3271218893Sdim      for (unsigned I = 0; I != *NumExpansions; ++I) {
3272218893Sdim        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
3273218893Sdim
3274218893Sdim        if (getDerived().TransformTemplateArgument(Pattern, Out))
3275218893Sdim          return true;
3276239462Sdim
3277218893Sdim        if (Out.getArgument().containsUnexpandedParameterPack()) {
3278218893Sdim          Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
3279218893Sdim                                                  OrigNumExpansions);
3280218893Sdim          if (Out.getArgument().isNull())
3281218893Sdim            return true;
3282218893Sdim        }
3283239462Sdim
3284218893Sdim        Outputs.addArgument(Out);
3285218893Sdim      }
3286239462Sdim
3287218893Sdim      // If we're supposed to retain a pack expansion, do so by temporarily
3288218893Sdim      // forgetting the partially-substituted parameter pack.
3289218893Sdim      if (RetainExpansion) {
3290218893Sdim        ForgetPartiallySubstitutedPackRAII Forget(getDerived());
3291239462Sdim
3292218893Sdim        if (getDerived().TransformTemplateArgument(Pattern, Out))
3293218893Sdim          return true;
3294239462Sdim
3295218893Sdim        Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
3296218893Sdim                                                OrigNumExpansions);
3297218893Sdim        if (Out.getArgument().isNull())
3298218893Sdim          return true;
3299239462Sdim
3300218893Sdim        Outputs.addArgument(Out);
3301218893Sdim      }
3302239462Sdim
3303218893Sdim      continue;
3304218893Sdim    }
3305239462Sdim
3306239462Sdim    // The simple case:
3307218893Sdim    if (getDerived().TransformTemplateArgument(In, Out))
3308218893Sdim      return true;
3309239462Sdim
3310218893Sdim    Outputs.addArgument(Out);
3311218893Sdim  }
3312239462Sdim
3313218893Sdim  return false;
3314218893Sdim
3315218893Sdim}
3316218893Sdim
3317198092Srdivacky//===----------------------------------------------------------------------===//
3318198092Srdivacky// Type transformation
3319198092Srdivacky//===----------------------------------------------------------------------===//
3320198092Srdivacky
3321198092Srdivackytemplate<typename Derived>
3322218893SdimQualType TreeTransform<Derived>::TransformType(QualType T) {
3323198092Srdivacky  if (getDerived().AlreadyTransformed(T))
3324198092Srdivacky    return T;
3325198092Srdivacky
3326198398Srdivacky  // Temporary workaround.  All of these transformations should
3327198398Srdivacky  // eventually turn into transformations on TypeLocs.
3328218893Sdim  TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
3329218893Sdim                                                getDerived().getBaseLocation());
3330239462Sdim
3331218893Sdim  TypeSourceInfo *NewDI = getDerived().TransformType(DI);
3332198092Srdivacky
3333198398Srdivacky  if (!NewDI)
3334198398Srdivacky    return QualType();
3335198092Srdivacky
3336198398Srdivacky  return NewDI->getType();
3337198092Srdivacky}
3338198092Srdivacky
3339198092Srdivackytemplate<typename Derived>
3340218893SdimTypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
3341234353Sdim  // Refine the base location to the type's location.
3342234353Sdim  TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
3343234353Sdim                       getDerived().getBaseEntity());
3344198398Srdivacky  if (getDerived().AlreadyTransformed(DI->getType()))
3345198398Srdivacky    return DI;
3346198092Srdivacky
3347198398Srdivacky  TypeLocBuilder TLB;
3348198398Srdivacky
3349198398Srdivacky  TypeLoc TL = DI->getTypeLoc();
3350198398Srdivacky  TLB.reserve(TL.getFullDataSize());
3351198398Srdivacky
3352218893Sdim  QualType Result = getDerived().TransformType(TLB, TL);
3353198398Srdivacky  if (Result.isNull())
3354198398Srdivacky    return 0;
3355198398Srdivacky
3356200583Srdivacky  return TLB.getTypeSourceInfo(SemaRef.Context, Result);
3357198092Srdivacky}
3358198092Srdivacky
3359198092Srdivackytemplate<typename Derived>
3360198398SrdivackyQualType
3361218893SdimTreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
3362198398Srdivacky  switch (T.getTypeLocClass()) {
3363198398Srdivacky#define ABSTRACT_TYPELOC(CLASS, PARENT)
3364249423Sdim#define TYPELOC(CLASS, PARENT)                                                 \
3365249423Sdim  case TypeLoc::CLASS:                                                         \
3366249423Sdim    return getDerived().Transform##CLASS##Type(TLB,                            \
3367249423Sdim                                               T.castAs<CLASS##TypeLoc>());
3368198398Srdivacky#include "clang/AST/TypeLocNodes.def"
3369198398Srdivacky  }
3370198092Srdivacky
3371200583Srdivacky  llvm_unreachable("unhandled type loc!");
3372198092Srdivacky}
3373198092Srdivacky
3374198398Srdivacky/// FIXME: By default, this routine adds type qualifiers only to types
3375198398Srdivacky/// that can have qualifiers, and silently suppresses those qualifiers
3376198398Srdivacky/// that are not permitted (e.g., qualifiers on reference or function
3377198398Srdivacky/// types). This is the right thing for template instantiation, but
3378198398Srdivacky/// probably not for other clients.
3379198092Srdivackytemplate<typename Derived>
3380198398SrdivackyQualType
3381198398SrdivackyTreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
3382218893Sdim                                               QualifiedTypeLoc T) {
3383199482Srdivacky  Qualifiers Quals = T.getType().getLocalQualifiers();
3384198092Srdivacky
3385218893Sdim  QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
3386198398Srdivacky  if (Result.isNull())
3387198092Srdivacky    return QualType();
3388198092Srdivacky
3389198398Srdivacky  // Silently suppress qualifiers if the result type can't be qualified.
3390198398Srdivacky  // FIXME: this is the right thing for template instantiation, but
3391198398Srdivacky  // probably not for other clients.
3392198398Srdivacky  if (Result->isFunctionType() || Result->isReferenceType())
3393198398Srdivacky    return Result;
3394198092Srdivacky
3395224145Sdim  // Suppress Objective-C lifetime qualifiers if they don't make sense for the
3396224145Sdim  // resulting type.
3397224145Sdim  if (Quals.hasObjCLifetime()) {
3398224145Sdim    if (!Result->isObjCLifetimeType() && !Result->isDependentType())
3399224145Sdim      Quals.removeObjCLifetime();
3400224145Sdim    else if (Result.getObjCLifetime()) {
3401239462Sdim      // Objective-C ARC:
3402224145Sdim      //   A lifetime qualifier applied to a substituted template parameter
3403224145Sdim      //   overrides the lifetime qualifier from the template argument.
3404249423Sdim      const AutoType *AutoTy;
3405239462Sdim      if (const SubstTemplateTypeParmType *SubstTypeParam
3406224145Sdim                                = dyn_cast<SubstTemplateTypeParmType>(Result)) {
3407224145Sdim        QualType Replacement = SubstTypeParam->getReplacementType();
3408224145Sdim        Qualifiers Qs = Replacement.getQualifiers();
3409224145Sdim        Qs.removeObjCLifetime();
3410239462Sdim        Replacement
3411224145Sdim          = SemaRef.Context.getQualifiedType(Replacement.getUnqualifiedType(),
3412224145Sdim                                             Qs);
3413224145Sdim        Result = SemaRef.Context.getSubstTemplateTypeParmType(
3414239462Sdim                                        SubstTypeParam->getReplacedParameter(),
3415224145Sdim                                                              Replacement);
3416224145Sdim        TLB.TypeWasModifiedSafely(Result);
3417249423Sdim      } else if ((AutoTy = dyn_cast<AutoType>(Result)) && AutoTy->isDeduced()) {
3418249423Sdim        // 'auto' types behave the same way as template parameters.
3419249423Sdim        QualType Deduced = AutoTy->getDeducedType();
3420249423Sdim        Qualifiers Qs = Deduced.getQualifiers();
3421249423Sdim        Qs.removeObjCLifetime();
3422249423Sdim        Deduced = SemaRef.Context.getQualifiedType(Deduced.getUnqualifiedType(),
3423249423Sdim                                                   Qs);
3424251662Sdim        Result = SemaRef.Context.getAutoType(Deduced, AutoTy->isDecltypeAuto());
3425249423Sdim        TLB.TypeWasModifiedSafely(Result);
3426224145Sdim      } else {
3427224145Sdim        // Otherwise, complain about the addition of a qualifier to an
3428224145Sdim        // already-qualified type.
3429224145Sdim        SourceRange R = TLB.getTemporaryTypeLoc(Result).getSourceRange();
3430224145Sdim        SemaRef.Diag(R.getBegin(), diag::err_attr_objc_ownership_redundant)
3431224145Sdim          << Result << R;
3432239462Sdim
3433224145Sdim        Quals.removeObjCLifetime();
3434224145Sdim      }
3435224145Sdim    }
3436224145Sdim  }
3437210299Sed  if (!Quals.empty()) {
3438210299Sed    Result = SemaRef.BuildQualifiedType(Result, T.getBeginLoc(), Quals);
3439249423Sdim    // BuildQualifiedType might not add qualifiers if they are invalid.
3440249423Sdim    if (Result.hasLocalQualifiers())
3441249423Sdim      TLB.push<QualifiedTypeLoc>(Result);
3442210299Sed    // No location information to preserve.
3443210299Sed  }
3444198398Srdivacky
3445198398Srdivacky  return Result;
3446198092Srdivacky}
3447198092Srdivacky
3448218893Sdimtemplate<typename Derived>
3449221345SdimTypeLoc
3450221345SdimTreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
3451218893Sdim                                                   QualType ObjectType,
3452218893Sdim                                                   NamedDecl *UnqualLookup,
3453221345Sdim                                                   CXXScopeSpec &SS) {
3454221345Sdim  QualType T = TL.getType();
3455218893Sdim  if (getDerived().AlreadyTransformed(T))
3456221345Sdim    return TL;
3457239462Sdim
3458218893Sdim  TypeLocBuilder TLB;
3459218893Sdim  QualType Result;
3460239462Sdim
3461218893Sdim  if (isa<TemplateSpecializationType>(T)) {
3462249423Sdim    TemplateSpecializationTypeLoc SpecTL =
3463249423Sdim        TL.castAs<TemplateSpecializationTypeLoc>();
3464239462Sdim
3465218893Sdim    TemplateName Template =
3466221345Sdim      getDerived().TransformTemplateName(SS,
3467221345Sdim                                         SpecTL.getTypePtr()->getTemplateName(),
3468221345Sdim                                         SpecTL.getTemplateNameLoc(),
3469218893Sdim                                         ObjectType, UnqualLookup);
3470239462Sdim    if (Template.isNull())
3471221345Sdim      return TypeLoc();
3472239462Sdim
3473239462Sdim    Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
3474221345Sdim                                                              Template);
3475218893Sdim  } else if (isa<DependentTemplateSpecializationType>(T)) {
3476249423Sdim    DependentTemplateSpecializationTypeLoc SpecTL =
3477249423Sdim        TL.castAs<DependentTemplateSpecializationTypeLoc>();
3478239462Sdim
3479221345Sdim    TemplateName Template
3480239462Sdim      = getDerived().RebuildTemplateName(SS,
3481239462Sdim                                         *SpecTL.getTypePtr()->getIdentifier(),
3482234353Sdim                                         SpecTL.getTemplateNameLoc(),
3483221345Sdim                                         ObjectType, UnqualLookup);
3484221345Sdim    if (Template.isNull())
3485221345Sdim      return TypeLoc();
3486239462Sdim
3487239462Sdim    Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
3488221345Sdim                                                                       SpecTL,
3489221345Sdim                                                                     Template,
3490221345Sdim                                                                       SS);
3491218893Sdim  } else {
3492218893Sdim    // Nothing special needs to be done for these.
3493221345Sdim    Result = getDerived().TransformType(TLB, TL);
3494218893Sdim  }
3495239462Sdim
3496239462Sdim  if (Result.isNull())
3497221345Sdim    return TypeLoc();
3498239462Sdim
3499221345Sdim  return TLB.getTypeSourceInfo(SemaRef.Context, Result)->getTypeLoc();
3500218893Sdim}
3501218893Sdim
3502219077Sdimtemplate<typename Derived>
3503221345SdimTypeSourceInfo *
3504221345SdimTreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
3505219077Sdim                                                   QualType ObjectType,
3506219077Sdim                                                   NamedDecl *UnqualLookup,
3507219077Sdim                                                   CXXScopeSpec &SS) {
3508219077Sdim  // FIXME: Painfully copy-paste from the above!
3509239462Sdim
3510221345Sdim  QualType T = TSInfo->getType();
3511219077Sdim  if (getDerived().AlreadyTransformed(T))
3512221345Sdim    return TSInfo;
3513239462Sdim
3514219077Sdim  TypeLocBuilder TLB;
3515219077Sdim  QualType Result;
3516239462Sdim
3517221345Sdim  TypeLoc TL = TSInfo->getTypeLoc();
3518219077Sdim  if (isa<TemplateSpecializationType>(T)) {
3519249423Sdim    TemplateSpecializationTypeLoc SpecTL =
3520249423Sdim        TL.castAs<TemplateSpecializationTypeLoc>();
3521239462Sdim
3522221345Sdim    TemplateName Template
3523221345Sdim    = getDerived().TransformTemplateName(SS,
3524221345Sdim                                         SpecTL.getTypePtr()->getTemplateName(),
3525221345Sdim                                         SpecTL.getTemplateNameLoc(),
3526219077Sdim                                         ObjectType, UnqualLookup);
3527239462Sdim    if (Template.isNull())
3528221345Sdim      return 0;
3529239462Sdim
3530239462Sdim    Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
3531219077Sdim                                                              Template);
3532219077Sdim  } else if (isa<DependentTemplateSpecializationType>(T)) {
3533249423Sdim    DependentTemplateSpecializationTypeLoc SpecTL =
3534249423Sdim        TL.castAs<DependentTemplateSpecializationTypeLoc>();
3535239462Sdim
3536221345Sdim    TemplateName Template
3537239462Sdim      = getDerived().RebuildTemplateName(SS,
3538239462Sdim                                         *SpecTL.getTypePtr()->getIdentifier(),
3539234353Sdim                                         SpecTL.getTemplateNameLoc(),
3540221345Sdim                                         ObjectType, UnqualLookup);
3541221345Sdim    if (Template.isNull())
3542221345Sdim      return 0;
3543239462Sdim
3544239462Sdim    Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
3545221345Sdim                                                                       SpecTL,
3546221345Sdim                                                                       Template,
3547221345Sdim                                                                       SS);
3548219077Sdim  } else {
3549219077Sdim    // Nothing special needs to be done for these.
3550219077Sdim    Result = getDerived().TransformType(TLB, TL);
3551219077Sdim  }
3552239462Sdim
3553239462Sdim  if (Result.isNull())
3554221345Sdim    return 0;
3555239462Sdim
3556221345Sdim  return TLB.getTypeSourceInfo(SemaRef.Context, Result);
3557219077Sdim}
3558219077Sdim
3559198398Srdivackytemplate <class TyLoc> static inline
3560198398SrdivackyQualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
3561198398Srdivacky  TyLoc NewT = TLB.push<TyLoc>(T.getType());
3562198398Srdivacky  NewT.setNameLoc(T.getNameLoc());
3563198398Srdivacky  return T.getType();
3564198398Srdivacky}
3565198092Srdivacky
3566198398Srdivackytemplate<typename Derived>
3567198398SrdivackyQualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
3568218893Sdim                                                      BuiltinTypeLoc T) {
3569202879Srdivacky  BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
3570202879Srdivacky  NewT.setBuiltinLoc(T.getBuiltinLoc());
3571202879Srdivacky  if (T.needsExtraLocalData())
3572202879Srdivacky    NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
3573202879Srdivacky  return T.getType();
3574198092Srdivacky}
3575198092Srdivacky
3576198092Srdivackytemplate<typename Derived>
3577198398SrdivackyQualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
3578218893Sdim                                                      ComplexTypeLoc T) {
3579198398Srdivacky  // FIXME: recurse?
3580198398Srdivacky  return TransformTypeSpecType(TLB, T);
3581198398Srdivacky}
3582198092Srdivacky
3583198398Srdivackytemplate<typename Derived>
3584198398SrdivackyQualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
3585218893Sdim                                                      PointerTypeLoc TL) {
3586239462Sdim  QualType PointeeType
3587239462Sdim    = getDerived().TransformType(TLB, TL.getPointeeLoc());
3588207619Srdivacky  if (PointeeType.isNull())
3589207619Srdivacky    return QualType();
3590207619Srdivacky
3591207619Srdivacky  QualType Result = TL.getType();
3592208600Srdivacky  if (PointeeType->getAs<ObjCObjectType>()) {
3593207619Srdivacky    // A dependent pointer type 'T *' has is being transformed such
3594207619Srdivacky    // that an Objective-C class type is being replaced for 'T'. The
3595207619Srdivacky    // resulting pointer type is an ObjCObjectPointerType, not a
3596207619Srdivacky    // PointerType.
3597208600Srdivacky    Result = SemaRef.Context.getObjCObjectPointerType(PointeeType);
3598239462Sdim
3599208600Srdivacky    ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
3600208600Srdivacky    NewT.setStarLoc(TL.getStarLoc());
3601207619Srdivacky    return Result;
3602207619Srdivacky  }
3603218893Sdim
3604207619Srdivacky  if (getDerived().AlwaysRebuild() ||
3605207619Srdivacky      PointeeType != TL.getPointeeLoc().getType()) {
3606207619Srdivacky    Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
3607207619Srdivacky    if (Result.isNull())
3608207619Srdivacky      return QualType();
3609207619Srdivacky  }
3610239462Sdim
3611224145Sdim  // Objective-C ARC can add lifetime qualifiers to the type that we're
3612224145Sdim  // pointing to.
3613224145Sdim  TLB.TypeWasModifiedSafely(Result->getPointeeType());
3614239462Sdim
3615207619Srdivacky  PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
3616207619Srdivacky  NewT.setSigilLoc(TL.getSigilLoc());
3617239462Sdim  return Result;
3618198092Srdivacky}
3619198092Srdivacky
3620198092Srdivackytemplate<typename Derived>
3621198092SrdivackyQualType
3622198398SrdivackyTreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
3623218893Sdim                                                  BlockPointerTypeLoc TL) {
3624207619Srdivacky  QualType PointeeType
3625239462Sdim    = getDerived().TransformType(TLB, TL.getPointeeLoc());
3626239462Sdim  if (PointeeType.isNull())
3627239462Sdim    return QualType();
3628239462Sdim
3629239462Sdim  QualType Result = TL.getType();
3630239462Sdim  if (getDerived().AlwaysRebuild() ||
3631239462Sdim      PointeeType != TL.getPointeeLoc().getType()) {
3632239462Sdim    Result = getDerived().RebuildBlockPointerType(PointeeType,
3633207619Srdivacky                                                  TL.getSigilLoc());
3634207619Srdivacky    if (Result.isNull())
3635207619Srdivacky      return QualType();
3636207619Srdivacky  }
3637207619Srdivacky
3638207619Srdivacky  BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
3639207619Srdivacky  NewT.setSigilLoc(TL.getSigilLoc());
3640207619Srdivacky  return Result;
3641198092Srdivacky}
3642198092Srdivacky
3643198893Srdivacky/// Transforms a reference type.  Note that somewhat paradoxically we
3644198893Srdivacky/// don't care whether the type itself is an l-value type or an r-value
3645198893Srdivacky/// type;  we only care if the type was *written* as an l-value type
3646198893Srdivacky/// or an r-value type.
3647198092Srdivackytemplate<typename Derived>
3648198092SrdivackyQualType
3649198893SrdivackyTreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
3650218893Sdim                                               ReferenceTypeLoc TL) {
3651198893Srdivacky  const ReferenceType *T = TL.getTypePtr();
3652198893Srdivacky
3653198893Srdivacky  // Note that this works with the pointee-as-written.
3654198893Srdivacky  QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
3655198893Srdivacky  if (PointeeType.isNull())
3656198893Srdivacky    return QualType();
3657198893Srdivacky
3658198893Srdivacky  QualType Result = TL.getType();
3659198893Srdivacky  if (getDerived().AlwaysRebuild() ||
3660198893Srdivacky      PointeeType != T->getPointeeTypeAsWritten()) {
3661198893Srdivacky    Result = getDerived().RebuildReferenceType(PointeeType,
3662198893Srdivacky                                               T->isSpelledAsLValue(),
3663198893Srdivacky                                               TL.getSigilLoc());
3664198893Srdivacky    if (Result.isNull())
3665198893Srdivacky      return QualType();
3666198893Srdivacky  }
3667198893Srdivacky
3668224145Sdim  // Objective-C ARC can add lifetime qualifiers to the type that we're
3669224145Sdim  // referring to.
3670224145Sdim  TLB.TypeWasModifiedSafely(
3671224145Sdim                     Result->getAs<ReferenceType>()->getPointeeTypeAsWritten());
3672224145Sdim
3673198893Srdivacky  // r-value references can be rebuilt as l-value references.
3674198893Srdivacky  ReferenceTypeLoc NewTL;
3675198893Srdivacky  if (isa<LValueReferenceType>(Result))
3676198893Srdivacky    NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
3677198893Srdivacky  else
3678198893Srdivacky    NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
3679198893Srdivacky  NewTL.setSigilLoc(TL.getSigilLoc());
3680198893Srdivacky
3681198893Srdivacky  return Result;
3682198893Srdivacky}
3683198893Srdivacky
3684198893Srdivackytemplate<typename Derived>
3685198893SrdivackyQualType
3686198398SrdivackyTreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
3687218893Sdim                                                 LValueReferenceTypeLoc TL) {
3688218893Sdim  return TransformReferenceType(TLB, TL);
3689198092Srdivacky}
3690198092Srdivacky
3691198092Srdivackytemplate<typename Derived>
3692198092SrdivackyQualType
3693198398SrdivackyTreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
3694218893Sdim                                                 RValueReferenceTypeLoc TL) {
3695218893Sdim  return TransformReferenceType(TLB, TL);
3696198092Srdivacky}
3697198092Srdivacky
3698198092Srdivackytemplate<typename Derived>
3699198092SrdivackyQualType
3700198398SrdivackyTreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
3701218893Sdim                                                   MemberPointerTypeLoc TL) {
3702198398Srdivacky  QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
3703198398Srdivacky  if (PointeeType.isNull())
3704198092Srdivacky    return QualType();
3705198092Srdivacky
3706221345Sdim  TypeSourceInfo* OldClsTInfo = TL.getClassTInfo();
3707221345Sdim  TypeSourceInfo* NewClsTInfo = 0;
3708221345Sdim  if (OldClsTInfo) {
3709221345Sdim    NewClsTInfo = getDerived().TransformType(OldClsTInfo);
3710221345Sdim    if (!NewClsTInfo)
3711221345Sdim      return QualType();
3712221345Sdim  }
3713198092Srdivacky
3714221345Sdim  const MemberPointerType *T = TL.getTypePtr();
3715221345Sdim  QualType OldClsType = QualType(T->getClass(), 0);
3716221345Sdim  QualType NewClsType;
3717221345Sdim  if (NewClsTInfo)
3718221345Sdim    NewClsType = NewClsTInfo->getType();
3719221345Sdim  else {
3720221345Sdim    NewClsType = getDerived().TransformType(OldClsType);
3721221345Sdim    if (NewClsType.isNull())
3722221345Sdim      return QualType();
3723221345Sdim  }
3724221345Sdim
3725198398Srdivacky  QualType Result = TL.getType();
3726198398Srdivacky  if (getDerived().AlwaysRebuild() ||
3727198398Srdivacky      PointeeType != T->getPointeeType() ||
3728221345Sdim      NewClsType != OldClsType) {
3729221345Sdim    Result = getDerived().RebuildMemberPointerType(PointeeType, NewClsType,
3730198893Srdivacky                                                   TL.getStarLoc());
3731198398Srdivacky    if (Result.isNull())
3732198398Srdivacky      return QualType();
3733198398Srdivacky  }
3734198092Srdivacky
3735198398Srdivacky  MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
3736198398Srdivacky  NewTL.setSigilLoc(TL.getSigilLoc());
3737221345Sdim  NewTL.setClassTInfo(NewClsTInfo);
3738198398Srdivacky
3739198398Srdivacky  return Result;
3740198092Srdivacky}
3741198092Srdivacky
3742198092Srdivackytemplate<typename Derived>
3743198092SrdivackyQualType
3744198398SrdivackyTreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
3745218893Sdim                                                   ConstantArrayTypeLoc TL) {
3746218893Sdim  const ConstantArrayType *T = TL.getTypePtr();
3747198398Srdivacky  QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
3748198092Srdivacky  if (ElementType.isNull())
3749198092Srdivacky    return QualType();
3750198092Srdivacky
3751198398Srdivacky  QualType Result = TL.getType();
3752198398Srdivacky  if (getDerived().AlwaysRebuild() ||
3753198398Srdivacky      ElementType != T->getElementType()) {
3754198398Srdivacky    Result = getDerived().RebuildConstantArrayType(ElementType,
3755198398Srdivacky                                                   T->getSizeModifier(),
3756198398Srdivacky                                                   T->getSize(),
3757198893Srdivacky                                             T->getIndexTypeCVRQualifiers(),
3758198893Srdivacky                                                   TL.getBracketsRange());
3759198398Srdivacky    if (Result.isNull())
3760198398Srdivacky      return QualType();
3761198398Srdivacky  }
3762234353Sdim
3763234353Sdim  // We might have either a ConstantArrayType or a VariableArrayType now:
3764234353Sdim  // a ConstantArrayType is allowed to have an element type which is a
3765234353Sdim  // VariableArrayType if the type is dependent.  Fortunately, all array
3766234353Sdim  // types have the same location layout.
3767234353Sdim  ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
3768198398Srdivacky  NewTL.setLBracketLoc(TL.getLBracketLoc());
3769198398Srdivacky  NewTL.setRBracketLoc(TL.getRBracketLoc());
3770198092Srdivacky
3771198398Srdivacky  Expr *Size = TL.getSizeExpr();
3772198398Srdivacky  if (Size) {
3773234353Sdim    EnterExpressionEvaluationContext Unevaluated(SemaRef,
3774234353Sdim                                                 Sema::ConstantEvaluated);
3775198398Srdivacky    Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
3776234353Sdim    Size = SemaRef.ActOnConstantExpression(Size).take();
3777198398Srdivacky  }
3778198398Srdivacky  NewTL.setSizeExpr(Size);
3779198398Srdivacky
3780198398Srdivacky  return Result;
3781198092Srdivacky}
3782198092Srdivacky
3783198092Srdivackytemplate<typename Derived>
3784198092SrdivackyQualType TreeTransform<Derived>::TransformIncompleteArrayType(
3785198398Srdivacky                                              TypeLocBuilder &TLB,
3786218893Sdim                                              IncompleteArrayTypeLoc TL) {
3787218893Sdim  const IncompleteArrayType *T = TL.getTypePtr();
3788198398Srdivacky  QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
3789198092Srdivacky  if (ElementType.isNull())
3790198092Srdivacky    return QualType();
3791198092Srdivacky
3792198398Srdivacky  QualType Result = TL.getType();
3793198398Srdivacky  if (getDerived().AlwaysRebuild() ||
3794198398Srdivacky      ElementType != T->getElementType()) {
3795198398Srdivacky    Result = getDerived().RebuildIncompleteArrayType(ElementType,
3796198398Srdivacky                                                     T->getSizeModifier(),
3797198893Srdivacky                                           T->getIndexTypeCVRQualifiers(),
3798198893Srdivacky                                                     TL.getBracketsRange());
3799198398Srdivacky    if (Result.isNull())
3800198398Srdivacky      return QualType();
3801198398Srdivacky  }
3802239462Sdim
3803198398Srdivacky  IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
3804198398Srdivacky  NewTL.setLBracketLoc(TL.getLBracketLoc());
3805198398Srdivacky  NewTL.setRBracketLoc(TL.getRBracketLoc());
3806198398Srdivacky  NewTL.setSizeExpr(0);
3807198092Srdivacky
3808198398Srdivacky  return Result;
3809198092Srdivacky}
3810198092Srdivacky
3811198092Srdivackytemplate<typename Derived>
3812198398SrdivackyQualType
3813198398SrdivackyTreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
3814218893Sdim                                                   VariableArrayTypeLoc TL) {
3815218893Sdim  const VariableArrayType *T = TL.getTypePtr();
3816198398Srdivacky  QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
3817198092Srdivacky  if (ElementType.isNull())
3818198092Srdivacky    return QualType();
3819198092Srdivacky
3820212904Sdim  ExprResult SizeResult
3821198398Srdivacky    = getDerived().TransformExpr(T->getSizeExpr());
3822198398Srdivacky  if (SizeResult.isInvalid())
3823198092Srdivacky    return QualType();
3824198092Srdivacky
3825212904Sdim  Expr *Size = SizeResult.take();
3826198398Srdivacky
3827198398Srdivacky  QualType Result = TL.getType();
3828198398Srdivacky  if (getDerived().AlwaysRebuild() ||
3829198398Srdivacky      ElementType != T->getElementType() ||
3830198398Srdivacky      Size != T->getSizeExpr()) {
3831198398Srdivacky    Result = getDerived().RebuildVariableArrayType(ElementType,
3832198398Srdivacky                                                   T->getSizeModifier(),
3833212904Sdim                                                   Size,
3834198398Srdivacky                                             T->getIndexTypeCVRQualifiers(),
3835198893Srdivacky                                                   TL.getBracketsRange());
3836198398Srdivacky    if (Result.isNull())
3837198398Srdivacky      return QualType();
3838198092Srdivacky  }
3839239462Sdim
3840198398Srdivacky  VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
3841198398Srdivacky  NewTL.setLBracketLoc(TL.getLBracketLoc());
3842198398Srdivacky  NewTL.setRBracketLoc(TL.getRBracketLoc());
3843198398Srdivacky  NewTL.setSizeExpr(Size);
3844198092Srdivacky
3845198398Srdivacky  return Result;
3846198092Srdivacky}
3847198092Srdivacky
3848198092Srdivackytemplate<typename Derived>
3849198398SrdivackyQualType
3850198398SrdivackyTreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
3851218893Sdim                                             DependentSizedArrayTypeLoc TL) {
3852218893Sdim  const DependentSizedArrayType *T = TL.getTypePtr();
3853198398Srdivacky  QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
3854198092Srdivacky  if (ElementType.isNull())
3855198092Srdivacky    return QualType();
3856198092Srdivacky
3857234353Sdim  // Array bounds are constant expressions.
3858234353Sdim  EnterExpressionEvaluationContext Unevaluated(SemaRef,
3859234353Sdim                                               Sema::ConstantEvaluated);
3860198092Srdivacky
3861218893Sdim  // Prefer the expression from the TypeLoc;  the other may have been uniqued.
3862218893Sdim  Expr *origSize = TL.getSizeExpr();
3863218893Sdim  if (!origSize) origSize = T->getSizeExpr();
3864218893Sdim
3865218893Sdim  ExprResult sizeResult
3866218893Sdim    = getDerived().TransformExpr(origSize);
3867234353Sdim  sizeResult = SemaRef.ActOnConstantExpression(sizeResult);
3868218893Sdim  if (sizeResult.isInvalid())
3869198092Srdivacky    return QualType();
3870198092Srdivacky
3871218893Sdim  Expr *size = sizeResult.get();
3872198398Srdivacky
3873198398Srdivacky  QualType Result = TL.getType();
3874198398Srdivacky  if (getDerived().AlwaysRebuild() ||
3875198398Srdivacky      ElementType != T->getElementType() ||
3876218893Sdim      size != origSize) {
3877198398Srdivacky    Result = getDerived().RebuildDependentSizedArrayType(ElementType,
3878198398Srdivacky                                                         T->getSizeModifier(),
3879218893Sdim                                                         size,
3880198398Srdivacky                                                T->getIndexTypeCVRQualifiers(),
3881198893Srdivacky                                                        TL.getBracketsRange());
3882198398Srdivacky    if (Result.isNull())
3883198398Srdivacky      return QualType();
3884198092Srdivacky  }
3885198092Srdivacky
3886198398Srdivacky  // We might have any sort of array type now, but fortunately they
3887198398Srdivacky  // all have the same location layout.
3888198398Srdivacky  ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
3889198398Srdivacky  NewTL.setLBracketLoc(TL.getLBracketLoc());
3890198398Srdivacky  NewTL.setRBracketLoc(TL.getRBracketLoc());
3891218893Sdim  NewTL.setSizeExpr(size);
3892198398Srdivacky
3893198398Srdivacky  return Result;
3894198092Srdivacky}
3895198092Srdivacky
3896198092Srdivackytemplate<typename Derived>
3897198092SrdivackyQualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
3898198398Srdivacky                                      TypeLocBuilder &TLB,
3899218893Sdim                                      DependentSizedExtVectorTypeLoc TL) {
3900218893Sdim  const DependentSizedExtVectorType *T = TL.getTypePtr();
3901198398Srdivacky
3902198398Srdivacky  // FIXME: ext vector locs should be nested
3903198092Srdivacky  QualType ElementType = getDerived().TransformType(T->getElementType());
3904198092Srdivacky  if (ElementType.isNull())
3905198092Srdivacky    return QualType();
3906198092Srdivacky
3907234353Sdim  // Vector sizes are constant expressions.
3908234353Sdim  EnterExpressionEvaluationContext Unevaluated(SemaRef,
3909234353Sdim                                               Sema::ConstantEvaluated);
3910198092Srdivacky
3911212904Sdim  ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
3912234353Sdim  Size = SemaRef.ActOnConstantExpression(Size);
3913198092Srdivacky  if (Size.isInvalid())
3914198092Srdivacky    return QualType();
3915198092Srdivacky
3916198398Srdivacky  QualType Result = TL.getType();
3917198398Srdivacky  if (getDerived().AlwaysRebuild() ||
3918198893Srdivacky      ElementType != T->getElementType() ||
3919198893Srdivacky      Size.get() != T->getSizeExpr()) {
3920198398Srdivacky    Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
3921212904Sdim                                                             Size.take(),
3922198398Srdivacky                                                         T->getAttributeLoc());
3923198398Srdivacky    if (Result.isNull())
3924198398Srdivacky      return QualType();
3925198092Srdivacky  }
3926198092Srdivacky
3927198398Srdivacky  // Result might be dependent or not.
3928198398Srdivacky  if (isa<DependentSizedExtVectorType>(Result)) {
3929198398Srdivacky    DependentSizedExtVectorTypeLoc NewTL
3930198398Srdivacky      = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
3931198398Srdivacky    NewTL.setNameLoc(TL.getNameLoc());
3932198398Srdivacky  } else {
3933198398Srdivacky    ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
3934198398Srdivacky    NewTL.setNameLoc(TL.getNameLoc());
3935198398Srdivacky  }
3936198398Srdivacky
3937198398Srdivacky  return Result;
3938198092Srdivacky}
3939198092Srdivacky
3940198092Srdivackytemplate<typename Derived>
3941198398SrdivackyQualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
3942218893Sdim                                                     VectorTypeLoc TL) {
3943218893Sdim  const VectorType *T = TL.getTypePtr();
3944198092Srdivacky  QualType ElementType = getDerived().TransformType(T->getElementType());
3945198092Srdivacky  if (ElementType.isNull())
3946198092Srdivacky    return QualType();
3947198092Srdivacky
3948198398Srdivacky  QualType Result = TL.getType();
3949198398Srdivacky  if (getDerived().AlwaysRebuild() ||
3950198398Srdivacky      ElementType != T->getElementType()) {
3951203955Srdivacky    Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
3952218893Sdim                                            T->getVectorKind());
3953198398Srdivacky    if (Result.isNull())
3954198398Srdivacky      return QualType();
3955198398Srdivacky  }
3956239462Sdim
3957198398Srdivacky  VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
3958198398Srdivacky  NewTL.setNameLoc(TL.getNameLoc());
3959198092Srdivacky
3960198398Srdivacky  return Result;
3961198092Srdivacky}
3962198092Srdivacky
3963198092Srdivackytemplate<typename Derived>
3964198398SrdivackyQualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
3965218893Sdim                                                        ExtVectorTypeLoc TL) {
3966218893Sdim  const VectorType *T = TL.getTypePtr();
3967198092Srdivacky  QualType ElementType = getDerived().TransformType(T->getElementType());
3968198092Srdivacky  if (ElementType.isNull())
3969198092Srdivacky    return QualType();
3970198092Srdivacky
3971198398Srdivacky  QualType Result = TL.getType();
3972198398Srdivacky  if (getDerived().AlwaysRebuild() ||
3973198398Srdivacky      ElementType != T->getElementType()) {
3974198398Srdivacky    Result = getDerived().RebuildExtVectorType(ElementType,
3975198398Srdivacky                                               T->getNumElements(),
3976198398Srdivacky                                               /*FIXME*/ SourceLocation());
3977198398Srdivacky    if (Result.isNull())
3978198398Srdivacky      return QualType();
3979198398Srdivacky  }
3980239462Sdim
3981198398Srdivacky  ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
3982198398Srdivacky  NewTL.setNameLoc(TL.getNameLoc());
3983198092Srdivacky
3984198398Srdivacky  return Result;
3985198092Srdivacky}
3986198092Srdivacky
3987249423Sdimtemplate <typename Derived>
3988249423SdimParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
3989249423Sdim    ParmVarDecl *OldParm, int indexAdjustment, Optional<unsigned> NumExpansions,
3990249423Sdim    bool ExpectParameterPack) {
3991205219Srdivacky  TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
3992218893Sdim  TypeSourceInfo *NewDI = 0;
3993239462Sdim
3994218893Sdim  if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
3995239462Sdim    // If we're substituting into a pack expansion type and we know the
3996234353Sdim    // length we want to expand to, just substitute for the pattern.
3997218893Sdim    TypeLoc OldTL = OldDI->getTypeLoc();
3998249423Sdim    PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
3999239462Sdim
4000218893Sdim    TypeLocBuilder TLB;
4001218893Sdim    TypeLoc NewTL = OldDI->getTypeLoc();
4002218893Sdim    TLB.reserve(NewTL.getFullDataSize());
4003239462Sdim
4004239462Sdim    QualType Result = getDerived().TransformType(TLB,
4005218893Sdim                                               OldExpansionTL.getPatternLoc());
4006218893Sdim    if (Result.isNull())
4007218893Sdim      return 0;
4008239462Sdim
4009239462Sdim    Result = RebuildPackExpansionType(Result,
4010239462Sdim                                OldExpansionTL.getPatternLoc().getSourceRange(),
4011218893Sdim                                      OldExpansionTL.getEllipsisLoc(),
4012218893Sdim                                      NumExpansions);
4013218893Sdim    if (Result.isNull())
4014218893Sdim      return 0;
4015239462Sdim
4016218893Sdim    PackExpansionTypeLoc NewExpansionTL
4017218893Sdim      = TLB.push<PackExpansionTypeLoc>(Result);
4018218893Sdim    NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
4019218893Sdim    NewDI = TLB.getTypeSourceInfo(SemaRef.Context, Result);
4020218893Sdim  } else
4021218893Sdim    NewDI = getDerived().TransformType(OldDI);
4022205219Srdivacky  if (!NewDI)
4023205219Srdivacky    return 0;
4024205219Srdivacky
4025221345Sdim  if (NewDI == OldDI && indexAdjustment == 0)
4026205219Srdivacky    return OldParm;
4027221345Sdim
4028221345Sdim  ParmVarDecl *newParm = ParmVarDecl::Create(SemaRef.Context,
4029221345Sdim                                             OldParm->getDeclContext(),
4030221345Sdim                                             OldParm->getInnerLocStart(),
4031221345Sdim                                             OldParm->getLocation(),
4032221345Sdim                                             OldParm->getIdentifier(),
4033221345Sdim                                             NewDI->getType(),
4034221345Sdim                                             NewDI,
4035221345Sdim                                             OldParm->getStorageClass(),
4036221345Sdim                                             /* DefArg */ NULL);
4037221345Sdim  newParm->setScopeInfo(OldParm->getFunctionScopeDepth(),
4038221345Sdim                        OldParm->getFunctionScopeIndex() + indexAdjustment);
4039221345Sdim  return newParm;
4040205219Srdivacky}
4041205219Srdivacky
4042205219Srdivackytemplate<typename Derived>
4043205219Srdivackybool TreeTransform<Derived>::
4044218893Sdim  TransformFunctionTypeParams(SourceLocation Loc,
4045218893Sdim                              ParmVarDecl **Params, unsigned NumParams,
4046218893Sdim                              const QualType *ParamTypes,
4047226633Sdim                              SmallVectorImpl<QualType> &OutParamTypes,
4048226633Sdim                              SmallVectorImpl<ParmVarDecl*> *PVars) {
4049221345Sdim  int indexAdjustment = 0;
4050221345Sdim
4051218893Sdim  for (unsigned i = 0; i != NumParams; ++i) {
4052218893Sdim    if (ParmVarDecl *OldParm = Params[i]) {
4053221345Sdim      assert(OldParm->getFunctionScopeIndex() == i);
4054221345Sdim
4055249423Sdim      Optional<unsigned> NumExpansions;
4056221345Sdim      ParmVarDecl *NewParm = 0;
4057218893Sdim      if (OldParm->isParameterPack()) {
4058218893Sdim        // We have a function parameter pack that may need to be expanded.
4059226633Sdim        SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4060198092Srdivacky
4061218893Sdim        // Find the parameter packs that could be expanded.
4062218893Sdim        TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
4063249423Sdim        PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
4064218893Sdim        TypeLoc Pattern = ExpansionTL.getPatternLoc();
4065218893Sdim        SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
4066221345Sdim        assert(Unexpanded.size() > 0 && "Could not find parameter packs!");
4067221345Sdim
4068218893Sdim        // Determine whether we should expand the parameter packs.
4069218893Sdim        bool ShouldExpand = false;
4070218893Sdim        bool RetainExpansion = false;
4071249423Sdim        Optional<unsigned> OrigNumExpansions =
4072249423Sdim            ExpansionTL.getTypePtr()->getNumExpansions();
4073218893Sdim        NumExpansions = OrigNumExpansions;
4074218893Sdim        if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
4075218893Sdim                                                 Pattern.getSourceRange(),
4076239462Sdim                                                 Unexpanded,
4077239462Sdim                                                 ShouldExpand,
4078218893Sdim                                                 RetainExpansion,
4079218893Sdim                                                 NumExpansions)) {
4080218893Sdim          return true;
4081218893Sdim        }
4082239462Sdim
4083218893Sdim        if (ShouldExpand) {
4084218893Sdim          // Expand the function parameter pack into multiple, separate
4085218893Sdim          // parameters.
4086218893Sdim          getDerived().ExpandingFunctionParameterPack(OldParm);
4087218893Sdim          for (unsigned I = 0; I != *NumExpansions; ++I) {
4088218893Sdim            Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4089239462Sdim            ParmVarDecl *NewParm
4090218893Sdim              = getDerived().TransformFunctionTypeParam(OldParm,
4091221345Sdim                                                        indexAdjustment++,
4092234353Sdim                                                        OrigNumExpansions,
4093234353Sdim                                                /*ExpectParameterPack=*/false);
4094218893Sdim            if (!NewParm)
4095218893Sdim              return true;
4096239462Sdim
4097218893Sdim            OutParamTypes.push_back(NewParm->getType());
4098218893Sdim            if (PVars)
4099218893Sdim              PVars->push_back(NewParm);
4100218893Sdim          }
4101198092Srdivacky
4102218893Sdim          // If we're supposed to retain a pack expansion, do so by temporarily
4103218893Sdim          // forgetting the partially-substituted parameter pack.
4104218893Sdim          if (RetainExpansion) {
4105218893Sdim            ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4106239462Sdim            ParmVarDecl *NewParm
4107218893Sdim              = getDerived().TransformFunctionTypeParam(OldParm,
4108221345Sdim                                                        indexAdjustment++,
4109234353Sdim                                                        OrigNumExpansions,
4110234353Sdim                                                /*ExpectParameterPack=*/false);
4111218893Sdim            if (!NewParm)
4112218893Sdim              return true;
4113239462Sdim
4114218893Sdim            OutParamTypes.push_back(NewParm->getType());
4115218893Sdim            if (PVars)
4116218893Sdim              PVars->push_back(NewParm);
4117218893Sdim          }
4118198398Srdivacky
4119221345Sdim          // The next parameter should have the same adjustment as the
4120221345Sdim          // last thing we pushed, but we post-incremented indexAdjustment
4121221345Sdim          // on every push.  Also, if we push nothing, the adjustment should
4122221345Sdim          // go down by one.
4123221345Sdim          indexAdjustment--;
4124221345Sdim
4125218893Sdim          // We're done with the pack expansion.
4126218893Sdim          continue;
4127218893Sdim        }
4128239462Sdim
4129239462Sdim        // We'll substitute the parameter now without expanding the pack
4130218893Sdim        // expansion.
4131221345Sdim        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4132221345Sdim        NewParm = getDerived().TransformFunctionTypeParam(OldParm,
4133221345Sdim                                                          indexAdjustment,
4134234353Sdim                                                          NumExpansions,
4135234353Sdim                                                  /*ExpectParameterPack=*/true);
4136221345Sdim      } else {
4137249423Sdim        NewParm = getDerived().TransformFunctionTypeParam(
4138249423Sdim            OldParm, indexAdjustment, None, /*ExpectParameterPack=*/ false);
4139218893Sdim      }
4140221345Sdim
4141205219Srdivacky      if (!NewParm)
4142205219Srdivacky        return true;
4143239462Sdim
4144218893Sdim      OutParamTypes.push_back(NewParm->getType());
4145218893Sdim      if (PVars)
4146218893Sdim        PVars->push_back(NewParm);
4147218893Sdim      continue;
4148218893Sdim    }
4149198398Srdivacky
4150198398Srdivacky    // Deal with the possibility that we don't have a parameter
4151198398Srdivacky    // declaration for this parameter.
4152218893Sdim    QualType OldType = ParamTypes[i];
4153218893Sdim    bool IsPackExpansion = false;
4154249423Sdim    Optional<unsigned> NumExpansions;
4155221345Sdim    QualType NewType;
4156239462Sdim    if (const PackExpansionType *Expansion
4157218893Sdim                                       = dyn_cast<PackExpansionType>(OldType)) {
4158218893Sdim      // We have a function parameter pack that may need to be expanded.
4159218893Sdim      QualType Pattern = Expansion->getPattern();
4160226633Sdim      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4161218893Sdim      getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4162239462Sdim
4163218893Sdim      // Determine whether we should expand the parameter packs.
4164218893Sdim      bool ShouldExpand = false;
4165218893Sdim      bool RetainExpansion = false;
4166218893Sdim      if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
4167239462Sdim                                               Unexpanded,
4168239462Sdim                                               ShouldExpand,
4169218893Sdim                                               RetainExpansion,
4170218893Sdim                                               NumExpansions)) {
4171218893Sdim        return true;
4172218893Sdim      }
4173239462Sdim
4174218893Sdim      if (ShouldExpand) {
4175239462Sdim        // Expand the function parameter pack into multiple, separate
4176218893Sdim        // parameters.
4177218893Sdim        for (unsigned I = 0; I != *NumExpansions; ++I) {
4178218893Sdim          Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
4179218893Sdim          QualType NewType = getDerived().TransformType(Pattern);
4180218893Sdim          if (NewType.isNull())
4181218893Sdim            return true;
4182198398Srdivacky
4183218893Sdim          OutParamTypes.push_back(NewType);
4184218893Sdim          if (PVars)
4185218893Sdim            PVars->push_back(0);
4186218893Sdim        }
4187239462Sdim
4188218893Sdim        // We're done with the pack expansion.
4189218893Sdim        continue;
4190218893Sdim      }
4191239462Sdim
4192218893Sdim      // If we're supposed to retain a pack expansion, do so by temporarily
4193218893Sdim      // forgetting the partially-substituted parameter pack.
4194218893Sdim      if (RetainExpansion) {
4195218893Sdim        ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4196218893Sdim        QualType NewType = getDerived().TransformType(Pattern);
4197218893Sdim        if (NewType.isNull())
4198218893Sdim          return true;
4199239462Sdim
4200218893Sdim        OutParamTypes.push_back(NewType);
4201218893Sdim        if (PVars)
4202218893Sdim          PVars->push_back(0);
4203218893Sdim      }
4204218893Sdim
4205239462Sdim      // We'll substitute the parameter now without expanding the pack
4206218893Sdim      // expansion.
4207218893Sdim      OldType = Expansion->getPattern();
4208218893Sdim      IsPackExpansion = true;
4209221345Sdim      Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
4210221345Sdim      NewType = getDerived().TransformType(OldType);
4211221345Sdim    } else {
4212221345Sdim      NewType = getDerived().TransformType(OldType);
4213198398Srdivacky    }
4214239462Sdim
4215218893Sdim    if (NewType.isNull())
4216218893Sdim      return true;
4217198398Srdivacky
4218218893Sdim    if (IsPackExpansion)
4219218893Sdim      NewType = getSema().Context.getPackExpansionType(NewType,
4220218893Sdim                                                       NumExpansions);
4221239462Sdim
4222218893Sdim    OutParamTypes.push_back(NewType);
4223218893Sdim    if (PVars)
4224218893Sdim      PVars->push_back(0);
4225198092Srdivacky  }
4226198092Srdivacky
4227221345Sdim#ifndef NDEBUG
4228221345Sdim  if (PVars) {
4229221345Sdim    for (unsigned i = 0, e = PVars->size(); i != e; ++i)
4230221345Sdim      if (ParmVarDecl *parm = (*PVars)[i])
4231221345Sdim        assert(parm->getFunctionScopeIndex() == i);
4232218893Sdim  }
4233221345Sdim#endif
4234205219Srdivacky
4235221345Sdim  return false;
4236221345Sdim}
4237221345Sdim
4238205219Srdivackytemplate<typename Derived>
4239205219SrdivackyQualType
4240205219SrdivackyTreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
4241218893Sdim                                                   FunctionProtoTypeLoc TL) {
4242234982Sdim  return getDerived().TransformFunctionProtoType(TLB, TL, 0, 0);
4243234982Sdim}
4244234982Sdim
4245234982Sdimtemplate<typename Derived>
4246234982SdimQualType
4247234982SdimTreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
4248234982Sdim                                                   FunctionProtoTypeLoc TL,
4249234982Sdim                                                   CXXRecordDecl *ThisContext,
4250234982Sdim                                                   unsigned ThisTypeQuals) {
4251212904Sdim  // Transform the parameters and return type.
4252212904Sdim  //
4253234982Sdim  // We are required to instantiate the params and return type in source order.
4254218893Sdim  // When the function has a trailing return type, we instantiate the
4255218893Sdim  // parameters before the return type,  since the return type can then refer
4256218893Sdim  // to the parameters themselves (via decltype, sizeof, etc.).
4257218893Sdim  //
4258226633Sdim  SmallVector<QualType, 4> ParamTypes;
4259226633Sdim  SmallVector<ParmVarDecl*, 4> ParamDecls;
4260218893Sdim  const FunctionProtoType *T = TL.getTypePtr();
4261212904Sdim
4262218893Sdim  QualType ResultType;
4263218893Sdim
4264239462Sdim  if (T->hasTrailingReturn()) {
4265239462Sdim    if (getDerived().TransformFunctionTypeParams(TL.getBeginLoc(),
4266218893Sdim                                                 TL.getParmArray(),
4267218893Sdim                                                 TL.getNumArgs(),
4268239462Sdim                                             TL.getTypePtr()->arg_type_begin(),
4269218893Sdim                                                 ParamTypes, &ParamDecls))
4270218893Sdim      return QualType();
4271218893Sdim
4272234982Sdim    {
4273234982Sdim      // C++11 [expr.prim.general]p3:
4274239462Sdim      //   If a declaration declares a member function or member function
4275239462Sdim      //   template of a class X, the expression this is a prvalue of type
4276234982Sdim      //   "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
4277239462Sdim      //   and the end of the function-definition, member-declarator, or
4278234982Sdim      //   declarator.
4279234982Sdim      Sema::CXXThisScopeRAII ThisScope(SemaRef, ThisContext, ThisTypeQuals);
4280239462Sdim
4281234982Sdim      ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
4282234982Sdim      if (ResultType.isNull())
4283234982Sdim        return QualType();
4284234982Sdim    }
4285218893Sdim  }
4286218893Sdim  else {
4287218893Sdim    ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
4288218893Sdim    if (ResultType.isNull())
4289218893Sdim      return QualType();
4290218893Sdim
4291239462Sdim    if (getDerived().TransformFunctionTypeParams(TL.getBeginLoc(),
4292218893Sdim                                                 TL.getParmArray(),
4293218893Sdim                                                 TL.getNumArgs(),
4294239462Sdim                                             TL.getTypePtr()->arg_type_begin(),
4295218893Sdim                                                 ParamTypes, &ParamDecls))
4296218893Sdim      return QualType();
4297218893Sdim  }
4298218893Sdim
4299234982Sdim  // FIXME: Need to transform the exception-specification too.
4300234982Sdim
4301198398Srdivacky  QualType Result = TL.getType();
4302198398Srdivacky  if (getDerived().AlwaysRebuild() ||
4303198398Srdivacky      ResultType != T->getResultType() ||
4304218893Sdim      T->getNumArgs() != ParamTypes.size() ||
4305198398Srdivacky      !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
4306249423Sdim    Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes,
4307249423Sdim                                                   T->getExtProtoInfo());
4308198398Srdivacky    if (Result.isNull())
4309198398Srdivacky      return QualType();
4310198398Srdivacky  }
4311198092Srdivacky
4312198398Srdivacky  FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
4313221345Sdim  NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
4314243830Sdim  NewTL.setLParenLoc(TL.getLParenLoc());
4315243830Sdim  NewTL.setRParenLoc(TL.getRParenLoc());
4316221345Sdim  NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
4317198398Srdivacky  for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
4318198398Srdivacky    NewTL.setArg(i, ParamDecls[i]);
4319198398Srdivacky
4320198398Srdivacky  return Result;
4321198092Srdivacky}
4322198092Srdivacky
4323198092Srdivackytemplate<typename Derived>
4324198092SrdivackyQualType TreeTransform<Derived>::TransformFunctionNoProtoType(
4325198398Srdivacky                                                 TypeLocBuilder &TLB,
4326218893Sdim                                                 FunctionNoProtoTypeLoc TL) {
4327218893Sdim  const FunctionNoProtoType *T = TL.getTypePtr();
4328198398Srdivacky  QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
4329198398Srdivacky  if (ResultType.isNull())
4330198398Srdivacky    return QualType();
4331198398Srdivacky
4332198398Srdivacky  QualType Result = TL.getType();
4333198398Srdivacky  if (getDerived().AlwaysRebuild() ||
4334198398Srdivacky      ResultType != T->getResultType())
4335198398Srdivacky    Result = getDerived().RebuildFunctionNoProtoType(ResultType);
4336198398Srdivacky
4337198398Srdivacky  FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
4338221345Sdim  NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
4339243830Sdim  NewTL.setLParenLoc(TL.getLParenLoc());
4340243830Sdim  NewTL.setRParenLoc(TL.getRParenLoc());
4341221345Sdim  NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
4342198398Srdivacky
4343198398Srdivacky  return Result;
4344198092Srdivacky}
4345198092Srdivacky
4346200583Srdivackytemplate<typename Derived> QualType
4347200583SrdivackyTreeTransform<Derived>::TransformUnresolvedUsingType(TypeLocBuilder &TLB,
4348218893Sdim                                                 UnresolvedUsingTypeLoc TL) {
4349218893Sdim  const UnresolvedUsingType *T = TL.getTypePtr();
4350204643Srdivacky  Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
4351200583Srdivacky  if (!D)
4352200583Srdivacky    return QualType();
4353200583Srdivacky
4354200583Srdivacky  QualType Result = TL.getType();
4355200583Srdivacky  if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
4356200583Srdivacky    Result = getDerived().RebuildUnresolvedUsingType(D);
4357200583Srdivacky    if (Result.isNull())
4358200583Srdivacky      return QualType();
4359200583Srdivacky  }
4360200583Srdivacky
4361200583Srdivacky  // We might get an arbitrary type spec type back.  We should at
4362200583Srdivacky  // least always get a type spec type, though.
4363200583Srdivacky  TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result);
4364200583Srdivacky  NewTL.setNameLoc(TL.getNameLoc());
4365200583Srdivacky
4366200583Srdivacky  return Result;
4367200583Srdivacky}
4368200583Srdivacky
4369198092Srdivackytemplate<typename Derived>
4370198398SrdivackyQualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
4371218893Sdim                                                      TypedefTypeLoc TL) {
4372218893Sdim  const TypedefType *T = TL.getTypePtr();
4373221345Sdim  TypedefNameDecl *Typedef
4374221345Sdim    = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
4375221345Sdim                                                               T->getDecl()));
4376198092Srdivacky  if (!Typedef)
4377198092Srdivacky    return QualType();
4378198092Srdivacky
4379198398Srdivacky  QualType Result = TL.getType();
4380198398Srdivacky  if (getDerived().AlwaysRebuild() ||
4381198398Srdivacky      Typedef != T->getDecl()) {
4382198398Srdivacky    Result = getDerived().RebuildTypedefType(Typedef);
4383198398Srdivacky    if (Result.isNull())
4384198398Srdivacky      return QualType();
4385198398Srdivacky  }
4386198092Srdivacky
4387198398Srdivacky  TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
4388198398Srdivacky  NewTL.setNameLoc(TL.getNameLoc());
4389198398Srdivacky
4390198398Srdivacky  return Result;
4391198092Srdivacky}
4392198092Srdivacky
4393198092Srdivackytemplate<typename Derived>
4394198398SrdivackyQualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
4395218893Sdim                                                      TypeOfExprTypeLoc TL) {
4396198092Srdivacky  // typeof expressions are not potentially evaluated contexts
4397243830Sdim  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated,
4398243830Sdim                                               Sema::ReuseLambdaContextDecl);
4399198092Srdivacky
4400212904Sdim  ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
4401198092Srdivacky  if (E.isInvalid())
4402198092Srdivacky    return QualType();
4403198092Srdivacky
4404234353Sdim  E = SemaRef.HandleExprEvaluationContextForTypeof(E.get());
4405234353Sdim  if (E.isInvalid())
4406234353Sdim    return QualType();
4407234353Sdim
4408198398Srdivacky  QualType Result = TL.getType();
4409198398Srdivacky  if (getDerived().AlwaysRebuild() ||
4410202379Srdivacky      E.get() != TL.getUnderlyingExpr()) {
4411218893Sdim    Result = getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc());
4412198398Srdivacky    if (Result.isNull())
4413198398Srdivacky      return QualType();
4414198092Srdivacky  }
4415198398Srdivacky  else E.take();
4416198092Srdivacky
4417198398Srdivacky  TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
4418202379Srdivacky  NewTL.setTypeofLoc(TL.getTypeofLoc());
4419202379Srdivacky  NewTL.setLParenLoc(TL.getLParenLoc());
4420202379Srdivacky  NewTL.setRParenLoc(TL.getRParenLoc());
4421198398Srdivacky
4422198398Srdivacky  return Result;
4423198092Srdivacky}
4424198092Srdivacky
4425198092Srdivackytemplate<typename Derived>
4426198398SrdivackyQualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
4427218893Sdim                                                     TypeOfTypeLoc TL) {
4428202379Srdivacky  TypeSourceInfo* Old_Under_TI = TL.getUnderlyingTInfo();
4429202379Srdivacky  TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
4430202379Srdivacky  if (!New_Under_TI)
4431198092Srdivacky    return QualType();
4432198092Srdivacky
4433198398Srdivacky  QualType Result = TL.getType();
4434202379Srdivacky  if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
4435202379Srdivacky    Result = getDerived().RebuildTypeOfType(New_Under_TI->getType());
4436198398Srdivacky    if (Result.isNull())
4437198398Srdivacky      return QualType();
4438198398Srdivacky  }
4439198092Srdivacky
4440198398Srdivacky  TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
4441202379Srdivacky  NewTL.setTypeofLoc(TL.getTypeofLoc());
4442202379Srdivacky  NewTL.setLParenLoc(TL.getLParenLoc());
4443202379Srdivacky  NewTL.setRParenLoc(TL.getRParenLoc());
4444202379Srdivacky  NewTL.setUnderlyingTInfo(New_Under_TI);
4445198398Srdivacky
4446198398Srdivacky  return Result;
4447198092Srdivacky}
4448198092Srdivacky
4449198092Srdivackytemplate<typename Derived>
4450198398SrdivackyQualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
4451218893Sdim                                                       DecltypeTypeLoc TL) {
4452218893Sdim  const DecltypeType *T = TL.getTypePtr();
4453198398Srdivacky
4454198092Srdivacky  // decltype expressions are not potentially evaluated contexts
4455234353Sdim  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated, 0,
4456234353Sdim                                               /*IsDecltype=*/ true);
4457198092Srdivacky
4458212904Sdim  ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
4459198092Srdivacky  if (E.isInvalid())
4460198092Srdivacky    return QualType();
4461198092Srdivacky
4462234353Sdim  E = getSema().ActOnDecltypeExpression(E.take());
4463234353Sdim  if (E.isInvalid())
4464234353Sdim    return QualType();
4465234353Sdim
4466198398Srdivacky  QualType Result = TL.getType();
4467198398Srdivacky  if (getDerived().AlwaysRebuild() ||
4468198398Srdivacky      E.get() != T->getUnderlyingExpr()) {
4469218893Sdim    Result = getDerived().RebuildDecltypeType(E.get(), TL.getNameLoc());
4470198398Srdivacky    if (Result.isNull())
4471198398Srdivacky      return QualType();
4472198092Srdivacky  }
4473198398Srdivacky  else E.take();
4474198092Srdivacky
4475198398Srdivacky  DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
4476198398Srdivacky  NewTL.setNameLoc(TL.getNameLoc());
4477198398Srdivacky
4478198398Srdivacky  return Result;
4479198092Srdivacky}
4480198092Srdivacky
4481198092Srdivackytemplate<typename Derived>
4482223017SdimQualType TreeTransform<Derived>::TransformUnaryTransformType(
4483223017Sdim                                                            TypeLocBuilder &TLB,
4484223017Sdim                                                     UnaryTransformTypeLoc TL) {
4485223017Sdim  QualType Result = TL.getType();
4486223017Sdim  if (Result->isDependentType()) {
4487223017Sdim    const UnaryTransformType *T = TL.getTypePtr();
4488223017Sdim    QualType NewBase =
4489223017Sdim      getDerived().TransformType(TL.getUnderlyingTInfo())->getType();
4490223017Sdim    Result = getDerived().RebuildUnaryTransformType(NewBase,
4491223017Sdim                                                    T->getUTTKind(),
4492223017Sdim                                                    TL.getKWLoc());
4493223017Sdim    if (Result.isNull())
4494223017Sdim      return QualType();
4495223017Sdim  }
4496223017Sdim
4497223017Sdim  UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
4498223017Sdim  NewTL.setKWLoc(TL.getKWLoc());
4499223017Sdim  NewTL.setParensRange(TL.getParensRange());
4500223017Sdim  NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
4501223017Sdim  return Result;
4502223017Sdim}
4503223017Sdim
4504223017Sdimtemplate<typename Derived>
4505218893SdimQualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
4506218893Sdim                                                   AutoTypeLoc TL) {
4507218893Sdim  const AutoType *T = TL.getTypePtr();
4508218893Sdim  QualType OldDeduced = T->getDeducedType();
4509218893Sdim  QualType NewDeduced;
4510218893Sdim  if (!OldDeduced.isNull()) {
4511218893Sdim    NewDeduced = getDerived().TransformType(OldDeduced);
4512218893Sdim    if (NewDeduced.isNull())
4513218893Sdim      return QualType();
4514218893Sdim  }
4515218893Sdim
4516218893Sdim  QualType Result = TL.getType();
4517251662Sdim  if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
4518251662Sdim      T->isDependentType()) {
4519251662Sdim    Result = getDerived().RebuildAutoType(NewDeduced, T->isDecltypeAuto());
4520218893Sdim    if (Result.isNull())
4521218893Sdim      return QualType();
4522218893Sdim  }
4523218893Sdim
4524218893Sdim  AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
4525218893Sdim  NewTL.setNameLoc(TL.getNameLoc());
4526218893Sdim
4527218893Sdim  return Result;
4528218893Sdim}
4529218893Sdim
4530218893Sdimtemplate<typename Derived>
4531198398SrdivackyQualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
4532218893Sdim                                                     RecordTypeLoc TL) {
4533218893Sdim  const RecordType *T = TL.getTypePtr();
4534198092Srdivacky  RecordDecl *Record
4535204643Srdivacky    = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
4536204643Srdivacky                                                          T->getDecl()));
4537198092Srdivacky  if (!Record)
4538198092Srdivacky    return QualType();
4539198092Srdivacky
4540198398Srdivacky  QualType Result = TL.getType();
4541198398Srdivacky  if (getDerived().AlwaysRebuild() ||
4542198398Srdivacky      Record != T->getDecl()) {
4543198398Srdivacky    Result = getDerived().RebuildRecordType(Record);
4544198398Srdivacky    if (Result.isNull())
4545198398Srdivacky      return QualType();
4546198398Srdivacky  }
4547198092Srdivacky
4548198398Srdivacky  RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
4549198398Srdivacky  NewTL.setNameLoc(TL.getNameLoc());
4550198398Srdivacky
4551198398Srdivacky  return Result;
4552198092Srdivacky}
4553198092Srdivacky
4554198092Srdivackytemplate<typename Derived>
4555198398SrdivackyQualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
4556218893Sdim                                                   EnumTypeLoc TL) {
4557218893Sdim  const EnumType *T = TL.getTypePtr();
4558198092Srdivacky  EnumDecl *Enum
4559204643Srdivacky    = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
4560204643Srdivacky                                                        T->getDecl()));
4561198092Srdivacky  if (!Enum)
4562198092Srdivacky    return QualType();
4563198092Srdivacky
4564198398Srdivacky  QualType Result = TL.getType();
4565198398Srdivacky  if (getDerived().AlwaysRebuild() ||
4566198398Srdivacky      Enum != T->getDecl()) {
4567198398Srdivacky    Result = getDerived().RebuildEnumType(Enum);
4568198398Srdivacky    if (Result.isNull())
4569198398Srdivacky      return QualType();
4570198398Srdivacky  }
4571198092Srdivacky
4572198398Srdivacky  EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
4573198398Srdivacky  NewTL.setNameLoc(TL.getNameLoc());
4574198398Srdivacky
4575198398Srdivacky  return Result;
4576198092Srdivacky}
4577198092Srdivacky
4578204962Srdivackytemplate<typename Derived>
4579204962SrdivackyQualType TreeTransform<Derived>::TransformInjectedClassNameType(
4580204962Srdivacky                                         TypeLocBuilder &TLB,
4581218893Sdim                                         InjectedClassNameTypeLoc TL) {
4582204962Srdivacky  Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
4583204962Srdivacky                                       TL.getTypePtr()->getDecl());
4584204962Srdivacky  if (!D) return QualType();
4585198092Srdivacky
4586204962Srdivacky  QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
4587204962Srdivacky  TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
4588204962Srdivacky  return T;
4589204962Srdivacky}
4590204962Srdivacky
4591198092Srdivackytemplate<typename Derived>
4592198092SrdivackyQualType TreeTransform<Derived>::TransformTemplateTypeParmType(
4593198398Srdivacky                                                TypeLocBuilder &TLB,
4594218893Sdim                                                TemplateTypeParmTypeLoc TL) {
4595198398Srdivacky  return TransformTypeSpecType(TLB, TL);
4596198092Srdivacky}
4597198092Srdivacky
4598198092Srdivackytemplate<typename Derived>
4599198398SrdivackyQualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
4600198398Srdivacky                                         TypeLocBuilder &TLB,
4601218893Sdim                                         SubstTemplateTypeParmTypeLoc TL) {
4602221345Sdim  const SubstTemplateTypeParmType *T = TL.getTypePtr();
4603239462Sdim
4604221345Sdim  // Substitute into the replacement type, which itself might involve something
4605221345Sdim  // that needs to be transformed. This only tends to occur with default
4606221345Sdim  // template arguments of template template parameters.
4607221345Sdim  TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
4608221345Sdim  QualType Replacement = getDerived().TransformType(T->getReplacementType());
4609221345Sdim  if (Replacement.isNull())
4610221345Sdim    return QualType();
4611239462Sdim
4612221345Sdim  // Always canonicalize the replacement type.
4613221345Sdim  Replacement = SemaRef.Context.getCanonicalType(Replacement);
4614221345Sdim  QualType Result
4615239462Sdim    = SemaRef.Context.getSubstTemplateTypeParmType(T->getReplacedParameter(),
4616221345Sdim                                                   Replacement);
4617239462Sdim
4618221345Sdim  // Propagate type-source information.
4619221345Sdim  SubstTemplateTypeParmTypeLoc NewTL
4620221345Sdim    = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
4621221345Sdim  NewTL.setNameLoc(TL.getNameLoc());
4622221345Sdim  return Result;
4623221345Sdim
4624198398Srdivacky}
4625198398Srdivacky
4626198398Srdivackytemplate<typename Derived>
4627218893SdimQualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
4628218893Sdim                                          TypeLocBuilder &TLB,
4629218893Sdim                                          SubstTemplateTypeParmPackTypeLoc TL) {
4630218893Sdim  return TransformTypeSpecType(TLB, TL);
4631218893Sdim}
4632198398Srdivacky
4633198398Srdivackytemplate<typename Derived>
4634198092SrdivackyQualType TreeTransform<Derived>::TransformTemplateSpecializationType(
4635198893Srdivacky                                                        TypeLocBuilder &TLB,
4636218893Sdim                                           TemplateSpecializationTypeLoc TL) {
4637198893Srdivacky  const TemplateSpecializationType *T = TL.getTypePtr();
4638198893Srdivacky
4639221345Sdim  // The nested-name-specifier never matters in a TemplateSpecializationType,
4640221345Sdim  // because we can't have a dependent nested-name-specifier anyway.
4641221345Sdim  CXXScopeSpec SS;
4642198092Srdivacky  TemplateName Template
4643221345Sdim    = getDerived().TransformTemplateName(SS, T->getTemplateName(),
4644221345Sdim                                         TL.getTemplateNameLoc());
4645198092Srdivacky  if (Template.isNull())
4646198092Srdivacky    return QualType();
4647198092Srdivacky
4648218893Sdim  return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
4649218893Sdim}
4650218893Sdim
4651226633Sdimtemplate<typename Derived>
4652226633SdimQualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
4653226633Sdim                                                     AtomicTypeLoc TL) {
4654226633Sdim  QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
4655226633Sdim  if (ValueType.isNull())
4656226633Sdim    return QualType();
4657226633Sdim
4658226633Sdim  QualType Result = TL.getType();
4659226633Sdim  if (getDerived().AlwaysRebuild() ||
4660226633Sdim      ValueType != TL.getValueLoc().getType()) {
4661226633Sdim    Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
4662226633Sdim    if (Result.isNull())
4663226633Sdim      return QualType();
4664226633Sdim  }
4665226633Sdim
4666226633Sdim  AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
4667226633Sdim  NewTL.setKWLoc(TL.getKWLoc());
4668226633Sdim  NewTL.setLParenLoc(TL.getLParenLoc());
4669226633Sdim  NewTL.setRParenLoc(TL.getRParenLoc());
4670226633Sdim
4671226633Sdim  return Result;
4672226633Sdim}
4673226633Sdim
4674239462Sdim  /// \brief Simple iterator that traverses the template arguments in a
4675218893Sdim  /// container that provides a \c getArgLoc() member function.
4676218893Sdim  ///
4677218893Sdim  /// This iterator is intended to be used with the iterator form of
4678218893Sdim  /// \c TreeTransform<Derived>::TransformTemplateArguments().
4679218893Sdim  template<typename ArgLocContainer>
4680218893Sdim  class TemplateArgumentLocContainerIterator {
4681218893Sdim    ArgLocContainer *Container;
4682218893Sdim    unsigned Index;
4683239462Sdim
4684218893Sdim  public:
4685218893Sdim    typedef TemplateArgumentLoc value_type;
4686218893Sdim    typedef TemplateArgumentLoc reference;
4687218893Sdim    typedef int difference_type;
4688218893Sdim    typedef std::input_iterator_tag iterator_category;
4689239462Sdim
4690218893Sdim    class pointer {
4691218893Sdim      TemplateArgumentLoc Arg;
4692239462Sdim
4693218893Sdim    public:
4694218893Sdim      explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4695239462Sdim
4696218893Sdim      const TemplateArgumentLoc *operator->() const {
4697218893Sdim        return &Arg;
4698218893Sdim      }
4699218893Sdim    };
4700239462Sdim
4701239462Sdim
4702218893Sdim    TemplateArgumentLocContainerIterator() {}
4703239462Sdim
4704218893Sdim    TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
4705218893Sdim                                 unsigned Index)
4706218893Sdim      : Container(&Container), Index(Index) { }
4707239462Sdim
4708218893Sdim    TemplateArgumentLocContainerIterator &operator++() {
4709218893Sdim      ++Index;
4710218893Sdim      return *this;
4711218893Sdim    }
4712239462Sdim
4713218893Sdim    TemplateArgumentLocContainerIterator operator++(int) {
4714218893Sdim      TemplateArgumentLocContainerIterator Old(*this);
4715218893Sdim      ++(*this);
4716218893Sdim      return Old;
4717218893Sdim    }
4718239462Sdim
4719218893Sdim    TemplateArgumentLoc operator*() const {
4720218893Sdim      return Container->getArgLoc(Index);
4721218893Sdim    }
4722239462Sdim
4723218893Sdim    pointer operator->() const {
4724218893Sdim      return pointer(Container->getArgLoc(Index));
4725218893Sdim    }
4726239462Sdim
4727218893Sdim    friend bool operator==(const TemplateArgumentLocContainerIterator &X,
4728218893Sdim                           const TemplateArgumentLocContainerIterator &Y) {
4729218893Sdim      return X.Container == Y.Container && X.Index == Y.Index;
4730218893Sdim    }
4731239462Sdim
4732218893Sdim    friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
4733218893Sdim                           const TemplateArgumentLocContainerIterator &Y) {
4734218893Sdim      return !(X == Y);
4735218893Sdim    }
4736218893Sdim  };
4737239462Sdim
4738239462Sdim
4739218893Sdimtemplate <typename Derived>
4740218893SdimQualType TreeTransform<Derived>::TransformTemplateSpecializationType(
4741218893Sdim                                                        TypeLocBuilder &TLB,
4742218893Sdim                                           TemplateSpecializationTypeLoc TL,
4743218893Sdim                                                      TemplateName Template) {
4744199990Srdivacky  TemplateArgumentListInfo NewTemplateArgs;
4745199990Srdivacky  NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
4746199990Srdivacky  NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
4747218893Sdim  typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
4748218893Sdim    ArgIterator;
4749239462Sdim  if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
4750218893Sdim                                              ArgIterator(TL, TL.getNumArgs()),
4751218893Sdim                                              NewTemplateArgs))
4752218893Sdim    return QualType();
4753199990Srdivacky
4754198893Srdivacky  // FIXME: maybe don't rebuild if all the template arguments are the same.
4755198893Srdivacky
4756198893Srdivacky  QualType Result =
4757198893Srdivacky    getDerived().RebuildTemplateSpecializationType(Template,
4758198893Srdivacky                                                   TL.getTemplateNameLoc(),
4759199990Srdivacky                                                   NewTemplateArgs);
4760198893Srdivacky
4761198893Srdivacky  if (!Result.isNull()) {
4762223017Sdim    // Specializations of template template parameters are represented as
4763223017Sdim    // TemplateSpecializationTypes, and substitution of type alias templates
4764223017Sdim    // within a dependent context can transform them into
4765223017Sdim    // DependentTemplateSpecializationTypes.
4766223017Sdim    if (isa<DependentTemplateSpecializationType>(Result)) {
4767223017Sdim      DependentTemplateSpecializationTypeLoc NewTL
4768223017Sdim        = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
4769234353Sdim      NewTL.setElaboratedKeywordLoc(SourceLocation());
4770223017Sdim      NewTL.setQualifierLoc(NestedNameSpecifierLoc());
4771234353Sdim      NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
4772234353Sdim      NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
4773223017Sdim      NewTL.setLAngleLoc(TL.getLAngleLoc());
4774223017Sdim      NewTL.setRAngleLoc(TL.getRAngleLoc());
4775223017Sdim      for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
4776223017Sdim        NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
4777223017Sdim      return Result;
4778223017Sdim    }
4779223017Sdim
4780198893Srdivacky    TemplateSpecializationTypeLoc NewTL
4781198893Srdivacky      = TLB.push<TemplateSpecializationTypeLoc>(Result);
4782234353Sdim    NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
4783198893Srdivacky    NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
4784198893Srdivacky    NewTL.setLAngleLoc(TL.getLAngleLoc());
4785198893Srdivacky    NewTL.setRAngleLoc(TL.getRAngleLoc());
4786198893Srdivacky    for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
4787198893Srdivacky      NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
4788198092Srdivacky  }
4789198092Srdivacky
4790198893Srdivacky  return Result;
4791198092Srdivacky}
4792198092Srdivacky
4793221345Sdimtemplate <typename Derived>
4794221345SdimQualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
4795221345Sdim                                     TypeLocBuilder &TLB,
4796221345Sdim                                     DependentTemplateSpecializationTypeLoc TL,
4797221345Sdim                                     TemplateName Template,
4798221345Sdim                                     CXXScopeSpec &SS) {
4799221345Sdim  TemplateArgumentListInfo NewTemplateArgs;
4800221345Sdim  NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
4801221345Sdim  NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
4802221345Sdim  typedef TemplateArgumentLocContainerIterator<
4803221345Sdim            DependentTemplateSpecializationTypeLoc> ArgIterator;
4804239462Sdim  if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
4805221345Sdim                                              ArgIterator(TL, TL.getNumArgs()),
4806221345Sdim                                              NewTemplateArgs))
4807221345Sdim    return QualType();
4808239462Sdim
4809221345Sdim  // FIXME: maybe don't rebuild if all the template arguments are the same.
4810239462Sdim
4811221345Sdim  if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
4812221345Sdim    QualType Result
4813221345Sdim      = getSema().Context.getDependentTemplateSpecializationType(
4814221345Sdim                                                TL.getTypePtr()->getKeyword(),
4815221345Sdim                                                         DTN->getQualifier(),
4816221345Sdim                                                         DTN->getIdentifier(),
4817221345Sdim                                                               NewTemplateArgs);
4818239462Sdim
4819221345Sdim    DependentTemplateSpecializationTypeLoc NewTL
4820221345Sdim      = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
4821234353Sdim    NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
4822221345Sdim    NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
4823234353Sdim    NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
4824234353Sdim    NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
4825221345Sdim    NewTL.setLAngleLoc(TL.getLAngleLoc());
4826221345Sdim    NewTL.setRAngleLoc(TL.getRAngleLoc());
4827221345Sdim    for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
4828221345Sdim      NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
4829221345Sdim    return Result;
4830221345Sdim  }
4831239462Sdim
4832239462Sdim  QualType Result
4833221345Sdim    = getDerived().RebuildTemplateSpecializationType(Template,
4834234353Sdim                                                     TL.getTemplateNameLoc(),
4835221345Sdim                                                     NewTemplateArgs);
4836239462Sdim
4837221345Sdim  if (!Result.isNull()) {
4838221345Sdim    /// FIXME: Wrap this in an elaborated-type-specifier?
4839221345Sdim    TemplateSpecializationTypeLoc NewTL
4840221345Sdim      = TLB.push<TemplateSpecializationTypeLoc>(Result);
4841234353Sdim    NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
4842234353Sdim    NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
4843221345Sdim    NewTL.setLAngleLoc(TL.getLAngleLoc());
4844221345Sdim    NewTL.setRAngleLoc(TL.getRAngleLoc());
4845221345Sdim    for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
4846221345Sdim      NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
4847221345Sdim  }
4848239462Sdim
4849221345Sdim  return Result;
4850221345Sdim}
4851221345Sdim
4852198092Srdivackytemplate<typename Derived>
4853198398SrdivackyQualType
4854208600SrdivackyTreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
4855218893Sdim                                                ElaboratedTypeLoc TL) {
4856218893Sdim  const ElaboratedType *T = TL.getTypePtr();
4857198092Srdivacky
4858221345Sdim  NestedNameSpecifierLoc QualifierLoc;
4859208600Srdivacky  // NOTE: the qualifier in an ElaboratedType is optional.
4860221345Sdim  if (TL.getQualifierLoc()) {
4861239462Sdim    QualifierLoc
4862221345Sdim      = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
4863221345Sdim    if (!QualifierLoc)
4864208600Srdivacky      return QualType();
4865208600Srdivacky  }
4866198092Srdivacky
4867218893Sdim  QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
4868218893Sdim  if (NamedT.isNull())
4869218893Sdim    return QualType();
4870208600Srdivacky
4871223017Sdim  // C++0x [dcl.type.elab]p2:
4872223017Sdim  //   If the identifier resolves to a typedef-name or the simple-template-id
4873223017Sdim  //   resolves to an alias template specialization, the
4874223017Sdim  //   elaborated-type-specifier is ill-formed.
4875223017Sdim  if (T->getKeyword() != ETK_None && T->getKeyword() != ETK_Typename) {
4876223017Sdim    if (const TemplateSpecializationType *TST =
4877223017Sdim          NamedT->getAs<TemplateSpecializationType>()) {
4878223017Sdim      TemplateName Template = TST->getTemplateName();
4879223017Sdim      if (TypeAliasTemplateDecl *TAT =
4880223017Sdim          dyn_cast_or_null<TypeAliasTemplateDecl>(Template.getAsTemplateDecl())) {
4881223017Sdim        SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
4882223017Sdim                     diag::err_tag_reference_non_tag) << 4;
4883223017Sdim        SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
4884223017Sdim      }
4885223017Sdim    }
4886223017Sdim  }
4887223017Sdim
4888198398Srdivacky  QualType Result = TL.getType();
4889198398Srdivacky  if (getDerived().AlwaysRebuild() ||
4890221345Sdim      QualifierLoc != TL.getQualifierLoc() ||
4891208600Srdivacky      NamedT != T->getNamedType()) {
4892234353Sdim    Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
4893239462Sdim                                                T->getKeyword(),
4894221345Sdim                                                QualifierLoc, NamedT);
4895198398Srdivacky    if (Result.isNull())
4896198398Srdivacky      return QualType();
4897198398Srdivacky  }
4898198092Srdivacky
4899208600Srdivacky  ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
4900234353Sdim  NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
4901221345Sdim  NewTL.setQualifierLoc(QualifierLoc);
4902198398Srdivacky  return Result;
4903198092Srdivacky}
4904198092Srdivacky
4905198092Srdivackytemplate<typename Derived>
4906218893SdimQualType TreeTransform<Derived>::TransformAttributedType(
4907218893Sdim                                                TypeLocBuilder &TLB,
4908218893Sdim                                                AttributedTypeLoc TL) {
4909218893Sdim  const AttributedType *oldType = TL.getTypePtr();
4910218893Sdim  QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
4911218893Sdim  if (modifiedType.isNull())
4912218893Sdim    return QualType();
4913218893Sdim
4914218893Sdim  QualType result = TL.getType();
4915218893Sdim
4916218893Sdim  // FIXME: dependent operand expressions?
4917218893Sdim  if (getDerived().AlwaysRebuild() ||
4918218893Sdim      modifiedType != oldType->getModifiedType()) {
4919218893Sdim    // TODO: this is really lame; we should really be rebuilding the
4920218893Sdim    // equivalent type from first principles.
4921218893Sdim    QualType equivalentType
4922218893Sdim      = getDerived().TransformType(oldType->getEquivalentType());
4923218893Sdim    if (equivalentType.isNull())
4924218893Sdim      return QualType();
4925218893Sdim    result = SemaRef.Context.getAttributedType(oldType->getAttrKind(),
4926218893Sdim                                               modifiedType,
4927218893Sdim                                               equivalentType);
4928218893Sdim  }
4929218893Sdim
4930218893Sdim  AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
4931218893Sdim  newTL.setAttrNameLoc(TL.getAttrNameLoc());
4932218893Sdim  if (TL.hasAttrOperand())
4933218893Sdim    newTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
4934218893Sdim  if (TL.hasAttrExprOperand())
4935218893Sdim    newTL.setAttrExprOperand(TL.getAttrExprOperand());
4936218893Sdim  else if (TL.hasAttrEnumOperand())
4937218893Sdim    newTL.setAttrEnumOperandLoc(TL.getAttrEnumOperandLoc());
4938218893Sdim
4939218893Sdim  return result;
4940218893Sdim}
4941218893Sdim
4942218893Sdimtemplate<typename Derived>
4943218893SdimQualType
4944218893SdimTreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
4945218893Sdim                                           ParenTypeLoc TL) {
4946218893Sdim  QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
4947218893Sdim  if (Inner.isNull())
4948218893Sdim    return QualType();
4949218893Sdim
4950218893Sdim  QualType Result = TL.getType();
4951218893Sdim  if (getDerived().AlwaysRebuild() ||
4952218893Sdim      Inner != TL.getInnerLoc().getType()) {
4953218893Sdim    Result = getDerived().RebuildParenType(Inner);
4954218893Sdim    if (Result.isNull())
4955218893Sdim      return QualType();
4956218893Sdim  }
4957218893Sdim
4958218893Sdim  ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
4959218893Sdim  NewTL.setLParenLoc(TL.getLParenLoc());
4960218893Sdim  NewTL.setRParenLoc(TL.getRParenLoc());
4961218893Sdim  return Result;
4962218893Sdim}
4963218893Sdim
4964218893Sdimtemplate<typename Derived>
4965206084SrdivackyQualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB,
4966218893Sdim                                                      DependentNameTypeLoc TL) {
4967218893Sdim  const DependentNameType *T = TL.getTypePtr();
4968198893Srdivacky
4969221345Sdim  NestedNameSpecifierLoc QualifierLoc
4970221345Sdim    = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
4971221345Sdim  if (!QualifierLoc)
4972198092Srdivacky    return QualType();
4973198092Srdivacky
4974210299Sed  QualType Result
4975221345Sdim    = getDerived().RebuildDependentNameType(T->getKeyword(),
4976234353Sdim                                            TL.getElaboratedKeywordLoc(),
4977221345Sdim                                            QualifierLoc,
4978210299Sed                                            T->getIdentifier(),
4979210299Sed                                            TL.getNameLoc());
4980198398Srdivacky  if (Result.isNull())
4981198398Srdivacky    return QualType();
4982198092Srdivacky
4983208600Srdivacky  if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
4984208600Srdivacky    QualType NamedT = ElabT->getNamedType();
4985210299Sed    TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
4986210299Sed
4987208600Srdivacky    ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
4988234353Sdim    NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
4989221345Sdim    NewTL.setQualifierLoc(QualifierLoc);
4990210299Sed  } else {
4991208600Srdivacky    DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
4992234353Sdim    NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
4993221345Sdim    NewTL.setQualifierLoc(QualifierLoc);
4994208600Srdivacky    NewTL.setNameLoc(TL.getNameLoc());
4995208600Srdivacky  }
4996198398Srdivacky  return Result;
4997198092Srdivacky}
4998198092Srdivacky
4999198092Srdivackytemplate<typename Derived>
5000210299SedQualType TreeTransform<Derived>::
5001210299Sed          TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
5002218893Sdim                                 DependentTemplateSpecializationTypeLoc TL) {
5003221345Sdim  NestedNameSpecifierLoc QualifierLoc;
5004221345Sdim  if (TL.getQualifierLoc()) {
5005221345Sdim    QualifierLoc
5006221345Sdim      = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
5007221345Sdim    if (!QualifierLoc)
5008221345Sdim      return QualType();
5009221345Sdim  }
5010239462Sdim
5011218893Sdim  return getDerived()
5012221345Sdim           .TransformDependentTemplateSpecializationType(TLB, TL, QualifierLoc);
5013218893Sdim}
5014218893Sdim
5015218893Sdimtemplate<typename Derived>
5016218893SdimQualType TreeTransform<Derived>::
5017221345SdimTransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
5018221345Sdim                                   DependentTemplateSpecializationTypeLoc TL,
5019221345Sdim                                       NestedNameSpecifierLoc QualifierLoc) {
5020218893Sdim  const DependentTemplateSpecializationType *T = TL.getTypePtr();
5021239462Sdim
5022210299Sed  TemplateArgumentListInfo NewTemplateArgs;
5023210299Sed  NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
5024210299Sed  NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
5025239462Sdim
5026218893Sdim  typedef TemplateArgumentLocContainerIterator<
5027221345Sdim  DependentTemplateSpecializationTypeLoc> ArgIterator;
5028218893Sdim  if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
5029218893Sdim                                              ArgIterator(TL, TL.getNumArgs()),
5030218893Sdim                                              NewTemplateArgs))
5031218893Sdim    return QualType();
5032239462Sdim
5033218893Sdim  QualType Result
5034218893Sdim    = getDerived().RebuildDependentTemplateSpecializationType(T->getKeyword(),
5035221345Sdim                                                              QualifierLoc,
5036218893Sdim                                                            T->getIdentifier(),
5037234353Sdim                                                       TL.getTemplateNameLoc(),
5038221345Sdim                                                            NewTemplateArgs);
5039210299Sed  if (Result.isNull())
5040210299Sed    return QualType();
5041239462Sdim
5042210299Sed  if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
5043210299Sed    QualType NamedT = ElabT->getNamedType();
5044239462Sdim
5045210299Sed    // Copy information relevant to the template specialization.
5046210299Sed    TemplateSpecializationTypeLoc NamedTL
5047210299Sed      = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
5048234353Sdim    NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
5049234353Sdim    NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
5050210299Sed    NamedTL.setLAngleLoc(TL.getLAngleLoc());
5051210299Sed    NamedTL.setRAngleLoc(TL.getRAngleLoc());
5052221345Sdim    for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
5053221345Sdim      NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
5054239462Sdim
5055210299Sed    // Copy information relevant to the elaborated type.
5056210299Sed    ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
5057234353Sdim    NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
5058221345Sdim    NewTL.setQualifierLoc(QualifierLoc);
5059221345Sdim  } else if (isa<DependentTemplateSpecializationType>(Result)) {
5060221345Sdim    DependentTemplateSpecializationTypeLoc SpecTL
5061221345Sdim      = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
5062234353Sdim    SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
5063221345Sdim    SpecTL.setQualifierLoc(QualifierLoc);
5064234353Sdim    SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
5065234353Sdim    SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
5066221345Sdim    SpecTL.setLAngleLoc(TL.getLAngleLoc());
5067221345Sdim    SpecTL.setRAngleLoc(TL.getRAngleLoc());
5068221345Sdim    for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
5069221345Sdim      SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
5070210299Sed  } else {
5071221345Sdim    TemplateSpecializationTypeLoc SpecTL
5072221345Sdim      = TLB.push<TemplateSpecializationTypeLoc>(Result);
5073234353Sdim    SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
5074234353Sdim    SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
5075221345Sdim    SpecTL.setLAngleLoc(TL.getLAngleLoc());
5076221345Sdim    SpecTL.setRAngleLoc(TL.getRAngleLoc());
5077221345Sdim    for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
5078221345Sdim      SpecTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
5079210299Sed  }
5080210299Sed  return Result;
5081210299Sed}
5082210299Sed
5083210299Sedtemplate<typename Derived>
5084218893SdimQualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
5085218893Sdim                                                      PackExpansionTypeLoc TL) {
5086239462Sdim  QualType Pattern
5087239462Sdim    = getDerived().TransformType(TLB, TL.getPatternLoc());
5088218893Sdim  if (Pattern.isNull())
5089218893Sdim    return QualType();
5090239462Sdim
5091239462Sdim  QualType Result = TL.getType();
5092218893Sdim  if (getDerived().AlwaysRebuild() ||
5093218893Sdim      Pattern != TL.getPatternLoc().getType()) {
5094239462Sdim    Result = getDerived().RebuildPackExpansionType(Pattern,
5095218893Sdim                                           TL.getPatternLoc().getSourceRange(),
5096218893Sdim                                                   TL.getEllipsisLoc(),
5097218893Sdim                                           TL.getTypePtr()->getNumExpansions());
5098218893Sdim    if (Result.isNull())
5099218893Sdim      return QualType();
5100218893Sdim  }
5101239462Sdim
5102218893Sdim  PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
5103218893Sdim  NewT.setEllipsisLoc(TL.getEllipsisLoc());
5104218893Sdim  return Result;
5105218893Sdim}
5106218893Sdim
5107218893Sdimtemplate<typename Derived>
5108198398SrdivackyQualType
5109198398SrdivackyTreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
5110218893Sdim                                                   ObjCInterfaceTypeLoc TL) {
5111207619Srdivacky  // ObjCInterfaceType is never dependent.
5112208600Srdivacky  TLB.pushFullCopy(TL);
5113207619Srdivacky  return TL.getType();
5114198092Srdivacky}
5115198092Srdivacky
5116198092Srdivackytemplate<typename Derived>
5117198398SrdivackyQualType
5118208600SrdivackyTreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
5119218893Sdim                                                ObjCObjectTypeLoc TL) {
5120208600Srdivacky  // ObjCObjectType is never dependent.
5121208600Srdivacky  TLB.pushFullCopy(TL);
5122208600Srdivacky  return TL.getType();
5123208600Srdivacky}
5124208600Srdivacky
5125208600Srdivackytemplate<typename Derived>
5126208600SrdivackyQualType
5127198398SrdivackyTreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
5128218893Sdim                                               ObjCObjectPointerTypeLoc TL) {
5129207619Srdivacky  // ObjCObjectPointerType is never dependent.
5130208600Srdivacky  TLB.pushFullCopy(TL);
5131207619Srdivacky  return TL.getType();
5132198092Srdivacky}
5133198092Srdivacky
5134198092Srdivacky//===----------------------------------------------------------------------===//
5135198092Srdivacky// Statement transformation
5136198092Srdivacky//===----------------------------------------------------------------------===//
5137198092Srdivackytemplate<typename Derived>
5138212904SdimStmtResult
5139198092SrdivackyTreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
5140218893Sdim  return SemaRef.Owned(S);
5141198092Srdivacky}
5142198092Srdivacky
5143198092Srdivackytemplate<typename Derived>
5144212904SdimStmtResult
5145198092SrdivackyTreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
5146198092Srdivacky  return getDerived().TransformCompoundStmt(S, false);
5147198092Srdivacky}
5148198092Srdivacky
5149198092Srdivackytemplate<typename Derived>
5150212904SdimStmtResult
5151198092SrdivackyTreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
5152198092Srdivacky                                              bool IsStmtExpr) {
5153234353Sdim  Sema::CompoundScopeRAII CompoundScope(getSema());
5154234353Sdim
5155212904Sdim  bool SubStmtInvalid = false;
5156198092Srdivacky  bool SubStmtChanged = false;
5157243830Sdim  SmallVector<Stmt*, 8> Statements;
5158198092Srdivacky  for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
5159198092Srdivacky       B != BEnd; ++B) {
5160212904Sdim    StmtResult Result = getDerived().TransformStmt(*B);
5161212904Sdim    if (Result.isInvalid()) {
5162212904Sdim      // Immediately fail if this was a DeclStmt, since it's very
5163212904Sdim      // likely that this will cause problems for future statements.
5164212904Sdim      if (isa<DeclStmt>(*B))
5165212904Sdim        return StmtError();
5166198092Srdivacky
5167212904Sdim      // Otherwise, just keep processing substatements and fail later.
5168212904Sdim      SubStmtInvalid = true;
5169212904Sdim      continue;
5170212904Sdim    }
5171212904Sdim
5172198092Srdivacky    SubStmtChanged = SubStmtChanged || Result.get() != *B;
5173198092Srdivacky    Statements.push_back(Result.takeAs<Stmt>());
5174198092Srdivacky  }
5175198092Srdivacky
5176212904Sdim  if (SubStmtInvalid)
5177212904Sdim    return StmtError();
5178212904Sdim
5179198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
5180198092Srdivacky      !SubStmtChanged)
5181218893Sdim    return SemaRef.Owned(S);
5182198092Srdivacky
5183198092Srdivacky  return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
5184243830Sdim                                          Statements,
5185198092Srdivacky                                          S->getRBracLoc(),
5186198092Srdivacky                                          IsStmtExpr);
5187198092Srdivacky}
5188198092Srdivacky
5189198092Srdivackytemplate<typename Derived>
5190212904SdimStmtResult
5191198092SrdivackyTreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
5192212904Sdim  ExprResult LHS, RHS;
5193199512Srdivacky  {
5194234353Sdim    EnterExpressionEvaluationContext Unevaluated(SemaRef,
5195234353Sdim                                                 Sema::ConstantEvaluated);
5196198092Srdivacky
5197199512Srdivacky    // Transform the left-hand case value.
5198199512Srdivacky    LHS = getDerived().TransformExpr(S->getLHS());
5199234353Sdim    LHS = SemaRef.ActOnConstantExpression(LHS);
5200199512Srdivacky    if (LHS.isInvalid())
5201212904Sdim      return StmtError();
5202198092Srdivacky
5203199512Srdivacky    // Transform the right-hand case value (for the GNU case-range extension).
5204199512Srdivacky    RHS = getDerived().TransformExpr(S->getRHS());
5205234353Sdim    RHS = SemaRef.ActOnConstantExpression(RHS);
5206199512Srdivacky    if (RHS.isInvalid())
5207212904Sdim      return StmtError();
5208199512Srdivacky  }
5209198092Srdivacky
5210198092Srdivacky  // Build the case statement.
5211198092Srdivacky  // Case statements are always rebuilt so that they will attached to their
5212198092Srdivacky  // transformed switch statement.
5213212904Sdim  StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
5214212904Sdim                                                       LHS.get(),
5215198092Srdivacky                                                       S->getEllipsisLoc(),
5216212904Sdim                                                       RHS.get(),
5217198092Srdivacky                                                       S->getColonLoc());
5218198092Srdivacky  if (Case.isInvalid())
5219212904Sdim    return StmtError();
5220198092Srdivacky
5221198092Srdivacky  // Transform the statement following the case
5222212904Sdim  StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
5223198092Srdivacky  if (SubStmt.isInvalid())
5224212904Sdim    return StmtError();
5225198092Srdivacky
5226198092Srdivacky  // Attach the body to the case statement
5227212904Sdim  return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
5228198092Srdivacky}
5229198092Srdivacky
5230198092Srdivackytemplate<typename Derived>
5231212904SdimStmtResult
5232198092SrdivackyTreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
5233198092Srdivacky  // Transform the statement following the default case
5234212904Sdim  StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
5235198092Srdivacky  if (SubStmt.isInvalid())
5236212904Sdim    return StmtError();
5237198092Srdivacky
5238198092Srdivacky  // Default statements are always rebuilt
5239198092Srdivacky  return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
5240212904Sdim                                         SubStmt.get());
5241198092Srdivacky}
5242198092Srdivacky
5243198092Srdivackytemplate<typename Derived>
5244212904SdimStmtResult
5245198092SrdivackyTreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
5246212904Sdim  StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
5247198092Srdivacky  if (SubStmt.isInvalid())
5248212904Sdim    return StmtError();
5249198092Srdivacky
5250218893Sdim  Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
5251218893Sdim                                        S->getDecl());
5252218893Sdim  if (!LD)
5253218893Sdim    return StmtError();
5254234982Sdim
5255234982Sdim
5256198092Srdivacky  // FIXME: Pass the real colon location in.
5257218893Sdim  return getDerived().RebuildLabelStmt(S->getIdentLoc(),
5258218893Sdim                                       cast<LabelDecl>(LD), SourceLocation(),
5259212904Sdim                                       SubStmt.get());
5260198092Srdivacky}
5261198092Srdivacky
5262198092Srdivackytemplate<typename Derived>
5263212904SdimStmtResult
5264234982SdimTreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S) {
5265234982Sdim  StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
5266234982Sdim  if (SubStmt.isInvalid())
5267234982Sdim    return StmtError();
5268234982Sdim
5269234982Sdim  // TODO: transform attributes
5270234982Sdim  if (SubStmt.get() == S->getSubStmt() /* && attrs are the same */)
5271234982Sdim    return S;
5272234982Sdim
5273234982Sdim  return getDerived().RebuildAttributedStmt(S->getAttrLoc(),
5274234982Sdim                                            S->getAttrs(),
5275234982Sdim                                            SubStmt.get());
5276234982Sdim}
5277234982Sdim
5278234982Sdimtemplate<typename Derived>
5279234982SdimStmtResult
5280198092SrdivackyTreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
5281198092Srdivacky  // Transform the condition
5282212904Sdim  ExprResult Cond;
5283199990Srdivacky  VarDecl *ConditionVar = 0;
5284199990Srdivacky  if (S->getConditionVariable()) {
5285239462Sdim    ConditionVar
5286199990Srdivacky      = cast_or_null<VarDecl>(
5287204643Srdivacky                   getDerived().TransformDefinition(
5288204643Srdivacky                                      S->getConditionVariable()->getLocation(),
5289204643Srdivacky                                                    S->getConditionVariable()));
5290199990Srdivacky    if (!ConditionVar)
5291212904Sdim      return StmtError();
5292199990Srdivacky  } else {
5293199990Srdivacky    Cond = getDerived().TransformExpr(S->getCond());
5294239462Sdim
5295199990Srdivacky    if (Cond.isInvalid())
5296212904Sdim      return StmtError();
5297239462Sdim
5298208600Srdivacky    // Convert the condition to a boolean value.
5299208600Srdivacky    if (S->getCond()) {
5300239462Sdim      ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getIfLoc(),
5301218893Sdim                                                         Cond.get());
5302208600Srdivacky      if (CondE.isInvalid())
5303212904Sdim        return StmtError();
5304239462Sdim
5305212904Sdim      Cond = CondE.get();
5306208600Srdivacky    }
5307199990Srdivacky  }
5308239462Sdim
5309212904Sdim  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
5310212904Sdim  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
5311212904Sdim    return StmtError();
5312239462Sdim
5313198092Srdivacky  // Transform the "then" branch.
5314212904Sdim  StmtResult Then = getDerived().TransformStmt(S->getThen());
5315198092Srdivacky  if (Then.isInvalid())
5316212904Sdim    return StmtError();
5317198092Srdivacky
5318198092Srdivacky  // Transform the "else" branch.
5319212904Sdim  StmtResult Else = getDerived().TransformStmt(S->getElse());
5320198092Srdivacky  if (Else.isInvalid())
5321212904Sdim    return StmtError();
5322198092Srdivacky
5323198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
5324212904Sdim      FullCond.get() == S->getCond() &&
5325199990Srdivacky      ConditionVar == S->getConditionVariable() &&
5326198092Srdivacky      Then.get() == S->getThen() &&
5327198092Srdivacky      Else.get() == S->getElse())
5328218893Sdim    return SemaRef.Owned(S);
5329198092Srdivacky
5330199990Srdivacky  return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, ConditionVar,
5331212904Sdim                                    Then.get(),
5332212904Sdim                                    S->getElseLoc(), Else.get());
5333198092Srdivacky}
5334198092Srdivacky
5335198092Srdivackytemplate<typename Derived>
5336212904SdimStmtResult
5337198092SrdivackyTreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
5338198092Srdivacky  // Transform the condition.
5339212904Sdim  ExprResult Cond;
5340199990Srdivacky  VarDecl *ConditionVar = 0;
5341199990Srdivacky  if (S->getConditionVariable()) {
5342239462Sdim    ConditionVar
5343199990Srdivacky      = cast_or_null<VarDecl>(
5344204643Srdivacky                   getDerived().TransformDefinition(
5345204643Srdivacky                                      S->getConditionVariable()->getLocation(),
5346204643Srdivacky                                                    S->getConditionVariable()));
5347199990Srdivacky    if (!ConditionVar)
5348212904Sdim      return StmtError();
5349199990Srdivacky  } else {
5350199990Srdivacky    Cond = getDerived().TransformExpr(S->getCond());
5351239462Sdim
5352199990Srdivacky    if (Cond.isInvalid())
5353212904Sdim      return StmtError();
5354199990Srdivacky  }
5355198092Srdivacky
5356198092Srdivacky  // Rebuild the switch statement.
5357212904Sdim  StmtResult Switch
5358212904Sdim    = getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), Cond.get(),
5359208600Srdivacky                                          ConditionVar);
5360198092Srdivacky  if (Switch.isInvalid())
5361212904Sdim    return StmtError();
5362198092Srdivacky
5363198092Srdivacky  // Transform the body of the switch statement.
5364212904Sdim  StmtResult Body = getDerived().TransformStmt(S->getBody());
5365198092Srdivacky  if (Body.isInvalid())
5366212904Sdim    return StmtError();
5367198092Srdivacky
5368198092Srdivacky  // Complete the switch statement.
5369212904Sdim  return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
5370212904Sdim                                            Body.get());
5371198092Srdivacky}
5372198092Srdivacky
5373198092Srdivackytemplate<typename Derived>
5374212904SdimStmtResult
5375198092SrdivackyTreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
5376198092Srdivacky  // Transform the condition
5377212904Sdim  ExprResult Cond;
5378199990Srdivacky  VarDecl *ConditionVar = 0;
5379199990Srdivacky  if (S->getConditionVariable()) {
5380239462Sdim    ConditionVar
5381199990Srdivacky      = cast_or_null<VarDecl>(
5382204643Srdivacky                   getDerived().TransformDefinition(
5383204643Srdivacky                                      S->getConditionVariable()->getLocation(),
5384204643Srdivacky                                                    S->getConditionVariable()));
5385199990Srdivacky    if (!ConditionVar)
5386212904Sdim      return StmtError();
5387199990Srdivacky  } else {
5388199990Srdivacky    Cond = getDerived().TransformExpr(S->getCond());
5389239462Sdim
5390199990Srdivacky    if (Cond.isInvalid())
5391212904Sdim      return StmtError();
5392208600Srdivacky
5393208600Srdivacky    if (S->getCond()) {
5394208600Srdivacky      // Convert the condition to a boolean value.
5395239462Sdim      ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getWhileLoc(),
5396218893Sdim                                                         Cond.get());
5397208600Srdivacky      if (CondE.isInvalid())
5398212904Sdim        return StmtError();
5399212904Sdim      Cond = CondE;
5400208600Srdivacky    }
5401199990Srdivacky  }
5402198092Srdivacky
5403212904Sdim  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
5404212904Sdim  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
5405212904Sdim    return StmtError();
5406198092Srdivacky
5407198092Srdivacky  // Transform the body
5408212904Sdim  StmtResult Body = getDerived().TransformStmt(S->getBody());
5409198092Srdivacky  if (Body.isInvalid())
5410212904Sdim    return StmtError();
5411198092Srdivacky
5412198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
5413212904Sdim      FullCond.get() == S->getCond() &&
5414199990Srdivacky      ConditionVar == S->getConditionVariable() &&
5415198092Srdivacky      Body.get() == S->getBody())
5416212904Sdim    return Owned(S);
5417198092Srdivacky
5418208600Srdivacky  return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond,
5419212904Sdim                                       ConditionVar, Body.get());
5420198092Srdivacky}
5421198092Srdivacky
5422198092Srdivackytemplate<typename Derived>
5423212904SdimStmtResult
5424198092SrdivackyTreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
5425198092Srdivacky  // Transform the body
5426212904Sdim  StmtResult Body = getDerived().TransformStmt(S->getBody());
5427198092Srdivacky  if (Body.isInvalid())
5428212904Sdim    return StmtError();
5429198092Srdivacky
5430208600Srdivacky  // Transform the condition
5431212904Sdim  ExprResult Cond = getDerived().TransformExpr(S->getCond());
5432208600Srdivacky  if (Cond.isInvalid())
5433212904Sdim    return StmtError();
5434239462Sdim
5435198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
5436198092Srdivacky      Cond.get() == S->getCond() &&
5437198092Srdivacky      Body.get() == S->getBody())
5438218893Sdim    return SemaRef.Owned(S);
5439198092Srdivacky
5440212904Sdim  return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
5441212904Sdim                                    /*FIXME:*/S->getWhileLoc(), Cond.get(),
5442198092Srdivacky                                    S->getRParenLoc());
5443198092Srdivacky}
5444198092Srdivacky
5445198092Srdivackytemplate<typename Derived>
5446212904SdimStmtResult
5447198092SrdivackyTreeTransform<Derived>::TransformForStmt(ForStmt *S) {
5448198092Srdivacky  // Transform the initialization statement
5449212904Sdim  StmtResult Init = getDerived().TransformStmt(S->getInit());
5450198092Srdivacky  if (Init.isInvalid())
5451212904Sdim    return StmtError();
5452198092Srdivacky
5453198092Srdivacky  // Transform the condition
5454212904Sdim  ExprResult Cond;
5455199990Srdivacky  VarDecl *ConditionVar = 0;
5456199990Srdivacky  if (S->getConditionVariable()) {
5457239462Sdim    ConditionVar
5458199990Srdivacky      = cast_or_null<VarDecl>(
5459204643Srdivacky                   getDerived().TransformDefinition(
5460204643Srdivacky                                      S->getConditionVariable()->getLocation(),
5461204643Srdivacky                                                    S->getConditionVariable()));
5462199990Srdivacky    if (!ConditionVar)
5463212904Sdim      return StmtError();
5464199990Srdivacky  } else {
5465199990Srdivacky    Cond = getDerived().TransformExpr(S->getCond());
5466239462Sdim
5467199990Srdivacky    if (Cond.isInvalid())
5468212904Sdim      return StmtError();
5469208600Srdivacky
5470208600Srdivacky    if (S->getCond()) {
5471208600Srdivacky      // Convert the condition to a boolean value.
5472239462Sdim      ExprResult CondE = getSema().ActOnBooleanCondition(0, S->getForLoc(),
5473218893Sdim                                                         Cond.get());
5474208600Srdivacky      if (CondE.isInvalid())
5475212904Sdim        return StmtError();
5476208600Srdivacky
5477212904Sdim      Cond = CondE.get();
5478208600Srdivacky    }
5479199990Srdivacky  }
5480198092Srdivacky
5481239462Sdim  Sema::FullExprArg FullCond(getSema().MakeFullExpr(Cond.take()));
5482212904Sdim  if (!S->getConditionVariable() && S->getCond() && !FullCond.get())
5483212904Sdim    return StmtError();
5484208600Srdivacky
5485198092Srdivacky  // Transform the increment
5486212904Sdim  ExprResult Inc = getDerived().TransformExpr(S->getInc());
5487198092Srdivacky  if (Inc.isInvalid())
5488212904Sdim    return StmtError();
5489198092Srdivacky
5490249423Sdim  Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
5491212904Sdim  if (S->getInc() && !FullInc.get())
5492212904Sdim    return StmtError();
5493208600Srdivacky
5494198092Srdivacky  // Transform the body
5495212904Sdim  StmtResult Body = getDerived().TransformStmt(S->getBody());
5496198092Srdivacky  if (Body.isInvalid())
5497212904Sdim    return StmtError();
5498198092Srdivacky
5499198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
5500198092Srdivacky      Init.get() == S->getInit() &&
5501212904Sdim      FullCond.get() == S->getCond() &&
5502198092Srdivacky      Inc.get() == S->getInc() &&
5503198092Srdivacky      Body.get() == S->getBody())
5504218893Sdim    return SemaRef.Owned(S);
5505198092Srdivacky
5506198092Srdivacky  return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
5507212904Sdim                                     Init.get(), FullCond, ConditionVar,
5508212904Sdim                                     FullInc, S->getRParenLoc(), Body.get());
5509198092Srdivacky}
5510198092Srdivacky
5511198092Srdivackytemplate<typename Derived>
5512212904SdimStmtResult
5513198092SrdivackyTreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
5514218893Sdim  Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
5515218893Sdim                                        S->getLabel());
5516218893Sdim  if (!LD)
5517218893Sdim    return StmtError();
5518239462Sdim
5519198092Srdivacky  // Goto statements must always be rebuilt, to resolve the label.
5520198092Srdivacky  return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
5521218893Sdim                                      cast<LabelDecl>(LD));
5522198092Srdivacky}
5523198092Srdivacky
5524198092Srdivackytemplate<typename Derived>
5525212904SdimStmtResult
5526198092SrdivackyTreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
5527212904Sdim  ExprResult Target = getDerived().TransformExpr(S->getTarget());
5528198092Srdivacky  if (Target.isInvalid())
5529212904Sdim    return StmtError();
5530234353Sdim  Target = SemaRef.MaybeCreateExprWithCleanups(Target.take());
5531198092Srdivacky
5532198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
5533198092Srdivacky      Target.get() == S->getTarget())
5534218893Sdim    return SemaRef.Owned(S);
5535198092Srdivacky
5536198092Srdivacky  return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
5537212904Sdim                                              Target.get());
5538198092Srdivacky}
5539198092Srdivacky
5540198092Srdivackytemplate<typename Derived>
5541212904SdimStmtResult
5542198092SrdivackyTreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
5543218893Sdim  return SemaRef.Owned(S);
5544198092Srdivacky}
5545198092Srdivacky
5546198092Srdivackytemplate<typename Derived>
5547212904SdimStmtResult
5548198092SrdivackyTreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
5549218893Sdim  return SemaRef.Owned(S);
5550198092Srdivacky}
5551198092Srdivacky
5552198092Srdivackytemplate<typename Derived>
5553212904SdimStmtResult
5554198092SrdivackyTreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
5555212904Sdim  ExprResult Result = getDerived().TransformExpr(S->getRetValue());
5556198092Srdivacky  if (Result.isInvalid())
5557212904Sdim    return StmtError();
5558198092Srdivacky
5559198092Srdivacky  // FIXME: We always rebuild the return statement because there is no way
5560198092Srdivacky  // to tell whether the return type of the function has changed.
5561212904Sdim  return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
5562198092Srdivacky}
5563198092Srdivacky
5564198092Srdivackytemplate<typename Derived>
5565212904SdimStmtResult
5566198092SrdivackyTreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
5567198092Srdivacky  bool DeclChanged = false;
5568226633Sdim  SmallVector<Decl *, 4> Decls;
5569198092Srdivacky  for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
5570198092Srdivacky       D != DEnd; ++D) {
5571204643Srdivacky    Decl *Transformed = getDerived().TransformDefinition((*D)->getLocation(),
5572204643Srdivacky                                                         *D);
5573198092Srdivacky    if (!Transformed)
5574212904Sdim      return StmtError();
5575198092Srdivacky
5576198092Srdivacky    if (Transformed != *D)
5577198092Srdivacky      DeclChanged = true;
5578198092Srdivacky
5579198092Srdivacky    Decls.push_back(Transformed);
5580198092Srdivacky  }
5581198092Srdivacky
5582198092Srdivacky  if (!getDerived().AlwaysRebuild() && !DeclChanged)
5583218893Sdim    return SemaRef.Owned(S);
5584198092Srdivacky
5585198092Srdivacky  return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
5586198092Srdivacky                                      S->getStartLoc(), S->getEndLoc());
5587198092Srdivacky}
5588198092Srdivacky
5589198092Srdivackytemplate<typename Derived>
5590212904SdimStmtResult
5591243830SdimTreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
5592239462Sdim
5593243830Sdim  SmallVector<Expr*, 8> Constraints;
5594243830Sdim  SmallVector<Expr*, 8> Exprs;
5595226633Sdim  SmallVector<IdentifierInfo *, 4> Names;
5596203955Srdivacky
5597212904Sdim  ExprResult AsmString;
5598243830Sdim  SmallVector<Expr*, 8> Clobbers;
5599203955Srdivacky
5600203955Srdivacky  bool ExprsChanged = false;
5601239462Sdim
5602203955Srdivacky  // Go through the outputs.
5603203955Srdivacky  for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
5604203955Srdivacky    Names.push_back(S->getOutputIdentifier(I));
5605239462Sdim
5606203955Srdivacky    // No need to transform the constraint literal.
5607218893Sdim    Constraints.push_back(S->getOutputConstraintLiteral(I));
5608239462Sdim
5609203955Srdivacky    // Transform the output expr.
5610203955Srdivacky    Expr *OutputExpr = S->getOutputExpr(I);
5611212904Sdim    ExprResult Result = getDerived().TransformExpr(OutputExpr);
5612203955Srdivacky    if (Result.isInvalid())
5613212904Sdim      return StmtError();
5614239462Sdim
5615203955Srdivacky    ExprsChanged |= Result.get() != OutputExpr;
5616239462Sdim
5617212904Sdim    Exprs.push_back(Result.get());
5618203955Srdivacky  }
5619239462Sdim
5620203955Srdivacky  // Go through the inputs.
5621203955Srdivacky  for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
5622203955Srdivacky    Names.push_back(S->getInputIdentifier(I));
5623239462Sdim
5624203955Srdivacky    // No need to transform the constraint literal.
5625218893Sdim    Constraints.push_back(S->getInputConstraintLiteral(I));
5626239462Sdim
5627203955Srdivacky    // Transform the input expr.
5628203955Srdivacky    Expr *InputExpr = S->getInputExpr(I);
5629212904Sdim    ExprResult Result = getDerived().TransformExpr(InputExpr);
5630203955Srdivacky    if (Result.isInvalid())
5631212904Sdim      return StmtError();
5632239462Sdim
5633203955Srdivacky    ExprsChanged |= Result.get() != InputExpr;
5634239462Sdim
5635212904Sdim    Exprs.push_back(Result.get());
5636203955Srdivacky  }
5637239462Sdim
5638203955Srdivacky  if (!getDerived().AlwaysRebuild() && !ExprsChanged)
5639218893Sdim    return SemaRef.Owned(S);
5640203955Srdivacky
5641203955Srdivacky  // Go through the clobbers.
5642203955Srdivacky  for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I)
5643243830Sdim    Clobbers.push_back(S->getClobberStringLiteral(I));
5644203955Srdivacky
5645203955Srdivacky  // No need to transform the asm string literal.
5646203955Srdivacky  AsmString = SemaRef.Owned(S->getAsmString());
5647243830Sdim  return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
5648243830Sdim                                        S->isVolatile(), S->getNumOutputs(),
5649243830Sdim                                        S->getNumInputs(), Names.data(),
5650243830Sdim                                        Constraints, Exprs, AsmString.get(),
5651243830Sdim                                        Clobbers, S->getRParenLoc());
5652198092Srdivacky}
5653198092Srdivacky
5654239462Sdimtemplate<typename Derived>
5655239462SdimStmtResult
5656239462SdimTreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
5657239462Sdim  ArrayRef<Token> AsmToks =
5658239462Sdim    llvm::makeArrayRef(S->getAsmToks(), S->getNumAsmToks());
5659198092Srdivacky
5660251662Sdim  bool HadError = false, HadChange = false;
5661251662Sdim
5662251662Sdim  ArrayRef<Expr*> SrcExprs = S->getAllExprs();
5663251662Sdim  SmallVector<Expr*, 8> TransformedExprs;
5664251662Sdim  TransformedExprs.reserve(SrcExprs.size());
5665251662Sdim  for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
5666251662Sdim    ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
5667251662Sdim    if (!Result.isUsable()) {
5668251662Sdim      HadError = true;
5669251662Sdim    } else {
5670251662Sdim      HadChange |= (Result.get() != SrcExprs[i]);
5671251662Sdim      TransformedExprs.push_back(Result.take());
5672251662Sdim    }
5673251662Sdim  }
5674251662Sdim
5675251662Sdim  if (HadError) return StmtError();
5676251662Sdim  if (!HadChange && !getDerived().AlwaysRebuild())
5677251662Sdim    return Owned(S);
5678251662Sdim
5679239462Sdim  return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
5680251662Sdim                                       AsmToks, S->getAsmString(),
5681251662Sdim                                       S->getNumOutputs(), S->getNumInputs(),
5682251662Sdim                                       S->getAllConstraints(), S->getClobbers(),
5683251662Sdim                                       TransformedExprs, S->getEndLoc());
5684239462Sdim}
5685239462Sdim
5686198092Srdivackytemplate<typename Derived>
5687212904SdimStmtResult
5688198092SrdivackyTreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
5689207619Srdivacky  // Transform the body of the @try.
5690212904Sdim  StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
5691207619Srdivacky  if (TryBody.isInvalid())
5692212904Sdim    return StmtError();
5693239462Sdim
5694207619Srdivacky  // Transform the @catch statements (if present).
5695207619Srdivacky  bool AnyCatchChanged = false;
5696243830Sdim  SmallVector<Stmt*, 8> CatchStmts;
5697207619Srdivacky  for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
5698212904Sdim    StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
5699207619Srdivacky    if (Catch.isInvalid())
5700212904Sdim      return StmtError();
5701207619Srdivacky    if (Catch.get() != S->getCatchStmt(I))
5702207619Srdivacky      AnyCatchChanged = true;
5703207619Srdivacky    CatchStmts.push_back(Catch.release());
5704207619Srdivacky  }
5705239462Sdim
5706207619Srdivacky  // Transform the @finally statement (if present).
5707212904Sdim  StmtResult Finally;
5708207619Srdivacky  if (S->getFinallyStmt()) {
5709207619Srdivacky    Finally = getDerived().TransformStmt(S->getFinallyStmt());
5710207619Srdivacky    if (Finally.isInvalid())
5711212904Sdim      return StmtError();
5712207619Srdivacky  }
5713207619Srdivacky
5714207619Srdivacky  // If nothing changed, just retain this statement.
5715207619Srdivacky  if (!getDerived().AlwaysRebuild() &&
5716207619Srdivacky      TryBody.get() == S->getTryBody() &&
5717207619Srdivacky      !AnyCatchChanged &&
5718207619Srdivacky      Finally.get() == S->getFinallyStmt())
5719218893Sdim    return SemaRef.Owned(S);
5720239462Sdim
5721207619Srdivacky  // Build a new statement.
5722212904Sdim  return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
5723243830Sdim                                           CatchStmts, Finally.get());
5724198092Srdivacky}
5725198092Srdivacky
5726198092Srdivackytemplate<typename Derived>
5727212904SdimStmtResult
5728198092SrdivackyTreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
5729207619Srdivacky  // Transform the @catch parameter, if there is one.
5730207619Srdivacky  VarDecl *Var = 0;
5731207619Srdivacky  if (VarDecl *FromVar = S->getCatchParamDecl()) {
5732207619Srdivacky    TypeSourceInfo *TSInfo = 0;
5733207619Srdivacky    if (FromVar->getTypeSourceInfo()) {
5734207619Srdivacky      TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
5735207619Srdivacky      if (!TSInfo)
5736212904Sdim        return StmtError();
5737207619Srdivacky    }
5738239462Sdim
5739207619Srdivacky    QualType T;
5740207619Srdivacky    if (TSInfo)
5741207619Srdivacky      T = TSInfo->getType();
5742207619Srdivacky    else {
5743207619Srdivacky      T = getDerived().TransformType(FromVar->getType());
5744207619Srdivacky      if (T.isNull())
5745239462Sdim        return StmtError();
5746207619Srdivacky    }
5747239462Sdim
5748207619Srdivacky    Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
5749207619Srdivacky    if (!Var)
5750212904Sdim      return StmtError();
5751207619Srdivacky  }
5752239462Sdim
5753212904Sdim  StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
5754207619Srdivacky  if (Body.isInvalid())
5755212904Sdim    return StmtError();
5756239462Sdim
5757239462Sdim  return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
5758207619Srdivacky                                             S->getRParenLoc(),
5759212904Sdim                                             Var, Body.get());
5760198092Srdivacky}
5761198092Srdivacky
5762198092Srdivackytemplate<typename Derived>
5763212904SdimStmtResult
5764198092SrdivackyTreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
5765207619Srdivacky  // Transform the body.
5766212904Sdim  StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
5767207619Srdivacky  if (Body.isInvalid())
5768212904Sdim    return StmtError();
5769239462Sdim
5770207619Srdivacky  // If nothing changed, just retain this statement.
5771207619Srdivacky  if (!getDerived().AlwaysRebuild() &&
5772207619Srdivacky      Body.get() == S->getFinallyBody())
5773218893Sdim    return SemaRef.Owned(S);
5774207619Srdivacky
5775207619Srdivacky  // Build a new statement.
5776207619Srdivacky  return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
5777212904Sdim                                               Body.get());
5778198092Srdivacky}
5779198092Srdivacky
5780198092Srdivackytemplate<typename Derived>
5781212904SdimStmtResult
5782198092SrdivackyTreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
5783212904Sdim  ExprResult Operand;
5784207619Srdivacky  if (S->getThrowExpr()) {
5785207619Srdivacky    Operand = getDerived().TransformExpr(S->getThrowExpr());
5786207619Srdivacky    if (Operand.isInvalid())
5787212904Sdim      return StmtError();
5788207619Srdivacky  }
5789239462Sdim
5790207619Srdivacky  if (!getDerived().AlwaysRebuild() &&
5791207619Srdivacky      Operand.get() == S->getThrowExpr())
5792218893Sdim    return getSema().Owned(S);
5793239462Sdim
5794212904Sdim  return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
5795198092Srdivacky}
5796198092Srdivacky
5797198092Srdivackytemplate<typename Derived>
5798212904SdimStmtResult
5799198092SrdivackyTreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
5800198092Srdivacky                                                  ObjCAtSynchronizedStmt *S) {
5801207619Srdivacky  // Transform the object we are locking.
5802212904Sdim  ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
5803207619Srdivacky  if (Object.isInvalid())
5804212904Sdim    return StmtError();
5805226633Sdim  Object =
5806226633Sdim    getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
5807226633Sdim                                                  Object.get());
5808226633Sdim  if (Object.isInvalid())
5809226633Sdim    return StmtError();
5810239462Sdim
5811207619Srdivacky  // Transform the body.
5812212904Sdim  StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
5813207619Srdivacky  if (Body.isInvalid())
5814212904Sdim    return StmtError();
5815239462Sdim
5816207619Srdivacky  // If nothing change, just retain the current statement.
5817207619Srdivacky  if (!getDerived().AlwaysRebuild() &&
5818207619Srdivacky      Object.get() == S->getSynchExpr() &&
5819207619Srdivacky      Body.get() == S->getSynchBody())
5820218893Sdim    return SemaRef.Owned(S);
5821207619Srdivacky
5822207619Srdivacky  // Build a new statement.
5823207619Srdivacky  return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
5824212904Sdim                                                    Object.get(), Body.get());
5825198092Srdivacky}
5826198092Srdivacky
5827198092Srdivackytemplate<typename Derived>
5828212904SdimStmtResult
5829224145SdimTreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
5830224145Sdim                                              ObjCAutoreleasePoolStmt *S) {
5831224145Sdim  // Transform the body.
5832224145Sdim  StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
5833224145Sdim  if (Body.isInvalid())
5834224145Sdim    return StmtError();
5835239462Sdim
5836224145Sdim  // If nothing changed, just retain this statement.
5837224145Sdim  if (!getDerived().AlwaysRebuild() &&
5838224145Sdim      Body.get() == S->getSubStmt())
5839224145Sdim    return SemaRef.Owned(S);
5840224145Sdim
5841224145Sdim  // Build a new statement.
5842224145Sdim  return getDerived().RebuildObjCAutoreleasePoolStmt(
5843224145Sdim                        S->getAtLoc(), Body.get());
5844224145Sdim}
5845224145Sdim
5846224145Sdimtemplate<typename Derived>
5847224145SdimStmtResult
5848198092SrdivackyTreeTransform<Derived>::TransformObjCForCollectionStmt(
5849198092Srdivacky                                                  ObjCForCollectionStmt *S) {
5850207619Srdivacky  // Transform the element statement.
5851212904Sdim  StmtResult Element = getDerived().TransformStmt(S->getElement());
5852207619Srdivacky  if (Element.isInvalid())
5853212904Sdim    return StmtError();
5854239462Sdim
5855207619Srdivacky  // Transform the collection expression.
5856212904Sdim  ExprResult Collection = getDerived().TransformExpr(S->getCollection());
5857207619Srdivacky  if (Collection.isInvalid())
5858212904Sdim    return StmtError();
5859239462Sdim
5860207619Srdivacky  // Transform the body.
5861212904Sdim  StmtResult Body = getDerived().TransformStmt(S->getBody());
5862207619Srdivacky  if (Body.isInvalid())
5863212904Sdim    return StmtError();
5864239462Sdim
5865207619Srdivacky  // If nothing changed, just retain this statement.
5866207619Srdivacky  if (!getDerived().AlwaysRebuild() &&
5867207619Srdivacky      Element.get() == S->getElement() &&
5868207619Srdivacky      Collection.get() == S->getCollection() &&
5869207619Srdivacky      Body.get() == S->getBody())
5870218893Sdim    return SemaRef.Owned(S);
5871239462Sdim
5872207619Srdivacky  // Build a new statement.
5873207619Srdivacky  return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
5874212904Sdim                                                   Element.get(),
5875212904Sdim                                                   Collection.get(),
5876207619Srdivacky                                                   S->getRParenLoc(),
5877212904Sdim                                                   Body.get());
5878198092Srdivacky}
5879198092Srdivacky
5880198092Srdivacky
5881198092Srdivackytemplate<typename Derived>
5882212904SdimStmtResult
5883198092SrdivackyTreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
5884198092Srdivacky  // Transform the exception declaration, if any.
5885198092Srdivacky  VarDecl *Var = 0;
5886198092Srdivacky  if (S->getExceptionDecl()) {
5887198092Srdivacky    VarDecl *ExceptionDecl = S->getExceptionDecl();
5888218893Sdim    TypeSourceInfo *T = getDerived().TransformType(
5889218893Sdim                                            ExceptionDecl->getTypeSourceInfo());
5890218893Sdim    if (!T)
5891212904Sdim      return StmtError();
5892198092Srdivacky
5893218893Sdim    Var = getDerived().RebuildExceptionDecl(ExceptionDecl, T,
5894221345Sdim                                            ExceptionDecl->getInnerLocStart(),
5895221345Sdim                                            ExceptionDecl->getLocation(),
5896221345Sdim                                            ExceptionDecl->getIdentifier());
5897212904Sdim    if (!Var || Var->isInvalidDecl())
5898212904Sdim      return StmtError();
5899198092Srdivacky  }
5900198092Srdivacky
5901198092Srdivacky  // Transform the actual exception handler.
5902212904Sdim  StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
5903212904Sdim  if (Handler.isInvalid())
5904212904Sdim    return StmtError();
5905198092Srdivacky
5906198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
5907198092Srdivacky      !Var &&
5908198092Srdivacky      Handler.get() == S->getHandlerBlock())
5909218893Sdim    return SemaRef.Owned(S);
5910198092Srdivacky
5911198092Srdivacky  return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
5912198092Srdivacky                                          Var,
5913212904Sdim                                          Handler.get());
5914198092Srdivacky}
5915198092Srdivacky
5916198092Srdivackytemplate<typename Derived>
5917212904SdimStmtResult
5918198092SrdivackyTreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
5919198092Srdivacky  // Transform the try block itself.
5920212904Sdim  StmtResult TryBlock
5921198092Srdivacky    = getDerived().TransformCompoundStmt(S->getTryBlock());
5922198092Srdivacky  if (TryBlock.isInvalid())
5923212904Sdim    return StmtError();
5924198092Srdivacky
5925198092Srdivacky  // Transform the handlers.
5926198092Srdivacky  bool HandlerChanged = false;
5927243830Sdim  SmallVector<Stmt*, 8> Handlers;
5928198092Srdivacky  for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
5929212904Sdim    StmtResult Handler
5930198092Srdivacky      = getDerived().TransformCXXCatchStmt(S->getHandler(I));
5931198092Srdivacky    if (Handler.isInvalid())
5932212904Sdim      return StmtError();
5933198092Srdivacky
5934198092Srdivacky    HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
5935198092Srdivacky    Handlers.push_back(Handler.takeAs<Stmt>());
5936198092Srdivacky  }
5937198092Srdivacky
5938198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
5939198092Srdivacky      TryBlock.get() == S->getTryBlock() &&
5940198092Srdivacky      !HandlerChanged)
5941218893Sdim    return SemaRef.Owned(S);
5942198092Srdivacky
5943212904Sdim  return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
5944243830Sdim                                        Handlers);
5945198092Srdivacky}
5946198092Srdivacky
5947221345Sdimtemplate<typename Derived>
5948221345SdimStmtResult
5949221345SdimTreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
5950221345Sdim  StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
5951221345Sdim  if (Range.isInvalid())
5952221345Sdim    return StmtError();
5953221345Sdim
5954221345Sdim  StmtResult BeginEnd = getDerived().TransformStmt(S->getBeginEndStmt());
5955221345Sdim  if (BeginEnd.isInvalid())
5956221345Sdim    return StmtError();
5957221345Sdim
5958221345Sdim  ExprResult Cond = getDerived().TransformExpr(S->getCond());
5959221345Sdim  if (Cond.isInvalid())
5960221345Sdim    return StmtError();
5961234353Sdim  if (Cond.get())
5962234353Sdim    Cond = SemaRef.CheckBooleanCondition(Cond.take(), S->getColonLoc());
5963234353Sdim  if (Cond.isInvalid())
5964234353Sdim    return StmtError();
5965234353Sdim  if (Cond.get())
5966234353Sdim    Cond = SemaRef.MaybeCreateExprWithCleanups(Cond.take());
5967221345Sdim
5968221345Sdim  ExprResult Inc = getDerived().TransformExpr(S->getInc());
5969221345Sdim  if (Inc.isInvalid())
5970221345Sdim    return StmtError();
5971234353Sdim  if (Inc.get())
5972234353Sdim    Inc = SemaRef.MaybeCreateExprWithCleanups(Inc.take());
5973221345Sdim
5974221345Sdim  StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
5975221345Sdim  if (LoopVar.isInvalid())
5976221345Sdim    return StmtError();
5977221345Sdim
5978221345Sdim  StmtResult NewStmt = S;
5979221345Sdim  if (getDerived().AlwaysRebuild() ||
5980221345Sdim      Range.get() != S->getRangeStmt() ||
5981221345Sdim      BeginEnd.get() != S->getBeginEndStmt() ||
5982221345Sdim      Cond.get() != S->getCond() ||
5983221345Sdim      Inc.get() != S->getInc() ||
5984251662Sdim      LoopVar.get() != S->getLoopVarStmt()) {
5985221345Sdim    NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
5986221345Sdim                                                  S->getColonLoc(), Range.get(),
5987221345Sdim                                                  BeginEnd.get(), Cond.get(),
5988221345Sdim                                                  Inc.get(), LoopVar.get(),
5989221345Sdim                                                  S->getRParenLoc());
5990251662Sdim    if (NewStmt.isInvalid())
5991251662Sdim      return StmtError();
5992251662Sdim  }
5993221345Sdim
5994221345Sdim  StmtResult Body = getDerived().TransformStmt(S->getBody());
5995221345Sdim  if (Body.isInvalid())
5996221345Sdim    return StmtError();
5997221345Sdim
5998221345Sdim  // Body has changed but we didn't rebuild the for-range statement. Rebuild
5999221345Sdim  // it now so we have a new statement to attach the body to.
6000251662Sdim  if (Body.get() != S->getBody() && NewStmt.get() == S) {
6001221345Sdim    NewStmt = getDerived().RebuildCXXForRangeStmt(S->getForLoc(),
6002221345Sdim                                                  S->getColonLoc(), Range.get(),
6003221345Sdim                                                  BeginEnd.get(), Cond.get(),
6004221345Sdim                                                  Inc.get(), LoopVar.get(),
6005221345Sdim                                                  S->getRParenLoc());
6006251662Sdim    if (NewStmt.isInvalid())
6007251662Sdim      return StmtError();
6008251662Sdim  }
6009221345Sdim
6010221345Sdim  if (NewStmt.get() == S)
6011221345Sdim    return SemaRef.Owned(S);
6012221345Sdim
6013221345Sdim  return FinishCXXForRangeStmt(NewStmt.get(), Body.get());
6014221345Sdim}
6015221345Sdim
6016221345Sdimtemplate<typename Derived>
6017221345SdimStmtResult
6018234353SdimTreeTransform<Derived>::TransformMSDependentExistsStmt(
6019234353Sdim                                                    MSDependentExistsStmt *S) {
6020234353Sdim  // Transform the nested-name-specifier, if any.
6021234353Sdim  NestedNameSpecifierLoc QualifierLoc;
6022234353Sdim  if (S->getQualifierLoc()) {
6023239462Sdim    QualifierLoc
6024234353Sdim      = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
6025234353Sdim    if (!QualifierLoc)
6026234353Sdim      return StmtError();
6027234353Sdim  }
6028234353Sdim
6029234353Sdim  // Transform the declaration name.
6030234353Sdim  DeclarationNameInfo NameInfo = S->getNameInfo();
6031234353Sdim  if (NameInfo.getName()) {
6032234353Sdim    NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
6033234353Sdim    if (!NameInfo.getName())
6034234353Sdim      return StmtError();
6035234353Sdim  }
6036234353Sdim
6037234353Sdim  // Check whether anything changed.
6038234353Sdim  if (!getDerived().AlwaysRebuild() &&
6039234353Sdim      QualifierLoc == S->getQualifierLoc() &&
6040234353Sdim      NameInfo.getName() == S->getNameInfo().getName())
6041234353Sdim    return S;
6042239462Sdim
6043234353Sdim  // Determine whether this name exists, if we can.
6044234353Sdim  CXXScopeSpec SS;
6045234353Sdim  SS.Adopt(QualifierLoc);
6046234353Sdim  bool Dependent = false;
6047234353Sdim  switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/0, SS, NameInfo)) {
6048234353Sdim  case Sema::IER_Exists:
6049234353Sdim    if (S->isIfExists())
6050234353Sdim      break;
6051239462Sdim
6052234353Sdim    return new (getSema().Context) NullStmt(S->getKeywordLoc());
6053234353Sdim
6054234353Sdim  case Sema::IER_DoesNotExist:
6055234353Sdim    if (S->isIfNotExists())
6056234353Sdim      break;
6057239462Sdim
6058234353Sdim    return new (getSema().Context) NullStmt(S->getKeywordLoc());
6059239462Sdim
6060234353Sdim  case Sema::IER_Dependent:
6061234353Sdim    Dependent = true;
6062234353Sdim    break;
6063239462Sdim
6064234353Sdim  case Sema::IER_Error:
6065234353Sdim    return StmtError();
6066234353Sdim  }
6067239462Sdim
6068234353Sdim  // We need to continue with the instantiation, so do so now.
6069234353Sdim  StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
6070234353Sdim  if (SubStmt.isInvalid())
6071234353Sdim    return StmtError();
6072239462Sdim
6073234353Sdim  // If we have resolved the name, just transform to the substatement.
6074234353Sdim  if (!Dependent)
6075234353Sdim    return SubStmt;
6076239462Sdim
6077234353Sdim  // The name is still dependent, so build a dependent expression again.
6078234353Sdim  return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
6079234353Sdim                                                   S->isIfExists(),
6080234353Sdim                                                   QualifierLoc,
6081234353Sdim                                                   NameInfo,
6082234353Sdim                                                   SubStmt.get());
6083234353Sdim}
6084234353Sdim
6085234353Sdimtemplate<typename Derived>
6086251662SdimExprResult
6087251662SdimTreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
6088251662Sdim  NestedNameSpecifierLoc QualifierLoc;
6089251662Sdim  if (E->getQualifierLoc()) {
6090251662Sdim    QualifierLoc
6091251662Sdim    = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
6092251662Sdim    if (!QualifierLoc)
6093251662Sdim      return ExprError();
6094251662Sdim  }
6095251662Sdim
6096251662Sdim  MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
6097251662Sdim    getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
6098251662Sdim  if (!PD)
6099251662Sdim    return ExprError();
6100251662Sdim
6101251662Sdim  ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
6102251662Sdim  if (Base.isInvalid())
6103251662Sdim    return ExprError();
6104251662Sdim
6105251662Sdim  return new (SemaRef.getASTContext())
6106251662Sdim      MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
6107251662Sdim                        SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
6108251662Sdim                        QualifierLoc, E->getMemberLoc());
6109251662Sdim}
6110251662Sdim
6111251662Sdimtemplate<typename Derived>
6112234353SdimStmtResult
6113221345SdimTreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
6114221345Sdim  StmtResult TryBlock; //  = getDerived().TransformCompoundStmt(S->getTryBlock());
6115221345Sdim  if(TryBlock.isInvalid()) return StmtError();
6116221345Sdim
6117221345Sdim  StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
6118221345Sdim  if(!getDerived().AlwaysRebuild() &&
6119221345Sdim     TryBlock.get() == S->getTryBlock() &&
6120221345Sdim     Handler.get() == S->getHandler())
6121221345Sdim    return SemaRef.Owned(S);
6122221345Sdim
6123221345Sdim  return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(),
6124221345Sdim                                        S->getTryLoc(),
6125221345Sdim                                        TryBlock.take(),
6126221345Sdim                                        Handler.take());
6127221345Sdim}
6128221345Sdim
6129221345Sdimtemplate<typename Derived>
6130221345SdimStmtResult
6131221345SdimTreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
6132221345Sdim  StmtResult Block; //  = getDerived().TransformCompoundStatement(S->getBlock());
6133221345Sdim  if(Block.isInvalid()) return StmtError();
6134221345Sdim
6135221345Sdim  return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(),
6136221345Sdim                                            Block.take());
6137221345Sdim}
6138221345Sdim
6139221345Sdimtemplate<typename Derived>
6140221345SdimStmtResult
6141221345SdimTreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
6142221345Sdim  ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
6143221345Sdim  if(FilterExpr.isInvalid()) return StmtError();
6144221345Sdim
6145221345Sdim  StmtResult Block; //  = getDerived().TransformCompoundStatement(S->getBlock());
6146221345Sdim  if(Block.isInvalid()) return StmtError();
6147221345Sdim
6148221345Sdim  return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(),
6149221345Sdim                                           FilterExpr.take(),
6150221345Sdim                                           Block.take());
6151221345Sdim}
6152221345Sdim
6153221345Sdimtemplate<typename Derived>
6154221345SdimStmtResult
6155221345SdimTreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
6156221345Sdim  if(isa<SEHFinallyStmt>(Handler))
6157221345Sdim    return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
6158221345Sdim  else
6159221345Sdim    return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
6160221345Sdim}
6161221345Sdim
6162198092Srdivacky//===----------------------------------------------------------------------===//
6163198092Srdivacky// Expression transformation
6164198092Srdivacky//===----------------------------------------------------------------------===//
6165198092Srdivackytemplate<typename Derived>
6166212904SdimExprResult
6167200583SrdivackyTreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
6168218893Sdim  return SemaRef.Owned(E);
6169198092Srdivacky}
6170198092Srdivacky
6171198092Srdivackytemplate<typename Derived>
6172212904SdimExprResult
6173200583SrdivackyTreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
6174221345Sdim  NestedNameSpecifierLoc QualifierLoc;
6175221345Sdim  if (E->getQualifierLoc()) {
6176221345Sdim    QualifierLoc
6177221345Sdim      = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
6178221345Sdim    if (!QualifierLoc)
6179212904Sdim      return ExprError();
6180198893Srdivacky  }
6181200583Srdivacky
6182200583Srdivacky  ValueDecl *ND
6183204643Srdivacky    = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
6184204643Srdivacky                                                         E->getDecl()));
6185198092Srdivacky  if (!ND)
6186212904Sdim    return ExprError();
6187198092Srdivacky
6188212904Sdim  DeclarationNameInfo NameInfo = E->getNameInfo();
6189212904Sdim  if (NameInfo.getName()) {
6190212904Sdim    NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
6191212904Sdim    if (!NameInfo.getName())
6192212904Sdim      return ExprError();
6193212904Sdim  }
6194212904Sdim
6195212904Sdim  if (!getDerived().AlwaysRebuild() &&
6196221345Sdim      QualifierLoc == E->getQualifierLoc() &&
6197198893Srdivacky      ND == E->getDecl() &&
6198212904Sdim      NameInfo.getName() == E->getDecl()->getDeclName() &&
6199212904Sdim      !E->hasExplicitTemplateArgs()) {
6200200583Srdivacky
6201200583Srdivacky    // Mark it referenced in the new context regardless.
6202200583Srdivacky    // FIXME: this is a bit instantiation-specific.
6203234353Sdim    SemaRef.MarkDeclRefReferenced(E);
6204200583Srdivacky
6205218893Sdim    return SemaRef.Owned(E);
6206200583Srdivacky  }
6207198092Srdivacky
6208200583Srdivacky  TemplateArgumentListInfo TransArgs, *TemplateArgs = 0;
6209212904Sdim  if (E->hasExplicitTemplateArgs()) {
6210200583Srdivacky    TemplateArgs = &TransArgs;
6211200583Srdivacky    TransArgs.setLAngleLoc(E->getLAngleLoc());
6212200583Srdivacky    TransArgs.setRAngleLoc(E->getRAngleLoc());
6213218893Sdim    if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
6214218893Sdim                                                E->getNumTemplateArgs(),
6215218893Sdim                                                TransArgs))
6216218893Sdim      return ExprError();
6217200583Srdivacky  }
6218198893Srdivacky
6219239462Sdim  return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
6220221345Sdim                                         TemplateArgs);
6221198092Srdivacky}
6222198092Srdivacky
6223198092Srdivackytemplate<typename Derived>
6224212904SdimExprResult
6225200583SrdivackyTreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
6226218893Sdim  return SemaRef.Owned(E);
6227198092Srdivacky}
6228198092Srdivacky
6229198092Srdivackytemplate<typename Derived>
6230212904SdimExprResult
6231200583SrdivackyTreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
6232218893Sdim  return SemaRef.Owned(E);
6233198092Srdivacky}
6234198092Srdivacky
6235198092Srdivackytemplate<typename Derived>
6236212904SdimExprResult
6237200583SrdivackyTreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
6238218893Sdim  return SemaRef.Owned(E);
6239198092Srdivacky}
6240198092Srdivacky
6241198092Srdivackytemplate<typename Derived>
6242212904SdimExprResult
6243200583SrdivackyTreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
6244218893Sdim  return SemaRef.Owned(E);
6245198092Srdivacky}
6246198092Srdivacky
6247198092Srdivackytemplate<typename Derived>
6248212904SdimExprResult
6249200583SrdivackyTreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
6250218893Sdim  return SemaRef.Owned(E);
6251198092Srdivacky}
6252198092Srdivacky
6253198092Srdivackytemplate<typename Derived>
6254212904SdimExprResult
6255234353SdimTreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
6256251662Sdim  if (FunctionDecl *FD = E->getDirectCallee())
6257251662Sdim    SemaRef.MarkFunctionReferenced(E->getLocStart(), FD);
6258234353Sdim  return SemaRef.MaybeBindToTemporary(E);
6259234353Sdim}
6260234353Sdim
6261234353Sdimtemplate<typename Derived>
6262234353SdimExprResult
6263221345SdimTreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
6264221345Sdim  ExprResult ControllingExpr =
6265221345Sdim    getDerived().TransformExpr(E->getControllingExpr());
6266221345Sdim  if (ControllingExpr.isInvalid())
6267221345Sdim    return ExprError();
6268221345Sdim
6269226633Sdim  SmallVector<Expr *, 4> AssocExprs;
6270226633Sdim  SmallVector<TypeSourceInfo *, 4> AssocTypes;
6271221345Sdim  for (unsigned i = 0; i != E->getNumAssocs(); ++i) {
6272221345Sdim    TypeSourceInfo *TS = E->getAssocTypeSourceInfo(i);
6273221345Sdim    if (TS) {
6274221345Sdim      TypeSourceInfo *AssocType = getDerived().TransformType(TS);
6275221345Sdim      if (!AssocType)
6276221345Sdim        return ExprError();
6277221345Sdim      AssocTypes.push_back(AssocType);
6278221345Sdim    } else {
6279221345Sdim      AssocTypes.push_back(0);
6280221345Sdim    }
6281221345Sdim
6282221345Sdim    ExprResult AssocExpr = getDerived().TransformExpr(E->getAssocExpr(i));
6283221345Sdim    if (AssocExpr.isInvalid())
6284221345Sdim      return ExprError();
6285221345Sdim    AssocExprs.push_back(AssocExpr.release());
6286221345Sdim  }
6287221345Sdim
6288221345Sdim  return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
6289221345Sdim                                                  E->getDefaultLoc(),
6290221345Sdim                                                  E->getRParenLoc(),
6291221345Sdim                                                  ControllingExpr.release(),
6292221345Sdim                                                  AssocTypes.data(),
6293221345Sdim                                                  AssocExprs.data(),
6294221345Sdim                                                  E->getNumAssocs());
6295221345Sdim}
6296221345Sdim
6297221345Sdimtemplate<typename Derived>
6298221345SdimExprResult
6299200583SrdivackyTreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
6300212904Sdim  ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
6301198092Srdivacky  if (SubExpr.isInvalid())
6302212904Sdim    return ExprError();
6303198092Srdivacky
6304198092Srdivacky  if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
6305218893Sdim    return SemaRef.Owned(E);
6306198092Srdivacky
6307212904Sdim  return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
6308198092Srdivacky                                       E->getRParen());
6309198092Srdivacky}
6310198092Srdivacky
6311243830Sdim/// \brief The operand of a unary address-of operator has special rules: it's
6312243830Sdim/// allowed to refer to a non-static member of a class even if there's no 'this'
6313243830Sdim/// object available.
6314198092Srdivackytemplate<typename Derived>
6315212904SdimExprResult
6316243830SdimTreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
6317243830Sdim  if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
6318243830Sdim    return getDerived().TransformDependentScopeDeclRefExpr(DRE, true);
6319243830Sdim  else
6320243830Sdim    return getDerived().TransformExpr(E);
6321243830Sdim}
6322243830Sdim
6323243830Sdimtemplate<typename Derived>
6324243830SdimExprResult
6325200583SrdivackyTreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
6326243830Sdim  ExprResult SubExpr = TransformAddressOfOperand(E->getSubExpr());
6327198092Srdivacky  if (SubExpr.isInvalid())
6328212904Sdim    return ExprError();
6329198092Srdivacky
6330198092Srdivacky  if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
6331218893Sdim    return SemaRef.Owned(E);
6332198092Srdivacky
6333198092Srdivacky  return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
6334198092Srdivacky                                           E->getOpcode(),
6335212904Sdim                                           SubExpr.get());
6336198092Srdivacky}
6337198092Srdivacky
6338198092Srdivackytemplate<typename Derived>
6339212904SdimExprResult
6340207619SrdivackyTreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
6341207619Srdivacky  // Transform the type.
6342207619Srdivacky  TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
6343207619Srdivacky  if (!Type)
6344212904Sdim    return ExprError();
6345239462Sdim
6346207619Srdivacky  // Transform all of the components into components similar to what the
6347207619Srdivacky  // parser uses.
6348239462Sdim  // FIXME: It would be slightly more efficient in the non-dependent case to
6349239462Sdim  // just map FieldDecls, rather than requiring the rebuilder to look for
6350239462Sdim  // the fields again. However, __builtin_offsetof is rare enough in
6351207619Srdivacky  // template code that we don't care.
6352207619Srdivacky  bool ExprChanged = false;
6353212904Sdim  typedef Sema::OffsetOfComponent Component;
6354207619Srdivacky  typedef OffsetOfExpr::OffsetOfNode Node;
6355226633Sdim  SmallVector<Component, 4> Components;
6356207619Srdivacky  for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
6357207619Srdivacky    const Node &ON = E->getComponent(I);
6358207619Srdivacky    Component Comp;
6359207619Srdivacky    Comp.isBrackets = true;
6360221345Sdim    Comp.LocStart = ON.getSourceRange().getBegin();
6361221345Sdim    Comp.LocEnd = ON.getSourceRange().getEnd();
6362207619Srdivacky    switch (ON.getKind()) {
6363207619Srdivacky    case Node::Array: {
6364207619Srdivacky      Expr *FromIndex = E->getIndexExpr(ON.getArrayExprIndex());
6365212904Sdim      ExprResult Index = getDerived().TransformExpr(FromIndex);
6366207619Srdivacky      if (Index.isInvalid())
6367212904Sdim        return ExprError();
6368239462Sdim
6369207619Srdivacky      ExprChanged = ExprChanged || Index.get() != FromIndex;
6370207619Srdivacky      Comp.isBrackets = true;
6371212904Sdim      Comp.U.E = Index.get();
6372207619Srdivacky      break;
6373207619Srdivacky    }
6374239462Sdim
6375207619Srdivacky    case Node::Field:
6376207619Srdivacky    case Node::Identifier:
6377207619Srdivacky      Comp.isBrackets = false;
6378207619Srdivacky      Comp.U.IdentInfo = ON.getFieldName();
6379207619Srdivacky      if (!Comp.U.IdentInfo)
6380207619Srdivacky        continue;
6381239462Sdim
6382207619Srdivacky      break;
6383239462Sdim
6384207619Srdivacky    case Node::Base:
6385207619Srdivacky      // Will be recomputed during the rebuild.
6386207619Srdivacky      continue;
6387207619Srdivacky    }
6388239462Sdim
6389207619Srdivacky    Components.push_back(Comp);
6390207619Srdivacky  }
6391239462Sdim
6392207619Srdivacky  // If nothing changed, retain the existing expression.
6393207619Srdivacky  if (!getDerived().AlwaysRebuild() &&
6394207619Srdivacky      Type == E->getTypeSourceInfo() &&
6395207619Srdivacky      !ExprChanged)
6396218893Sdim    return SemaRef.Owned(E);
6397239462Sdim
6398207619Srdivacky  // Build a new offsetof expression.
6399207619Srdivacky  return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
6400207619Srdivacky                                          Components.data(), Components.size(),
6401207619Srdivacky                                          E->getRParenLoc());
6402207619Srdivacky}
6403207619Srdivacky
6404207619Srdivackytemplate<typename Derived>
6405212904SdimExprResult
6406218893SdimTreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
6407218893Sdim  assert(getDerived().AlreadyTransformed(E->getType()) &&
6408218893Sdim         "opaque value expression requires transformation");
6409218893Sdim  return SemaRef.Owned(E);
6410218893Sdim}
6411218893Sdim
6412218893Sdimtemplate<typename Derived>
6413218893SdimExprResult
6414234353SdimTreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
6415234353Sdim  // Rebuild the syntactic form.  The original syntactic form has
6416234353Sdim  // opaque-value expressions in it, so strip those away and rebuild
6417234353Sdim  // the result.  This is a really awful way of doing this, but the
6418234353Sdim  // better solution (rebuilding the semantic expressions and
6419234353Sdim  // rebinding OVEs as necessary) doesn't work; we'd need
6420234353Sdim  // TreeTransform to not strip away implicit conversions.
6421234353Sdim  Expr *newSyntacticForm = SemaRef.recreateSyntacticForm(E);
6422234353Sdim  ExprResult result = getDerived().TransformExpr(newSyntacticForm);
6423234353Sdim  if (result.isInvalid()) return ExprError();
6424234353Sdim
6425234353Sdim  // If that gives us a pseudo-object result back, the pseudo-object
6426234353Sdim  // expression must have been an lvalue-to-rvalue conversion which we
6427234353Sdim  // should reapply.
6428234353Sdim  if (result.get()->hasPlaceholderType(BuiltinType::PseudoObject))
6429234353Sdim    result = SemaRef.checkPseudoObjectRValue(result.take());
6430234353Sdim
6431234353Sdim  return result;
6432234353Sdim}
6433234353Sdim
6434234353Sdimtemplate<typename Derived>
6435234353SdimExprResult
6436221345SdimTreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
6437221345Sdim                                                UnaryExprOrTypeTraitExpr *E) {
6438198092Srdivacky  if (E->isArgumentType()) {
6439200583Srdivacky    TypeSourceInfo *OldT = E->getArgumentTypeInfo();
6440198893Srdivacky
6441200583Srdivacky    TypeSourceInfo *NewT = getDerived().TransformType(OldT);
6442198893Srdivacky    if (!NewT)
6443212904Sdim      return ExprError();
6444198092Srdivacky
6445198893Srdivacky    if (!getDerived().AlwaysRebuild() && OldT == NewT)
6446218893Sdim      return SemaRef.Owned(E);
6447198092Srdivacky
6448221345Sdim    return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
6449221345Sdim                                                    E->getKind(),
6450221345Sdim                                                    E->getSourceRange());
6451198092Srdivacky  }
6452198092Srdivacky
6453234353Sdim  // C++0x [expr.sizeof]p1:
6454234353Sdim  //   The operand is either an expression, which is an unevaluated operand
6455234353Sdim  //   [...]
6456243830Sdim  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated,
6457243830Sdim                                               Sema::ReuseLambdaContextDecl);
6458198092Srdivacky
6459234353Sdim  ExprResult SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
6460234353Sdim  if (SubExpr.isInvalid())
6461234353Sdim    return ExprError();
6462198092Srdivacky
6463234353Sdim  if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
6464234353Sdim    return SemaRef.Owned(E);
6465198092Srdivacky
6466221345Sdim  return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
6467221345Sdim                                                  E->getOperatorLoc(),
6468221345Sdim                                                  E->getKind(),
6469221345Sdim                                                  E->getSourceRange());
6470198092Srdivacky}
6471198092Srdivacky
6472198092Srdivackytemplate<typename Derived>
6473212904SdimExprResult
6474200583SrdivackyTreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
6475212904Sdim  ExprResult LHS = getDerived().TransformExpr(E->getLHS());
6476198092Srdivacky  if (LHS.isInvalid())
6477212904Sdim    return ExprError();
6478198092Srdivacky
6479212904Sdim  ExprResult RHS = getDerived().TransformExpr(E->getRHS());
6480198092Srdivacky  if (RHS.isInvalid())
6481212904Sdim    return ExprError();
6482198092Srdivacky
6483198092Srdivacky
6484198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
6485198092Srdivacky      LHS.get() == E->getLHS() &&
6486198092Srdivacky      RHS.get() == E->getRHS())
6487218893Sdim    return SemaRef.Owned(E);
6488198092Srdivacky
6489212904Sdim  return getDerived().RebuildArraySubscriptExpr(LHS.get(),
6490198092Srdivacky                                           /*FIXME:*/E->getLHS()->getLocStart(),
6491212904Sdim                                                RHS.get(),
6492198092Srdivacky                                                E->getRBracketLoc());
6493198092Srdivacky}
6494198092Srdivacky
6495198092Srdivackytemplate<typename Derived>
6496212904SdimExprResult
6497200583SrdivackyTreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
6498198092Srdivacky  // Transform the callee.
6499212904Sdim  ExprResult Callee = getDerived().TransformExpr(E->getCallee());
6500198092Srdivacky  if (Callee.isInvalid())
6501212904Sdim    return ExprError();
6502198092Srdivacky
6503198092Srdivacky  // Transform arguments.
6504198092Srdivacky  bool ArgChanged = false;
6505243830Sdim  SmallVector<Expr*, 8> Args;
6506239462Sdim  if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
6507218893Sdim                                  &ArgChanged))
6508218893Sdim    return ExprError();
6509239462Sdim
6510198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
6511198092Srdivacky      Callee.get() == E->getCallee() &&
6512198092Srdivacky      !ArgChanged)
6513243830Sdim    return SemaRef.MaybeBindToTemporary(E);
6514198092Srdivacky
6515198092Srdivacky  // FIXME: Wrong source location information for the '('.
6516198092Srdivacky  SourceLocation FakeLParenLoc
6517198092Srdivacky    = ((Expr *)Callee.get())->getSourceRange().getBegin();
6518212904Sdim  return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
6519243830Sdim                                      Args,
6520198092Srdivacky                                      E->getRParenLoc());
6521198092Srdivacky}
6522198092Srdivacky
6523198092Srdivackytemplate<typename Derived>
6524212904SdimExprResult
6525200583SrdivackyTreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
6526212904Sdim  ExprResult Base = getDerived().TransformExpr(E->getBase());
6527198092Srdivacky  if (Base.isInvalid())
6528212904Sdim    return ExprError();
6529198092Srdivacky
6530221345Sdim  NestedNameSpecifierLoc QualifierLoc;
6531198092Srdivacky  if (E->hasQualifier()) {
6532221345Sdim    QualifierLoc
6533221345Sdim      = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
6534239462Sdim
6535221345Sdim    if (!QualifierLoc)
6536212904Sdim      return ExprError();
6537198092Srdivacky  }
6538234353Sdim  SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
6539198092Srdivacky
6540200583Srdivacky  ValueDecl *Member
6541204643Srdivacky    = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
6542204643Srdivacky                                                         E->getMemberDecl()));
6543198092Srdivacky  if (!Member)
6544212904Sdim    return ExprError();
6545198092Srdivacky
6546206084Srdivacky  NamedDecl *FoundDecl = E->getFoundDecl();
6547206084Srdivacky  if (FoundDecl == E->getMemberDecl()) {
6548206084Srdivacky    FoundDecl = Member;
6549206084Srdivacky  } else {
6550206084Srdivacky    FoundDecl = cast_or_null<NamedDecl>(
6551206084Srdivacky                   getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
6552206084Srdivacky    if (!FoundDecl)
6553212904Sdim      return ExprError();
6554206084Srdivacky  }
6555206084Srdivacky
6556198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
6557198092Srdivacky      Base.get() == E->getBase() &&
6558221345Sdim      QualifierLoc == E->getQualifierLoc() &&
6559198954Srdivacky      Member == E->getMemberDecl() &&
6560206084Srdivacky      FoundDecl == E->getFoundDecl() &&
6561212904Sdim      !E->hasExplicitTemplateArgs()) {
6562239462Sdim
6563201361Srdivacky    // Mark it referenced in the new context regardless.
6564201361Srdivacky    // FIXME: this is a bit instantiation-specific.
6565234353Sdim    SemaRef.MarkMemberReferenced(E);
6566234353Sdim
6567218893Sdim    return SemaRef.Owned(E);
6568201361Srdivacky  }
6569198092Srdivacky
6570199990Srdivacky  TemplateArgumentListInfo TransArgs;
6571212904Sdim  if (E->hasExplicitTemplateArgs()) {
6572199990Srdivacky    TransArgs.setLAngleLoc(E->getLAngleLoc());
6573199990Srdivacky    TransArgs.setRAngleLoc(E->getRAngleLoc());
6574218893Sdim    if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
6575218893Sdim                                                E->getNumTemplateArgs(),
6576218893Sdim                                                TransArgs))
6577218893Sdim      return ExprError();
6578198954Srdivacky  }
6579239462Sdim
6580198092Srdivacky  // FIXME: Bogus source location for the operator
6581198092Srdivacky  SourceLocation FakeOperatorLoc
6582198092Srdivacky    = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
6583198092Srdivacky
6584202379Srdivacky  // FIXME: to do this check properly, we will need to preserve the
6585202379Srdivacky  // first-qualifier-in-scope here, just in case we had a dependent
6586202379Srdivacky  // base (and therefore couldn't do the check) and a
6587202379Srdivacky  // nested-name-qualifier (and therefore could do the lookup).
6588202379Srdivacky  NamedDecl *FirstQualifierInScope = 0;
6589202379Srdivacky
6590212904Sdim  return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
6591198092Srdivacky                                        E->isArrow(),
6592221345Sdim                                        QualifierLoc,
6593234353Sdim                                        TemplateKWLoc,
6594212904Sdim                                        E->getMemberNameInfo(),
6595198954Srdivacky                                        Member,
6596206084Srdivacky                                        FoundDecl,
6597212904Sdim                                        (E->hasExplicitTemplateArgs()
6598199990Srdivacky                                           ? &TransArgs : 0),
6599202379Srdivacky                                        FirstQualifierInScope);
6600198092Srdivacky}
6601198092Srdivacky
6602198092Srdivackytemplate<typename Derived>
6603212904SdimExprResult
6604200583SrdivackyTreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
6605212904Sdim  ExprResult LHS = getDerived().TransformExpr(E->getLHS());
6606198092Srdivacky  if (LHS.isInvalid())
6607212904Sdim    return ExprError();
6608198092Srdivacky
6609212904Sdim  ExprResult RHS = getDerived().TransformExpr(E->getRHS());
6610198092Srdivacky  if (RHS.isInvalid())
6611212904Sdim    return ExprError();
6612198092Srdivacky
6613198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
6614198092Srdivacky      LHS.get() == E->getLHS() &&
6615198092Srdivacky      RHS.get() == E->getRHS())
6616218893Sdim    return SemaRef.Owned(E);
6617198092Srdivacky
6618243830Sdim  Sema::FPContractStateRAII FPContractState(getSema());
6619243830Sdim  getSema().FPFeatures.fp_contract = E->isFPContractable();
6620243830Sdim
6621198092Srdivacky  return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
6622212904Sdim                                            LHS.get(), RHS.get());
6623198092Srdivacky}
6624198092Srdivacky
6625198092Srdivackytemplate<typename Derived>
6626212904SdimExprResult
6627198092SrdivackyTreeTransform<Derived>::TransformCompoundAssignOperator(
6628200583Srdivacky                                                      CompoundAssignOperator *E) {
6629200583Srdivacky  return getDerived().TransformBinaryOperator(E);
6630198092Srdivacky}
6631198092Srdivacky
6632198092Srdivackytemplate<typename Derived>
6633218893SdimExprResult TreeTransform<Derived>::
6634218893SdimTransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
6635218893Sdim  // Just rebuild the common and RHS expressions and see whether we
6636218893Sdim  // get any changes.
6637218893Sdim
6638218893Sdim  ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
6639218893Sdim  if (commonExpr.isInvalid())
6640218893Sdim    return ExprError();
6641218893Sdim
6642218893Sdim  ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
6643218893Sdim  if (rhs.isInvalid())
6644218893Sdim    return ExprError();
6645218893Sdim
6646218893Sdim  if (!getDerived().AlwaysRebuild() &&
6647218893Sdim      commonExpr.get() == e->getCommon() &&
6648218893Sdim      rhs.get() == e->getFalseExpr())
6649218893Sdim    return SemaRef.Owned(e);
6650218893Sdim
6651218893Sdim  return getDerived().RebuildConditionalOperator(commonExpr.take(),
6652218893Sdim                                                 e->getQuestionLoc(),
6653218893Sdim                                                 0,
6654218893Sdim                                                 e->getColonLoc(),
6655218893Sdim                                                 rhs.get());
6656218893Sdim}
6657218893Sdim
6658218893Sdimtemplate<typename Derived>
6659212904SdimExprResult
6660200583SrdivackyTreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
6661212904Sdim  ExprResult Cond = getDerived().TransformExpr(E->getCond());
6662198092Srdivacky  if (Cond.isInvalid())
6663212904Sdim    return ExprError();
6664198092Srdivacky
6665212904Sdim  ExprResult LHS = getDerived().TransformExpr(E->getLHS());
6666198092Srdivacky  if (LHS.isInvalid())
6667212904Sdim    return ExprError();
6668198092Srdivacky
6669212904Sdim  ExprResult RHS = getDerived().TransformExpr(E->getRHS());
6670198092Srdivacky  if (RHS.isInvalid())
6671212904Sdim    return ExprError();
6672198092Srdivacky
6673198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
6674198092Srdivacky      Cond.get() == E->getCond() &&
6675198092Srdivacky      LHS.get() == E->getLHS() &&
6676198092Srdivacky      RHS.get() == E->getRHS())
6677218893Sdim    return SemaRef.Owned(E);
6678198092Srdivacky
6679212904Sdim  return getDerived().RebuildConditionalOperator(Cond.get(),
6680198092Srdivacky                                                 E->getQuestionLoc(),
6681212904Sdim                                                 LHS.get(),
6682198092Srdivacky                                                 E->getColonLoc(),
6683212904Sdim                                                 RHS.get());
6684198092Srdivacky}
6685198092Srdivacky
6686198092Srdivackytemplate<typename Derived>
6687212904SdimExprResult
6688200583SrdivackyTreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
6689200583Srdivacky  // Implicit casts are eliminated during transformation, since they
6690200583Srdivacky  // will be recomputed by semantic analysis after transformation.
6691200583Srdivacky  return getDerived().TransformExpr(E->getSubExprAsWritten());
6692198092Srdivacky}
6693198092Srdivacky
6694198092Srdivackytemplate<typename Derived>
6695212904SdimExprResult
6696200583SrdivackyTreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
6697218893Sdim  TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
6698218893Sdim  if (!Type)
6699218893Sdim    return ExprError();
6700239462Sdim
6701212904Sdim  ExprResult SubExpr
6702200583Srdivacky    = getDerived().TransformExpr(E->getSubExprAsWritten());
6703198092Srdivacky  if (SubExpr.isInvalid())
6704212904Sdim    return ExprError();
6705198092Srdivacky
6706198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
6707218893Sdim      Type == E->getTypeInfoAsWritten() &&
6708198092Srdivacky      SubExpr.get() == E->getSubExpr())
6709218893Sdim    return SemaRef.Owned(E);
6710198092Srdivacky
6711202879Srdivacky  return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
6712218893Sdim                                            Type,
6713198092Srdivacky                                            E->getRParenLoc(),
6714212904Sdim                                            SubExpr.get());
6715198092Srdivacky}
6716198092Srdivacky
6717198092Srdivackytemplate<typename Derived>
6718212904SdimExprResult
6719200583SrdivackyTreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
6720202879Srdivacky  TypeSourceInfo *OldT = E->getTypeSourceInfo();
6721202879Srdivacky  TypeSourceInfo *NewT = getDerived().TransformType(OldT);
6722202879Srdivacky  if (!NewT)
6723212904Sdim    return ExprError();
6724198092Srdivacky
6725212904Sdim  ExprResult Init = getDerived().TransformExpr(E->getInitializer());
6726198092Srdivacky  if (Init.isInvalid())
6727212904Sdim    return ExprError();
6728198092Srdivacky
6729198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
6730202879Srdivacky      OldT == NewT &&
6731198092Srdivacky      Init.get() == E->getInitializer())
6732234353Sdim    return SemaRef.MaybeBindToTemporary(E);
6733198092Srdivacky
6734202879Srdivacky  // Note: the expression type doesn't necessarily match the
6735202879Srdivacky  // type-as-written, but that's okay, because it should always be
6736202879Srdivacky  // derivable from the initializer.
6737202879Srdivacky
6738202879Srdivacky  return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), NewT,
6739198092Srdivacky                                   /*FIXME:*/E->getInitializer()->getLocEnd(),
6740212904Sdim                                                 Init.get());
6741198092Srdivacky}
6742198092Srdivacky
6743198092Srdivackytemplate<typename Derived>
6744212904SdimExprResult
6745200583SrdivackyTreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
6746212904Sdim  ExprResult Base = getDerived().TransformExpr(E->getBase());
6747198092Srdivacky  if (Base.isInvalid())
6748212904Sdim    return ExprError();
6749198092Srdivacky
6750198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
6751198092Srdivacky      Base.get() == E->getBase())
6752218893Sdim    return SemaRef.Owned(E);
6753198092Srdivacky
6754198092Srdivacky  // FIXME: Bad source location
6755198092Srdivacky  SourceLocation FakeOperatorLoc
6756198092Srdivacky    = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
6757212904Sdim  return getDerived().RebuildExtVectorElementExpr(Base.get(), FakeOperatorLoc,
6758198092Srdivacky                                                  E->getAccessorLoc(),
6759198092Srdivacky                                                  E->getAccessor());
6760198092Srdivacky}
6761198092Srdivacky
6762198092Srdivackytemplate<typename Derived>
6763212904SdimExprResult
6764200583SrdivackyTreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
6765198092Srdivacky  bool InitChanged = false;
6766198092Srdivacky
6767243830Sdim  SmallVector<Expr*, 4> Inits;
6768239462Sdim  if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
6769218893Sdim                                  Inits, &InitChanged))
6770218893Sdim    return ExprError();
6771239462Sdim
6772198092Srdivacky  if (!getDerived().AlwaysRebuild() && !InitChanged)
6773218893Sdim    return SemaRef.Owned(E);
6774198092Srdivacky
6775243830Sdim  return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
6776199482Srdivacky                                      E->getRBraceLoc(), E->getType());
6777198092Srdivacky}
6778198092Srdivacky
6779198092Srdivackytemplate<typename Derived>
6780212904SdimExprResult
6781200583SrdivackyTreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
6782198092Srdivacky  Designation Desig;
6783198092Srdivacky
6784198092Srdivacky  // transform the initializer value
6785212904Sdim  ExprResult Init = getDerived().TransformExpr(E->getInit());
6786198092Srdivacky  if (Init.isInvalid())
6787212904Sdim    return ExprError();
6788198092Srdivacky
6789198092Srdivacky  // transform the designators.
6790243830Sdim  SmallVector<Expr*, 4> ArrayExprs;
6791198092Srdivacky  bool ExprChanged = false;
6792198092Srdivacky  for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
6793198092Srdivacky                                             DEnd = E->designators_end();
6794198092Srdivacky       D != DEnd; ++D) {
6795198092Srdivacky    if (D->isFieldDesignator()) {
6796198092Srdivacky      Desig.AddDesignator(Designator::getField(D->getFieldName(),
6797198092Srdivacky                                               D->getDotLoc(),
6798198092Srdivacky                                               D->getFieldLoc()));
6799198092Srdivacky      continue;
6800198092Srdivacky    }
6801198092Srdivacky
6802198092Srdivacky    if (D->isArrayDesignator()) {
6803212904Sdim      ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
6804198092Srdivacky      if (Index.isInvalid())
6805212904Sdim        return ExprError();
6806198092Srdivacky
6807198092Srdivacky      Desig.AddDesignator(Designator::getArray(Index.get(),
6808198092Srdivacky                                               D->getLBracketLoc()));
6809198092Srdivacky
6810198092Srdivacky      ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
6811198092Srdivacky      ArrayExprs.push_back(Index.release());
6812198092Srdivacky      continue;
6813198092Srdivacky    }
6814198092Srdivacky
6815198092Srdivacky    assert(D->isArrayRangeDesignator() && "New kind of designator?");
6816212904Sdim    ExprResult Start
6817198092Srdivacky      = getDerived().TransformExpr(E->getArrayRangeStart(*D));
6818198092Srdivacky    if (Start.isInvalid())
6819212904Sdim      return ExprError();
6820198092Srdivacky
6821212904Sdim    ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
6822198092Srdivacky    if (End.isInvalid())
6823212904Sdim      return ExprError();
6824198092Srdivacky
6825198092Srdivacky    Desig.AddDesignator(Designator::getArrayRange(Start.get(),
6826198092Srdivacky                                                  End.get(),
6827198092Srdivacky                                                  D->getLBracketLoc(),
6828198092Srdivacky                                                  D->getEllipsisLoc()));
6829198092Srdivacky
6830198092Srdivacky    ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
6831198092Srdivacky      End.get() != E->getArrayRangeEnd(*D);
6832198092Srdivacky
6833198092Srdivacky    ArrayExprs.push_back(Start.release());
6834198092Srdivacky    ArrayExprs.push_back(End.release());
6835198092Srdivacky  }
6836198092Srdivacky
6837198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
6838198092Srdivacky      Init.get() == E->getInit() &&
6839198092Srdivacky      !ExprChanged)
6840218893Sdim    return SemaRef.Owned(E);
6841198092Srdivacky
6842243830Sdim  return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
6843198092Srdivacky                                                E->getEqualOrColonLoc(),
6844212904Sdim                                                E->usesGNUSyntax(), Init.get());
6845198092Srdivacky}
6846198092Srdivacky
6847198092Srdivackytemplate<typename Derived>
6848212904SdimExprResult
6849198092SrdivackyTreeTransform<Derived>::TransformImplicitValueInitExpr(
6850200583Srdivacky                                                     ImplicitValueInitExpr *E) {
6851198893Srdivacky  TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
6852239462Sdim
6853198893Srdivacky  // FIXME: Will we ever have proper type location here? Will we actually
6854198893Srdivacky  // need to transform the type?
6855198092Srdivacky  QualType T = getDerived().TransformType(E->getType());
6856198092Srdivacky  if (T.isNull())
6857212904Sdim    return ExprError();
6858198092Srdivacky
6859198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
6860198092Srdivacky      T == E->getType())
6861218893Sdim    return SemaRef.Owned(E);
6862198092Srdivacky
6863198092Srdivacky  return getDerived().RebuildImplicitValueInitExpr(T);
6864198092Srdivacky}
6865198092Srdivacky
6866198092Srdivackytemplate<typename Derived>
6867212904SdimExprResult
6868200583SrdivackyTreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
6869212904Sdim  TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
6870212904Sdim  if (!TInfo)
6871212904Sdim    return ExprError();
6872198092Srdivacky
6873212904Sdim  ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
6874198092Srdivacky  if (SubExpr.isInvalid())
6875212904Sdim    return ExprError();
6876198092Srdivacky
6877198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
6878212904Sdim      TInfo == E->getWrittenTypeInfo() &&
6879198092Srdivacky      SubExpr.get() == E->getSubExpr())
6880218893Sdim    return SemaRef.Owned(E);
6881198092Srdivacky
6882212904Sdim  return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
6883212904Sdim                                       TInfo, E->getRParenLoc());
6884198092Srdivacky}
6885198092Srdivacky
6886198092Srdivackytemplate<typename Derived>
6887212904SdimExprResult
6888200583SrdivackyTreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
6889198092Srdivacky  bool ArgumentChanged = false;
6890243830Sdim  SmallVector<Expr*, 4> Inits;
6891218893Sdim  if (TransformExprs(E->getExprs(), E->getNumExprs(), true, Inits,
6892218893Sdim                     &ArgumentChanged))
6893218893Sdim    return ExprError();
6894239462Sdim
6895198092Srdivacky  return getDerived().RebuildParenListExpr(E->getLParenLoc(),
6896243830Sdim                                           Inits,
6897198092Srdivacky                                           E->getRParenLoc());
6898198092Srdivacky}
6899198092Srdivacky
6900198092Srdivacky/// \brief Transform an address-of-label expression.
6901198092Srdivacky///
6902198092Srdivacky/// By default, the transformation of an address-of-label expression always
6903198092Srdivacky/// rebuilds the expression, so that the label identifier can be resolved to
6904198092Srdivacky/// the corresponding label statement by semantic analysis.
6905198092Srdivackytemplate<typename Derived>
6906212904SdimExprResult
6907200583SrdivackyTreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
6908218893Sdim  Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
6909218893Sdim                                        E->getLabel());
6910218893Sdim  if (!LD)
6911218893Sdim    return ExprError();
6912239462Sdim
6913198092Srdivacky  return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
6914218893Sdim                                           cast<LabelDecl>(LD));
6915198092Srdivacky}
6916198092Srdivacky
6917198092Srdivackytemplate<typename Derived>
6918239462SdimExprResult
6919200583SrdivackyTreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
6920234353Sdim  SemaRef.ActOnStartStmtExpr();
6921212904Sdim  StmtResult SubStmt
6922198092Srdivacky    = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
6923234353Sdim  if (SubStmt.isInvalid()) {
6924234353Sdim    SemaRef.ActOnStmtExprError();
6925212904Sdim    return ExprError();
6926234353Sdim  }
6927198092Srdivacky
6928198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
6929234353Sdim      SubStmt.get() == E->getSubStmt()) {
6930234353Sdim    // Calling this an 'error' is unintuitive, but it does the right thing.
6931234353Sdim    SemaRef.ActOnStmtExprError();
6932234353Sdim    return SemaRef.MaybeBindToTemporary(E);
6933234353Sdim  }
6934198092Srdivacky
6935198092Srdivacky  return getDerived().RebuildStmtExpr(E->getLParenLoc(),
6936212904Sdim                                      SubStmt.get(),
6937198092Srdivacky                                      E->getRParenLoc());
6938198092Srdivacky}
6939198092Srdivacky
6940198092Srdivackytemplate<typename Derived>
6941212904SdimExprResult
6942200583SrdivackyTreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
6943212904Sdim  ExprResult Cond = getDerived().TransformExpr(E->getCond());
6944198092Srdivacky  if (Cond.isInvalid())
6945212904Sdim    return ExprError();
6946198092Srdivacky
6947212904Sdim  ExprResult LHS = getDerived().TransformExpr(E->getLHS());
6948198092Srdivacky  if (LHS.isInvalid())
6949212904Sdim    return ExprError();
6950198092Srdivacky
6951212904Sdim  ExprResult RHS = getDerived().TransformExpr(E->getRHS());
6952198092Srdivacky  if (RHS.isInvalid())
6953212904Sdim    return ExprError();
6954198092Srdivacky
6955198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
6956198092Srdivacky      Cond.get() == E->getCond() &&
6957198092Srdivacky      LHS.get() == E->getLHS() &&
6958198092Srdivacky      RHS.get() == E->getRHS())
6959218893Sdim    return SemaRef.Owned(E);
6960198092Srdivacky
6961198092Srdivacky  return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
6962212904Sdim                                        Cond.get(), LHS.get(), RHS.get(),
6963198092Srdivacky                                        E->getRParenLoc());
6964198092Srdivacky}
6965198092Srdivacky
6966198092Srdivackytemplate<typename Derived>
6967212904SdimExprResult
6968200583SrdivackyTreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
6969218893Sdim  return SemaRef.Owned(E);
6970198092Srdivacky}
6971198092Srdivacky
6972198092Srdivackytemplate<typename Derived>
6973212904SdimExprResult
6974200583SrdivackyTreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
6975200583Srdivacky  switch (E->getOperator()) {
6976200583Srdivacky  case OO_New:
6977200583Srdivacky  case OO_Delete:
6978200583Srdivacky  case OO_Array_New:
6979200583Srdivacky  case OO_Array_Delete:
6980200583Srdivacky    llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
6981239462Sdim
6982200583Srdivacky  case OO_Call: {
6983200583Srdivacky    // This is a call to an object's operator().
6984200583Srdivacky    assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
6985200583Srdivacky
6986200583Srdivacky    // Transform the object itself.
6987212904Sdim    ExprResult Object = getDerived().TransformExpr(E->getArg(0));
6988200583Srdivacky    if (Object.isInvalid())
6989212904Sdim      return ExprError();
6990200583Srdivacky
6991200583Srdivacky    // FIXME: Poor location information
6992200583Srdivacky    SourceLocation FakeLParenLoc
6993200583Srdivacky      = SemaRef.PP.getLocForEndOfToken(
6994200583Srdivacky                              static_cast<Expr *>(Object.get())->getLocEnd());
6995200583Srdivacky
6996200583Srdivacky    // Transform the call arguments.
6997243830Sdim    SmallVector<Expr*, 8> Args;
6998239462Sdim    if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
6999218893Sdim                                    Args))
7000218893Sdim      return ExprError();
7001200583Srdivacky
7002212904Sdim    return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc,
7003243830Sdim                                        Args,
7004200583Srdivacky                                        E->getLocEnd());
7005200583Srdivacky  }
7006200583Srdivacky
7007200583Srdivacky#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
7008200583Srdivacky  case OO_##Name:
7009200583Srdivacky#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
7010200583Srdivacky#include "clang/Basic/OperatorKinds.def"
7011200583Srdivacky  case OO_Subscript:
7012200583Srdivacky    // Handled below.
7013200583Srdivacky    break;
7014200583Srdivacky
7015200583Srdivacky  case OO_Conditional:
7016200583Srdivacky    llvm_unreachable("conditional operator is not actually overloadable");
7017200583Srdivacky
7018200583Srdivacky  case OO_None:
7019200583Srdivacky  case NUM_OVERLOADED_OPERATORS:
7020200583Srdivacky    llvm_unreachable("not an overloaded operator?");
7021200583Srdivacky  }
7022200583Srdivacky
7023212904Sdim  ExprResult Callee = getDerived().TransformExpr(E->getCallee());
7024198092Srdivacky  if (Callee.isInvalid())
7025212904Sdim    return ExprError();
7026198092Srdivacky
7027243830Sdim  ExprResult First;
7028243830Sdim  if (E->getOperator() == OO_Amp)
7029243830Sdim    First = getDerived().TransformAddressOfOperand(E->getArg(0));
7030243830Sdim  else
7031243830Sdim    First = getDerived().TransformExpr(E->getArg(0));
7032198092Srdivacky  if (First.isInvalid())
7033212904Sdim    return ExprError();
7034198092Srdivacky
7035212904Sdim  ExprResult Second;
7036198092Srdivacky  if (E->getNumArgs() == 2) {
7037198092Srdivacky    Second = getDerived().TransformExpr(E->getArg(1));
7038198092Srdivacky    if (Second.isInvalid())
7039212904Sdim      return ExprError();
7040198092Srdivacky  }
7041198092Srdivacky
7042198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
7043198092Srdivacky      Callee.get() == E->getCallee() &&
7044198092Srdivacky      First.get() == E->getArg(0) &&
7045198092Srdivacky      (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
7046234353Sdim    return SemaRef.MaybeBindToTemporary(E);
7047198092Srdivacky
7048243830Sdim  Sema::FPContractStateRAII FPContractState(getSema());
7049243830Sdim  getSema().FPFeatures.fp_contract = E->isFPContractable();
7050243830Sdim
7051198092Srdivacky  return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
7052198092Srdivacky                                                 E->getOperatorLoc(),
7053212904Sdim                                                 Callee.get(),
7054212904Sdim                                                 First.get(),
7055212904Sdim                                                 Second.get());
7056198092Srdivacky}
7057198092Srdivacky
7058198092Srdivackytemplate<typename Derived>
7059212904SdimExprResult
7060200583SrdivackyTreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
7061200583Srdivacky  return getDerived().TransformCallExpr(E);
7062198092Srdivacky}
7063198092Srdivacky
7064198092Srdivackytemplate<typename Derived>
7065212904SdimExprResult
7066218893SdimTreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
7067218893Sdim  // Transform the callee.
7068218893Sdim  ExprResult Callee = getDerived().TransformExpr(E->getCallee());
7069218893Sdim  if (Callee.isInvalid())
7070218893Sdim    return ExprError();
7071198092Srdivacky
7072218893Sdim  // Transform exec config.
7073218893Sdim  ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
7074218893Sdim  if (EC.isInvalid())
7075218893Sdim    return ExprError();
7076198092Srdivacky
7077218893Sdim  // Transform arguments.
7078218893Sdim  bool ArgChanged = false;
7079243830Sdim  SmallVector<Expr*, 8> Args;
7080239462Sdim  if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
7081218893Sdim                                  &ArgChanged))
7082218893Sdim    return ExprError();
7083218893Sdim
7084218893Sdim  if (!getDerived().AlwaysRebuild() &&
7085218893Sdim      Callee.get() == E->getCallee() &&
7086218893Sdim      !ArgChanged)
7087234353Sdim    return SemaRef.MaybeBindToTemporary(E);
7088218893Sdim
7089218893Sdim  // FIXME: Wrong source location information for the '('.
7090218893Sdim  SourceLocation FakeLParenLoc
7091218893Sdim    = ((Expr *)Callee.get())->getSourceRange().getBegin();
7092218893Sdim  return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
7093243830Sdim                                      Args,
7094218893Sdim                                      E->getRParenLoc(), EC.get());
7095218893Sdim}
7096218893Sdim
7097218893Sdimtemplate<typename Derived>
7098218893SdimExprResult
7099218893SdimTreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
7100218893Sdim  TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
7101218893Sdim  if (!Type)
7102218893Sdim    return ExprError();
7103239462Sdim
7104212904Sdim  ExprResult SubExpr
7105200583Srdivacky    = getDerived().TransformExpr(E->getSubExprAsWritten());
7106198092Srdivacky  if (SubExpr.isInvalid())
7107212904Sdim    return ExprError();
7108198092Srdivacky
7109198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
7110218893Sdim      Type == E->getTypeInfoAsWritten() &&
7111198092Srdivacky      SubExpr.get() == E->getSubExpr())
7112218893Sdim    return SemaRef.Owned(E);
7113198092Srdivacky  return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
7114198092Srdivacky                                              E->getStmtClass(),
7115249423Sdim                                              E->getAngleBrackets().getBegin(),
7116218893Sdim                                              Type,
7117249423Sdim                                              E->getAngleBrackets().getEnd(),
7118249423Sdim                                              // FIXME. this should be '(' location
7119249423Sdim                                              E->getAngleBrackets().getEnd(),
7120212904Sdim                                              SubExpr.get(),
7121243830Sdim                                              E->getRParenLoc());
7122198092Srdivacky}
7123198092Srdivacky
7124198092Srdivackytemplate<typename Derived>
7125212904SdimExprResult
7126200583SrdivackyTreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
7127200583Srdivacky  return getDerived().TransformCXXNamedCastExpr(E);
7128198092Srdivacky}
7129198092Srdivacky
7130198092Srdivackytemplate<typename Derived>
7131212904SdimExprResult
7132200583SrdivackyTreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
7133200583Srdivacky  return getDerived().TransformCXXNamedCastExpr(E);
7134198092Srdivacky}
7135198092Srdivacky
7136198092Srdivackytemplate<typename Derived>
7137212904SdimExprResult
7138198092SrdivackyTreeTransform<Derived>::TransformCXXReinterpretCastExpr(
7139200583Srdivacky                                                      CXXReinterpretCastExpr *E) {
7140200583Srdivacky  return getDerived().TransformCXXNamedCastExpr(E);
7141198092Srdivacky}
7142198092Srdivacky
7143198092Srdivackytemplate<typename Derived>
7144212904SdimExprResult
7145200583SrdivackyTreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
7146200583Srdivacky  return getDerived().TransformCXXNamedCastExpr(E);
7147198092Srdivacky}
7148198092Srdivacky
7149198092Srdivackytemplate<typename Derived>
7150212904SdimExprResult
7151198092SrdivackyTreeTransform<Derived>::TransformCXXFunctionalCastExpr(
7152200583Srdivacky                                                     CXXFunctionalCastExpr *E) {
7153218893Sdim  TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
7154218893Sdim  if (!Type)
7155218893Sdim    return ExprError();
7156198092Srdivacky
7157212904Sdim  ExprResult SubExpr
7158200583Srdivacky    = getDerived().TransformExpr(E->getSubExprAsWritten());
7159198092Srdivacky  if (SubExpr.isInvalid())
7160212904Sdim    return ExprError();
7161198092Srdivacky
7162198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
7163218893Sdim      Type == E->getTypeInfoAsWritten() &&
7164198092Srdivacky      SubExpr.get() == E->getSubExpr())
7165218893Sdim    return SemaRef.Owned(E);
7166198092Srdivacky
7167218893Sdim  return getDerived().RebuildCXXFunctionalCastExpr(Type,
7168198092Srdivacky                                      /*FIXME:*/E->getSubExpr()->getLocStart(),
7169212904Sdim                                                   SubExpr.get(),
7170198092Srdivacky                                                   E->getRParenLoc());
7171198092Srdivacky}
7172198092Srdivacky
7173198092Srdivackytemplate<typename Derived>
7174212904SdimExprResult
7175200583SrdivackyTreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
7176198092Srdivacky  if (E->isTypeOperand()) {
7177207619Srdivacky    TypeSourceInfo *TInfo
7178207619Srdivacky      = getDerived().TransformType(E->getTypeOperandSourceInfo());
7179207619Srdivacky    if (!TInfo)
7180212904Sdim      return ExprError();
7181198092Srdivacky
7182198092Srdivacky    if (!getDerived().AlwaysRebuild() &&
7183207619Srdivacky        TInfo == E->getTypeOperandSourceInfo())
7184218893Sdim      return SemaRef.Owned(E);
7185198092Srdivacky
7186207619Srdivacky    return getDerived().RebuildCXXTypeidExpr(E->getType(),
7187207619Srdivacky                                             E->getLocStart(),
7188207619Srdivacky                                             TInfo,
7189198092Srdivacky                                             E->getLocEnd());
7190198092Srdivacky  }
7191198092Srdivacky
7192234353Sdim  // We don't know whether the subexpression is potentially evaluated until
7193234353Sdim  // after we perform semantic analysis.  We speculatively assume it is
7194234353Sdim  // unevaluated; it will get fixed later if the subexpression is in fact
7195198092Srdivacky  // potentially evaluated.
7196243830Sdim  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated,
7197243830Sdim                                               Sema::ReuseLambdaContextDecl);
7198198092Srdivacky
7199212904Sdim  ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
7200198092Srdivacky  if (SubExpr.isInvalid())
7201212904Sdim    return ExprError();
7202198092Srdivacky
7203198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
7204198092Srdivacky      SubExpr.get() == E->getExprOperand())
7205218893Sdim    return SemaRef.Owned(E);
7206198092Srdivacky
7207207619Srdivacky  return getDerived().RebuildCXXTypeidExpr(E->getType(),
7208207619Srdivacky                                           E->getLocStart(),
7209212904Sdim                                           SubExpr.get(),
7210198092Srdivacky                                           E->getLocEnd());
7211198092Srdivacky}
7212198092Srdivacky
7213198092Srdivackytemplate<typename Derived>
7214212904SdimExprResult
7215218893SdimTreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
7216218893Sdim  if (E->isTypeOperand()) {
7217218893Sdim    TypeSourceInfo *TInfo
7218218893Sdim      = getDerived().TransformType(E->getTypeOperandSourceInfo());
7219218893Sdim    if (!TInfo)
7220218893Sdim      return ExprError();
7221218893Sdim
7222218893Sdim    if (!getDerived().AlwaysRebuild() &&
7223218893Sdim        TInfo == E->getTypeOperandSourceInfo())
7224218893Sdim      return SemaRef.Owned(E);
7225218893Sdim
7226221345Sdim    return getDerived().RebuildCXXUuidofExpr(E->getType(),
7227218893Sdim                                             E->getLocStart(),
7228218893Sdim                                             TInfo,
7229218893Sdim                                             E->getLocEnd());
7230218893Sdim  }
7231218893Sdim
7232218893Sdim  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
7233218893Sdim
7234218893Sdim  ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
7235218893Sdim  if (SubExpr.isInvalid())
7236218893Sdim    return ExprError();
7237218893Sdim
7238218893Sdim  if (!getDerived().AlwaysRebuild() &&
7239218893Sdim      SubExpr.get() == E->getExprOperand())
7240218893Sdim    return SemaRef.Owned(E);
7241218893Sdim
7242218893Sdim  return getDerived().RebuildCXXUuidofExpr(E->getType(),
7243218893Sdim                                           E->getLocStart(),
7244218893Sdim                                           SubExpr.get(),
7245218893Sdim                                           E->getLocEnd());
7246218893Sdim}
7247218893Sdim
7248218893Sdimtemplate<typename Derived>
7249218893SdimExprResult
7250200583SrdivackyTreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
7251218893Sdim  return SemaRef.Owned(E);
7252198092Srdivacky}
7253198092Srdivacky
7254198092Srdivackytemplate<typename Derived>
7255212904SdimExprResult
7256198092SrdivackyTreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
7257200583Srdivacky                                                     CXXNullPtrLiteralExpr *E) {
7258218893Sdim  return SemaRef.Owned(E);
7259198092Srdivacky}
7260198092Srdivacky
7261198092Srdivackytemplate<typename Derived>
7262212904SdimExprResult
7263200583SrdivackyTreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
7264218893Sdim  DeclContext *DC = getSema().getFunctionLevelDeclContext();
7265223017Sdim  QualType T;
7266223017Sdim  if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(DC))
7267223017Sdim    T = MD->getThisType(getSema().Context);
7268249423Sdim  else if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(DC)) {
7269223017Sdim    T = getSema().Context.getPointerType(
7270249423Sdim          getSema().Context.getRecordType(Record));
7271249423Sdim  } else {
7272249423Sdim    assert(SemaRef.Context.getDiagnostics().hasErrorOccurred() &&
7273249423Sdim           "this in the wrong scope?");
7274249423Sdim    return ExprError();
7275249423Sdim  }
7276198092Srdivacky
7277234353Sdim  if (!getDerived().AlwaysRebuild() && T == E->getType()) {
7278234353Sdim    // Make sure that we capture 'this'.
7279234353Sdim    getSema().CheckCXXThisCapture(E->getLocStart());
7280218893Sdim    return SemaRef.Owned(E);
7281234353Sdim  }
7282239462Sdim
7283202379Srdivacky  return getDerived().RebuildCXXThisExpr(E->getLocStart(), T, E->isImplicit());
7284198092Srdivacky}
7285198092Srdivacky
7286198092Srdivackytemplate<typename Derived>
7287212904SdimExprResult
7288200583SrdivackyTreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
7289212904Sdim  ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
7290198092Srdivacky  if (SubExpr.isInvalid())
7291212904Sdim    return ExprError();
7292198092Srdivacky
7293198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
7294198092Srdivacky      SubExpr.get() == E->getSubExpr())
7295218893Sdim    return SemaRef.Owned(E);
7296198092Srdivacky
7297224145Sdim  return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
7298224145Sdim                                          E->isThrownVariableInScope());
7299198092Srdivacky}
7300198092Srdivacky
7301198092Srdivackytemplate<typename Derived>
7302212904SdimExprResult
7303200583SrdivackyTreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
7304198092Srdivacky  ParmVarDecl *Param
7305204643Srdivacky    = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getLocStart(),
7306204643Srdivacky                                                           E->getParam()));
7307198092Srdivacky  if (!Param)
7308212904Sdim    return ExprError();
7309198092Srdivacky
7310203955Srdivacky  if (!getDerived().AlwaysRebuild() &&
7311198092Srdivacky      Param == E->getParam())
7312218893Sdim    return SemaRef.Owned(E);
7313198092Srdivacky
7314201361Srdivacky  return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param);
7315198092Srdivacky}
7316198092Srdivacky
7317198092Srdivackytemplate<typename Derived>
7318212904SdimExprResult
7319251662SdimTreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
7320251662Sdim  FieldDecl *Field
7321251662Sdim    = cast_or_null<FieldDecl>(getDerived().TransformDecl(E->getLocStart(),
7322251662Sdim                                                         E->getField()));
7323251662Sdim  if (!Field)
7324251662Sdim    return ExprError();
7325251662Sdim
7326251662Sdim  if (!getDerived().AlwaysRebuild() && Field == E->getField())
7327251662Sdim    return SemaRef.Owned(E);
7328251662Sdim
7329251662Sdim  return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
7330251662Sdim}
7331251662Sdim
7332251662Sdimtemplate<typename Derived>
7333251662SdimExprResult
7334218893SdimTreeTransform<Derived>::TransformCXXScalarValueInitExpr(
7335218893Sdim                                                    CXXScalarValueInitExpr *E) {
7336218893Sdim  TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
7337218893Sdim  if (!T)
7338212904Sdim    return ExprError();
7339239462Sdim
7340198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
7341218893Sdim      T == E->getTypeSourceInfo())
7342218893Sdim    return SemaRef.Owned(E);
7343198092Srdivacky
7344239462Sdim  return getDerived().RebuildCXXScalarValueInitExpr(T,
7345218893Sdim                                          /*FIXME:*/T->getTypeLoc().getEndLoc(),
7346210299Sed                                                    E->getRParenLoc());
7347198092Srdivacky}
7348198092Srdivacky
7349198092Srdivackytemplate<typename Derived>
7350212904SdimExprResult
7351200583SrdivackyTreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
7352198092Srdivacky  // Transform the type that we're allocating
7353218893Sdim  TypeSourceInfo *AllocTypeInfo
7354218893Sdim    = getDerived().TransformType(E->getAllocatedTypeSourceInfo());
7355218893Sdim  if (!AllocTypeInfo)
7356212904Sdim    return ExprError();
7357198092Srdivacky
7358198092Srdivacky  // Transform the size of the array we're allocating (if any).
7359212904Sdim  ExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
7360198092Srdivacky  if (ArraySize.isInvalid())
7361212904Sdim    return ExprError();
7362198092Srdivacky
7363198092Srdivacky  // Transform the placement arguments (if any).
7364198092Srdivacky  bool ArgumentChanged = false;
7365243830Sdim  SmallVector<Expr*, 8> PlacementArgs;
7366239462Sdim  if (getDerived().TransformExprs(E->getPlacementArgs(),
7367218893Sdim                                  E->getNumPlacementArgs(), true,
7368218893Sdim                                  PlacementArgs, &ArgumentChanged))
7369234353Sdim    return ExprError();
7370198092Srdivacky
7371234353Sdim  // Transform the initializer (if any).
7372234353Sdim  Expr *OldInit = E->getInitializer();
7373234353Sdim  ExprResult NewInit;
7374234353Sdim  if (OldInit)
7375234353Sdim    NewInit = getDerived().TransformExpr(OldInit);
7376234353Sdim  if (NewInit.isInvalid())
7377234353Sdim    return ExprError();
7378198092Srdivacky
7379234353Sdim  // Transform new operator and delete operator.
7380204643Srdivacky  FunctionDecl *OperatorNew = 0;
7381204643Srdivacky  if (E->getOperatorNew()) {
7382204643Srdivacky    OperatorNew = cast_or_null<FunctionDecl>(
7383204643Srdivacky                                 getDerived().TransformDecl(E->getLocStart(),
7384204643Srdivacky                                                         E->getOperatorNew()));
7385204643Srdivacky    if (!OperatorNew)
7386212904Sdim      return ExprError();
7387204643Srdivacky  }
7388204643Srdivacky
7389204643Srdivacky  FunctionDecl *OperatorDelete = 0;
7390204643Srdivacky  if (E->getOperatorDelete()) {
7391204643Srdivacky    OperatorDelete = cast_or_null<FunctionDecl>(
7392204643Srdivacky                                   getDerived().TransformDecl(E->getLocStart(),
7393204643Srdivacky                                                       E->getOperatorDelete()));
7394204643Srdivacky    if (!OperatorDelete)
7395212904Sdim      return ExprError();
7396204643Srdivacky  }
7397239462Sdim
7398198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
7399218893Sdim      AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
7400198092Srdivacky      ArraySize.get() == E->getArraySize() &&
7401234353Sdim      NewInit.get() == OldInit &&
7402204643Srdivacky      OperatorNew == E->getOperatorNew() &&
7403204643Srdivacky      OperatorDelete == E->getOperatorDelete() &&
7404204643Srdivacky      !ArgumentChanged) {
7405204643Srdivacky    // Mark any declarations we need as referenced.
7406204643Srdivacky    // FIXME: instantiation-specific.
7407204643Srdivacky    if (OperatorNew)
7408234353Sdim      SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorNew);
7409204643Srdivacky    if (OperatorDelete)
7410234353Sdim      SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorDelete);
7411239462Sdim
7412234353Sdim    if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
7413226633Sdim      QualType ElementType
7414226633Sdim        = SemaRef.Context.getBaseElementType(E->getAllocatedType());
7415226633Sdim      if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
7416226633Sdim        CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
7417226633Sdim        if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
7418234353Sdim          SemaRef.MarkFunctionReferenced(E->getLocStart(), Destructor);
7419226633Sdim        }
7420226633Sdim      }
7421226633Sdim    }
7422234353Sdim
7423218893Sdim    return SemaRef.Owned(E);
7424204643Srdivacky  }
7425198092Srdivacky
7426218893Sdim  QualType AllocType = AllocTypeInfo->getType();
7427201361Srdivacky  if (!ArraySize.get()) {
7428201361Srdivacky    // If no array size was specified, but the new expression was
7429201361Srdivacky    // instantiated with an array type (e.g., "new T" where T is
7430201361Srdivacky    // instantiated with "int[4]"), extract the outer bound from the
7431201361Srdivacky    // array type as our array size. We do this with constant and
7432201361Srdivacky    // dependently-sized array types.
7433201361Srdivacky    const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(AllocType);
7434201361Srdivacky    if (!ArrayT) {
7435201361Srdivacky      // Do nothing
7436201361Srdivacky    } else if (const ConstantArrayType *ConsArrayT
7437201361Srdivacky                                     = dyn_cast<ConstantArrayType>(ArrayT)) {
7438239462Sdim      ArraySize
7439212904Sdim        = SemaRef.Owned(IntegerLiteral::Create(SemaRef.Context,
7440239462Sdim                                               ConsArrayT->getSize(),
7441212904Sdim                                               SemaRef.Context.getSizeType(),
7442212904Sdim                                               /*FIXME:*/E->getLocStart()));
7443201361Srdivacky      AllocType = ConsArrayT->getElementType();
7444201361Srdivacky    } else if (const DependentSizedArrayType *DepArrayT
7445201361Srdivacky                              = dyn_cast<DependentSizedArrayType>(ArrayT)) {
7446201361Srdivacky      if (DepArrayT->getSizeExpr()) {
7447218893Sdim        ArraySize = SemaRef.Owned(DepArrayT->getSizeExpr());
7448201361Srdivacky        AllocType = DepArrayT->getElementType();
7449201361Srdivacky      }
7450201361Srdivacky    }
7451201361Srdivacky  }
7452234353Sdim
7453198092Srdivacky  return getDerived().RebuildCXXNewExpr(E->getLocStart(),
7454198092Srdivacky                                        E->isGlobalNew(),
7455198092Srdivacky                                        /*FIXME:*/E->getLocStart(),
7456243830Sdim                                        PlacementArgs,
7457198092Srdivacky                                        /*FIXME:*/E->getLocStart(),
7458210299Sed                                        E->getTypeIdParens(),
7459198092Srdivacky                                        AllocType,
7460218893Sdim                                        AllocTypeInfo,
7461212904Sdim                                        ArraySize.get(),
7462234353Sdim                                        E->getDirectInitRange(),
7463234353Sdim                                        NewInit.take());
7464198092Srdivacky}
7465198092Srdivacky
7466198092Srdivackytemplate<typename Derived>
7467212904SdimExprResult
7468200583SrdivackyTreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
7469212904Sdim  ExprResult Operand = getDerived().TransformExpr(E->getArgument());
7470198092Srdivacky  if (Operand.isInvalid())
7471212904Sdim    return ExprError();
7472198092Srdivacky
7473204643Srdivacky  // Transform the delete operator, if known.
7474204643Srdivacky  FunctionDecl *OperatorDelete = 0;
7475204643Srdivacky  if (E->getOperatorDelete()) {
7476204643Srdivacky    OperatorDelete = cast_or_null<FunctionDecl>(
7477204643Srdivacky                                   getDerived().TransformDecl(E->getLocStart(),
7478204643Srdivacky                                                       E->getOperatorDelete()));
7479204643Srdivacky    if (!OperatorDelete)
7480212904Sdim      return ExprError();
7481204643Srdivacky  }
7482239462Sdim
7483198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
7484204643Srdivacky      Operand.get() == E->getArgument() &&
7485204643Srdivacky      OperatorDelete == E->getOperatorDelete()) {
7486204643Srdivacky    // Mark any declarations we need as referenced.
7487204643Srdivacky    // FIXME: instantiation-specific.
7488204643Srdivacky    if (OperatorDelete)
7489234353Sdim      SemaRef.MarkFunctionReferenced(E->getLocStart(), OperatorDelete);
7490239462Sdim
7491218893Sdim    if (!E->getArgument()->isTypeDependent()) {
7492218893Sdim      QualType Destroyed = SemaRef.Context.getBaseElementType(
7493218893Sdim                                                         E->getDestroyedType());
7494218893Sdim      if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
7495218893Sdim        CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
7496239462Sdim        SemaRef.MarkFunctionReferenced(E->getLocStart(),
7497234353Sdim                                       SemaRef.LookupDestructor(Record));
7498218893Sdim      }
7499218893Sdim    }
7500239462Sdim
7501218893Sdim    return SemaRef.Owned(E);
7502204643Srdivacky  }
7503198092Srdivacky
7504198092Srdivacky  return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
7505198092Srdivacky                                           E->isGlobalDelete(),
7506198092Srdivacky                                           E->isArrayForm(),
7507212904Sdim                                           Operand.get());
7508198092Srdivacky}
7509198092Srdivacky
7510198092Srdivackytemplate<typename Derived>
7511212904SdimExprResult
7512198092SrdivackyTreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
7513200583Srdivacky                                                     CXXPseudoDestructorExpr *E) {
7514212904Sdim  ExprResult Base = getDerived().TransformExpr(E->getBase());
7515198092Srdivacky  if (Base.isInvalid())
7516212904Sdim    return ExprError();
7517198092Srdivacky
7518212904Sdim  ParsedType ObjectTypePtr;
7519204643Srdivacky  bool MayBePseudoDestructor = false;
7520239462Sdim  Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(),
7521204643Srdivacky                                              E->getOperatorLoc(),
7522204643Srdivacky                                        E->isArrow()? tok::arrow : tok::period,
7523204643Srdivacky                                              ObjectTypePtr,
7524204643Srdivacky                                              MayBePseudoDestructor);
7525204643Srdivacky  if (Base.isInvalid())
7526212904Sdim    return ExprError();
7527239462Sdim
7528212904Sdim  QualType ObjectType = ObjectTypePtr.get();
7529219077Sdim  NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
7530219077Sdim  if (QualifierLoc) {
7531219077Sdim    QualifierLoc
7532219077Sdim      = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
7533219077Sdim    if (!QualifierLoc)
7534218893Sdim      return ExprError();
7535218893Sdim  }
7536219077Sdim  CXXScopeSpec SS;
7537219077Sdim  SS.Adopt(QualifierLoc);
7538198092Srdivacky
7539204643Srdivacky  PseudoDestructorTypeStorage Destroyed;
7540204643Srdivacky  if (E->getDestroyedTypeInfo()) {
7541204643Srdivacky    TypeSourceInfo *DestroyedTypeInfo
7542218893Sdim      = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
7543221345Sdim                                                ObjectType, 0, SS);
7544204643Srdivacky    if (!DestroyedTypeInfo)
7545212904Sdim      return ExprError();
7546204643Srdivacky    Destroyed = DestroyedTypeInfo;
7547234353Sdim  } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
7548204643Srdivacky    // We aren't likely to be able to resolve the identifier down to a type
7549204643Srdivacky    // now anyway, so just retain the identifier.
7550204643Srdivacky    Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
7551204643Srdivacky                                            E->getDestroyedTypeLoc());
7552204643Srdivacky  } else {
7553204643Srdivacky    // Look for a destructor known with the given name.
7554212904Sdim    ParsedType T = SemaRef.getDestructorName(E->getTildeLoc(),
7555204643Srdivacky                                              *E->getDestroyedTypeIdentifier(),
7556204643Srdivacky                                                E->getDestroyedTypeLoc(),
7557204643Srdivacky                                                /*Scope=*/0,
7558204643Srdivacky                                                SS, ObjectTypePtr,
7559204643Srdivacky                                                false);
7560204643Srdivacky    if (!T)
7561212904Sdim      return ExprError();
7562239462Sdim
7563204643Srdivacky    Destroyed
7564204643Srdivacky      = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.GetTypeFromParser(T),
7565204643Srdivacky                                                 E->getDestroyedTypeLoc());
7566198092Srdivacky  }
7567198092Srdivacky
7568204643Srdivacky  TypeSourceInfo *ScopeTypeInfo = 0;
7569204643Srdivacky  if (E->getScopeTypeInfo()) {
7570249423Sdim    CXXScopeSpec EmptySS;
7571249423Sdim    ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
7572249423Sdim                      E->getScopeTypeInfo(), ObjectType, 0, EmptySS);
7573204643Srdivacky    if (!ScopeTypeInfo)
7574212904Sdim      return ExprError();
7575204643Srdivacky  }
7576239462Sdim
7577212904Sdim  return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
7578198092Srdivacky                                                     E->getOperatorLoc(),
7579198092Srdivacky                                                     E->isArrow(),
7580219077Sdim                                                     SS,
7581204643Srdivacky                                                     ScopeTypeInfo,
7582204643Srdivacky                                                     E->getColonColonLoc(),
7583204643Srdivacky                                                     E->getTildeLoc(),
7584204643Srdivacky                                                     Destroyed);
7585198092Srdivacky}
7586198092Srdivacky
7587198092Srdivackytemplate<typename Derived>
7588212904SdimExprResult
7589199990SrdivackyTreeTransform<Derived>::TransformUnresolvedLookupExpr(
7590200583Srdivacky                                                  UnresolvedLookupExpr *Old) {
7591199990Srdivacky  LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
7592199990Srdivacky                 Sema::LookupOrdinaryName);
7593199990Srdivacky
7594199990Srdivacky  // Transform all the decls.
7595199990Srdivacky  for (UnresolvedLookupExpr::decls_iterator I = Old->decls_begin(),
7596199990Srdivacky         E = Old->decls_end(); I != E; ++I) {
7597204643Srdivacky    NamedDecl *InstD = static_cast<NamedDecl*>(
7598204643Srdivacky                                 getDerived().TransformDecl(Old->getNameLoc(),
7599204643Srdivacky                                                            *I));
7600200583Srdivacky    if (!InstD) {
7601200583Srdivacky      // Silently ignore these if a UsingShadowDecl instantiated to nothing.
7602200583Srdivacky      // This can happen because of dependent hiding.
7603200583Srdivacky      if (isa<UsingShadowDecl>(*I))
7604200583Srdivacky        continue;
7605200583Srdivacky      else
7606212904Sdim        return ExprError();
7607200583Srdivacky    }
7608199990Srdivacky
7609199990Srdivacky    // Expand using declarations.
7610199990Srdivacky    if (isa<UsingDecl>(InstD)) {
7611199990Srdivacky      UsingDecl *UD = cast<UsingDecl>(InstD);
7612199990Srdivacky      for (UsingDecl::shadow_iterator I = UD->shadow_begin(),
7613199990Srdivacky             E = UD->shadow_end(); I != E; ++I)
7614199990Srdivacky        R.addDecl(*I);
7615199990Srdivacky      continue;
7616199990Srdivacky    }
7617199990Srdivacky
7618199990Srdivacky    R.addDecl(InstD);
7619199990Srdivacky  }
7620199990Srdivacky
7621199990Srdivacky  // Resolve a kind, but don't do any further analysis.  If it's
7622199990Srdivacky  // ambiguous, the callee needs to deal with it.
7623199990Srdivacky  R.resolveKind();
7624199990Srdivacky
7625199990Srdivacky  // Rebuild the nested-name qualifier, if present.
7626199990Srdivacky  CXXScopeSpec SS;
7627221345Sdim  if (Old->getQualifierLoc()) {
7628221345Sdim    NestedNameSpecifierLoc QualifierLoc
7629221345Sdim      = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
7630221345Sdim    if (!QualifierLoc)
7631212904Sdim      return ExprError();
7632239462Sdim
7633221345Sdim    SS.Adopt(QualifierLoc);
7634239462Sdim  }
7635239462Sdim
7636207619Srdivacky  if (Old->getNamingClass()) {
7637207619Srdivacky    CXXRecordDecl *NamingClass
7638207619Srdivacky      = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
7639207619Srdivacky                                                            Old->getNameLoc(),
7640207619Srdivacky                                                        Old->getNamingClass()));
7641207619Srdivacky    if (!NamingClass)
7642212904Sdim      return ExprError();
7643239462Sdim
7644207619Srdivacky    R.setNamingClass(NamingClass);
7645199990Srdivacky  }
7646199990Srdivacky
7647234353Sdim  SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
7648234353Sdim
7649234353Sdim  // If we have neither explicit template arguments, nor the template keyword,
7650234353Sdim  // it's a normal declaration name.
7651234353Sdim  if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
7652199990Srdivacky    return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
7653199990Srdivacky
7654199990Srdivacky  // If we have template arguments, rebuild them, then rebuild the
7655199990Srdivacky  // templateid expression.
7656199990Srdivacky  TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
7657243830Sdim  if (Old->hasExplicitTemplateArgs() &&
7658243830Sdim      getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
7659218893Sdim                                              Old->getNumTemplateArgs(),
7660218893Sdim                                              TransArgs))
7661218893Sdim    return ExprError();
7662199990Srdivacky
7663234353Sdim  return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
7664234353Sdim                                            Old->requiresADL(), &TransArgs);
7665198092Srdivacky}
7666198092Srdivacky
7667198092Srdivackytemplate<typename Derived>
7668212904SdimExprResult
7669200583SrdivackyTreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
7670218893Sdim  TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
7671218893Sdim  if (!T)
7672212904Sdim    return ExprError();
7673198092Srdivacky
7674198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
7675218893Sdim      T == E->getQueriedTypeSourceInfo())
7676218893Sdim    return SemaRef.Owned(E);
7677198092Srdivacky
7678198092Srdivacky  return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
7679198092Srdivacky                                            E->getLocStart(),
7680198092Srdivacky                                            T,
7681198092Srdivacky                                            E->getLocEnd());
7682198092Srdivacky}
7683198092Srdivacky
7684198092Srdivackytemplate<typename Derived>
7685212904SdimExprResult
7686218893SdimTreeTransform<Derived>::TransformBinaryTypeTraitExpr(BinaryTypeTraitExpr *E) {
7687218893Sdim  TypeSourceInfo *LhsT = getDerived().TransformType(E->getLhsTypeSourceInfo());
7688218893Sdim  if (!LhsT)
7689218893Sdim    return ExprError();
7690218893Sdim
7691218893Sdim  TypeSourceInfo *RhsT = getDerived().TransformType(E->getRhsTypeSourceInfo());
7692218893Sdim  if (!RhsT)
7693218893Sdim    return ExprError();
7694218893Sdim
7695218893Sdim  if (!getDerived().AlwaysRebuild() &&
7696218893Sdim      LhsT == E->getLhsTypeSourceInfo() && RhsT == E->getRhsTypeSourceInfo())
7697218893Sdim    return SemaRef.Owned(E);
7698218893Sdim
7699218893Sdim  return getDerived().RebuildBinaryTypeTrait(E->getTrait(),
7700218893Sdim                                            E->getLocStart(),
7701218893Sdim                                            LhsT, RhsT,
7702218893Sdim                                            E->getLocEnd());
7703218893Sdim}
7704218893Sdim
7705218893Sdimtemplate<typename Derived>
7706218893SdimExprResult
7707234353SdimTreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
7708234353Sdim  bool ArgChanged = false;
7709249423Sdim  SmallVector<TypeSourceInfo *, 4> Args;
7710234353Sdim  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
7711234353Sdim    TypeSourceInfo *From = E->getArg(I);
7712234353Sdim    TypeLoc FromTL = From->getTypeLoc();
7713249423Sdim    if (!FromTL.getAs<PackExpansionTypeLoc>()) {
7714234353Sdim      TypeLocBuilder TLB;
7715234353Sdim      TLB.reserve(FromTL.getFullDataSize());
7716234353Sdim      QualType To = getDerived().TransformType(TLB, FromTL);
7717234353Sdim      if (To.isNull())
7718234353Sdim        return ExprError();
7719239462Sdim
7720234353Sdim      if (To == From->getType())
7721234353Sdim        Args.push_back(From);
7722234353Sdim      else {
7723234353Sdim        Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
7724234353Sdim        ArgChanged = true;
7725234353Sdim      }
7726234353Sdim      continue;
7727234353Sdim    }
7728239462Sdim
7729234353Sdim    ArgChanged = true;
7730239462Sdim
7731234353Sdim    // We have a pack expansion. Instantiate it.
7732249423Sdim    PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
7733234353Sdim    TypeLoc PatternTL = ExpansionTL.getPatternLoc();
7734234353Sdim    SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7735234353Sdim    SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
7736239462Sdim
7737234353Sdim    // Determine whether the set of unexpanded parameter packs can and should
7738234353Sdim    // be expanded.
7739234353Sdim    bool Expand = true;
7740234353Sdim    bool RetainExpansion = false;
7741249423Sdim    Optional<unsigned> OrigNumExpansions =
7742249423Sdim        ExpansionTL.getTypePtr()->getNumExpansions();
7743249423Sdim    Optional<unsigned> NumExpansions = OrigNumExpansions;
7744234353Sdim    if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
7745234353Sdim                                             PatternTL.getSourceRange(),
7746234353Sdim                                             Unexpanded,
7747234353Sdim                                             Expand, RetainExpansion,
7748234353Sdim                                             NumExpansions))
7749234353Sdim      return ExprError();
7750239462Sdim
7751234353Sdim    if (!Expand) {
7752234353Sdim      // The transform has determined that we should perform a simple
7753239462Sdim      // transformation on the pack expansion, producing another pack
7754234353Sdim      // expansion.
7755234353Sdim      Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
7756239462Sdim
7757234353Sdim      TypeLocBuilder TLB;
7758234353Sdim      TLB.reserve(From->getTypeLoc().getFullDataSize());
7759234353Sdim
7760234353Sdim      QualType To = getDerived().TransformType(TLB, PatternTL);
7761234353Sdim      if (To.isNull())
7762234353Sdim        return ExprError();
7763234353Sdim
7764239462Sdim      To = getDerived().RebuildPackExpansionType(To,
7765234353Sdim                                                 PatternTL.getSourceRange(),
7766234353Sdim                                                 ExpansionTL.getEllipsisLoc(),
7767234353Sdim                                                 NumExpansions);
7768234353Sdim      if (To.isNull())
7769234353Sdim        return ExprError();
7770239462Sdim
7771234353Sdim      PackExpansionTypeLoc ToExpansionTL
7772234353Sdim        = TLB.push<PackExpansionTypeLoc>(To);
7773234353Sdim      ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
7774234353Sdim      Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
7775234353Sdim      continue;
7776234353Sdim    }
7777234353Sdim
7778234353Sdim    // Expand the pack expansion by substituting for each argument in the
7779234353Sdim    // pack(s).
7780234353Sdim    for (unsigned I = 0; I != *NumExpansions; ++I) {
7781234353Sdim      Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I);
7782234353Sdim      TypeLocBuilder TLB;
7783234353Sdim      TLB.reserve(PatternTL.getFullDataSize());
7784234353Sdim      QualType To = getDerived().TransformType(TLB, PatternTL);
7785234353Sdim      if (To.isNull())
7786234353Sdim        return ExprError();
7787234353Sdim
7788234353Sdim      Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
7789234353Sdim    }
7790239462Sdim
7791234353Sdim    if (!RetainExpansion)
7792234353Sdim      continue;
7793239462Sdim
7794234353Sdim    // If we're supposed to retain a pack expansion, do so by temporarily
7795234353Sdim    // forgetting the partially-substituted parameter pack.
7796234353Sdim    ForgetPartiallySubstitutedPackRAII Forget(getDerived());
7797234353Sdim
7798234353Sdim    TypeLocBuilder TLB;
7799234353Sdim    TLB.reserve(From->getTypeLoc().getFullDataSize());
7800239462Sdim
7801234353Sdim    QualType To = getDerived().TransformType(TLB, PatternTL);
7802234353Sdim    if (To.isNull())
7803234353Sdim      return ExprError();
7804239462Sdim
7805239462Sdim    To = getDerived().RebuildPackExpansionType(To,
7806234353Sdim                                               PatternTL.getSourceRange(),
7807234353Sdim                                               ExpansionTL.getEllipsisLoc(),
7808234353Sdim                                               NumExpansions);
7809234353Sdim    if (To.isNull())
7810234353Sdim      return ExprError();
7811239462Sdim
7812234353Sdim    PackExpansionTypeLoc ToExpansionTL
7813234353Sdim      = TLB.push<PackExpansionTypeLoc>(To);
7814234353Sdim    ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
7815234353Sdim    Args.push_back(TLB.getTypeSourceInfo(SemaRef.Context, To));
7816234353Sdim  }
7817239462Sdim
7818234353Sdim  if (!getDerived().AlwaysRebuild() && !ArgChanged)
7819234353Sdim    return SemaRef.Owned(E);
7820234353Sdim
7821234353Sdim  return getDerived().RebuildTypeTrait(E->getTrait(),
7822234353Sdim                                       E->getLocStart(),
7823234353Sdim                                       Args,
7824234353Sdim                                       E->getLocEnd());
7825234353Sdim}
7826234353Sdim
7827234353Sdimtemplate<typename Derived>
7828234353SdimExprResult
7829221345SdimTreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
7830221345Sdim  TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
7831221345Sdim  if (!T)
7832221345Sdim    return ExprError();
7833221345Sdim
7834221345Sdim  if (!getDerived().AlwaysRebuild() &&
7835221345Sdim      T == E->getQueriedTypeSourceInfo())
7836221345Sdim    return SemaRef.Owned(E);
7837221345Sdim
7838221345Sdim  ExprResult SubExpr;
7839221345Sdim  {
7840221345Sdim    EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
7841221345Sdim    SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
7842221345Sdim    if (SubExpr.isInvalid())
7843221345Sdim      return ExprError();
7844221345Sdim
7845221345Sdim    if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getDimensionExpression())
7846221345Sdim      return SemaRef.Owned(E);
7847221345Sdim  }
7848221345Sdim
7849221345Sdim  return getDerived().RebuildArrayTypeTrait(E->getTrait(),
7850221345Sdim                                            E->getLocStart(),
7851221345Sdim                                            T,
7852221345Sdim                                            SubExpr.get(),
7853221345Sdim                                            E->getLocEnd());
7854221345Sdim}
7855221345Sdim
7856221345Sdimtemplate<typename Derived>
7857221345SdimExprResult
7858221345SdimTreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
7859221345Sdim  ExprResult SubExpr;
7860221345Sdim  {
7861221345Sdim    EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
7862221345Sdim    SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
7863221345Sdim    if (SubExpr.isInvalid())
7864221345Sdim      return ExprError();
7865221345Sdim
7866221345Sdim    if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
7867221345Sdim      return SemaRef.Owned(E);
7868221345Sdim  }
7869221345Sdim
7870221345Sdim  return getDerived().RebuildExpressionTrait(
7871221345Sdim      E->getTrait(), E->getLocStart(), SubExpr.get(), E->getLocEnd());
7872221345Sdim}
7873221345Sdim
7874221345Sdimtemplate<typename Derived>
7875221345SdimExprResult
7876199990SrdivackyTreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
7877212904Sdim                                               DependentScopeDeclRefExpr *E) {
7878243830Sdim  return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand*/false);
7879243830Sdim}
7880243830Sdim
7881243830Sdimtemplate<typename Derived>
7882243830SdimExprResult
7883243830SdimTreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
7884243830Sdim                                               DependentScopeDeclRefExpr *E,
7885243830Sdim                                               bool IsAddressOfOperand) {
7886219077Sdim  NestedNameSpecifierLoc QualifierLoc
7887219077Sdim  = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
7888219077Sdim  if (!QualifierLoc)
7889212904Sdim    return ExprError();
7890234353Sdim  SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
7891198092Srdivacky
7892218893Sdim  // TODO: If this is a conversion-function-id, verify that the
7893218893Sdim  // destination type name (if present) resolves the same way after
7894218893Sdim  // instantiation as it did in the local scope.
7895218893Sdim
7896212904Sdim  DeclarationNameInfo NameInfo
7897212904Sdim    = getDerived().TransformDeclarationNameInfo(E->getNameInfo());
7898212904Sdim  if (!NameInfo.getName())
7899212904Sdim    return ExprError();
7900198092Srdivacky
7901199990Srdivacky  if (!E->hasExplicitTemplateArgs()) {
7902199990Srdivacky    if (!getDerived().AlwaysRebuild() &&
7903219077Sdim        QualifierLoc == E->getQualifierLoc() &&
7904212904Sdim        // Note: it is sufficient to compare the Name component of NameInfo:
7905212904Sdim        // if name has not changed, DNLoc has not changed either.
7906212904Sdim        NameInfo.getName() == E->getDeclName())
7907218893Sdim      return SemaRef.Owned(E);
7908198092Srdivacky
7909219077Sdim    return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc,
7910234353Sdim                                                         TemplateKWLoc,
7911212904Sdim                                                         NameInfo,
7912243830Sdim                                                         /*TemplateArgs*/ 0,
7913243830Sdim                                                         IsAddressOfOperand);
7914199990Srdivacky  }
7915198092Srdivacky
7916199990Srdivacky  TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
7917218893Sdim  if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
7918218893Sdim                                              E->getNumTemplateArgs(),
7919218893Sdim                                              TransArgs))
7920218893Sdim    return ExprError();
7921198092Srdivacky
7922219077Sdim  return getDerived().RebuildDependentScopeDeclRefExpr(QualifierLoc,
7923234353Sdim                                                       TemplateKWLoc,
7924212904Sdim                                                       NameInfo,
7925243830Sdim                                                       &TransArgs,
7926243830Sdim                                                       IsAddressOfOperand);
7927198092Srdivacky}
7928198092Srdivacky
7929198092Srdivackytemplate<typename Derived>
7930212904SdimExprResult
7931200583SrdivackyTreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
7932249423Sdim  // CXXConstructExprs other than for list-initialization and
7933249423Sdim  // CXXTemporaryObjectExpr are always implicit, so when we have
7934249423Sdim  // a 1-argument construction we just transform that argument.
7935249423Sdim  if ((E->getNumArgs() == 1 ||
7936249423Sdim       (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(1)))) &&
7937249423Sdim      (!getDerived().DropCallArgument(E->getArg(0))) &&
7938249423Sdim      !E->isListInitialization())
7939203955Srdivacky    return getDerived().TransformExpr(E->getArg(0));
7940203955Srdivacky
7941198092Srdivacky  TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
7942198092Srdivacky
7943198092Srdivacky  QualType T = getDerived().TransformType(E->getType());
7944198092Srdivacky  if (T.isNull())
7945212904Sdim    return ExprError();
7946198092Srdivacky
7947198092Srdivacky  CXXConstructorDecl *Constructor
7948198092Srdivacky    = cast_or_null<CXXConstructorDecl>(
7949204643Srdivacky                                getDerived().TransformDecl(E->getLocStart(),
7950204643Srdivacky                                                         E->getConstructor()));
7951198092Srdivacky  if (!Constructor)
7952212904Sdim    return ExprError();
7953198092Srdivacky
7954198092Srdivacky  bool ArgumentChanged = false;
7955243830Sdim  SmallVector<Expr*, 8> Args;
7956239462Sdim  if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
7957218893Sdim                                  &ArgumentChanged))
7958218893Sdim    return ExprError();
7959239462Sdim
7960198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
7961198092Srdivacky      T == E->getType() &&
7962198092Srdivacky      Constructor == E->getConstructor() &&
7963204643Srdivacky      !ArgumentChanged) {
7964204643Srdivacky    // Mark the constructor as referenced.
7965204643Srdivacky    // FIXME: Instantiation-specific
7966234353Sdim    SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor);
7967218893Sdim    return SemaRef.Owned(E);
7968204643Srdivacky  }
7969198092Srdivacky
7970200583Srdivacky  return getDerived().RebuildCXXConstructExpr(T, /*FIXME:*/E->getLocStart(),
7971200583Srdivacky                                              Constructor, E->isElidable(),
7972243830Sdim                                              Args,
7973226633Sdim                                              E->hadMultipleCandidates(),
7974249423Sdim                                              E->isListInitialization(),
7975212904Sdim                                              E->requiresZeroInitialization(),
7976218893Sdim                                              E->getConstructionKind(),
7977218893Sdim                                              E->getParenRange());
7978198092Srdivacky}
7979198092Srdivacky
7980198092Srdivacky/// \brief Transform a C++ temporary-binding expression.
7981198092Srdivacky///
7982201361Srdivacky/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
7983201361Srdivacky/// transform the subexpression and return that.
7984198092Srdivackytemplate<typename Derived>
7985212904SdimExprResult
7986200583SrdivackyTreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
7987201361Srdivacky  return getDerived().TransformExpr(E->getSubExpr());
7988198092Srdivacky}
7989198092Srdivacky
7990218893Sdim/// \brief Transform a C++ expression that contains cleanups that should
7991218893Sdim/// be run after the expression is evaluated.
7992198092Srdivacky///
7993218893Sdim/// Since ExprWithCleanups nodes are implicitly generated, we
7994201361Srdivacky/// just transform the subexpression and return that.
7995198092Srdivackytemplate<typename Derived>
7996212904SdimExprResult
7997218893SdimTreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
7998201361Srdivacky  return getDerived().TransformExpr(E->getSubExpr());
7999198092Srdivacky}
8000198092Srdivacky
8001198092Srdivackytemplate<typename Derived>
8002212904SdimExprResult
8003198092SrdivackyTreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
8004218893Sdim                                                    CXXTemporaryObjectExpr *E) {
8005218893Sdim  TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
8006218893Sdim  if (!T)
8007212904Sdim    return ExprError();
8008198092Srdivacky
8009198092Srdivacky  CXXConstructorDecl *Constructor
8010198092Srdivacky    = cast_or_null<CXXConstructorDecl>(
8011239462Sdim                                  getDerived().TransformDecl(E->getLocStart(),
8012204643Srdivacky                                                         E->getConstructor()));
8013198092Srdivacky  if (!Constructor)
8014212904Sdim    return ExprError();
8015198092Srdivacky
8016198092Srdivacky  bool ArgumentChanged = false;
8017243830Sdim  SmallVector<Expr*, 8> Args;
8018198092Srdivacky  Args.reserve(E->getNumArgs());
8019239462Sdim  if (TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
8020218893Sdim                     &ArgumentChanged))
8021218893Sdim    return ExprError();
8022204643Srdivacky
8023198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
8024218893Sdim      T == E->getTypeSourceInfo() &&
8025198092Srdivacky      Constructor == E->getConstructor() &&
8026204643Srdivacky      !ArgumentChanged) {
8027204643Srdivacky    // FIXME: Instantiation-specific
8028234353Sdim    SemaRef.MarkFunctionReferenced(E->getLocStart(), Constructor);
8029218893Sdim    return SemaRef.MaybeBindToTemporary(E);
8030204643Srdivacky  }
8031239462Sdim
8032249423Sdim  // FIXME: Pass in E->isListInitialization().
8033218893Sdim  return getDerived().RebuildCXXTemporaryObjectExpr(T,
8034218893Sdim                                          /*FIXME:*/T->getTypeLoc().getEndLoc(),
8035243830Sdim                                                    Args,
8036198092Srdivacky                                                    E->getLocEnd());
8037198092Srdivacky}
8038198092Srdivacky
8039198092Srdivackytemplate<typename Derived>
8040212904SdimExprResult
8041234353SdimTreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
8042234353Sdim  // Transform the type of the lambda parameters and start the definition of
8043234353Sdim  // the lambda itself.
8044234353Sdim  TypeSourceInfo *MethodTy
8045239462Sdim    = TransformType(E->getCallOperator()->getTypeSourceInfo());
8046234353Sdim  if (!MethodTy)
8047234353Sdim    return ExprError();
8048234353Sdim
8049243830Sdim  // Create the local class that will describe the lambda.
8050243830Sdim  CXXRecordDecl *Class
8051243830Sdim    = getSema().createLambdaClosureType(E->getIntroducerRange(),
8052243830Sdim                                        MethodTy,
8053243830Sdim                                        /*KnownDependent=*/false);
8054243830Sdim  getDerived().transformedLocalDecl(E->getLambdaClass(), Class);
8055243830Sdim
8056234353Sdim  // Transform lambda parameters.
8057249423Sdim  SmallVector<QualType, 4> ParamTypes;
8058249423Sdim  SmallVector<ParmVarDecl *, 4> Params;
8059234353Sdim  if (getDerived().TransformFunctionTypeParams(E->getLocStart(),
8060234353Sdim        E->getCallOperator()->param_begin(),
8061234353Sdim        E->getCallOperator()->param_size(),
8062234353Sdim        0, ParamTypes, &Params))
8063239462Sdim    return ExprError();
8064234353Sdim
8065234353Sdim  // Build the call operator.
8066234353Sdim  CXXMethodDecl *CallOperator
8067234353Sdim    = getSema().startLambdaDefinition(Class, E->getIntroducerRange(),
8068239462Sdim                                      MethodTy,
8069234353Sdim                                      E->getCallOperator()->getLocEnd(),
8070239462Sdim                                      Params);
8071234353Sdim  getDerived().transformAttrs(E->getCallOperator(), CallOperator);
8072234353Sdim
8073239462Sdim  return getDerived().TransformLambdaScope(E, CallOperator);
8074239462Sdim}
8075239462Sdim
8076239462Sdimtemplate<typename Derived>
8077239462SdimExprResult
8078239462SdimTreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E,
8079239462Sdim                                             CXXMethodDecl *CallOperator) {
8080234353Sdim  // Introduce the context of the call operator.
8081234353Sdim  Sema::ContextRAII SavedContext(getSema(), CallOperator);
8082234353Sdim
8083234353Sdim  // Enter the scope of the lambda.
8084234353Sdim  sema::LambdaScopeInfo *LSI
8085234353Sdim    = getSema().enterLambdaScope(CallOperator, E->getIntroducerRange(),
8086234353Sdim                                 E->getCaptureDefault(),
8087234353Sdim                                 E->hasExplicitParameters(),
8088234353Sdim                                 E->hasExplicitResultType(),
8089234353Sdim                                 E->isMutable());
8090239462Sdim
8091234353Sdim  // Transform captures.
8092239462Sdim  bool Invalid = false;
8093234353Sdim  bool FinishedExplicitCaptures = false;
8094239462Sdim  for (LambdaExpr::capture_iterator C = E->capture_begin(),
8095234353Sdim                                 CEnd = E->capture_end();
8096234353Sdim       C != CEnd; ++C) {
8097234353Sdim    // When we hit the first implicit capture, tell Sema that we've finished
8098234353Sdim    // the list of explicit captures.
8099234353Sdim    if (!FinishedExplicitCaptures && C->isImplicit()) {
8100234353Sdim      getSema().finishLambdaExplicitCaptures(LSI);
8101234353Sdim      FinishedExplicitCaptures = true;
8102234353Sdim    }
8103239462Sdim
8104234353Sdim    // Capturing 'this' is trivial.
8105234353Sdim    if (C->capturesThis()) {
8106234353Sdim      getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit());
8107234353Sdim      continue;
8108234353Sdim    }
8109239462Sdim
8110234353Sdim    // Determine the capture kind for Sema.
8111234353Sdim    Sema::TryCaptureKind Kind
8112234353Sdim      = C->isImplicit()? Sema::TryCapture_Implicit
8113234353Sdim                       : C->getCaptureKind() == LCK_ByCopy
8114234353Sdim                           ? Sema::TryCapture_ExplicitByVal
8115234353Sdim                           : Sema::TryCapture_ExplicitByRef;
8116234353Sdim    SourceLocation EllipsisLoc;
8117234353Sdim    if (C->isPackExpansion()) {
8118234353Sdim      UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
8119234353Sdim      bool ShouldExpand = false;
8120234353Sdim      bool RetainExpansion = false;
8121249423Sdim      Optional<unsigned> NumExpansions;
8122239462Sdim      if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
8123239462Sdim                                               C->getLocation(),
8124234353Sdim                                               Unexpanded,
8125234353Sdim                                               ShouldExpand, RetainExpansion,
8126234353Sdim                                               NumExpansions))
8127234353Sdim        return ExprError();
8128239462Sdim
8129234353Sdim      if (ShouldExpand) {
8130234353Sdim        // The transform has determined that we should perform an expansion;
8131234353Sdim        // transform and capture each of the arguments.
8132234353Sdim        // expansion of the pattern. Do so.
8133234353Sdim        VarDecl *Pack = C->getCapturedVar();
8134234353Sdim        for (unsigned I = 0; I != *NumExpansions; ++I) {
8135234353Sdim          Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
8136234353Sdim          VarDecl *CapturedVar
8137239462Sdim            = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
8138234353Sdim                                                               Pack));
8139234353Sdim          if (!CapturedVar) {
8140234353Sdim            Invalid = true;
8141234353Sdim            continue;
8142234353Sdim          }
8143239462Sdim
8144234353Sdim          // Capture the transformed variable.
8145239462Sdim          getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
8146239462Sdim        }
8147234353Sdim        continue;
8148234353Sdim      }
8149239462Sdim
8150234353Sdim      EllipsisLoc = C->getEllipsisLoc();
8151234353Sdim    }
8152239462Sdim
8153234353Sdim    // Transform the captured variable.
8154234353Sdim    VarDecl *CapturedVar
8155239462Sdim      = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
8156234353Sdim                                                         C->getCapturedVar()));
8157234353Sdim    if (!CapturedVar) {
8158234353Sdim      Invalid = true;
8159234353Sdim      continue;
8160234353Sdim    }
8161239462Sdim
8162234353Sdim    // Capture the transformed variable.
8163234353Sdim    getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
8164234353Sdim  }
8165234353Sdim  if (!FinishedExplicitCaptures)
8166234353Sdim    getSema().finishLambdaExplicitCaptures(LSI);
8167234353Sdim
8168234353Sdim
8169234353Sdim  // Enter a new evaluation context to insulate the lambda from any
8170234353Sdim  // cleanups from the enclosing full-expression.
8171239462Sdim  getSema().PushExpressionEvaluationContext(Sema::PotentiallyEvaluated);
8172234353Sdim
8173234353Sdim  if (Invalid) {
8174239462Sdim    getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0,
8175234353Sdim                               /*IsInstantiation=*/true);
8176234353Sdim    return ExprError();
8177234353Sdim  }
8178234353Sdim
8179234353Sdim  // Instantiate the body of the lambda expression.
8180234353Sdim  StmtResult Body = getDerived().TransformStmt(E->getBody());
8181234353Sdim  if (Body.isInvalid()) {
8182239462Sdim    getSema().ActOnLambdaError(E->getLocStart(), /*CurScope=*/0,
8183234353Sdim                               /*IsInstantiation=*/true);
8184239462Sdim    return ExprError();
8185234353Sdim  }
8186234353Sdim
8187239462Sdim  return getSema().ActOnLambdaExpr(E->getLocStart(), Body.take(),
8188234353Sdim                                   /*CurScope=*/0, /*IsInstantiation=*/true);
8189234353Sdim}
8190234353Sdim
8191234353Sdimtemplate<typename Derived>
8192234353SdimExprResult
8193198092SrdivackyTreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
8194200583Srdivacky                                                  CXXUnresolvedConstructExpr *E) {
8195218893Sdim  TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
8196218893Sdim  if (!T)
8197212904Sdim    return ExprError();
8198198092Srdivacky
8199198092Srdivacky  bool ArgumentChanged = false;
8200243830Sdim  SmallVector<Expr*, 8> Args;
8201218893Sdim  Args.reserve(E->arg_size());
8202239462Sdim  if (getDerived().TransformExprs(E->arg_begin(), E->arg_size(), true, Args,
8203218893Sdim                                  &ArgumentChanged))
8204218893Sdim    return ExprError();
8205239462Sdim
8206198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
8207218893Sdim      T == E->getTypeSourceInfo() &&
8208198092Srdivacky      !ArgumentChanged)
8209218893Sdim    return SemaRef.Owned(E);
8210198092Srdivacky
8211198092Srdivacky  // FIXME: we're faking the locations of the commas
8212218893Sdim  return getDerived().RebuildCXXUnresolvedConstructExpr(T,
8213198092Srdivacky                                                        E->getLParenLoc(),
8214243830Sdim                                                        Args,
8215198092Srdivacky                                                        E->getRParenLoc());
8216198092Srdivacky}
8217198092Srdivacky
8218198092Srdivackytemplate<typename Derived>
8219212904SdimExprResult
8220199990SrdivackyTreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
8221212904Sdim                                             CXXDependentScopeMemberExpr *E) {
8222198092Srdivacky  // Transform the base of the expression.
8223212904Sdim  ExprResult Base((Expr*) 0);
8224200583Srdivacky  Expr *OldBase;
8225200583Srdivacky  QualType BaseType;
8226200583Srdivacky  QualType ObjectType;
8227200583Srdivacky  if (!E->isImplicitAccess()) {
8228200583Srdivacky    OldBase = E->getBase();
8229200583Srdivacky    Base = getDerived().TransformExpr(OldBase);
8230200583Srdivacky    if (Base.isInvalid())
8231212904Sdim      return ExprError();
8232198092Srdivacky
8233200583Srdivacky    // Start the member reference and compute the object's type.
8234212904Sdim    ParsedType ObjectTy;
8235204643Srdivacky    bool MayBePseudoDestructor = false;
8236212904Sdim    Base = SemaRef.ActOnStartCXXMemberReference(0, Base.get(),
8237200583Srdivacky                                                E->getOperatorLoc(),
8238198092Srdivacky                                      E->isArrow()? tok::arrow : tok::period,
8239204643Srdivacky                                                ObjectTy,
8240204643Srdivacky                                                MayBePseudoDestructor);
8241200583Srdivacky    if (Base.isInvalid())
8242212904Sdim      return ExprError();
8243198092Srdivacky
8244212904Sdim    ObjectType = ObjectTy.get();
8245200583Srdivacky    BaseType = ((Expr*) Base.get())->getType();
8246200583Srdivacky  } else {
8247200583Srdivacky    OldBase = 0;
8248200583Srdivacky    BaseType = getDerived().TransformType(E->getBaseType());
8249200583Srdivacky    ObjectType = BaseType->getAs<PointerType>()->getPointeeType();
8250200583Srdivacky  }
8251200583Srdivacky
8252198398Srdivacky  // Transform the first part of the nested-name-specifier that qualifies
8253198398Srdivacky  // the member name.
8254198092Srdivacky  NamedDecl *FirstQualifierInScope
8255198398Srdivacky    = getDerived().TransformFirstQualifierInScope(
8256221345Sdim                                            E->getFirstQualifierFoundInScope(),
8257221345Sdim                                            E->getQualifierLoc().getBeginLoc());
8258198092Srdivacky
8259221345Sdim  NestedNameSpecifierLoc QualifierLoc;
8260198092Srdivacky  if (E->getQualifier()) {
8261221345Sdim    QualifierLoc
8262221345Sdim      = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
8263221345Sdim                                                     ObjectType,
8264221345Sdim                                                     FirstQualifierInScope);
8265221345Sdim    if (!QualifierLoc)
8266212904Sdim      return ExprError();
8267198092Srdivacky  }
8268198092Srdivacky
8269234353Sdim  SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
8270234353Sdim
8271218893Sdim  // TODO: If this is a conversion-function-id, verify that the
8272218893Sdim  // destination type name (if present) resolves the same way after
8273218893Sdim  // instantiation as it did in the local scope.
8274218893Sdim
8275212904Sdim  DeclarationNameInfo NameInfo
8276218893Sdim    = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
8277212904Sdim  if (!NameInfo.getName())
8278212904Sdim    return ExprError();
8279198092Srdivacky
8280200583Srdivacky  if (!E->hasExplicitTemplateArgs()) {
8281198092Srdivacky    // This is a reference to a member without an explicitly-specified
8282198092Srdivacky    // template argument list. Optimize for this common case.
8283198092Srdivacky    if (!getDerived().AlwaysRebuild() &&
8284200583Srdivacky        Base.get() == OldBase &&
8285200583Srdivacky        BaseType == E->getBaseType() &&
8286221345Sdim        QualifierLoc == E->getQualifierLoc() &&
8287212904Sdim        NameInfo.getName() == E->getMember() &&
8288198092Srdivacky        FirstQualifierInScope == E->getFirstQualifierFoundInScope())
8289218893Sdim      return SemaRef.Owned(E);
8290198092Srdivacky
8291212904Sdim    return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
8292200583Srdivacky                                                       BaseType,
8293198092Srdivacky                                                       E->isArrow(),
8294198092Srdivacky                                                       E->getOperatorLoc(),
8295221345Sdim                                                       QualifierLoc,
8296234353Sdim                                                       TemplateKWLoc,
8297199990Srdivacky                                                       FirstQualifierInScope,
8298212904Sdim                                                       NameInfo,
8299199990Srdivacky                                                       /*TemplateArgs*/ 0);
8300198092Srdivacky  }
8301198092Srdivacky
8302199990Srdivacky  TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
8303218893Sdim  if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
8304218893Sdim                                              E->getNumTemplateArgs(),
8305218893Sdim                                              TransArgs))
8306218893Sdim    return ExprError();
8307198092Srdivacky
8308212904Sdim  return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
8309200583Srdivacky                                                     BaseType,
8310198092Srdivacky                                                     E->isArrow(),
8311198092Srdivacky                                                     E->getOperatorLoc(),
8312221345Sdim                                                     QualifierLoc,
8313234353Sdim                                                     TemplateKWLoc,
8314199990Srdivacky                                                     FirstQualifierInScope,
8315212904Sdim                                                     NameInfo,
8316199990Srdivacky                                                     &TransArgs);
8317198092Srdivacky}
8318198092Srdivacky
8319198092Srdivackytemplate<typename Derived>
8320212904SdimExprResult
8321200583SrdivackyTreeTransform<Derived>::TransformUnresolvedMemberExpr(UnresolvedMemberExpr *Old) {
8322199990Srdivacky  // Transform the base of the expression.
8323212904Sdim  ExprResult Base((Expr*) 0);
8324200583Srdivacky  QualType BaseType;
8325200583Srdivacky  if (!Old->isImplicitAccess()) {
8326200583Srdivacky    Base = getDerived().TransformExpr(Old->getBase());
8327200583Srdivacky    if (Base.isInvalid())
8328212904Sdim      return ExprError();
8329234353Sdim    Base = getSema().PerformMemberExprBaseConversion(Base.take(),
8330234353Sdim                                                     Old->isArrow());
8331234353Sdim    if (Base.isInvalid())
8332234353Sdim      return ExprError();
8333234353Sdim    BaseType = Base.get()->getType();
8334200583Srdivacky  } else {
8335200583Srdivacky    BaseType = getDerived().TransformType(Old->getBaseType());
8336200583Srdivacky  }
8337199990Srdivacky
8338221345Sdim  NestedNameSpecifierLoc QualifierLoc;
8339221345Sdim  if (Old->getQualifierLoc()) {
8340221345Sdim    QualifierLoc
8341221345Sdim    = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
8342221345Sdim    if (!QualifierLoc)
8343212904Sdim      return ExprError();
8344199990Srdivacky  }
8345199990Srdivacky
8346234353Sdim  SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
8347234353Sdim
8348212904Sdim  LookupResult R(SemaRef, Old->getMemberNameInfo(),
8349199990Srdivacky                 Sema::LookupOrdinaryName);
8350199990Srdivacky
8351199990Srdivacky  // Transform all the decls.
8352199990Srdivacky  for (UnresolvedMemberExpr::decls_iterator I = Old->decls_begin(),
8353199990Srdivacky         E = Old->decls_end(); I != E; ++I) {
8354204643Srdivacky    NamedDecl *InstD = static_cast<NamedDecl*>(
8355204643Srdivacky                                getDerived().TransformDecl(Old->getMemberLoc(),
8356204643Srdivacky                                                           *I));
8357200583Srdivacky    if (!InstD) {
8358200583Srdivacky      // Silently ignore these if a UsingShadowDecl instantiated to nothing.
8359200583Srdivacky      // This can happen because of dependent hiding.
8360200583Srdivacky      if (isa<UsingShadowDecl>(*I))
8361200583Srdivacky        continue;
8362221345Sdim      else {
8363221345Sdim        R.clear();
8364212904Sdim        return ExprError();
8365221345Sdim      }
8366200583Srdivacky    }
8367199990Srdivacky
8368199990Srdivacky    // Expand using declarations.
8369199990Srdivacky    if (isa<UsingDecl>(InstD)) {
8370199990Srdivacky      UsingDecl *UD = cast<UsingDecl>(InstD);
8371199990Srdivacky      for (UsingDecl::shadow_iterator I = UD->shadow_begin(),
8372199990Srdivacky             E = UD->shadow_end(); I != E; ++I)
8373199990Srdivacky        R.addDecl(*I);
8374199990Srdivacky      continue;
8375199990Srdivacky    }
8376199990Srdivacky
8377199990Srdivacky    R.addDecl(InstD);
8378199990Srdivacky  }
8379199990Srdivacky
8380199990Srdivacky  R.resolveKind();
8381199990Srdivacky
8382207619Srdivacky  // Determine the naming class.
8383208600Srdivacky  if (Old->getNamingClass()) {
8384239462Sdim    CXXRecordDecl *NamingClass
8385207619Srdivacky      = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
8386207619Srdivacky                                                          Old->getMemberLoc(),
8387207619Srdivacky                                                        Old->getNamingClass()));
8388207619Srdivacky    if (!NamingClass)
8389212904Sdim      return ExprError();
8390239462Sdim
8391207619Srdivacky    R.setNamingClass(NamingClass);
8392207619Srdivacky  }
8393239462Sdim
8394199990Srdivacky  TemplateArgumentListInfo TransArgs;
8395199990Srdivacky  if (Old->hasExplicitTemplateArgs()) {
8396199990Srdivacky    TransArgs.setLAngleLoc(Old->getLAngleLoc());
8397199990Srdivacky    TransArgs.setRAngleLoc(Old->getRAngleLoc());
8398218893Sdim    if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
8399218893Sdim                                                Old->getNumTemplateArgs(),
8400218893Sdim                                                TransArgs))
8401218893Sdim      return ExprError();
8402199990Srdivacky  }
8403202379Srdivacky
8404202379Srdivacky  // FIXME: to do this check properly, we will need to preserve the
8405202379Srdivacky  // first-qualifier-in-scope here, just in case we had a dependent
8406202379Srdivacky  // base (and therefore couldn't do the check) and a
8407202379Srdivacky  // nested-name-qualifier (and therefore could do the lookup).
8408202379Srdivacky  NamedDecl *FirstQualifierInScope = 0;
8409239462Sdim
8410212904Sdim  return getDerived().RebuildUnresolvedMemberExpr(Base.get(),
8411200583Srdivacky                                                  BaseType,
8412199990Srdivacky                                                  Old->getOperatorLoc(),
8413199990Srdivacky                                                  Old->isArrow(),
8414221345Sdim                                                  QualifierLoc,
8415234353Sdim                                                  TemplateKWLoc,
8416202379Srdivacky                                                  FirstQualifierInScope,
8417199990Srdivacky                                                  R,
8418199990Srdivacky                                              (Old->hasExplicitTemplateArgs()
8419199990Srdivacky                                                  ? &TransArgs : 0));
8420199990Srdivacky}
8421199990Srdivacky
8422199990Srdivackytemplate<typename Derived>
8423212904SdimExprResult
8424218893SdimTreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
8425223017Sdim  EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated);
8426218893Sdim  ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
8427218893Sdim  if (SubExpr.isInvalid())
8428218893Sdim    return ExprError();
8429218893Sdim
8430218893Sdim  if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
8431218893Sdim    return SemaRef.Owned(E);
8432218893Sdim
8433218893Sdim  return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
8434218893Sdim}
8435218893Sdim
8436218893Sdimtemplate<typename Derived>
8437218893SdimExprResult
8438218893SdimTreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
8439218893Sdim  ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
8440218893Sdim  if (Pattern.isInvalid())
8441218893Sdim    return ExprError();
8442239462Sdim
8443218893Sdim  if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
8444218893Sdim    return SemaRef.Owned(E);
8445218893Sdim
8446218893Sdim  return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
8447218893Sdim                                           E->getNumExpansions());
8448218893Sdim}
8449218893Sdim
8450218893Sdimtemplate<typename Derived>
8451218893SdimExprResult
8452218893SdimTreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
8453218893Sdim  // If E is not value-dependent, then nothing will change when we transform it.
8454218893Sdim  // Note: This is an instantiation-centric view.
8455218893Sdim  if (!E->isValueDependent())
8456218893Sdim    return SemaRef.Owned(E);
8457218893Sdim
8458218893Sdim  // Note: None of the implementations of TryExpandParameterPacks can ever
8459218893Sdim  // produce a diagnostic when given only a single unexpanded parameter pack,
8460239462Sdim  // so
8461218893Sdim  UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
8462218893Sdim  bool ShouldExpand = false;
8463218893Sdim  bool RetainExpansion = false;
8464249423Sdim  Optional<unsigned> NumExpansions;
8465239462Sdim  if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
8466226633Sdim                                           Unexpanded,
8467218893Sdim                                           ShouldExpand, RetainExpansion,
8468218893Sdim                                           NumExpansions))
8469218893Sdim    return ExprError();
8470239462Sdim
8471226633Sdim  if (RetainExpansion)
8472218893Sdim    return SemaRef.Owned(E);
8473239462Sdim
8474226633Sdim  NamedDecl *Pack = E->getPack();
8475226633Sdim  if (!ShouldExpand) {
8476239462Sdim    Pack = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getPackLoc(),
8477226633Sdim                                                              Pack));
8478226633Sdim    if (!Pack)
8479226633Sdim      return ExprError();
8480226633Sdim  }
8481226633Sdim
8482239462Sdim
8483218893Sdim  // We now know the length of the parameter pack, so build a new expression
8484218893Sdim  // that stores that length.
8485239462Sdim  return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), Pack,
8486239462Sdim                                            E->getPackLoc(), E->getRParenLoc(),
8487226633Sdim                                            NumExpansions);
8488218893Sdim}
8489218893Sdim
8490218893Sdimtemplate<typename Derived>
8491218893SdimExprResult
8492218893SdimTreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
8493218893Sdim                                          SubstNonTypeTemplateParmPackExpr *E) {
8494218893Sdim  // Default behavior is to do nothing with this transformation.
8495218893Sdim  return SemaRef.Owned(E);
8496218893Sdim}
8497218893Sdim
8498218893Sdimtemplate<typename Derived>
8499218893SdimExprResult
8500224145SdimTreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
8501224145Sdim                                          SubstNonTypeTemplateParmExpr *E) {
8502224145Sdim  // Default behavior is to do nothing with this transformation.
8503224145Sdim  return SemaRef.Owned(E);
8504224145Sdim}
8505224145Sdim
8506224145Sdimtemplate<typename Derived>
8507224145SdimExprResult
8508243830SdimTreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
8509243830Sdim  // Default behavior is to do nothing with this transformation.
8510243830Sdim  return SemaRef.Owned(E);
8511243830Sdim}
8512243830Sdim
8513243830Sdimtemplate<typename Derived>
8514243830SdimExprResult
8515224145SdimTreeTransform<Derived>::TransformMaterializeTemporaryExpr(
8516224145Sdim                                                  MaterializeTemporaryExpr *E) {
8517224145Sdim  return getDerived().TransformExpr(E->GetTemporaryExpr());
8518224145Sdim}
8519239462Sdim
8520224145Sdimtemplate<typename Derived>
8521224145SdimExprResult
8522200583SrdivackyTreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
8523234353Sdim  return SemaRef.MaybeBindToTemporary(E);
8524234353Sdim}
8525234353Sdim
8526234353Sdimtemplate<typename Derived>
8527234353SdimExprResult
8528234353SdimTreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
8529218893Sdim  return SemaRef.Owned(E);
8530198092Srdivacky}
8531198092Srdivacky
8532198092Srdivackytemplate<typename Derived>
8533212904SdimExprResult
8534239462SdimTreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
8535239462Sdim  ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
8536239462Sdim  if (SubExpr.isInvalid())
8537239462Sdim    return ExprError();
8538239462Sdim
8539239462Sdim  if (!getDerived().AlwaysRebuild() &&
8540239462Sdim      SubExpr.get() == E->getSubExpr())
8541239462Sdim    return SemaRef.Owned(E);
8542239462Sdim
8543239462Sdim  return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
8544234353Sdim}
8545234353Sdim
8546234353Sdimtemplate<typename Derived>
8547234353SdimExprResult
8548234353SdimTreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
8549234353Sdim  // Transform each of the elements.
8550249423Sdim  SmallVector<Expr *, 8> Elements;
8551234353Sdim  bool ArgChanged = false;
8552239462Sdim  if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
8553234353Sdim                                  /*IsCall=*/false, Elements, &ArgChanged))
8554234353Sdim    return ExprError();
8555239462Sdim
8556234353Sdim  if (!getDerived().AlwaysRebuild() && !ArgChanged)
8557234353Sdim    return SemaRef.MaybeBindToTemporary(E);
8558239462Sdim
8559234353Sdim  return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
8560234353Sdim                                              Elements.data(),
8561234353Sdim                                              Elements.size());
8562234353Sdim}
8563234353Sdim
8564234353Sdimtemplate<typename Derived>
8565234353SdimExprResult
8566234353SdimTreeTransform<Derived>::TransformObjCDictionaryLiteral(
8567239462Sdim                                                    ObjCDictionaryLiteral *E) {
8568234353Sdim  // Transform each of the elements.
8569249423Sdim  SmallVector<ObjCDictionaryElement, 8> Elements;
8570234353Sdim  bool ArgChanged = false;
8571234353Sdim  for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
8572234353Sdim    ObjCDictionaryElement OrigElement = E->getKeyValueElement(I);
8573239462Sdim
8574234353Sdim    if (OrigElement.isPackExpansion()) {
8575234353Sdim      // This key/value element is a pack expansion.
8576234353Sdim      SmallVector<UnexpandedParameterPack, 2> Unexpanded;
8577234353Sdim      getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
8578234353Sdim      getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
8579234353Sdim      assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
8580234353Sdim
8581234353Sdim      // Determine whether the set of unexpanded parameter packs can
8582234353Sdim      // and should be expanded.
8583234353Sdim      bool Expand = true;
8584234353Sdim      bool RetainExpansion = false;
8585249423Sdim      Optional<unsigned> OrigNumExpansions = OrigElement.NumExpansions;
8586249423Sdim      Optional<unsigned> NumExpansions = OrigNumExpansions;
8587234353Sdim      SourceRange PatternRange(OrigElement.Key->getLocStart(),
8588234353Sdim                               OrigElement.Value->getLocEnd());
8589234353Sdim     if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
8590234353Sdim                                               PatternRange,
8591234353Sdim                                               Unexpanded,
8592234353Sdim                                               Expand, RetainExpansion,
8593234353Sdim                                               NumExpansions))
8594234353Sdim        return ExprError();
8595234353Sdim
8596234353Sdim      if (!Expand) {
8597234353Sdim        // The transform has determined that we should perform a simple
8598239462Sdim        // transformation on the pack expansion, producing another pack
8599234353Sdim        // expansion.
8600234353Sdim        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), -1);
8601234353Sdim        ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
8602234353Sdim        if (Key.isInvalid())
8603234353Sdim          return ExprError();
8604234353Sdim
8605234353Sdim        if (Key.get() != OrigElement.Key)
8606234353Sdim          ArgChanged = true;
8607234353Sdim
8608234353Sdim        ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
8609234353Sdim        if (Value.isInvalid())
8610234353Sdim          return ExprError();
8611239462Sdim
8612234353Sdim        if (Value.get() != OrigElement.Value)
8613234353Sdim          ArgChanged = true;
8614234353Sdim
8615239462Sdim        ObjCDictionaryElement Expansion = {
8616234353Sdim          Key.get(), Value.get(), OrigElement.EllipsisLoc, NumExpansions
8617234353Sdim        };
8618234353Sdim        Elements.push_back(Expansion);
8619234353Sdim        continue;
8620234353Sdim      }
8621234353Sdim
8622234353Sdim      // Record right away that the argument was changed.  This needs
8623234353Sdim      // to happen even if the array expands to nothing.
8624234353Sdim      ArgChanged = true;
8625239462Sdim
8626234353Sdim      // The transform has determined that we should perform an elementwise
8627234353Sdim      // expansion of the pattern. Do so.
8628234353Sdim      for (unsigned I = 0; I != *NumExpansions; ++I) {
8629234353Sdim        Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
8630234353Sdim        ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
8631234353Sdim        if (Key.isInvalid())
8632234353Sdim          return ExprError();
8633234353Sdim
8634234353Sdim        ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
8635234353Sdim        if (Value.isInvalid())
8636234353Sdim          return ExprError();
8637234353Sdim
8638239462Sdim        ObjCDictionaryElement Element = {
8639234353Sdim          Key.get(), Value.get(), SourceLocation(), NumExpansions
8640234353Sdim        };
8641234353Sdim
8642234353Sdim        // If any unexpanded parameter packs remain, we still have a
8643234353Sdim        // pack expansion.
8644234353Sdim        if (Key.get()->containsUnexpandedParameterPack() ||
8645234353Sdim            Value.get()->containsUnexpandedParameterPack())
8646234353Sdim          Element.EllipsisLoc = OrigElement.EllipsisLoc;
8647239462Sdim
8648234353Sdim        Elements.push_back(Element);
8649234353Sdim      }
8650234353Sdim
8651234353Sdim      // We've finished with this pack expansion.
8652234353Sdim      continue;
8653234353Sdim    }
8654234353Sdim
8655234353Sdim    // Transform and check key.
8656234353Sdim    ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
8657234353Sdim    if (Key.isInvalid())
8658234353Sdim      return ExprError();
8659239462Sdim
8660234353Sdim    if (Key.get() != OrigElement.Key)
8661234353Sdim      ArgChanged = true;
8662239462Sdim
8663234353Sdim    // Transform and check value.
8664234353Sdim    ExprResult Value
8665234353Sdim      = getDerived().TransformExpr(OrigElement.Value);
8666234353Sdim    if (Value.isInvalid())
8667234353Sdim      return ExprError();
8668239462Sdim
8669234353Sdim    if (Value.get() != OrigElement.Value)
8670234353Sdim      ArgChanged = true;
8671239462Sdim
8672239462Sdim    ObjCDictionaryElement Element = {
8673249423Sdim      Key.get(), Value.get(), SourceLocation(), None
8674234353Sdim    };
8675234353Sdim    Elements.push_back(Element);
8676234353Sdim  }
8677239462Sdim
8678234353Sdim  if (!getDerived().AlwaysRebuild() && !ArgChanged)
8679234353Sdim    return SemaRef.MaybeBindToTemporary(E);
8680234353Sdim
8681234353Sdim  return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
8682234353Sdim                                                   Elements.data(),
8683234353Sdim                                                   Elements.size());
8684234353Sdim}
8685234353Sdim
8686234353Sdimtemplate<typename Derived>
8687234353SdimExprResult
8688200583SrdivackyTreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
8689207619Srdivacky  TypeSourceInfo *EncodedTypeInfo
8690207619Srdivacky    = getDerived().TransformType(E->getEncodedTypeSourceInfo());
8691207619Srdivacky  if (!EncodedTypeInfo)
8692212904Sdim    return ExprError();
8693198092Srdivacky
8694198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
8695207619Srdivacky      EncodedTypeInfo == E->getEncodedTypeSourceInfo())
8696218893Sdim    return SemaRef.Owned(E);
8697198092Srdivacky
8698198092Srdivacky  return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
8699207619Srdivacky                                            EncodedTypeInfo,
8700198092Srdivacky                                            E->getRParenLoc());
8701198092Srdivacky}
8702198092Srdivacky
8703198092Srdivackytemplate<typename Derived>
8704224145SdimExprResult TreeTransform<Derived>::
8705224145SdimTransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
8706251662Sdim  // This is a kind of implicit conversion, and it needs to get dropped
8707251662Sdim  // and recomputed for the same general reasons that ImplicitCastExprs
8708251662Sdim  // do, as well a more specific one: this expression is only valid when
8709251662Sdim  // it appears *immediately* as an argument expression.
8710251662Sdim  return getDerived().TransformExpr(E->getSubExpr());
8711224145Sdim}
8712224145Sdim
8713224145Sdimtemplate<typename Derived>
8714224145SdimExprResult TreeTransform<Derived>::
8715224145SdimTransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
8716239462Sdim  TypeSourceInfo *TSInfo
8717224145Sdim    = getDerived().TransformType(E->getTypeInfoAsWritten());
8718224145Sdim  if (!TSInfo)
8719224145Sdim    return ExprError();
8720239462Sdim
8721224145Sdim  ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
8722239462Sdim  if (Result.isInvalid())
8723224145Sdim    return ExprError();
8724239462Sdim
8725224145Sdim  if (!getDerived().AlwaysRebuild() &&
8726224145Sdim      TSInfo == E->getTypeInfoAsWritten() &&
8727224145Sdim      Result.get() == E->getSubExpr())
8728224145Sdim    return SemaRef.Owned(E);
8729239462Sdim
8730224145Sdim  return SemaRef.BuildObjCBridgedCast(E->getLParenLoc(), E->getBridgeKind(),
8731239462Sdim                                      E->getBridgeKeywordLoc(), TSInfo,
8732224145Sdim                                      Result.get());
8733224145Sdim}
8734224145Sdim
8735224145Sdimtemplate<typename Derived>
8736212904SdimExprResult
8737200583SrdivackyTreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
8738207619Srdivacky  // Transform arguments.
8739207619Srdivacky  bool ArgChanged = false;
8740243830Sdim  SmallVector<Expr*, 8> Args;
8741218893Sdim  Args.reserve(E->getNumArgs());
8742239462Sdim  if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
8743218893Sdim                                  &ArgChanged))
8744218893Sdim    return ExprError();
8745239462Sdim
8746207619Srdivacky  if (E->getReceiverKind() == ObjCMessageExpr::Class) {
8747207619Srdivacky    // Class message: transform the receiver type.
8748207619Srdivacky    TypeSourceInfo *ReceiverTypeInfo
8749207619Srdivacky      = getDerived().TransformType(E->getClassReceiverTypeInfo());
8750207619Srdivacky    if (!ReceiverTypeInfo)
8751212904Sdim      return ExprError();
8752239462Sdim
8753207619Srdivacky    // If nothing changed, just retain the existing message send.
8754207619Srdivacky    if (!getDerived().AlwaysRebuild() &&
8755207619Srdivacky        ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
8756234353Sdim      return SemaRef.MaybeBindToTemporary(E);
8757207619Srdivacky
8758207619Srdivacky    // Build a new class message send.
8759226633Sdim    SmallVector<SourceLocation, 16> SelLocs;
8760226633Sdim    E->getSelectorLocs(SelLocs);
8761207619Srdivacky    return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
8762207619Srdivacky                                               E->getSelector(),
8763226633Sdim                                               SelLocs,
8764207619Srdivacky                                               E->getMethodDecl(),
8765207619Srdivacky                                               E->getLeftLoc(),
8766243830Sdim                                               Args,
8767207619Srdivacky                                               E->getRightLoc());
8768207619Srdivacky  }
8769207619Srdivacky
8770207619Srdivacky  // Instance message: transform the receiver
8771207619Srdivacky  assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
8772207619Srdivacky         "Only class and instance messages may be instantiated");
8773212904Sdim  ExprResult Receiver
8774207619Srdivacky    = getDerived().TransformExpr(E->getInstanceReceiver());
8775207619Srdivacky  if (Receiver.isInvalid())
8776212904Sdim    return ExprError();
8777207619Srdivacky
8778207619Srdivacky  // If nothing changed, just retain the existing message send.
8779207619Srdivacky  if (!getDerived().AlwaysRebuild() &&
8780207619Srdivacky      Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
8781234353Sdim    return SemaRef.MaybeBindToTemporary(E);
8782239462Sdim
8783207619Srdivacky  // Build a new instance message send.
8784226633Sdim  SmallVector<SourceLocation, 16> SelLocs;
8785226633Sdim  E->getSelectorLocs(SelLocs);
8786212904Sdim  return getDerived().RebuildObjCMessageExpr(Receiver.get(),
8787207619Srdivacky                                             E->getSelector(),
8788226633Sdim                                             SelLocs,
8789207619Srdivacky                                             E->getMethodDecl(),
8790207619Srdivacky                                             E->getLeftLoc(),
8791243830Sdim                                             Args,
8792207619Srdivacky                                             E->getRightLoc());
8793198092Srdivacky}
8794198092Srdivacky
8795198092Srdivackytemplate<typename Derived>
8796212904SdimExprResult
8797200583SrdivackyTreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
8798218893Sdim  return SemaRef.Owned(E);
8799198092Srdivacky}
8800198092Srdivacky
8801198092Srdivackytemplate<typename Derived>
8802212904SdimExprResult
8803200583SrdivackyTreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
8804218893Sdim  return SemaRef.Owned(E);
8805198092Srdivacky}
8806198092Srdivacky
8807198092Srdivackytemplate<typename Derived>
8808212904SdimExprResult
8809200583SrdivackyTreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
8810207619Srdivacky  // Transform the base expression.
8811212904Sdim  ExprResult Base = getDerived().TransformExpr(E->getBase());
8812207619Srdivacky  if (Base.isInvalid())
8813212904Sdim    return ExprError();
8814207619Srdivacky
8815207619Srdivacky  // We don't need to transform the ivar; it will never change.
8816239462Sdim
8817207619Srdivacky  // If nothing changed, just retain the existing expression.
8818207619Srdivacky  if (!getDerived().AlwaysRebuild() &&
8819207619Srdivacky      Base.get() == E->getBase())
8820218893Sdim    return SemaRef.Owned(E);
8821239462Sdim
8822212904Sdim  return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
8823207619Srdivacky                                             E->getLocation(),
8824207619Srdivacky                                             E->isArrow(), E->isFreeIvar());
8825198092Srdivacky}
8826198092Srdivacky
8827198092Srdivackytemplate<typename Derived>
8828212904SdimExprResult
8829200583SrdivackyTreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
8830218893Sdim  // 'super' and types never change. Property never changes. Just
8831218893Sdim  // retain the existing expression.
8832218893Sdim  if (!E->isObjectReceiver())
8833218893Sdim    return SemaRef.Owned(E);
8834239462Sdim
8835207619Srdivacky  // Transform the base expression.
8836212904Sdim  ExprResult Base = getDerived().TransformExpr(E->getBase());
8837207619Srdivacky  if (Base.isInvalid())
8838212904Sdim    return ExprError();
8839239462Sdim
8840207619Srdivacky  // We don't need to transform the property; it will never change.
8841239462Sdim
8842207619Srdivacky  // If nothing changed, just retain the existing expression.
8843207619Srdivacky  if (!getDerived().AlwaysRebuild() &&
8844207619Srdivacky      Base.get() == E->getBase())
8845218893Sdim    return SemaRef.Owned(E);
8846198092Srdivacky
8847218893Sdim  if (E->isExplicitProperty())
8848218893Sdim    return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
8849218893Sdim                                                   E->getExplicitProperty(),
8850218893Sdim                                                   E->getLocation());
8851198092Srdivacky
8852218893Sdim  return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
8853234353Sdim                                                 SemaRef.Context.PseudoObjectTy,
8854218893Sdim                                                 E->getImplicitPropertyGetter(),
8855218893Sdim                                                 E->getImplicitPropertySetter(),
8856218893Sdim                                                 E->getLocation());
8857198092Srdivacky}
8858198092Srdivacky
8859198092Srdivackytemplate<typename Derived>
8860212904SdimExprResult
8861234353SdimTreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
8862234353Sdim  // Transform the base expression.
8863234353Sdim  ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
8864234353Sdim  if (Base.isInvalid())
8865234353Sdim    return ExprError();
8866234353Sdim
8867234353Sdim  // Transform the key expression.
8868234353Sdim  ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
8869234353Sdim  if (Key.isInvalid())
8870234353Sdim    return ExprError();
8871234353Sdim
8872234353Sdim  // If nothing changed, just retain the existing expression.
8873234353Sdim  if (!getDerived().AlwaysRebuild() &&
8874234353Sdim      Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
8875234353Sdim    return SemaRef.Owned(E);
8876234353Sdim
8877239462Sdim  return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
8878234353Sdim                                                  Base.get(), Key.get(),
8879234353Sdim                                                  E->getAtIndexMethodDecl(),
8880234353Sdim                                                  E->setAtIndexMethodDecl());
8881234353Sdim}
8882234353Sdim
8883234353Sdimtemplate<typename Derived>
8884234353SdimExprResult
8885200583SrdivackyTreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
8886207619Srdivacky  // Transform the base expression.
8887212904Sdim  ExprResult Base = getDerived().TransformExpr(E->getBase());
8888207619Srdivacky  if (Base.isInvalid())
8889212904Sdim    return ExprError();
8890239462Sdim
8891207619Srdivacky  // If nothing changed, just retain the existing expression.
8892207619Srdivacky  if (!getDerived().AlwaysRebuild() &&
8893207619Srdivacky      Base.get() == E->getBase())
8894218893Sdim    return SemaRef.Owned(E);
8895239462Sdim
8896212904Sdim  return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
8897249423Sdim                                         E->getOpLoc(),
8898207619Srdivacky                                         E->isArrow());
8899198092Srdivacky}
8900198092Srdivacky
8901198092Srdivackytemplate<typename Derived>
8902212904SdimExprResult
8903200583SrdivackyTreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
8904198092Srdivacky  bool ArgumentChanged = false;
8905243830Sdim  SmallVector<Expr*, 8> SubExprs;
8906218893Sdim  SubExprs.reserve(E->getNumSubExprs());
8907239462Sdim  if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
8908218893Sdim                                  SubExprs, &ArgumentChanged))
8909218893Sdim    return ExprError();
8910198092Srdivacky
8911198092Srdivacky  if (!getDerived().AlwaysRebuild() &&
8912198092Srdivacky      !ArgumentChanged)
8913218893Sdim    return SemaRef.Owned(E);
8914198092Srdivacky
8915198092Srdivacky  return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
8916243830Sdim                                               SubExprs,
8917198092Srdivacky                                               E->getRParenLoc());
8918198092Srdivacky}
8919198092Srdivacky
8920198092Srdivackytemplate<typename Derived>
8921212904SdimExprResult
8922200583SrdivackyTreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
8923218893Sdim  BlockDecl *oldBlock = E->getBlockDecl();
8924239462Sdim
8925218893Sdim  SemaRef.ActOnBlockStart(E->getCaretLocation(), /*Scope=*/0);
8926218893Sdim  BlockScopeInfo *blockScope = SemaRef.getCurBlock();
8927218893Sdim
8928218893Sdim  blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
8929234353Sdim  blockScope->TheDecl->setBlockMissingReturnType(
8930234353Sdim                         oldBlock->blockMissingReturnType());
8931239462Sdim
8932226633Sdim  SmallVector<ParmVarDecl*, 4> params;
8933226633Sdim  SmallVector<QualType, 4> paramTypes;
8934239462Sdim
8935210299Sed  // Parameter substitution.
8936218893Sdim  if (getDerived().TransformFunctionTypeParams(E->getCaretLocation(),
8937218893Sdim                                               oldBlock->param_begin(),
8938218893Sdim                                               oldBlock->param_size(),
8939234353Sdim                                               0, paramTypes, &params)) {
8940234353Sdim    getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/0);
8941234353Sdim    return ExprError();
8942234353Sdim  }
8943218893Sdim
8944249423Sdim  const FunctionProtoType *exprFunctionType = E->getFunctionType();
8945234353Sdim  QualType exprResultType =
8946234353Sdim      getDerived().TransformType(exprFunctionType->getResultType());
8947218893Sdim
8948218893Sdim  // Don't allow returning a objc interface by value.
8949234353Sdim  if (exprResultType->isObjCObjectType()) {
8950239462Sdim    getSema().Diag(E->getCaretLocation(),
8951239462Sdim                   diag::err_object_cannot_be_passed_returned_by_value)
8952234353Sdim      << 0 << exprResultType;
8953234353Sdim    getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/0);
8954218893Sdim    return ExprError();
8955210299Sed  }
8956218893Sdim
8957249423Sdim  QualType functionType =
8958249423Sdim    getDerived().RebuildFunctionProtoType(exprResultType, paramTypes,
8959249423Sdim                                          exprFunctionType->getExtProtoInfo());
8960218893Sdim  blockScope->FunctionType = functionType;
8961218893Sdim
8962218893Sdim  // Set the parameters on the block decl.
8963218893Sdim  if (!params.empty())
8964226633Sdim    blockScope->TheDecl->setParams(params);
8965234353Sdim
8966234353Sdim  if (!oldBlock->blockMissingReturnType()) {
8967234353Sdim    blockScope->HasImplicitReturnType = false;
8968234353Sdim    blockScope->ReturnType = exprResultType;
8969234353Sdim  }
8970239462Sdim
8971210299Sed  // Transform the body
8972218893Sdim  StmtResult body = getDerived().TransformStmt(E->getBody());
8973234353Sdim  if (body.isInvalid()) {
8974234353Sdim    getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/0);
8975212904Sdim    return ExprError();
8976234353Sdim  }
8977218893Sdim
8978218893Sdim#ifndef NDEBUG
8979218893Sdim  // In builds with assertions, make sure that we captured everything we
8980218893Sdim  // captured before.
8981223017Sdim  if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
8982223017Sdim    for (BlockDecl::capture_iterator i = oldBlock->capture_begin(),
8983223017Sdim           e = oldBlock->capture_end(); i != e; ++i) {
8984223017Sdim      VarDecl *oldCapture = i->getVariable();
8985218893Sdim
8986223017Sdim      // Ignore parameter packs.
8987223017Sdim      if (isa<ParmVarDecl>(oldCapture) &&
8988223017Sdim          cast<ParmVarDecl>(oldCapture)->isParameterPack())
8989223017Sdim        continue;
8990218893Sdim
8991223017Sdim      VarDecl *newCapture =
8992223017Sdim        cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
8993223017Sdim                                                 oldCapture));
8994223017Sdim      assert(blockScope->CaptureMap.count(newCapture));
8995223017Sdim    }
8996234353Sdim    assert(oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured());
8997218893Sdim  }
8998218893Sdim#endif
8999218893Sdim
9000218893Sdim  return SemaRef.ActOnBlockStmtExpr(E->getCaretLocation(), body.get(),
9001218893Sdim                                    /*Scope=*/0);
9002198092Srdivacky}
9003198092Srdivacky
9004198092Srdivackytemplate<typename Derived>
9005212904SdimExprResult
9006223017SdimTreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
9007226633Sdim  llvm_unreachable("Cannot transform asType expressions yet");
9008223017Sdim}
9009226633Sdim
9010226633Sdimtemplate<typename Derived>
9011226633SdimExprResult
9012226633SdimTreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
9013226633Sdim  QualType RetTy = getDerived().TransformType(E->getType());
9014226633Sdim  bool ArgumentChanged = false;
9015243830Sdim  SmallVector<Expr*, 8> SubExprs;
9016226633Sdim  SubExprs.reserve(E->getNumSubExprs());
9017226633Sdim  if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
9018226633Sdim                                  SubExprs, &ArgumentChanged))
9019226633Sdim    return ExprError();
9020226633Sdim
9021226633Sdim  if (!getDerived().AlwaysRebuild() &&
9022226633Sdim      !ArgumentChanged)
9023226633Sdim    return SemaRef.Owned(E);
9024226633Sdim
9025243830Sdim  return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
9026226633Sdim                                        RetTy, E->getOp(), E->getRParenLoc());
9027226633Sdim}
9028239462Sdim
9029198092Srdivacky//===----------------------------------------------------------------------===//
9030198092Srdivacky// Type reconstruction
9031198092Srdivacky//===----------------------------------------------------------------------===//
9032198092Srdivacky
9033198092Srdivackytemplate<typename Derived>
9034198893SrdivackyQualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
9035198893Srdivacky                                                    SourceLocation Star) {
9036210299Sed  return SemaRef.BuildPointerType(PointeeType, Star,
9037198092Srdivacky                                  getDerived().getBaseEntity());
9038198092Srdivacky}
9039198092Srdivacky
9040198092Srdivackytemplate<typename Derived>
9041198893SrdivackyQualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
9042198893Srdivacky                                                         SourceLocation Star) {
9043210299Sed  return SemaRef.BuildBlockPointerType(PointeeType, Star,
9044198092Srdivacky                                       getDerived().getBaseEntity());
9045198092Srdivacky}
9046198092Srdivacky
9047198092Srdivackytemplate<typename Derived>
9048198092SrdivackyQualType
9049198893SrdivackyTreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
9050198893Srdivacky                                             bool WrittenAsLValue,
9051198893Srdivacky                                             SourceLocation Sigil) {
9052210299Sed  return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue,
9053198893Srdivacky                                    Sigil, getDerived().getBaseEntity());
9054198092Srdivacky}
9055198092Srdivacky
9056198092Srdivackytemplate<typename Derived>
9057198092SrdivackyQualType
9058198893SrdivackyTreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
9059198893Srdivacky                                                 QualType ClassType,
9060198893Srdivacky                                                 SourceLocation Sigil) {
9061210299Sed  return SemaRef.BuildMemberPointerType(PointeeType, ClassType,
9062198893Srdivacky                                        Sigil, getDerived().getBaseEntity());
9063198092Srdivacky}
9064198092Srdivacky
9065198092Srdivackytemplate<typename Derived>
9066198092SrdivackyQualType
9067198092SrdivackyTreeTransform<Derived>::RebuildArrayType(QualType ElementType,
9068198092Srdivacky                                         ArrayType::ArraySizeModifier SizeMod,
9069198092Srdivacky                                         const llvm::APInt *Size,
9070198092Srdivacky                                         Expr *SizeExpr,
9071198092Srdivacky                                         unsigned IndexTypeQuals,
9072198092Srdivacky                                         SourceRange BracketsRange) {
9073198092Srdivacky  if (SizeExpr || !Size)
9074198092Srdivacky    return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
9075198092Srdivacky                                  IndexTypeQuals, BracketsRange,
9076198092Srdivacky                                  getDerived().getBaseEntity());
9077198092Srdivacky
9078198092Srdivacky  QualType Types[] = {
9079198092Srdivacky    SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
9080198092Srdivacky    SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
9081198092Srdivacky    SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
9082198092Srdivacky  };
9083198092Srdivacky  const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
9084198092Srdivacky  QualType SizeType;
9085198092Srdivacky  for (unsigned I = 0; I != NumTypes; ++I)
9086198092Srdivacky    if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
9087198092Srdivacky      SizeType = Types[I];
9088198092Srdivacky      break;
9089198092Srdivacky    }
9090198092Srdivacky
9091234353Sdim  // Note that we can return a VariableArrayType here in the case where
9092234353Sdim  // the element type was a dependent VariableArrayType.
9093234353Sdim  IntegerLiteral *ArraySize
9094234353Sdim      = IntegerLiteral::Create(SemaRef.Context, *Size, SizeType,
9095234353Sdim                               /*FIXME*/BracketsRange.getBegin());
9096234353Sdim  return SemaRef.BuildArrayType(ElementType, SizeMod, ArraySize,
9097198092Srdivacky                                IndexTypeQuals, BracketsRange,
9098198092Srdivacky                                getDerived().getBaseEntity());
9099198092Srdivacky}
9100198092Srdivacky
9101198092Srdivackytemplate<typename Derived>
9102198092SrdivackyQualType
9103198092SrdivackyTreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
9104198092Srdivacky                                                 ArrayType::ArraySizeModifier SizeMod,
9105198092Srdivacky                                                 const llvm::APInt &Size,
9106198893Srdivacky                                                 unsigned IndexTypeQuals,
9107198893Srdivacky                                                 SourceRange BracketsRange) {
9108198092Srdivacky  return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
9109198893Srdivacky                                        IndexTypeQuals, BracketsRange);
9110198092Srdivacky}
9111198092Srdivacky
9112198092Srdivackytemplate<typename Derived>
9113198092SrdivackyQualType
9114198092SrdivackyTreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
9115198092Srdivacky                                          ArrayType::ArraySizeModifier SizeMod,
9116198893Srdivacky                                                 unsigned IndexTypeQuals,
9117198893Srdivacky                                                   SourceRange BracketsRange) {
9118198092Srdivacky  return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
9119198893Srdivacky                                       IndexTypeQuals, BracketsRange);
9120198092Srdivacky}
9121198092Srdivacky
9122198092Srdivackytemplate<typename Derived>
9123198092SrdivackyQualType
9124198092SrdivackyTreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
9125198092Srdivacky                                          ArrayType::ArraySizeModifier SizeMod,
9126212904Sdim                                                 Expr *SizeExpr,
9127198092Srdivacky                                                 unsigned IndexTypeQuals,
9128198092Srdivacky                                                 SourceRange BracketsRange) {
9129198092Srdivacky  return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
9130212904Sdim                                       SizeExpr,
9131198092Srdivacky                                       IndexTypeQuals, BracketsRange);
9132198092Srdivacky}
9133198092Srdivacky
9134198092Srdivackytemplate<typename Derived>
9135198092SrdivackyQualType
9136198092SrdivackyTreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
9137198092Srdivacky                                          ArrayType::ArraySizeModifier SizeMod,
9138212904Sdim                                                       Expr *SizeExpr,
9139198092Srdivacky                                                       unsigned IndexTypeQuals,
9140198092Srdivacky                                                   SourceRange BracketsRange) {
9141198092Srdivacky  return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
9142212904Sdim                                       SizeExpr,
9143198092Srdivacky                                       IndexTypeQuals, BracketsRange);
9144198092Srdivacky}
9145198092Srdivacky
9146198092Srdivackytemplate<typename Derived>
9147198092SrdivackyQualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
9148218893Sdim                                               unsigned NumElements,
9149218893Sdim                                               VectorType::VectorKind VecKind) {
9150198092Srdivacky  // FIXME: semantic checking!
9151218893Sdim  return SemaRef.Context.getVectorType(ElementType, NumElements, VecKind);
9152198092Srdivacky}
9153198092Srdivacky
9154198092Srdivackytemplate<typename Derived>
9155198092SrdivackyQualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
9156198092Srdivacky                                                      unsigned NumElements,
9157198092Srdivacky                                                 SourceLocation AttributeLoc) {
9158198092Srdivacky  llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
9159198092Srdivacky                          NumElements, true);
9160198092Srdivacky  IntegerLiteral *VectorSize
9161212904Sdim    = IntegerLiteral::Create(SemaRef.Context, numElements, SemaRef.Context.IntTy,
9162212904Sdim                             AttributeLoc);
9163212904Sdim  return SemaRef.BuildExtVectorType(ElementType, VectorSize, AttributeLoc);
9164198092Srdivacky}
9165198092Srdivacky
9166198092Srdivackytemplate<typename Derived>
9167198092SrdivackyQualType
9168198092SrdivackyTreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
9169212904Sdim                                                           Expr *SizeExpr,
9170198092Srdivacky                                                  SourceLocation AttributeLoc) {
9171212904Sdim  return SemaRef.BuildExtVectorType(ElementType, SizeExpr, AttributeLoc);
9172198092Srdivacky}
9173198092Srdivacky
9174198092Srdivackytemplate<typename Derived>
9175249423SdimQualType TreeTransform<Derived>::RebuildFunctionProtoType(
9176249423Sdim    QualType T,
9177249423Sdim    llvm::MutableArrayRef<QualType> ParamTypes,
9178249423Sdim    const FunctionProtoType::ExtProtoInfo &EPI) {
9179249423Sdim  return SemaRef.BuildFunctionType(T, ParamTypes,
9180198092Srdivacky                                   getDerived().getBaseLocation(),
9181212904Sdim                                   getDerived().getBaseEntity(),
9182249423Sdim                                   EPI);
9183198092Srdivacky}
9184198092Srdivacky
9185198092Srdivackytemplate<typename Derived>
9186198398SrdivackyQualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
9187198398Srdivacky  return SemaRef.Context.getFunctionNoProtoType(T);
9188198398Srdivacky}
9189198398Srdivacky
9190198398Srdivackytemplate<typename Derived>
9191200583SrdivackyQualType TreeTransform<Derived>::RebuildUnresolvedUsingType(Decl *D) {
9192200583Srdivacky  assert(D && "no decl found");
9193200583Srdivacky  if (D->isInvalidDecl()) return QualType();
9194200583Srdivacky
9195207619Srdivacky  // FIXME: Doesn't account for ObjCInterfaceDecl!
9196200583Srdivacky  TypeDecl *Ty;
9197200583Srdivacky  if (isa<UsingDecl>(D)) {
9198200583Srdivacky    UsingDecl *Using = cast<UsingDecl>(D);
9199200583Srdivacky    assert(Using->isTypeName() &&
9200200583Srdivacky           "UnresolvedUsingTypenameDecl transformed to non-typename using");
9201200583Srdivacky
9202200583Srdivacky    // A valid resolved using typename decl points to exactly one type decl.
9203200583Srdivacky    assert(++Using->shadow_begin() == Using->shadow_end());
9204200583Srdivacky    Ty = cast<TypeDecl>((*Using->shadow_begin())->getTargetDecl());
9205239462Sdim
9206200583Srdivacky  } else {
9207200583Srdivacky    assert(isa<UnresolvedUsingTypenameDecl>(D) &&
9208200583Srdivacky           "UnresolvedUsingTypenameDecl transformed to non-using decl");
9209200583Srdivacky    Ty = cast<UnresolvedUsingTypenameDecl>(D);
9210200583Srdivacky  }
9211200583Srdivacky
9212200583Srdivacky  return SemaRef.Context.getTypeDeclType(Ty);
9213200583Srdivacky}
9214200583Srdivacky
9215200583Srdivackytemplate<typename Derived>
9216218893SdimQualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E,
9217218893Sdim                                                       SourceLocation Loc) {
9218218893Sdim  return SemaRef.BuildTypeofExprType(E, Loc);
9219198092Srdivacky}
9220198092Srdivacky
9221198092Srdivackytemplate<typename Derived>
9222198092SrdivackyQualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
9223198092Srdivacky  return SemaRef.Context.getTypeOfType(Underlying);
9224198092Srdivacky}
9225198092Srdivacky
9226198092Srdivackytemplate<typename Derived>
9227218893SdimQualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E,
9228218893Sdim                                                     SourceLocation Loc) {
9229218893Sdim  return SemaRef.BuildDecltypeType(E, Loc);
9230198092Srdivacky}
9231198092Srdivacky
9232198092Srdivackytemplate<typename Derived>
9233223017SdimQualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
9234223017Sdim                                            UnaryTransformType::UTTKind UKind,
9235223017Sdim                                            SourceLocation Loc) {
9236223017Sdim  return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
9237223017Sdim}
9238223017Sdim
9239223017Sdimtemplate<typename Derived>
9240198092SrdivackyQualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
9241198893Srdivacky                                                      TemplateName Template,
9242198893Srdivacky                                             SourceLocation TemplateNameLoc,
9243221345Sdim                                     TemplateArgumentListInfo &TemplateArgs) {
9244199990Srdivacky  return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
9245198092Srdivacky}
9246198092Srdivacky
9247198092Srdivackytemplate<typename Derived>
9248226633SdimQualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
9249226633Sdim                                                   SourceLocation KWLoc) {
9250226633Sdim  return SemaRef.BuildAtomicType(ValueType, KWLoc);
9251226633Sdim}
9252226633Sdim
9253226633Sdimtemplate<typename Derived>
9254198092SrdivackyTemplateName
9255221345SdimTreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
9256198092Srdivacky                                            bool TemplateKW,
9257198092Srdivacky                                            TemplateDecl *Template) {
9258221345Sdim  return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW,
9259198092Srdivacky                                                  Template);
9260198092Srdivacky}
9261198092Srdivacky
9262198092Srdivackytemplate<typename Derived>
9263198092SrdivackyTemplateName
9264221345SdimTreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
9265221345Sdim                                            const IdentifierInfo &Name,
9266221345Sdim                                            SourceLocation NameLoc,
9267218893Sdim                                            QualType ObjectType,
9268218893Sdim                                            NamedDecl *FirstQualifierInScope) {
9269221345Sdim  UnqualifiedId TemplateName;
9270221345Sdim  TemplateName.setIdentifier(&Name, NameLoc);
9271210299Sed  Sema::TemplateTy Template;
9272234353Sdim  SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
9273210299Sed  getSema().ActOnDependentTemplateName(/*Scope=*/0,
9274234353Sdim                                       SS, TemplateKWLoc, TemplateName,
9275212904Sdim                                       ParsedType::make(ObjectType),
9276210299Sed                                       /*EnteringContext=*/false,
9277210299Sed                                       Template);
9278218893Sdim  return Template.get();
9279198092Srdivacky}
9280198092Srdivacky
9281198092Srdivackytemplate<typename Derived>
9282198893SrdivackyTemplateName
9283221345SdimTreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
9284198893Srdivacky                                            OverloadedOperatorKind Operator,
9285221345Sdim                                            SourceLocation NameLoc,
9286198893Srdivacky                                            QualType ObjectType) {
9287198893Srdivacky  UnqualifiedId Name;
9288221345Sdim  // FIXME: Bogus location information.
9289234353Sdim  SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
9290221345Sdim  Name.setOperatorFunctionId(NameLoc, Operator, SymbolLocations);
9291234353Sdim  SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
9292210299Sed  Sema::TemplateTy Template;
9293210299Sed  getSema().ActOnDependentTemplateName(/*Scope=*/0,
9294234353Sdim                                       SS, TemplateKWLoc, Name,
9295212904Sdim                                       ParsedType::make(ObjectType),
9296210299Sed                                       /*EnteringContext=*/false,
9297210299Sed                                       Template);
9298210299Sed  return Template.template getAsVal<TemplateName>();
9299198893Srdivacky}
9300239462Sdim
9301198893Srdivackytemplate<typename Derived>
9302212904SdimExprResult
9303198092SrdivackyTreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
9304198092Srdivacky                                                   SourceLocation OpLoc,
9305212904Sdim                                                   Expr *OrigCallee,
9306212904Sdim                                                   Expr *First,
9307212904Sdim                                                   Expr *Second) {
9308212904Sdim  Expr *Callee = OrigCallee->IgnoreParenCasts();
9309212904Sdim  bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
9310198092Srdivacky
9311198092Srdivacky  // Determine whether this should be a builtin operation.
9312198893Srdivacky  if (Op == OO_Subscript) {
9313212904Sdim    if (!First->getType()->isOverloadableType() &&
9314212904Sdim        !Second->getType()->isOverloadableType())
9315212904Sdim      return getSema().CreateBuiltinArraySubscriptExpr(First,
9316212904Sdim                                                       Callee->getLocStart(),
9317212904Sdim                                                       Second, OpLoc);
9318199482Srdivacky  } else if (Op == OO_Arrow) {
9319199482Srdivacky    // -> is never a builtin operation.
9320212904Sdim    return SemaRef.BuildOverloadedArrowExpr(0, First, OpLoc);
9321212904Sdim  } else if (Second == 0 || isPostIncDec) {
9322212904Sdim    if (!First->getType()->isOverloadableType()) {
9323198092Srdivacky      // The argument is not of overloadable type, so try to create a
9324198092Srdivacky      // built-in unary operation.
9325212904Sdim      UnaryOperatorKind Opc
9326198092Srdivacky        = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
9327198092Srdivacky
9328212904Sdim      return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
9329198092Srdivacky    }
9330198092Srdivacky  } else {
9331212904Sdim    if (!First->getType()->isOverloadableType() &&
9332212904Sdim        !Second->getType()->isOverloadableType()) {
9333198092Srdivacky      // Neither of the arguments is an overloadable type, so try to
9334198092Srdivacky      // create a built-in binary operation.
9335212904Sdim      BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
9336212904Sdim      ExprResult Result
9337212904Sdim        = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, First, Second);
9338198092Srdivacky      if (Result.isInvalid())
9339212904Sdim        return ExprError();
9340198092Srdivacky
9341243830Sdim      return Result;
9342198092Srdivacky    }
9343198092Srdivacky  }
9344198092Srdivacky
9345198092Srdivacky  // Compute the transformed set of functions (and function templates) to be
9346198092Srdivacky  // used during overload resolution.
9347203955Srdivacky  UnresolvedSet<16> Functions;
9348198092Srdivacky
9349212904Sdim  if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
9350199990Srdivacky    assert(ULE->requiresADL());
9351198092Srdivacky
9352199990Srdivacky    // FIXME: Do we have to check
9353199990Srdivacky    // IsAcceptableNonMemberOperatorCandidate for each of these?
9354203955Srdivacky    Functions.append(ULE->decls_begin(), ULE->decls_end());
9355199990Srdivacky  } else {
9356243830Sdim    // If we've resolved this to a particular non-member function, just call
9357243830Sdim    // that function. If we resolved it to a member function,
9358243830Sdim    // CreateOverloaded* will find that function for us.
9359243830Sdim    NamedDecl *ND = cast<DeclRefExpr>(Callee)->getDecl();
9360243830Sdim    if (!isa<CXXMethodDecl>(ND))
9361243830Sdim      Functions.addDecl(ND);
9362199990Srdivacky  }
9363199990Srdivacky
9364198092Srdivacky  // Add any functions found via argument-dependent lookup.
9365212904Sdim  Expr *Args[2] = { First, Second };
9366212904Sdim  unsigned NumArgs = 1 + (Second != 0);
9367198092Srdivacky
9368198092Srdivacky  // Create the overloaded operator invocation for unary operators.
9369198092Srdivacky  if (NumArgs == 1 || isPostIncDec) {
9370212904Sdim    UnaryOperatorKind Opc
9371198092Srdivacky      = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
9372212904Sdim    return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, First);
9373198092Srdivacky  }
9374198092Srdivacky
9375224145Sdim  if (Op == OO_Subscript) {
9376224145Sdim    SourceLocation LBrace;
9377224145Sdim    SourceLocation RBrace;
9378198893Srdivacky
9379224145Sdim    if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee)) {
9380224145Sdim        DeclarationNameLoc &NameLoc = DRE->getNameInfo().getInfo();
9381224145Sdim        LBrace = SourceLocation::getFromRawEncoding(
9382224145Sdim                    NameLoc.CXXOperatorName.BeginOpNameLoc);
9383224145Sdim        RBrace = SourceLocation::getFromRawEncoding(
9384224145Sdim                    NameLoc.CXXOperatorName.EndOpNameLoc);
9385224145Sdim    } else {
9386224145Sdim        LBrace = Callee->getLocStart();
9387224145Sdim        RBrace = OpLoc;
9388224145Sdim    }
9389224145Sdim
9390224145Sdim    return SemaRef.CreateOverloadedArraySubscriptExpr(LBrace, RBrace,
9391224145Sdim                                                      First, Second);
9392224145Sdim  }
9393224145Sdim
9394198092Srdivacky  // Create the overloaded operator invocation for binary operators.
9395212904Sdim  BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(Op);
9396212904Sdim  ExprResult Result
9397198092Srdivacky    = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
9398198092Srdivacky  if (Result.isInvalid())
9399212904Sdim    return ExprError();
9400198092Srdivacky
9401243830Sdim  return Result;
9402198092Srdivacky}
9403198092Srdivacky
9404204643Srdivackytemplate<typename Derived>
9405239462SdimExprResult
9406212904SdimTreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
9407204643Srdivacky                                                     SourceLocation OperatorLoc,
9408204643Srdivacky                                                       bool isArrow,
9409219077Sdim                                                       CXXScopeSpec &SS,
9410204643Srdivacky                                                     TypeSourceInfo *ScopeType,
9411204643Srdivacky                                                       SourceLocation CCLoc,
9412204643Srdivacky                                                       SourceLocation TildeLoc,
9413204643Srdivacky                                        PseudoDestructorTypeStorage Destroyed) {
9414212904Sdim  QualType BaseType = Base->getType();
9415212904Sdim  if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
9416204643Srdivacky      (!isArrow && !BaseType->getAs<RecordType>()) ||
9417239462Sdim      (isArrow && BaseType->getAs<PointerType>() &&
9418204643Srdivacky       !BaseType->getAs<PointerType>()->getPointeeType()
9419204643Srdivacky                                              ->template getAs<RecordType>())){
9420204643Srdivacky    // This pseudo-destructor expression is still a pseudo-destructor.
9421212904Sdim    return SemaRef.BuildPseudoDestructorExpr(Base, OperatorLoc,
9422204643Srdivacky                                             isArrow? tok::arrow : tok::period,
9423204643Srdivacky                                             SS, ScopeType, CCLoc, TildeLoc,
9424204643Srdivacky                                             Destroyed,
9425204643Srdivacky                                             /*FIXME?*/true);
9426204643Srdivacky  }
9427212904Sdim
9428204643Srdivacky  TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
9429212904Sdim  DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
9430212904Sdim                 SemaRef.Context.getCanonicalType(DestroyedType->getType())));
9431212904Sdim  DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
9432212904Sdim  NameInfo.setNamedTypeInfo(DestroyedType);
9433212904Sdim
9434239462Sdim  // The scope type is now known to be a valid nested name specifier
9435239462Sdim  // component. Tack it on to the end of the nested name specifier.
9436239462Sdim  if (ScopeType)
9437239462Sdim    SS.Extend(SemaRef.Context, SourceLocation(),
9438239462Sdim              ScopeType->getTypeLoc(), CCLoc);
9439212904Sdim
9440234353Sdim  SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
9441212904Sdim  return getSema().BuildMemberReferenceExpr(Base, BaseType,
9442204643Srdivacky                                            OperatorLoc, isArrow,
9443234353Sdim                                            SS, TemplateKWLoc,
9444234353Sdim                                            /*FIXME: FirstQualifier*/ 0,
9445212904Sdim                                            NameInfo,
9446204643Srdivacky                                            /*TemplateArgs*/ 0);
9447204643Srdivacky}
9448204643Srdivacky
9449251662Sdimtemplate<typename Derived>
9450251662SdimStmtResult
9451251662SdimTreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
9452251662Sdim  SourceLocation Loc = S->getLocStart();
9453251662Sdim  unsigned NumParams = S->getCapturedDecl()->getNumParams();
9454251662Sdim  getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/0,
9455251662Sdim                                     S->getCapturedRegionKind(), NumParams);
9456251662Sdim  StmtResult Body = getDerived().TransformStmt(S->getCapturedStmt());
9457251662Sdim
9458251662Sdim  if (Body.isInvalid()) {
9459251662Sdim    getSema().ActOnCapturedRegionError();
9460251662Sdim    return StmtError();
9461251662Sdim  }
9462251662Sdim
9463251662Sdim  return getSema().ActOnCapturedRegionEnd(Body.take());
9464251662Sdim}
9465251662Sdim
9466198092Srdivacky} // end namespace clang
9467198092Srdivacky
9468198092Srdivacky#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H
9469