blob: a7a9cfaca8491fac9ed3e621236c7012856365a1 [file] [log] [blame]
John McCalla2becad2009-10-21 00:40:46 +00001//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===/
Douglas Gregor577f75a2009-08-04 16:50:30 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//===----------------------------------------------------------------------===/
8//
9// This file implements a semantic tree transformation that takes a given
10// AST and rebuilds it, possibly transforming some nodes in the process.
11//
12//===----------------------------------------------------------------------===/
13#ifndef LLVM_CLANG_SEMA_TREETRANSFORM_H
14#define LLVM_CLANG_SEMA_TREETRANSFORM_H
15
16#include "Sema.h"
Douglas Gregordcee1a12009-08-06 05:28:30 +000017#include "clang/Sema/SemaDiagnostic.h"
Douglas Gregorc68afe22009-09-03 21:38:09 +000018#include "clang/AST/Decl.h"
Douglas Gregor657c1ac2009-08-06 22:17:10 +000019#include "clang/AST/Expr.h"
Douglas Gregorb98b1992009-08-11 05:31:07 +000020#include "clang/AST/ExprCXX.h"
21#include "clang/AST/ExprObjC.h"
Douglas Gregor43959a92009-08-20 07:17:43 +000022#include "clang/AST/Stmt.h"
23#include "clang/AST/StmtCXX.h"
24#include "clang/AST/StmtObjC.h"
John McCalla2becad2009-10-21 00:40:46 +000025#include "clang/AST/TypeLocBuilder.h"
Douglas Gregorb98b1992009-08-11 05:31:07 +000026#include "clang/Parse/Ownership.h"
27#include "clang/Parse/Designator.h"
28#include "clang/Lex/Preprocessor.h"
John McCalla2becad2009-10-21 00:40:46 +000029#include "llvm/Support/ErrorHandling.h"
Douglas Gregor577f75a2009-08-04 16:50:30 +000030#include <algorithm>
31
32namespace clang {
Mike Stump1eb44332009-09-09 15:08:12 +000033
Douglas Gregor577f75a2009-08-04 16:50:30 +000034/// \brief A semantic tree transformation that allows one to transform one
35/// abstract syntax tree into another.
36///
Mike Stump1eb44332009-09-09 15:08:12 +000037/// A new tree transformation is defined by creating a new subclass \c X of
38/// \c TreeTransform<X> and then overriding certain operations to provide
39/// behavior specific to that transformation. For example, template
Douglas Gregor577f75a2009-08-04 16:50:30 +000040/// instantiation is implemented as a tree transformation where the
41/// transformation of TemplateTypeParmType nodes involves substituting the
42/// template arguments for their corresponding template parameters; a similar
43/// transformation is performed for non-type template parameters and
44/// template template parameters.
45///
46/// This tree-transformation template uses static polymorphism to allow
Mike Stump1eb44332009-09-09 15:08:12 +000047/// subclasses to customize any of its operations. Thus, a subclass can
Douglas Gregor577f75a2009-08-04 16:50:30 +000048/// override any of the transformation or rebuild operators by providing an
49/// operation with the same signature as the default implementation. The
50/// overridding function should not be virtual.
51///
52/// Semantic tree transformations are split into two stages, either of which
53/// can be replaced by a subclass. The "transform" step transforms an AST node
54/// or the parts of an AST node using the various transformation functions,
55/// then passes the pieces on to the "rebuild" step, which constructs a new AST
56/// node of the appropriate kind from the pieces. The default transformation
57/// routines recursively transform the operands to composite AST nodes (e.g.,
58/// the pointee type of a PointerType node) and, if any of those operand nodes
59/// were changed by the transformation, invokes the rebuild operation to create
60/// a new AST node.
61///
Mike Stump1eb44332009-09-09 15:08:12 +000062/// Subclasses can customize the transformation at various levels. The
Douglas Gregor670444e2009-08-04 22:27:00 +000063/// most coarse-grained transformations involve replacing TransformType(),
Douglas Gregor577f75a2009-08-04 16:50:30 +000064/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifier(),
65/// TransformTemplateName(), or TransformTemplateArgument() with entirely
66/// new implementations.
67///
68/// For more fine-grained transformations, subclasses can replace any of the
69/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
Douglas Gregor43959a92009-08-20 07:17:43 +000070/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
Douglas Gregor577f75a2009-08-04 16:50:30 +000071/// replacing TransformTemplateTypeParmType() allows template instantiation
Mike Stump1eb44332009-09-09 15:08:12 +000072/// to substitute template arguments for their corresponding template
Douglas Gregor577f75a2009-08-04 16:50:30 +000073/// parameters. Additionally, subclasses can override the \c RebuildXXX
74/// functions to control how AST nodes are rebuilt when their operands change.
75/// By default, \c TreeTransform will invoke semantic analysis to rebuild
76/// AST nodes. However, certain other tree transformations (e.g, cloning) may
77/// be able to use more efficient rebuild steps.
78///
79/// There are a handful of other functions that can be overridden, allowing one
Mike Stump1eb44332009-09-09 15:08:12 +000080/// to avoid traversing nodes that don't need any transformation
Douglas Gregor577f75a2009-08-04 16:50:30 +000081/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
82/// operands have not changed (\c AlwaysRebuild()), and customize the
83/// default locations and entity names used for type-checking
84/// (\c getBaseLocation(), \c getBaseEntity()).
Douglas Gregor577f75a2009-08-04 16:50:30 +000085template<typename Derived>
86class TreeTransform {
87protected:
88 Sema &SemaRef;
Mike Stump1eb44332009-09-09 15:08:12 +000089
90public:
Douglas Gregorb98b1992009-08-11 05:31:07 +000091 typedef Sema::OwningStmtResult OwningStmtResult;
92 typedef Sema::OwningExprResult OwningExprResult;
93 typedef Sema::StmtArg StmtArg;
94 typedef Sema::ExprArg ExprArg;
95 typedef Sema::MultiExprArg MultiExprArg;
Douglas Gregor43959a92009-08-20 07:17:43 +000096 typedef Sema::MultiStmtArg MultiStmtArg;
Mike Stump1eb44332009-09-09 15:08:12 +000097
Douglas Gregor577f75a2009-08-04 16:50:30 +000098 /// \brief Initializes a new tree transformer.
99 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
Mike Stump1eb44332009-09-09 15:08:12 +0000100
Douglas Gregor577f75a2009-08-04 16:50:30 +0000101 /// \brief Retrieves a reference to the derived class.
102 Derived &getDerived() { return static_cast<Derived&>(*this); }
103
104 /// \brief Retrieves a reference to the derived class.
Mike Stump1eb44332009-09-09 15:08:12 +0000105 const Derived &getDerived() const {
106 return static_cast<const Derived&>(*this);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000107 }
108
109 /// \brief Retrieves a reference to the semantic analysis object used for
110 /// this tree transform.
111 Sema &getSema() const { return SemaRef; }
Mike Stump1eb44332009-09-09 15:08:12 +0000112
Douglas Gregor577f75a2009-08-04 16:50:30 +0000113 /// \brief Whether the transformation should always rebuild AST nodes, even
114 /// if none of the children have changed.
115 ///
116 /// Subclasses may override this function to specify when the transformation
117 /// should rebuild all AST nodes.
118 bool AlwaysRebuild() { return false; }
Mike Stump1eb44332009-09-09 15:08:12 +0000119
Douglas Gregor577f75a2009-08-04 16:50:30 +0000120 /// \brief Returns the location of the entity being transformed, if that
121 /// information was not available elsewhere in the AST.
122 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000123 /// By default, returns no source-location information. Subclasses can
Douglas Gregor577f75a2009-08-04 16:50:30 +0000124 /// provide an alternative implementation that provides better location
125 /// information.
126 SourceLocation getBaseLocation() { return SourceLocation(); }
Mike Stump1eb44332009-09-09 15:08:12 +0000127
Douglas Gregor577f75a2009-08-04 16:50:30 +0000128 /// \brief Returns the name of the entity being transformed, if that
129 /// information was not available elsewhere in the AST.
130 ///
131 /// By default, returns an empty name. Subclasses can provide an alternative
132 /// implementation with a more precise name.
133 DeclarationName getBaseEntity() { return DeclarationName(); }
134
Douglas Gregorb98b1992009-08-11 05:31:07 +0000135 /// \brief Sets the "base" location and entity when that
136 /// information is known based on another transformation.
137 ///
138 /// By default, the source location and entity are ignored. Subclasses can
139 /// override this function to provide a customized implementation.
140 void setBase(SourceLocation Loc, DeclarationName Entity) { }
Mike Stump1eb44332009-09-09 15:08:12 +0000141
Douglas Gregorb98b1992009-08-11 05:31:07 +0000142 /// \brief RAII object that temporarily sets the base location and entity
143 /// used for reporting diagnostics in types.
144 class TemporaryBase {
145 TreeTransform &Self;
146 SourceLocation OldLocation;
147 DeclarationName OldEntity;
Mike Stump1eb44332009-09-09 15:08:12 +0000148
Douglas Gregorb98b1992009-08-11 05:31:07 +0000149 public:
150 TemporaryBase(TreeTransform &Self, SourceLocation Location,
Mike Stump1eb44332009-09-09 15:08:12 +0000151 DeclarationName Entity) : Self(Self) {
Douglas Gregorb98b1992009-08-11 05:31:07 +0000152 OldLocation = Self.getDerived().getBaseLocation();
153 OldEntity = Self.getDerived().getBaseEntity();
154 Self.getDerived().setBase(Location, Entity);
155 }
Mike Stump1eb44332009-09-09 15:08:12 +0000156
Douglas Gregorb98b1992009-08-11 05:31:07 +0000157 ~TemporaryBase() {
158 Self.getDerived().setBase(OldLocation, OldEntity);
159 }
160 };
Mike Stump1eb44332009-09-09 15:08:12 +0000161
162 /// \brief Determine whether the given type \p T has already been
Douglas Gregor577f75a2009-08-04 16:50:30 +0000163 /// transformed.
164 ///
165 /// Subclasses can provide an alternative implementation of this routine
Mike Stump1eb44332009-09-09 15:08:12 +0000166 /// to short-circuit evaluation when it is known that a given type will
Douglas Gregor577f75a2009-08-04 16:50:30 +0000167 /// not change. For example, template instantiation need not traverse
168 /// non-dependent types.
169 bool AlreadyTransformed(QualType T) {
170 return T.isNull();
171 }
172
173 /// \brief Transforms the given type into another type.
174 ///
John McCalla2becad2009-10-21 00:40:46 +0000175 /// By default, this routine transforms a type by creating a
176 /// DeclaratorInfo for it and delegating to the appropriate
177 /// function. This is expensive, but we don't mind, because
178 /// this method is deprecated anyway; all users should be
179 /// switched to storing DeclaratorInfos.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000180 ///
181 /// \returns the transformed type.
182 QualType TransformType(QualType T);
Mike Stump1eb44332009-09-09 15:08:12 +0000183
John McCalla2becad2009-10-21 00:40:46 +0000184 /// \brief Transforms the given type-with-location into a new
185 /// type-with-location.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000186 ///
John McCalla2becad2009-10-21 00:40:46 +0000187 /// By default, this routine transforms a type by delegating to the
188 /// appropriate TransformXXXType to build a new type. Subclasses
189 /// may override this function (to take over all type
190 /// transformations) or some set of the TransformXXXType functions
191 /// to alter the transformation.
192 DeclaratorInfo *TransformType(DeclaratorInfo *DI);
193
194 /// \brief Transform the given type-with-location into a new
195 /// type, collecting location information in the given builder
196 /// as necessary.
197 ///
198 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
Mike Stump1eb44332009-09-09 15:08:12 +0000199
Douglas Gregor657c1ac2009-08-06 22:17:10 +0000200 /// \brief Transform the given statement.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000201 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000202 /// By default, this routine transforms a statement by delegating to the
Douglas Gregor43959a92009-08-20 07:17:43 +0000203 /// appropriate TransformXXXStmt function to transform a specific kind of
204 /// statement or the TransformExpr() function to transform an expression.
205 /// Subclasses may override this function to transform statements using some
206 /// other mechanism.
207 ///
208 /// \returns the transformed statement.
Douglas Gregorb98b1992009-08-11 05:31:07 +0000209 OwningStmtResult TransformStmt(Stmt *S);
Mike Stump1eb44332009-09-09 15:08:12 +0000210
Douglas Gregor657c1ac2009-08-06 22:17:10 +0000211 /// \brief Transform the given expression.
212 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000213 /// By default, this routine transforms an expression by delegating to the
214 /// appropriate TransformXXXExpr function to build a new expression.
215 /// Subclasses may override this function to transform expressions using some
216 /// other mechanism.
217 ///
218 /// \returns the transformed expression.
219 OwningExprResult TransformExpr(Expr *E) {
220 return getDerived().TransformExpr(E, /*isAddressOfOperand=*/false);
221 }
222
223 /// \brief Transform the given expression.
224 ///
225 /// By default, this routine transforms an expression by delegating to the
226 /// appropriate TransformXXXExpr function to build a new expression.
227 /// Subclasses may override this function to transform expressions using some
228 /// other mechanism.
229 ///
230 /// \returns the transformed expression.
231 OwningExprResult TransformExpr(Expr *E, bool isAddressOfOperand);
Mike Stump1eb44332009-09-09 15:08:12 +0000232
Douglas Gregor577f75a2009-08-04 16:50:30 +0000233 /// \brief Transform the given declaration, which is referenced from a type
234 /// or expression.
235 ///
Douglas Gregordcee1a12009-08-06 05:28:30 +0000236 /// By default, acts as the identity function on declarations. Subclasses
237 /// may override this function to provide alternate behavior.
238 Decl *TransformDecl(Decl *D) { return D; }
Douglas Gregor43959a92009-08-20 07:17:43 +0000239
240 /// \brief Transform the definition of the given declaration.
241 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000242 /// By default, invokes TransformDecl() to transform the declaration.
Douglas Gregor43959a92009-08-20 07:17:43 +0000243 /// Subclasses may override this function to provide alternate behavior.
244 Decl *TransformDefinition(Decl *D) { return getDerived().TransformDecl(D); }
Mike Stump1eb44332009-09-09 15:08:12 +0000245
Douglas Gregor6cd21982009-10-20 05:58:46 +0000246 /// \brief Transform the given declaration, which was the first part of a
247 /// nested-name-specifier in a member access expression.
248 ///
249 /// This specific declaration transformation only applies to the first
250 /// identifier in a nested-name-specifier of a member access expression, e.g.,
251 /// the \c T in \c x->T::member
252 ///
253 /// By default, invokes TransformDecl() to transform the declaration.
254 /// Subclasses may override this function to provide alternate behavior.
255 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
256 return cast_or_null<NamedDecl>(getDerived().TransformDecl(D));
257 }
258
Douglas Gregor577f75a2009-08-04 16:50:30 +0000259 /// \brief Transform the given nested-name-specifier.
260 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000261 /// By default, transforms all of the types and declarations within the
Douglas Gregordcee1a12009-08-06 05:28:30 +0000262 /// nested-name-specifier. Subclasses may override this function to provide
263 /// alternate behavior.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000264 NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregora38c6872009-09-03 16:14:30 +0000265 SourceRange Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +0000266 QualType ObjectType = QualType(),
267 NamedDecl *FirstQualifierInScope = 0);
Mike Stump1eb44332009-09-09 15:08:12 +0000268
Douglas Gregor81499bb2009-09-03 22:13:48 +0000269 /// \brief Transform the given declaration name.
270 ///
271 /// By default, transforms the types of conversion function, constructor,
272 /// and destructor names and then (if needed) rebuilds the declaration name.
273 /// Identifiers and selectors are returned unmodified. Sublcasses may
274 /// override this function to provide alternate behavior.
275 DeclarationName TransformDeclarationName(DeclarationName Name,
Douglas Gregordd62b152009-10-19 22:04:39 +0000276 SourceLocation Loc,
277 QualType ObjectType = QualType());
Mike Stump1eb44332009-09-09 15:08:12 +0000278
Douglas Gregor577f75a2009-08-04 16:50:30 +0000279 /// \brief Transform the given template name.
Mike Stump1eb44332009-09-09 15:08:12 +0000280 ///
Douglas Gregord1067e52009-08-06 06:41:21 +0000281 /// By default, transforms the template name by transforming the declarations
Mike Stump1eb44332009-09-09 15:08:12 +0000282 /// and nested-name-specifiers that occur within the template name.
Douglas Gregord1067e52009-08-06 06:41:21 +0000283 /// Subclasses may override this function to provide alternate behavior.
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000284 TemplateName TransformTemplateName(TemplateName Name,
285 QualType ObjectType = QualType());
Mike Stump1eb44332009-09-09 15:08:12 +0000286
Douglas Gregor577f75a2009-08-04 16:50:30 +0000287 /// \brief Transform the given template argument.
288 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000289 /// By default, this operation transforms the type, expression, or
290 /// declaration stored within the template argument and constructs a
Douglas Gregor670444e2009-08-04 22:27:00 +0000291 /// new template argument from the transformed result. Subclasses may
292 /// override this function to provide alternate behavior.
John McCall833ca992009-10-29 08:12:44 +0000293 ///
294 /// Returns true if there was an error.
295 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
296 TemplateArgumentLoc &Output);
297
298 /// \brief Fakes up a TemplateArgumentLoc for a given TemplateArgument.
299 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
300 TemplateArgumentLoc &ArgLoc);
301
302 /// \brief Fakes up a DeclaratorInfo for a type.
303 DeclaratorInfo *InventDeclaratorInfo(QualType T) {
304 return SemaRef.Context.getTrivialDeclaratorInfo(T,
305 getDerived().getBaseLocation());
306 }
Mike Stump1eb44332009-09-09 15:08:12 +0000307
John McCalla2becad2009-10-21 00:40:46 +0000308#define ABSTRACT_TYPELOC(CLASS, PARENT)
309#define TYPELOC(CLASS, PARENT) \
310 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
311#include "clang/AST/TypeLocNodes.def"
Douglas Gregor577f75a2009-08-04 16:50:30 +0000312
John McCall85737a72009-10-30 00:06:24 +0000313 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
314
Douglas Gregordd62b152009-10-19 22:04:39 +0000315 QualType
316 TransformTemplateSpecializationType(const TemplateSpecializationType *T,
317 QualType ObjectType);
John McCall833ca992009-10-29 08:12:44 +0000318
319 QualType
320 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
321 TemplateSpecializationTypeLoc TL,
322 QualType ObjectType);
Douglas Gregordd62b152009-10-19 22:04:39 +0000323
Douglas Gregor43959a92009-08-20 07:17:43 +0000324 OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
Mike Stump1eb44332009-09-09 15:08:12 +0000325
Douglas Gregor43959a92009-08-20 07:17:43 +0000326#define STMT(Node, Parent) \
327 OwningStmtResult Transform##Node(Node *S);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000328#define EXPR(Node, Parent) \
Douglas Gregorc86a6e92009-11-04 07:01:15 +0000329 OwningExprResult Transform##Node(Node *E, bool isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000330#define ABSTRACT_EXPR(Node, Parent)
331#include "clang/AST/StmtNodes.def"
Mike Stump1eb44332009-09-09 15:08:12 +0000332
Douglas Gregor577f75a2009-08-04 16:50:30 +0000333 /// \brief Build a new pointer type given its pointee type.
334 ///
335 /// By default, performs semantic analysis when building the pointer type.
336 /// Subclasses may override this routine to provide different behavior.
John McCall85737a72009-10-30 00:06:24 +0000337 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000338
339 /// \brief Build a new block pointer type given its pointee type.
340 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000341 /// By default, performs semantic analysis when building the block pointer
Douglas Gregor577f75a2009-08-04 16:50:30 +0000342 /// type. Subclasses may override this routine to provide different behavior.
John McCall85737a72009-10-30 00:06:24 +0000343 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000344
John McCall85737a72009-10-30 00:06:24 +0000345 /// \brief Build a new reference type given the type it references.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000346 ///
John McCall85737a72009-10-30 00:06:24 +0000347 /// By default, performs semantic analysis when building the
348 /// reference type. Subclasses may override this routine to provide
349 /// different behavior.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000350 ///
John McCall85737a72009-10-30 00:06:24 +0000351 /// \param LValue whether the type was written with an lvalue sigil
352 /// or an rvalue sigil.
353 QualType RebuildReferenceType(QualType ReferentType,
354 bool LValue,
355 SourceLocation Sigil);
Mike Stump1eb44332009-09-09 15:08:12 +0000356
Douglas Gregor577f75a2009-08-04 16:50:30 +0000357 /// \brief Build a new member pointer type given the pointee type and the
358 /// class type it refers into.
359 ///
360 /// By default, performs semantic analysis when building the member pointer
361 /// type. Subclasses may override this routine to provide different behavior.
John McCall85737a72009-10-30 00:06:24 +0000362 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
363 SourceLocation Sigil);
Mike Stump1eb44332009-09-09 15:08:12 +0000364
John McCalla2becad2009-10-21 00:40:46 +0000365 /// \brief Build a new Objective C object pointer type.
John McCall85737a72009-10-30 00:06:24 +0000366 QualType RebuildObjCObjectPointerType(QualType PointeeType,
367 SourceLocation Sigil);
John McCalla2becad2009-10-21 00:40:46 +0000368
Douglas Gregor577f75a2009-08-04 16:50:30 +0000369 /// \brief Build a new array type given the element type, size
370 /// modifier, size of the array (if known), size expression, and index type
371 /// qualifiers.
372 ///
373 /// By default, performs semantic analysis when building the array type.
374 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000375 /// Also by default, all of the other Rebuild*Array
Douglas Gregor577f75a2009-08-04 16:50:30 +0000376 QualType RebuildArrayType(QualType ElementType,
377 ArrayType::ArraySizeModifier SizeMod,
378 const llvm::APInt *Size,
379 Expr *SizeExpr,
380 unsigned IndexTypeQuals,
381 SourceRange BracketsRange);
Mike Stump1eb44332009-09-09 15:08:12 +0000382
Douglas Gregor577f75a2009-08-04 16:50:30 +0000383 /// \brief Build a new constant array type given the element type, size
384 /// modifier, (known) size of the array, and index type qualifiers.
385 ///
386 /// By default, performs semantic analysis when building the array type.
387 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000388 QualType RebuildConstantArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000389 ArrayType::ArraySizeModifier SizeMod,
390 const llvm::APInt &Size,
John McCall85737a72009-10-30 00:06:24 +0000391 unsigned IndexTypeQuals,
392 SourceRange BracketsRange);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000393
Douglas Gregor577f75a2009-08-04 16:50:30 +0000394 /// \brief Build a new incomplete array type given the element type, size
395 /// modifier, and index type qualifiers.
396 ///
397 /// By default, performs semantic analysis when building the array type.
398 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000399 QualType RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000400 ArrayType::ArraySizeModifier SizeMod,
John McCall85737a72009-10-30 00:06:24 +0000401 unsigned IndexTypeQuals,
402 SourceRange BracketsRange);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000403
Mike Stump1eb44332009-09-09 15:08:12 +0000404 /// \brief Build a new variable-length array type given the element type,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000405 /// size modifier, size expression, and index type qualifiers.
406 ///
407 /// By default, performs semantic analysis when building the array type.
408 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000409 QualType RebuildVariableArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000410 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000411 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000412 unsigned IndexTypeQuals,
413 SourceRange BracketsRange);
414
Mike Stump1eb44332009-09-09 15:08:12 +0000415 /// \brief Build a new dependent-sized array type given the element type,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000416 /// size modifier, size expression, and index type qualifiers.
417 ///
418 /// By default, performs semantic analysis when building the array type.
419 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000420 QualType RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000421 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000422 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000423 unsigned IndexTypeQuals,
424 SourceRange BracketsRange);
425
426 /// \brief Build a new vector type given the element type and
427 /// number of elements.
428 ///
429 /// By default, performs semantic analysis when building the vector type.
430 /// Subclasses may override this routine to provide different behavior.
431 QualType RebuildVectorType(QualType ElementType, unsigned NumElements);
Mike Stump1eb44332009-09-09 15:08:12 +0000432
Douglas Gregor577f75a2009-08-04 16:50:30 +0000433 /// \brief Build a new extended vector type given the element type and
434 /// number of elements.
435 ///
436 /// By default, performs semantic analysis when building the vector type.
437 /// Subclasses may override this routine to provide different behavior.
438 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
439 SourceLocation AttributeLoc);
Mike Stump1eb44332009-09-09 15:08:12 +0000440
441 /// \brief Build a new potentially dependently-sized extended vector type
Douglas Gregor577f75a2009-08-04 16:50:30 +0000442 /// given the element type and number of elements.
443 ///
444 /// By default, performs semantic analysis when building the vector type.
445 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000446 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000447 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000448 SourceLocation AttributeLoc);
Mike Stump1eb44332009-09-09 15:08:12 +0000449
Douglas Gregor577f75a2009-08-04 16:50:30 +0000450 /// \brief Build a new function type.
451 ///
452 /// By default, performs semantic analysis when building the function type.
453 /// Subclasses may override this routine to provide different behavior.
454 QualType RebuildFunctionProtoType(QualType T,
Mike Stump1eb44332009-09-09 15:08:12 +0000455 QualType *ParamTypes,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000456 unsigned NumParamTypes,
457 bool Variadic, unsigned Quals);
Mike Stump1eb44332009-09-09 15:08:12 +0000458
John McCalla2becad2009-10-21 00:40:46 +0000459 /// \brief Build a new unprototyped function type.
460 QualType RebuildFunctionNoProtoType(QualType ResultType);
461
Douglas Gregor577f75a2009-08-04 16:50:30 +0000462 /// \brief Build a new typedef type.
463 QualType RebuildTypedefType(TypedefDecl *Typedef) {
464 return SemaRef.Context.getTypeDeclType(Typedef);
465 }
466
467 /// \brief Build a new class/struct/union type.
468 QualType RebuildRecordType(RecordDecl *Record) {
469 return SemaRef.Context.getTypeDeclType(Record);
470 }
471
472 /// \brief Build a new Enum type.
473 QualType RebuildEnumType(EnumDecl *Enum) {
474 return SemaRef.Context.getTypeDeclType(Enum);
475 }
John McCall7da24312009-09-05 00:15:47 +0000476
477 /// \brief Build a new elaborated type.
478 QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag) {
479 return SemaRef.Context.getElaboratedType(T, Tag);
480 }
Mike Stump1eb44332009-09-09 15:08:12 +0000481
482 /// \brief Build a new typeof(expr) type.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000483 ///
484 /// By default, performs semantic analysis when building the typeof type.
485 /// Subclasses may override this routine to provide different behavior.
Douglas Gregorb98b1992009-08-11 05:31:07 +0000486 QualType RebuildTypeOfExprType(ExprArg Underlying);
Douglas Gregor577f75a2009-08-04 16:50:30 +0000487
Mike Stump1eb44332009-09-09 15:08:12 +0000488 /// \brief Build a new typeof(type) type.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000489 ///
490 /// By default, builds a new TypeOfType with the given underlying type.
491 QualType RebuildTypeOfType(QualType Underlying);
492
Mike Stump1eb44332009-09-09 15:08:12 +0000493 /// \brief Build a new C++0x decltype type.
Douglas Gregor577f75a2009-08-04 16:50:30 +0000494 ///
495 /// By default, performs semantic analysis when building the decltype type.
496 /// Subclasses may override this routine to provide different behavior.
Douglas Gregorb98b1992009-08-11 05:31:07 +0000497 QualType RebuildDecltypeType(ExprArg Underlying);
Mike Stump1eb44332009-09-09 15:08:12 +0000498
Douglas Gregor577f75a2009-08-04 16:50:30 +0000499 /// \brief Build a new template specialization type.
500 ///
501 /// By default, performs semantic analysis when building the template
502 /// specialization type. Subclasses may override this routine to provide
503 /// different behavior.
504 QualType RebuildTemplateSpecializationType(TemplateName Template,
John McCall833ca992009-10-29 08:12:44 +0000505 SourceLocation TemplateLoc,
John McCalld5532b62009-11-23 01:53:49 +0000506 const TemplateArgumentListInfo &Args);
Mike Stump1eb44332009-09-09 15:08:12 +0000507
Douglas Gregor577f75a2009-08-04 16:50:30 +0000508 /// \brief Build a new qualified name type.
509 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000510 /// By default, builds a new QualifiedNameType type from the
511 /// nested-name-specifier and the named type. Subclasses may override
Douglas Gregor577f75a2009-08-04 16:50:30 +0000512 /// this routine to provide different behavior.
513 QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
514 return SemaRef.Context.getQualifiedNameType(NNS, Named);
Mike Stump1eb44332009-09-09 15:08:12 +0000515 }
Douglas Gregor577f75a2009-08-04 16:50:30 +0000516
517 /// \brief Build a new typename type that refers to a template-id.
518 ///
519 /// By default, builds a new TypenameType type from the nested-name-specifier
Mike Stump1eb44332009-09-09 15:08:12 +0000520 /// and the given type. Subclasses may override this routine to provide
Douglas Gregor577f75a2009-08-04 16:50:30 +0000521 /// different behavior.
522 QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
523 if (NNS->isDependent())
Mike Stump1eb44332009-09-09 15:08:12 +0000524 return SemaRef.Context.getTypenameType(NNS,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000525 cast<TemplateSpecializationType>(T));
Mike Stump1eb44332009-09-09 15:08:12 +0000526
Douglas Gregor577f75a2009-08-04 16:50:30 +0000527 return SemaRef.Context.getQualifiedNameType(NNS, T);
Mike Stump1eb44332009-09-09 15:08:12 +0000528 }
Douglas Gregor577f75a2009-08-04 16:50:30 +0000529
530 /// \brief Build a new typename type that refers to an identifier.
531 ///
532 /// By default, performs semantic analysis when building the typename type
Mike Stump1eb44332009-09-09 15:08:12 +0000533 /// (or qualified name type). Subclasses may override this routine to provide
Douglas Gregor577f75a2009-08-04 16:50:30 +0000534 /// different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000535 QualType RebuildTypenameType(NestedNameSpecifier *NNS,
John McCall833ca992009-10-29 08:12:44 +0000536 const IdentifierInfo *Id,
537 SourceRange SR) {
538 return SemaRef.CheckTypenameType(NNS, *Id, SR);
Douglas Gregordcee1a12009-08-06 05:28:30 +0000539 }
Mike Stump1eb44332009-09-09 15:08:12 +0000540
Douglas Gregordcee1a12009-08-06 05:28:30 +0000541 /// \brief Build a new nested-name-specifier given the prefix and an
542 /// identifier that names the next step in the nested-name-specifier.
543 ///
544 /// By default, performs semantic analysis when building the new
545 /// nested-name-specifier. Subclasses may override this routine to provide
546 /// different behavior.
547 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
548 SourceRange Range,
Douglas Gregora38c6872009-09-03 16:14:30 +0000549 IdentifierInfo &II,
Douglas Gregorc68afe22009-09-03 21:38:09 +0000550 QualType ObjectType,
551 NamedDecl *FirstQualifierInScope);
Douglas Gregordcee1a12009-08-06 05:28:30 +0000552
553 /// \brief Build a new nested-name-specifier given the prefix and the
554 /// namespace named in the next step in the nested-name-specifier.
555 ///
556 /// By default, performs semantic analysis when building the new
557 /// nested-name-specifier. Subclasses may override this routine to provide
558 /// different behavior.
559 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
560 SourceRange Range,
561 NamespaceDecl *NS);
562
563 /// \brief Build a new nested-name-specifier given the prefix and the
564 /// type named in the next step in the nested-name-specifier.
565 ///
566 /// By default, performs semantic analysis when building the new
567 /// nested-name-specifier. Subclasses may override this routine to provide
568 /// different behavior.
569 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
570 SourceRange Range,
571 bool TemplateKW,
572 QualType T);
Douglas Gregord1067e52009-08-06 06:41:21 +0000573
574 /// \brief Build a new template name given a nested name specifier, a flag
575 /// indicating whether the "template" keyword was provided, and the template
576 /// that the template name refers to.
577 ///
578 /// By default, builds the new template name directly. Subclasses may override
579 /// this routine to provide different behavior.
580 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
581 bool TemplateKW,
582 TemplateDecl *Template);
583
584 /// \brief Build a new template name given a nested name specifier, a flag
585 /// indicating whether the "template" keyword was provided, and a set of
586 /// overloaded function templates.
587 ///
588 /// By default, builds the new template name directly. Subclasses may override
589 /// this routine to provide different behavior.
590 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
591 bool TemplateKW,
592 OverloadedFunctionDecl *Ovl);
Mike Stump1eb44332009-09-09 15:08:12 +0000593
Douglas Gregord1067e52009-08-06 06:41:21 +0000594 /// \brief Build a new template name given a nested name specifier and the
595 /// name that is referred to as a template.
596 ///
597 /// By default, performs semantic analysis to determine whether the name can
598 /// be resolved to a specific template, then builds the appropriate kind of
599 /// template name. Subclasses may override this routine to provide different
600 /// behavior.
601 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000602 const IdentifierInfo &II,
603 QualType ObjectType);
Mike Stump1eb44332009-09-09 15:08:12 +0000604
Douglas Gregorca1bdd72009-11-04 00:56:37 +0000605 /// \brief Build a new template name given a nested name specifier and the
606 /// overloaded operator name that is referred to as a template.
607 ///
608 /// By default, performs semantic analysis to determine whether the name can
609 /// be resolved to a specific template, then builds the appropriate kind of
610 /// template name. Subclasses may override this routine to provide different
611 /// behavior.
612 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
613 OverloadedOperatorKind Operator,
614 QualType ObjectType);
615
Douglas Gregor43959a92009-08-20 07:17:43 +0000616 /// \brief Build a new compound statement.
617 ///
618 /// By default, performs semantic analysis to build the new statement.
619 /// Subclasses may override this routine to provide different behavior.
620 OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
621 MultiStmtArg Statements,
622 SourceLocation RBraceLoc,
623 bool IsStmtExpr) {
624 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
625 IsStmtExpr);
626 }
627
628 /// \brief Build a new case statement.
629 ///
630 /// By default, performs semantic analysis to build the new statement.
631 /// Subclasses may override this routine to provide different behavior.
632 OwningStmtResult RebuildCaseStmt(SourceLocation CaseLoc,
633 ExprArg LHS,
634 SourceLocation EllipsisLoc,
635 ExprArg RHS,
636 SourceLocation ColonLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +0000637 return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
Douglas Gregor43959a92009-08-20 07:17:43 +0000638 ColonLoc);
639 }
Mike Stump1eb44332009-09-09 15:08:12 +0000640
Douglas Gregor43959a92009-08-20 07:17:43 +0000641 /// \brief Attach the body to a new case statement.
642 ///
643 /// By default, performs semantic analysis to build the new statement.
644 /// Subclasses may override this routine to provide different behavior.
645 OwningStmtResult RebuildCaseStmtBody(StmtArg S, StmtArg Body) {
646 getSema().ActOnCaseStmtBody(S.get(), move(Body));
647 return move(S);
648 }
Mike Stump1eb44332009-09-09 15:08:12 +0000649
Douglas Gregor43959a92009-08-20 07:17:43 +0000650 /// \brief Build a new default statement.
651 ///
652 /// By default, performs semantic analysis to build the new statement.
653 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000654 OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000655 SourceLocation ColonLoc,
656 StmtArg SubStmt) {
Mike Stump1eb44332009-09-09 15:08:12 +0000657 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
Douglas Gregor43959a92009-08-20 07:17:43 +0000658 /*CurScope=*/0);
659 }
Mike Stump1eb44332009-09-09 15:08:12 +0000660
Douglas Gregor43959a92009-08-20 07:17:43 +0000661 /// \brief Build a new label statement.
662 ///
663 /// By default, performs semantic analysis to build the new statement.
664 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000665 OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000666 IdentifierInfo *Id,
667 SourceLocation ColonLoc,
668 StmtArg SubStmt) {
669 return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
670 }
Mike Stump1eb44332009-09-09 15:08:12 +0000671
Douglas Gregor43959a92009-08-20 07:17:43 +0000672 /// \brief Build a new "if" statement.
673 ///
674 /// By default, performs semantic analysis to build the new statement.
675 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000676 OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
677 StmtArg Then, SourceLocation ElseLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000678 StmtArg Else) {
679 return getSema().ActOnIfStmt(IfLoc, Cond, move(Then), ElseLoc, move(Else));
680 }
Mike Stump1eb44332009-09-09 15:08:12 +0000681
Douglas Gregor43959a92009-08-20 07:17:43 +0000682 /// \brief Start building a new switch statement.
683 ///
684 /// By default, performs semantic analysis to build the new statement.
685 /// Subclasses may override this routine to provide different behavior.
686 OwningStmtResult RebuildSwitchStmtStart(ExprArg Cond) {
687 return getSema().ActOnStartOfSwitchStmt(move(Cond));
688 }
Mike Stump1eb44332009-09-09 15:08:12 +0000689
Douglas Gregor43959a92009-08-20 07:17:43 +0000690 /// \brief Attach the body to the switch statement.
691 ///
692 /// By default, performs semantic analysis to build the new statement.
693 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000694 OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000695 StmtArg Switch, StmtArg Body) {
696 return getSema().ActOnFinishSwitchStmt(SwitchLoc, move(Switch),
697 move(Body));
698 }
699
700 /// \brief Build a new while statement.
701 ///
702 /// By default, performs semantic analysis to build the new statement.
703 /// Subclasses may override this routine to provide different behavior.
704 OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc,
705 Sema::FullExprArg Cond,
706 StmtArg Body) {
707 return getSema().ActOnWhileStmt(WhileLoc, Cond, move(Body));
708 }
Mike Stump1eb44332009-09-09 15:08:12 +0000709
Douglas Gregor43959a92009-08-20 07:17:43 +0000710 /// \brief Build a new do-while statement.
711 ///
712 /// By default, performs semantic analysis to build the new statement.
713 /// Subclasses may override this routine to provide different behavior.
714 OwningStmtResult RebuildDoStmt(SourceLocation DoLoc, StmtArg Body,
715 SourceLocation WhileLoc,
716 SourceLocation LParenLoc,
717 ExprArg Cond,
718 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +0000719 return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000720 move(Cond), RParenLoc);
721 }
722
723 /// \brief Build a new for statement.
724 ///
725 /// By default, performs semantic analysis to build the new statement.
726 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000727 OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000728 SourceLocation LParenLoc,
729 StmtArg Init, ExprArg Cond, ExprArg Inc,
730 SourceLocation RParenLoc, StmtArg Body) {
Mike Stump1eb44332009-09-09 15:08:12 +0000731 return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), move(Cond),
Douglas Gregor43959a92009-08-20 07:17:43 +0000732 move(Inc), RParenLoc, move(Body));
733 }
Mike Stump1eb44332009-09-09 15:08:12 +0000734
Douglas Gregor43959a92009-08-20 07:17:43 +0000735 /// \brief Build a new goto statement.
736 ///
737 /// By default, performs semantic analysis to build the new statement.
738 /// Subclasses may override this routine to provide different behavior.
739 OwningStmtResult RebuildGotoStmt(SourceLocation GotoLoc,
740 SourceLocation LabelLoc,
741 LabelStmt *Label) {
742 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
743 }
744
745 /// \brief Build a new indirect goto statement.
746 ///
747 /// By default, performs semantic analysis to build the new statement.
748 /// Subclasses may override this routine to provide different behavior.
749 OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
750 SourceLocation StarLoc,
751 ExprArg Target) {
752 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
753 }
Mike Stump1eb44332009-09-09 15:08:12 +0000754
Douglas Gregor43959a92009-08-20 07:17:43 +0000755 /// \brief Build a new return statement.
756 ///
757 /// By default, performs semantic analysis to build the new statement.
758 /// Subclasses may override this routine to provide different behavior.
759 OwningStmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
760 ExprArg Result) {
Mike Stump1eb44332009-09-09 15:08:12 +0000761
Douglas Gregor43959a92009-08-20 07:17:43 +0000762 return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
763 }
Mike Stump1eb44332009-09-09 15:08:12 +0000764
Douglas Gregor43959a92009-08-20 07:17:43 +0000765 /// \brief Build a new declaration statement.
766 ///
767 /// By default, performs semantic analysis to build the new statement.
768 /// Subclasses may override this routine to provide different behavior.
769 OwningStmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
Mike Stump1eb44332009-09-09 15:08:12 +0000770 SourceLocation StartLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000771 SourceLocation EndLoc) {
772 return getSema().Owned(
773 new (getSema().Context) DeclStmt(
774 DeclGroupRef::Create(getSema().Context,
775 Decls, NumDecls),
776 StartLoc, EndLoc));
777 }
Mike Stump1eb44332009-09-09 15:08:12 +0000778
Douglas Gregor43959a92009-08-20 07:17:43 +0000779 /// \brief Build a new C++ exception declaration.
780 ///
781 /// By default, performs semantic analysis to build the new decaration.
782 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000783 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
Douglas Gregor43959a92009-08-20 07:17:43 +0000784 DeclaratorInfo *Declarator,
785 IdentifierInfo *Name,
786 SourceLocation Loc,
787 SourceRange TypeRange) {
Mike Stump1eb44332009-09-09 15:08:12 +0000788 return getSema().BuildExceptionDeclaration(0, T, Declarator, Name, Loc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000789 TypeRange);
790 }
791
792 /// \brief Build a new C++ catch statement.
793 ///
794 /// By default, performs semantic analysis to build the new statement.
795 /// Subclasses may override this routine to provide different behavior.
796 OwningStmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
797 VarDecl *ExceptionDecl,
798 StmtArg Handler) {
799 return getSema().Owned(
Mike Stump1eb44332009-09-09 15:08:12 +0000800 new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
Douglas Gregor43959a92009-08-20 07:17:43 +0000801 Handler.takeAs<Stmt>()));
802 }
Mike Stump1eb44332009-09-09 15:08:12 +0000803
Douglas Gregor43959a92009-08-20 07:17:43 +0000804 /// \brief Build a new C++ try statement.
805 ///
806 /// By default, performs semantic analysis to build the new statement.
807 /// Subclasses may override this routine to provide different behavior.
808 OwningStmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
809 StmtArg TryBlock,
810 MultiStmtArg Handlers) {
811 return getSema().ActOnCXXTryBlock(TryLoc, move(TryBlock), move(Handlers));
812 }
Mike Stump1eb44332009-09-09 15:08:12 +0000813
Douglas Gregorb98b1992009-08-11 05:31:07 +0000814 /// \brief Build a new expression that references a declaration.
815 ///
816 /// By default, performs semantic analysis to build the new expression.
817 /// Subclasses may override this routine to provide different behavior.
Douglas Gregora2813ce2009-10-23 18:54:35 +0000818 OwningExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
819 SourceRange QualifierRange,
Douglas Gregorc86a6e92009-11-04 07:01:15 +0000820 NamedDecl *ND, SourceLocation Loc,
821 bool isAddressOfOperand) {
Douglas Gregora2813ce2009-10-23 18:54:35 +0000822 CXXScopeSpec SS;
823 SS.setScopeRep(Qualifier);
824 SS.setRange(QualifierRange);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000825 return getSema().BuildDeclarationNameExpr(Loc, ND,
826 /*FIXME:*/false,
Douglas Gregora2813ce2009-10-23 18:54:35 +0000827 &SS,
Douglas Gregorc86a6e92009-11-04 07:01:15 +0000828 isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000829 }
Mike Stump1eb44332009-09-09 15:08:12 +0000830
Douglas Gregorb98b1992009-08-11 05:31:07 +0000831 /// \brief Build a new expression in parentheses.
Mike Stump1eb44332009-09-09 15:08:12 +0000832 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000833 /// By default, performs semantic analysis to build the new expression.
834 /// Subclasses may override this routine to provide different behavior.
835 OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
836 SourceLocation RParen) {
837 return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
838 }
839
Douglas Gregora71d8192009-09-04 17:36:40 +0000840 /// \brief Build a new pseudo-destructor expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000841 ///
Douglas Gregora71d8192009-09-04 17:36:40 +0000842 /// By default, performs semantic analysis to build the new expression.
843 /// Subclasses may override this routine to provide different behavior.
844 OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
845 SourceLocation OperatorLoc,
846 bool isArrow,
847 SourceLocation DestroyedTypeLoc,
848 QualType DestroyedType,
849 NestedNameSpecifier *Qualifier,
850 SourceRange QualifierRange) {
851 CXXScopeSpec SS;
852 if (Qualifier) {
853 SS.setRange(QualifierRange);
854 SS.setScopeRep(Qualifier);
855 }
856
Mike Stump1eb44332009-09-09 15:08:12 +0000857 DeclarationName Name
Douglas Gregora71d8192009-09-04 17:36:40 +0000858 = SemaRef.Context.DeclarationNames.getCXXDestructorName(
859 SemaRef.Context.getCanonicalType(DestroyedType));
Mike Stump1eb44332009-09-09 15:08:12 +0000860
861 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregora71d8192009-09-04 17:36:40 +0000862 OperatorLoc,
863 isArrow? tok::arrow : tok::period,
864 DestroyedTypeLoc,
865 Name,
866 Sema::DeclPtrTy::make((Decl *)0),
867 &SS);
Mike Stump1eb44332009-09-09 15:08:12 +0000868 }
869
Douglas Gregorb98b1992009-08-11 05:31:07 +0000870 /// \brief Build a new unary operator expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000871 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000872 /// By default, performs semantic analysis to build the new expression.
873 /// Subclasses may override this routine to provide different behavior.
874 OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
875 UnaryOperator::Opcode Opc,
876 ExprArg SubExpr) {
Douglas Gregor6ca7cfb2009-11-05 00:51:44 +0000877 return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, move(SubExpr));
Douglas Gregorb98b1992009-08-11 05:31:07 +0000878 }
Mike Stump1eb44332009-09-09 15:08:12 +0000879
Douglas Gregorb98b1992009-08-11 05:31:07 +0000880 /// \brief Build a new sizeof or alignof expression with a type argument.
Mike Stump1eb44332009-09-09 15:08:12 +0000881 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000882 /// By default, performs semantic analysis to build the new expression.
883 /// Subclasses may override this routine to provide different behavior.
John McCall5ab75172009-11-04 07:28:41 +0000884 OwningExprResult RebuildSizeOfAlignOf(DeclaratorInfo *DInfo,
885 SourceLocation OpLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000886 bool isSizeOf, SourceRange R) {
John McCall5ab75172009-11-04 07:28:41 +0000887 return getSema().CreateSizeOfAlignOfExpr(DInfo, OpLoc, isSizeOf, R);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000888 }
889
Mike Stump1eb44332009-09-09 15:08:12 +0000890 /// \brief Build a new sizeof or alignof expression with an expression
Douglas Gregorb98b1992009-08-11 05:31:07 +0000891 /// argument.
Mike Stump1eb44332009-09-09 15:08:12 +0000892 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000893 /// By default, performs semantic analysis to build the new expression.
894 /// Subclasses may override this routine to provide different behavior.
895 OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
896 bool isSizeOf, SourceRange R) {
Mike Stump1eb44332009-09-09 15:08:12 +0000897 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +0000898 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
899 OpLoc, isSizeOf, R);
900 if (Result.isInvalid())
901 return getSema().ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +0000902
Douglas Gregorb98b1992009-08-11 05:31:07 +0000903 SubExpr.release();
904 return move(Result);
905 }
Mike Stump1eb44332009-09-09 15:08:12 +0000906
Douglas Gregorb98b1992009-08-11 05:31:07 +0000907 /// \brief Build a new array subscript expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000908 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000909 /// By default, performs semantic analysis to build the new expression.
910 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000911 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000912 SourceLocation LBracketLoc,
913 ExprArg RHS,
914 SourceLocation RBracketLoc) {
915 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
Mike Stump1eb44332009-09-09 15:08:12 +0000916 LBracketLoc, move(RHS),
Douglas Gregorb98b1992009-08-11 05:31:07 +0000917 RBracketLoc);
918 }
919
920 /// \brief Build a new call expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000921 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000922 /// By default, performs semantic analysis to build the new expression.
923 /// Subclasses may override this routine to provide different behavior.
924 OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
925 MultiExprArg Args,
926 SourceLocation *CommaLocs,
927 SourceLocation RParenLoc) {
928 return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
929 move(Args), CommaLocs, RParenLoc);
930 }
931
932 /// \brief Build a new member access expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000933 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000934 /// By default, performs semantic analysis to build the new expression.
935 /// Subclasses may override this routine to provide different behavior.
936 OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
Mike Stump1eb44332009-09-09 15:08:12 +0000937 bool isArrow,
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000938 NestedNameSpecifier *Qualifier,
939 SourceRange QualifierRange,
940 SourceLocation MemberLoc,
Douglas Gregor8a4386b2009-11-04 23:20:05 +0000941 NamedDecl *Member,
John McCalld5532b62009-11-23 01:53:49 +0000942 const TemplateArgumentListInfo *ExplicitTemplateArgs,
Douglas Gregor8a4386b2009-11-04 23:20:05 +0000943 NamedDecl *FirstQualifierInScope) {
Anders Carlssond8b285f2009-09-01 04:26:58 +0000944 if (!Member->getDeclName()) {
945 // We have a reference to an unnamed field.
946 assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
Mike Stump1eb44332009-09-09 15:08:12 +0000947
948 MemberExpr *ME =
Anders Carlssond8b285f2009-09-01 04:26:58 +0000949 new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
950 Member, MemberLoc,
951 cast<FieldDecl>(Member)->getType());
952 return getSema().Owned(ME);
953 }
Mike Stump1eb44332009-09-09 15:08:12 +0000954
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000955 CXXScopeSpec SS;
956 if (Qualifier) {
957 SS.setRange(QualifierRange);
958 SS.setScopeRep(Qualifier);
959 }
960
Douglas Gregor017dde52009-08-31 20:00:26 +0000961 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000962 isArrow? tok::arrow : tok::period,
963 MemberLoc,
Douglas Gregor017dde52009-08-31 20:00:26 +0000964 Member->getDeclName(),
Douglas Gregor8a4386b2009-11-04 23:20:05 +0000965 ExplicitTemplateArgs,
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000966 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregor8a4386b2009-11-04 23:20:05 +0000967 &SS,
968 FirstQualifierInScope);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000969 }
Mike Stump1eb44332009-09-09 15:08:12 +0000970
Douglas Gregorb98b1992009-08-11 05:31:07 +0000971 /// \brief Build a new binary operator expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000972 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000973 /// By default, performs semantic analysis to build the new expression.
974 /// Subclasses may override this routine to provide different behavior.
975 OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
976 BinaryOperator::Opcode Opc,
977 ExprArg LHS, ExprArg RHS) {
Douglas Gregor6ca7cfb2009-11-05 00:51:44 +0000978 return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc,
979 LHS.takeAs<Expr>(), RHS.takeAs<Expr>());
Douglas Gregorb98b1992009-08-11 05:31:07 +0000980 }
981
982 /// \brief Build a new conditional operator expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000983 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000984 /// By default, performs semantic analysis to build the new expression.
985 /// Subclasses may override this routine to provide different behavior.
986 OwningExprResult RebuildConditionalOperator(ExprArg Cond,
987 SourceLocation QuestionLoc,
988 ExprArg LHS,
989 SourceLocation ColonLoc,
990 ExprArg RHS) {
Mike Stump1eb44332009-09-09 15:08:12 +0000991 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
Douglas Gregorb98b1992009-08-11 05:31:07 +0000992 move(LHS), move(RHS));
993 }
994
995 /// \brief Build a new implicit cast expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000996 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000997 /// By default, builds a new implicit cast without any semantic analysis.
998 /// Subclasses may override this routine to provide different behavior.
999 OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
1000 ExprArg SubExpr, bool isLvalue) {
1001 ImplicitCastExpr *ICE
Mike Stump1eb44332009-09-09 15:08:12 +00001002 = new (getSema().Context) ImplicitCastExpr(T, Kind,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001003 (Expr *)SubExpr.release(),
1004 isLvalue);
1005 return getSema().Owned(ICE);
1006 }
1007
1008 /// \brief Build a new C-style cast expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001009 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001010 /// By default, performs semantic analysis to build the new expression.
1011 /// Subclasses may override this routine to provide different behavior.
1012 OwningExprResult RebuildCStyleCaseExpr(SourceLocation LParenLoc,
1013 QualType ExplicitTy,
1014 SourceLocation RParenLoc,
1015 ExprArg SubExpr) {
1016 return getSema().ActOnCastExpr(/*Scope=*/0,
1017 LParenLoc,
1018 ExplicitTy.getAsOpaquePtr(),
1019 RParenLoc,
1020 move(SubExpr));
1021 }
Mike Stump1eb44332009-09-09 15:08:12 +00001022
Douglas Gregorb98b1992009-08-11 05:31:07 +00001023 /// \brief Build a new compound literal expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001024 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001025 /// By default, performs semantic analysis to build the new expression.
1026 /// Subclasses may override this routine to provide different behavior.
1027 OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
1028 QualType T,
1029 SourceLocation RParenLoc,
1030 ExprArg Init) {
1031 return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
1032 RParenLoc, move(Init));
1033 }
Mike Stump1eb44332009-09-09 15:08:12 +00001034
Douglas Gregorb98b1992009-08-11 05:31:07 +00001035 /// \brief Build a new extended vector element access expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001036 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001037 /// By default, performs semantic analysis to build the new expression.
1038 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001039 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001040 SourceLocation OpLoc,
1041 SourceLocation AccessorLoc,
1042 IdentifierInfo &Accessor) {
Douglas Gregor2d1c2142009-11-03 19:44:04 +00001043 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001044 tok::period, AccessorLoc,
Douglas Gregor2d1c2142009-11-03 19:44:04 +00001045 DeclarationName(&Accessor),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001046 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
1047 }
Mike Stump1eb44332009-09-09 15:08:12 +00001048
Douglas Gregorb98b1992009-08-11 05:31:07 +00001049 /// \brief Build a new initializer list expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001050 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001051 /// By default, performs semantic analysis to build the new expression.
1052 /// Subclasses may override this routine to provide different behavior.
1053 OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
1054 MultiExprArg Inits,
Douglas Gregore48319a2009-11-09 17:16:50 +00001055 SourceLocation RBraceLoc,
1056 QualType ResultTy) {
1057 OwningExprResult Result
1058 = SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
1059 if (Result.isInvalid() || ResultTy->isDependentType())
1060 return move(Result);
1061
1062 // Patch in the result type we were given, which may have been computed
1063 // when the initial InitListExpr was built.
1064 InitListExpr *ILE = cast<InitListExpr>((Expr *)Result.get());
1065 ILE->setType(ResultTy);
1066 return move(Result);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001067 }
Mike Stump1eb44332009-09-09 15:08:12 +00001068
Douglas Gregorb98b1992009-08-11 05:31:07 +00001069 /// \brief Build a new designated initializer expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001070 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001071 /// By default, performs semantic analysis to build the new expression.
1072 /// Subclasses may override this routine to provide different behavior.
1073 OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
1074 MultiExprArg ArrayExprs,
1075 SourceLocation EqualOrColonLoc,
1076 bool GNUSyntax,
1077 ExprArg Init) {
1078 OwningExprResult Result
1079 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1080 move(Init));
1081 if (Result.isInvalid())
1082 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00001083
Douglas Gregorb98b1992009-08-11 05:31:07 +00001084 ArrayExprs.release();
1085 return move(Result);
1086 }
Mike Stump1eb44332009-09-09 15:08:12 +00001087
Douglas Gregorb98b1992009-08-11 05:31:07 +00001088 /// \brief Build a new value-initialized expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001089 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001090 /// By default, builds the implicit value initialization without performing
1091 /// any semantic analysis. Subclasses may override this routine to provide
1092 /// different behavior.
1093 OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
1094 return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1095 }
Mike Stump1eb44332009-09-09 15:08:12 +00001096
Douglas Gregorb98b1992009-08-11 05:31:07 +00001097 /// \brief Build a new \c va_arg expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001098 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001099 /// By default, performs semantic analysis to build the new expression.
1100 /// Subclasses may override this routine to provide different behavior.
1101 OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
1102 QualType T, SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001103 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001104 RParenLoc);
1105 }
1106
1107 /// \brief Build a new expression list in parentheses.
Mike Stump1eb44332009-09-09 15:08:12 +00001108 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001109 /// By default, performs semantic analysis to build the new expression.
1110 /// Subclasses may override this routine to provide different behavior.
1111 OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1112 MultiExprArg SubExprs,
1113 SourceLocation RParenLoc) {
1114 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
1115 }
Mike Stump1eb44332009-09-09 15:08:12 +00001116
Douglas Gregorb98b1992009-08-11 05:31:07 +00001117 /// \brief Build a new address-of-label expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001118 ///
1119 /// By default, performs semantic analysis, using the name of the label
Douglas Gregorb98b1992009-08-11 05:31:07 +00001120 /// rather than attempting to map the label statement itself.
1121 /// Subclasses may override this routine to provide different behavior.
1122 OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1123 SourceLocation LabelLoc,
1124 LabelStmt *Label) {
1125 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
1126 }
Mike Stump1eb44332009-09-09 15:08:12 +00001127
Douglas Gregorb98b1992009-08-11 05:31:07 +00001128 /// \brief Build a new GNU statement expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001129 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001130 /// By default, performs semantic analysis to build the new expression.
1131 /// Subclasses may override this routine to provide different behavior.
1132 OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
1133 StmtArg SubStmt,
1134 SourceLocation RParenLoc) {
1135 return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
1136 }
Mike Stump1eb44332009-09-09 15:08:12 +00001137
Douglas Gregorb98b1992009-08-11 05:31:07 +00001138 /// \brief Build a new __builtin_types_compatible_p expression.
1139 ///
1140 /// By default, performs semantic analysis to build the new expression.
1141 /// Subclasses may override this routine to provide different behavior.
1142 OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
1143 QualType T1, QualType T2,
1144 SourceLocation RParenLoc) {
1145 return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
1146 T1.getAsOpaquePtr(),
1147 T2.getAsOpaquePtr(),
1148 RParenLoc);
1149 }
Mike Stump1eb44332009-09-09 15:08:12 +00001150
Douglas Gregorb98b1992009-08-11 05:31:07 +00001151 /// \brief Build a new __builtin_choose_expr expression.
1152 ///
1153 /// By default, performs semantic analysis to build the new expression.
1154 /// Subclasses may override this routine to provide different behavior.
1155 OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1156 ExprArg Cond, ExprArg LHS, ExprArg RHS,
1157 SourceLocation RParenLoc) {
1158 return SemaRef.ActOnChooseExpr(BuiltinLoc,
1159 move(Cond), move(LHS), move(RHS),
1160 RParenLoc);
1161 }
Mike Stump1eb44332009-09-09 15:08:12 +00001162
Douglas Gregorb98b1992009-08-11 05:31:07 +00001163 /// \brief Build a new overloaded operator call expression.
1164 ///
1165 /// By default, performs semantic analysis to build the new expression.
1166 /// The semantic analysis provides the behavior of template instantiation,
1167 /// copying with transformations that turn what looks like an overloaded
Mike Stump1eb44332009-09-09 15:08:12 +00001168 /// operator call into a use of a builtin operator, performing
Douglas Gregorb98b1992009-08-11 05:31:07 +00001169 /// argument-dependent lookup, etc. Subclasses may override this routine to
1170 /// provide different behavior.
1171 OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1172 SourceLocation OpLoc,
1173 ExprArg Callee,
1174 ExprArg First,
1175 ExprArg Second);
Mike Stump1eb44332009-09-09 15:08:12 +00001176
1177 /// \brief Build a new C++ "named" cast expression, such as static_cast or
Douglas Gregorb98b1992009-08-11 05:31:07 +00001178 /// reinterpret_cast.
1179 ///
1180 /// By default, this routine dispatches to one of the more-specific routines
Mike Stump1eb44332009-09-09 15:08:12 +00001181 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
Douglas Gregorb98b1992009-08-11 05:31:07 +00001182 /// Subclasses may override this routine to provide different behavior.
1183 OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1184 Stmt::StmtClass Class,
1185 SourceLocation LAngleLoc,
1186 QualType T,
1187 SourceLocation RAngleLoc,
1188 SourceLocation LParenLoc,
1189 ExprArg SubExpr,
1190 SourceLocation RParenLoc) {
1191 switch (Class) {
1192 case Stmt::CXXStaticCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001193 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1194 RAngleLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001195 move(SubExpr), RParenLoc);
1196
1197 case Stmt::CXXDynamicCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001198 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
1199 RAngleLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001200 move(SubExpr), RParenLoc);
Mike Stump1eb44332009-09-09 15:08:12 +00001201
Douglas Gregorb98b1992009-08-11 05:31:07 +00001202 case Stmt::CXXReinterpretCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001203 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1204 RAngleLoc, LParenLoc,
1205 move(SubExpr),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001206 RParenLoc);
Mike Stump1eb44332009-09-09 15:08:12 +00001207
Douglas Gregorb98b1992009-08-11 05:31:07 +00001208 case Stmt::CXXConstCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001209 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1210 RAngleLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001211 move(SubExpr), RParenLoc);
Mike Stump1eb44332009-09-09 15:08:12 +00001212
Douglas Gregorb98b1992009-08-11 05:31:07 +00001213 default:
1214 assert(false && "Invalid C++ named cast");
1215 break;
1216 }
Mike Stump1eb44332009-09-09 15:08:12 +00001217
Douglas Gregorb98b1992009-08-11 05:31:07 +00001218 return getSema().ExprError();
1219 }
Mike Stump1eb44332009-09-09 15:08:12 +00001220
Douglas Gregorb98b1992009-08-11 05:31:07 +00001221 /// \brief Build a new C++ static_cast expression.
1222 ///
1223 /// By default, performs semantic analysis to build the new expression.
1224 /// Subclasses may override this routine to provide different behavior.
1225 OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1226 SourceLocation LAngleLoc,
1227 QualType T,
1228 SourceLocation RAngleLoc,
1229 SourceLocation LParenLoc,
1230 ExprArg SubExpr,
1231 SourceLocation RParenLoc) {
1232 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
Mike Stump1eb44332009-09-09 15:08:12 +00001233 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001234 LParenLoc, move(SubExpr), RParenLoc);
1235 }
1236
1237 /// \brief Build a new C++ dynamic_cast expression.
1238 ///
1239 /// By default, performs semantic analysis to build the new expression.
1240 /// Subclasses may override this routine to provide different behavior.
1241 OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1242 SourceLocation LAngleLoc,
1243 QualType T,
1244 SourceLocation RAngleLoc,
1245 SourceLocation LParenLoc,
1246 ExprArg SubExpr,
1247 SourceLocation RParenLoc) {
1248 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
Mike Stump1eb44332009-09-09 15:08:12 +00001249 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001250 LParenLoc, move(SubExpr), RParenLoc);
1251 }
1252
1253 /// \brief Build a new C++ reinterpret_cast expression.
1254 ///
1255 /// By default, performs semantic analysis to build the new expression.
1256 /// Subclasses may override this routine to provide different behavior.
1257 OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1258 SourceLocation LAngleLoc,
1259 QualType T,
1260 SourceLocation RAngleLoc,
1261 SourceLocation LParenLoc,
1262 ExprArg SubExpr,
1263 SourceLocation RParenLoc) {
1264 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1265 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1266 LParenLoc, move(SubExpr), RParenLoc);
1267 }
1268
1269 /// \brief Build a new C++ const_cast expression.
1270 ///
1271 /// By default, performs semantic analysis to build the new expression.
1272 /// Subclasses may override this routine to provide different behavior.
1273 OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1274 SourceLocation LAngleLoc,
1275 QualType T,
1276 SourceLocation RAngleLoc,
1277 SourceLocation LParenLoc,
1278 ExprArg SubExpr,
1279 SourceLocation RParenLoc) {
1280 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
Mike Stump1eb44332009-09-09 15:08:12 +00001281 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001282 LParenLoc, move(SubExpr), RParenLoc);
1283 }
Mike Stump1eb44332009-09-09 15:08:12 +00001284
Douglas Gregorb98b1992009-08-11 05:31:07 +00001285 /// \brief Build a new C++ functional-style cast expression.
1286 ///
1287 /// By default, performs semantic analysis to build the new expression.
1288 /// Subclasses may override this routine to provide different behavior.
1289 OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
1290 QualType T,
1291 SourceLocation LParenLoc,
1292 ExprArg SubExpr,
1293 SourceLocation RParenLoc) {
Chris Lattner88650c32009-08-24 05:19:01 +00001294 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregorb98b1992009-08-11 05:31:07 +00001295 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1296 T.getAsOpaquePtr(),
1297 LParenLoc,
Chris Lattner88650c32009-08-24 05:19:01 +00001298 Sema::MultiExprArg(getSema(), &Sub, 1),
Mike Stump1eb44332009-09-09 15:08:12 +00001299 /*CommaLocs=*/0,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001300 RParenLoc);
1301 }
Mike Stump1eb44332009-09-09 15:08:12 +00001302
Douglas Gregorb98b1992009-08-11 05:31:07 +00001303 /// \brief Build a new C++ typeid(type) expression.
1304 ///
1305 /// By default, performs semantic analysis to build the new expression.
1306 /// Subclasses may override this routine to provide different behavior.
1307 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1308 SourceLocation LParenLoc,
1309 QualType T,
1310 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001311 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001312 T.getAsOpaquePtr(), RParenLoc);
1313 }
Mike Stump1eb44332009-09-09 15:08:12 +00001314
Douglas Gregorb98b1992009-08-11 05:31:07 +00001315 /// \brief Build a new C++ typeid(expr) expression.
1316 ///
1317 /// By default, performs semantic analysis to build the new expression.
1318 /// Subclasses may override this routine to provide different behavior.
1319 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1320 SourceLocation LParenLoc,
1321 ExprArg Operand,
1322 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001323 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +00001324 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1325 RParenLoc);
1326 if (Result.isInvalid())
1327 return getSema().ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00001328
Douglas Gregorb98b1992009-08-11 05:31:07 +00001329 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1330 return move(Result);
Mike Stump1eb44332009-09-09 15:08:12 +00001331 }
1332
Douglas Gregorb98b1992009-08-11 05:31:07 +00001333 /// \brief Build a new C++ "this" expression.
1334 ///
1335 /// By default, builds a new "this" expression without performing any
Mike Stump1eb44332009-09-09 15:08:12 +00001336 /// semantic analysis. Subclasses may override this routine to provide
Douglas Gregorb98b1992009-08-11 05:31:07 +00001337 /// different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001338 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001339 QualType ThisType) {
1340 return getSema().Owned(
1341 new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
1342 }
1343
1344 /// \brief Build a new C++ throw expression.
1345 ///
1346 /// By default, performs semantic analysis to build the new expression.
1347 /// Subclasses may override this routine to provide different behavior.
1348 OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
1349 return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
1350 }
1351
1352 /// \brief Build a new C++ default-argument expression.
1353 ///
1354 /// By default, builds a new default-argument expression, which does not
1355 /// require any semantic analysis. Subclasses may override this routine to
1356 /// provide different behavior.
1357 OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
Anders Carlssonf1480ee2009-08-14 18:30:22 +00001358 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001359 }
1360
1361 /// \brief Build a new C++ zero-initialization expression.
1362 ///
1363 /// By default, performs semantic analysis to build the new expression.
1364 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001365 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001366 SourceLocation LParenLoc,
1367 QualType T,
1368 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001369 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1370 T.getAsOpaquePtr(), LParenLoc,
1371 MultiExprArg(getSema(), 0, 0),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001372 0, RParenLoc);
1373 }
Mike Stump1eb44332009-09-09 15:08:12 +00001374
Douglas Gregorb98b1992009-08-11 05:31:07 +00001375 /// \brief Build a new C++ conditional declaration expression.
1376 ///
1377 /// By default, performs semantic analysis to build the new expression.
1378 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001379 OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001380 SourceLocation EqLoc,
1381 VarDecl *Var) {
1382 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(StartLoc,
1383 EqLoc,
1384 Var));
1385 }
Mike Stump1eb44332009-09-09 15:08:12 +00001386
Douglas Gregorb98b1992009-08-11 05:31:07 +00001387 /// \brief Build a new C++ "new" expression.
1388 ///
1389 /// By default, performs semantic analysis to build the new expression.
1390 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001391 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001392 bool UseGlobal,
1393 SourceLocation PlacementLParen,
1394 MultiExprArg PlacementArgs,
1395 SourceLocation PlacementRParen,
Mike Stump1eb44332009-09-09 15:08:12 +00001396 bool ParenTypeId,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001397 QualType AllocType,
1398 SourceLocation TypeLoc,
1399 SourceRange TypeRange,
1400 ExprArg ArraySize,
1401 SourceLocation ConstructorLParen,
1402 MultiExprArg ConstructorArgs,
1403 SourceLocation ConstructorRParen) {
Mike Stump1eb44332009-09-09 15:08:12 +00001404 return getSema().BuildCXXNew(StartLoc, UseGlobal,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001405 PlacementLParen,
1406 move(PlacementArgs),
1407 PlacementRParen,
1408 ParenTypeId,
1409 AllocType,
1410 TypeLoc,
1411 TypeRange,
1412 move(ArraySize),
1413 ConstructorLParen,
1414 move(ConstructorArgs),
1415 ConstructorRParen);
1416 }
Mike Stump1eb44332009-09-09 15:08:12 +00001417
Douglas Gregorb98b1992009-08-11 05:31:07 +00001418 /// \brief Build a new C++ "delete" expression.
1419 ///
1420 /// By default, performs semantic analysis to build the new expression.
1421 /// Subclasses may override this routine to provide different behavior.
1422 OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
1423 bool IsGlobalDelete,
1424 bool IsArrayForm,
1425 ExprArg Operand) {
1426 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
1427 move(Operand));
1428 }
Mike Stump1eb44332009-09-09 15:08:12 +00001429
Douglas Gregorb98b1992009-08-11 05:31:07 +00001430 /// \brief Build a new unary type trait expression.
1431 ///
1432 /// By default, performs semantic analysis to build the new expression.
1433 /// Subclasses may override this routine to provide different behavior.
1434 OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
1435 SourceLocation StartLoc,
1436 SourceLocation LParenLoc,
1437 QualType T,
1438 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001439 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001440 T.getAsOpaquePtr(), RParenLoc);
1441 }
1442
Mike Stump1eb44332009-09-09 15:08:12 +00001443 /// \brief Build a new (previously unresolved) declaration reference
Douglas Gregorb98b1992009-08-11 05:31:07 +00001444 /// expression.
1445 ///
1446 /// By default, performs semantic analysis to build the new expression.
1447 /// Subclasses may override this routine to provide different behavior.
John McCall865d4472009-11-19 22:55:06 +00001448 OwningExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifier *NNS,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001449 SourceRange QualifierRange,
1450 DeclarationName Name,
1451 SourceLocation Location,
1452 bool IsAddressOfOperand) {
1453 CXXScopeSpec SS;
1454 SS.setRange(QualifierRange);
1455 SS.setScopeRep(NNS);
Mike Stump1eb44332009-09-09 15:08:12 +00001456 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001457 Location,
1458 Name,
1459 /*Trailing lparen=*/false,
1460 &SS,
1461 IsAddressOfOperand);
1462 }
1463
1464 /// \brief Build a new template-id expression.
1465 ///
1466 /// By default, performs semantic analysis to build the new expression.
1467 /// Subclasses may override this routine to provide different behavior.
Douglas Gregorf17bb742009-10-22 17:20:55 +00001468 OwningExprResult RebuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
1469 SourceRange QualifierRange,
1470 TemplateName Template,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001471 SourceLocation TemplateLoc,
John McCalld5532b62009-11-23 01:53:49 +00001472 const TemplateArgumentListInfo &TemplateArgs) {
Douglas Gregorf17bb742009-10-22 17:20:55 +00001473 return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
John McCalld5532b62009-11-23 01:53:49 +00001474 Template, TemplateLoc, TemplateArgs);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001475 }
1476
1477 /// \brief Build a new object-construction expression.
1478 ///
1479 /// By default, performs semantic analysis to build the new expression.
1480 /// Subclasses may override this routine to provide different behavior.
1481 OwningExprResult RebuildCXXConstructExpr(QualType T,
1482 CXXConstructorDecl *Constructor,
1483 bool IsElidable,
1484 MultiExprArg Args) {
Anders Carlssonec8e5ea2009-09-05 07:40:38 +00001485 return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/
1486 SourceLocation(),
1487 T, Constructor, IsElidable,
Anders Carlssonf47511a2009-09-07 22:23:31 +00001488 move(Args));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001489 }
1490
1491 /// \brief Build a new object-construction expression.
1492 ///
1493 /// By default, performs semantic analysis to build the new expression.
1494 /// Subclasses may override this routine to provide different behavior.
1495 OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
1496 QualType T,
1497 SourceLocation LParenLoc,
1498 MultiExprArg Args,
1499 SourceLocation *Commas,
1500 SourceLocation RParenLoc) {
1501 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
1502 T.getAsOpaquePtr(),
1503 LParenLoc,
1504 move(Args),
1505 Commas,
1506 RParenLoc);
1507 }
1508
1509 /// \brief Build a new object-construction expression.
1510 ///
1511 /// By default, performs semantic analysis to build the new expression.
1512 /// Subclasses may override this routine to provide different behavior.
1513 OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
1514 QualType T,
1515 SourceLocation LParenLoc,
1516 MultiExprArg Args,
1517 SourceLocation *Commas,
1518 SourceLocation RParenLoc) {
1519 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
1520 /*FIXME*/LParenLoc),
1521 T.getAsOpaquePtr(),
1522 LParenLoc,
1523 move(Args),
1524 Commas,
1525 RParenLoc);
1526 }
Mike Stump1eb44332009-09-09 15:08:12 +00001527
Douglas Gregorb98b1992009-08-11 05:31:07 +00001528 /// \brief Build a new member reference expression.
1529 ///
1530 /// By default, performs semantic analysis to build the new expression.
1531 /// Subclasses may override this routine to provide different behavior.
John McCall865d4472009-11-19 22:55:06 +00001532 OwningExprResult RebuildCXXDependentScopeMemberExpr(ExprArg BaseE,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001533 bool IsArrow,
1534 SourceLocation OperatorLoc,
Douglas Gregora38c6872009-09-03 16:14:30 +00001535 NestedNameSpecifier *Qualifier,
1536 SourceRange QualifierRange,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001537 DeclarationName Name,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001538 SourceLocation MemberLoc,
1539 NamedDecl *FirstQualifierInScope) {
Douglas Gregor0dec56d2009-08-11 15:56:57 +00001540 OwningExprResult Base = move(BaseE);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001541 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregora38c6872009-09-03 16:14:30 +00001542
Douglas Gregorb98b1992009-08-11 05:31:07 +00001543 CXXScopeSpec SS;
Douglas Gregora38c6872009-09-03 16:14:30 +00001544 SS.setRange(QualifierRange);
1545 SS.setScopeRep(Qualifier);
Mike Stump1eb44332009-09-09 15:08:12 +00001546
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001547 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001548 move(Base), OperatorLoc, OpKind,
Douglas Gregor017dde52009-08-31 20:00:26 +00001549 MemberLoc,
1550 Name,
Douglas Gregora38c6872009-09-03 16:14:30 +00001551 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregorc68afe22009-09-03 21:38:09 +00001552 &SS,
1553 FirstQualifierInScope);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001554 }
1555
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001556 /// \brief Build a new member reference expression with explicit template
1557 /// arguments.
1558 ///
1559 /// By default, performs semantic analysis to build the new expression.
1560 /// Subclasses may override this routine to provide different behavior.
John McCall865d4472009-11-19 22:55:06 +00001561 OwningExprResult RebuildCXXDependentScopeMemberExpr(ExprArg BaseE,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001562 bool IsArrow,
1563 SourceLocation OperatorLoc,
1564 NestedNameSpecifier *Qualifier,
1565 SourceRange QualifierRange,
1566 TemplateName Template,
1567 SourceLocation TemplateNameLoc,
1568 NamedDecl *FirstQualifierInScope,
John McCalld5532b62009-11-23 01:53:49 +00001569 const TemplateArgumentListInfo &TemplateArgs) {
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001570 OwningExprResult Base = move(BaseE);
1571 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Mike Stump1eb44332009-09-09 15:08:12 +00001572
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001573 CXXScopeSpec SS;
1574 SS.setRange(QualifierRange);
1575 SS.setScopeRep(Qualifier);
Mike Stump1eb44332009-09-09 15:08:12 +00001576
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001577 // FIXME: We're going to end up looking up the template based on its name,
Douglas Gregor2d1c2142009-11-03 19:44:04 +00001578 // twice! Also, duplicates part of Sema::BuildMemberAccessExpr.
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001579 DeclarationName Name;
1580 if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
1581 Name = ActualTemplate->getDeclName();
Mike Stump1eb44332009-09-09 15:08:12 +00001582 else if (OverloadedFunctionDecl *Ovl
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001583 = Template.getAsOverloadedFunctionDecl())
1584 Name = Ovl->getDeclName();
Douglas Gregorca1bdd72009-11-04 00:56:37 +00001585 else {
1586 DependentTemplateName *DTN = Template.getAsDependentTemplateName();
1587 if (DTN->isIdentifier())
1588 Name = DTN->getIdentifier();
1589 else
1590 Name = SemaRef.Context.DeclarationNames.getCXXOperatorName(
1591 DTN->getOperator());
1592 }
John McCalld5532b62009-11-23 01:53:49 +00001593 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
1594 OperatorLoc, OpKind,
1595 TemplateNameLoc, Name,
1596 &TemplateArgs,
1597 Sema::DeclPtrTy(), &SS);
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001598 }
Mike Stump1eb44332009-09-09 15:08:12 +00001599
Douglas Gregorb98b1992009-08-11 05:31:07 +00001600 /// \brief Build a new Objective-C @encode expression.
1601 ///
1602 /// By default, performs semantic analysis to build the new expression.
1603 /// Subclasses may override this routine to provide different behavior.
1604 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1605 QualType T,
1606 SourceLocation RParenLoc) {
1607 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1608 RParenLoc));
Mike Stump1eb44332009-09-09 15:08:12 +00001609 }
Douglas Gregorb98b1992009-08-11 05:31:07 +00001610
1611 /// \brief Build a new Objective-C protocol expression.
1612 ///
1613 /// By default, performs semantic analysis to build the new expression.
1614 /// Subclasses may override this routine to provide different behavior.
1615 OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1616 SourceLocation AtLoc,
1617 SourceLocation ProtoLoc,
1618 SourceLocation LParenLoc,
1619 SourceLocation RParenLoc) {
1620 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1621 Protocol->getIdentifier(),
1622 AtLoc,
1623 ProtoLoc,
1624 LParenLoc,
Mike Stump1eb44332009-09-09 15:08:12 +00001625 RParenLoc));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001626 }
Mike Stump1eb44332009-09-09 15:08:12 +00001627
Douglas Gregorb98b1992009-08-11 05:31:07 +00001628 /// \brief Build a new shuffle vector expression.
1629 ///
1630 /// By default, performs semantic analysis to build the new expression.
1631 /// Subclasses may override this routine to provide different behavior.
1632 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1633 MultiExprArg SubExprs,
1634 SourceLocation RParenLoc) {
1635 // Find the declaration for __builtin_shufflevector
Mike Stump1eb44332009-09-09 15:08:12 +00001636 const IdentifierInfo &Name
Douglas Gregorb98b1992009-08-11 05:31:07 +00001637 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1638 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1639 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1640 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
Mike Stump1eb44332009-09-09 15:08:12 +00001641
Douglas Gregorb98b1992009-08-11 05:31:07 +00001642 // Build a reference to the __builtin_shufflevector builtin
1643 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Mike Stump1eb44332009-09-09 15:08:12 +00001644 Expr *Callee
Douglas Gregorb98b1992009-08-11 05:31:07 +00001645 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
Douglas Gregor0da76df2009-11-23 11:41:28 +00001646 BuiltinLoc);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001647 SemaRef.UsualUnaryConversions(Callee);
Mike Stump1eb44332009-09-09 15:08:12 +00001648
1649 // Build the CallExpr
Douglas Gregorb98b1992009-08-11 05:31:07 +00001650 unsigned NumSubExprs = SubExprs.size();
1651 Expr **Subs = (Expr **)SubExprs.release();
1652 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1653 Subs, NumSubExprs,
1654 Builtin->getResultType(),
1655 RParenLoc);
1656 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
Mike Stump1eb44332009-09-09 15:08:12 +00001657
Douglas Gregorb98b1992009-08-11 05:31:07 +00001658 // Type-check the __builtin_shufflevector expression.
1659 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1660 if (Result.isInvalid())
1661 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00001662
Douglas Gregorb98b1992009-08-11 05:31:07 +00001663 OwnedCall.release();
Mike Stump1eb44332009-09-09 15:08:12 +00001664 return move(Result);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001665 }
Douglas Gregor577f75a2009-08-04 16:50:30 +00001666};
Douglas Gregorb98b1992009-08-11 05:31:07 +00001667
Douglas Gregor43959a92009-08-20 07:17:43 +00001668template<typename Derived>
1669Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1670 if (!S)
1671 return SemaRef.Owned(S);
Mike Stump1eb44332009-09-09 15:08:12 +00001672
Douglas Gregor43959a92009-08-20 07:17:43 +00001673 switch (S->getStmtClass()) {
1674 case Stmt::NoStmtClass: break;
Mike Stump1eb44332009-09-09 15:08:12 +00001675
Douglas Gregor43959a92009-08-20 07:17:43 +00001676 // Transform individual statement nodes
1677#define STMT(Node, Parent) \
1678 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1679#define EXPR(Node, Parent)
1680#include "clang/AST/StmtNodes.def"
Mike Stump1eb44332009-09-09 15:08:12 +00001681
Douglas Gregor43959a92009-08-20 07:17:43 +00001682 // Transform expressions by calling TransformExpr.
1683#define STMT(Node, Parent)
1684#define EXPR(Node, Parent) case Stmt::Node##Class:
1685#include "clang/AST/StmtNodes.def"
1686 {
1687 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1688 if (E.isInvalid())
1689 return getSema().StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00001690
Douglas Gregorafe7ec22009-11-13 18:34:26 +00001691 return getSema().ActOnExprStmt(getSema().FullExpr(E));
Douglas Gregor43959a92009-08-20 07:17:43 +00001692 }
Mike Stump1eb44332009-09-09 15:08:12 +00001693 }
1694
Douglas Gregor43959a92009-08-20 07:17:43 +00001695 return SemaRef.Owned(S->Retain());
1696}
Mike Stump1eb44332009-09-09 15:08:12 +00001697
1698
Douglas Gregor670444e2009-08-04 22:27:00 +00001699template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00001700Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1701 bool isAddressOfOperand) {
1702 if (!E)
1703 return SemaRef.Owned(E);
1704
1705 switch (E->getStmtClass()) {
1706 case Stmt::NoStmtClass: break;
1707#define STMT(Node, Parent) case Stmt::Node##Class: break;
1708#define EXPR(Node, Parent) \
Douglas Gregorc86a6e92009-11-04 07:01:15 +00001709 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E), \
1710 isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001711#include "clang/AST/StmtNodes.def"
Mike Stump1eb44332009-09-09 15:08:12 +00001712 }
1713
Douglas Gregorb98b1992009-08-11 05:31:07 +00001714 return SemaRef.Owned(E->Retain());
Douglas Gregor657c1ac2009-08-06 22:17:10 +00001715}
1716
1717template<typename Derived>
Douglas Gregordcee1a12009-08-06 05:28:30 +00001718NestedNameSpecifier *
1719TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregora38c6872009-09-03 16:14:30 +00001720 SourceRange Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001721 QualType ObjectType,
1722 NamedDecl *FirstQualifierInScope) {
Douglas Gregor0979c802009-08-31 21:41:48 +00001723 if (!NNS)
1724 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001725
Douglas Gregor43959a92009-08-20 07:17:43 +00001726 // Transform the prefix of this nested name specifier.
Douglas Gregordcee1a12009-08-06 05:28:30 +00001727 NestedNameSpecifier *Prefix = NNS->getPrefix();
1728 if (Prefix) {
Mike Stump1eb44332009-09-09 15:08:12 +00001729 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001730 ObjectType,
1731 FirstQualifierInScope);
Douglas Gregordcee1a12009-08-06 05:28:30 +00001732 if (!Prefix)
1733 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001734
1735 // Clear out the object type and the first qualifier in scope; they only
Douglas Gregorc68afe22009-09-03 21:38:09 +00001736 // apply to the first element in the nested-name-specifier.
Douglas Gregora38c6872009-09-03 16:14:30 +00001737 ObjectType = QualType();
Douglas Gregorc68afe22009-09-03 21:38:09 +00001738 FirstQualifierInScope = 0;
Douglas Gregordcee1a12009-08-06 05:28:30 +00001739 }
Mike Stump1eb44332009-09-09 15:08:12 +00001740
Douglas Gregordcee1a12009-08-06 05:28:30 +00001741 switch (NNS->getKind()) {
1742 case NestedNameSpecifier::Identifier:
Mike Stump1eb44332009-09-09 15:08:12 +00001743 assert((Prefix || !ObjectType.isNull()) &&
Douglas Gregora38c6872009-09-03 16:14:30 +00001744 "Identifier nested-name-specifier with no prefix or object type");
1745 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
1746 ObjectType.isNull())
Douglas Gregordcee1a12009-08-06 05:28:30 +00001747 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001748
1749 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregora38c6872009-09-03 16:14:30 +00001750 *NNS->getAsIdentifier(),
Douglas Gregorc68afe22009-09-03 21:38:09 +00001751 ObjectType,
1752 FirstQualifierInScope);
Mike Stump1eb44332009-09-09 15:08:12 +00001753
Douglas Gregordcee1a12009-08-06 05:28:30 +00001754 case NestedNameSpecifier::Namespace: {
Mike Stump1eb44332009-09-09 15:08:12 +00001755 NamespaceDecl *NS
Douglas Gregordcee1a12009-08-06 05:28:30 +00001756 = cast_or_null<NamespaceDecl>(
1757 getDerived().TransformDecl(NNS->getAsNamespace()));
Mike Stump1eb44332009-09-09 15:08:12 +00001758 if (!getDerived().AlwaysRebuild() &&
Douglas Gregordcee1a12009-08-06 05:28:30 +00001759 Prefix == NNS->getPrefix() &&
1760 NS == NNS->getAsNamespace())
1761 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001762
Douglas Gregordcee1a12009-08-06 05:28:30 +00001763 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1764 }
Mike Stump1eb44332009-09-09 15:08:12 +00001765
Douglas Gregordcee1a12009-08-06 05:28:30 +00001766 case NestedNameSpecifier::Global:
1767 // There is no meaningful transformation that one could perform on the
1768 // global scope.
1769 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001770
Douglas Gregordcee1a12009-08-06 05:28:30 +00001771 case NestedNameSpecifier::TypeSpecWithTemplate:
1772 case NestedNameSpecifier::TypeSpec: {
Douglas Gregorfbf2c942009-10-29 22:21:39 +00001773 TemporaryBase Rebase(*this, Range.getBegin(), DeclarationName());
Douglas Gregordcee1a12009-08-06 05:28:30 +00001774 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregord1067e52009-08-06 06:41:21 +00001775 if (T.isNull())
1776 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001777
Douglas Gregordcee1a12009-08-06 05:28:30 +00001778 if (!getDerived().AlwaysRebuild() &&
1779 Prefix == NNS->getPrefix() &&
1780 T == QualType(NNS->getAsType(), 0))
1781 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001782
1783 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1784 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
Douglas Gregordcee1a12009-08-06 05:28:30 +00001785 T);
1786 }
1787 }
Mike Stump1eb44332009-09-09 15:08:12 +00001788
Douglas Gregordcee1a12009-08-06 05:28:30 +00001789 // Required to silence a GCC warning
Mike Stump1eb44332009-09-09 15:08:12 +00001790 return 0;
Douglas Gregordcee1a12009-08-06 05:28:30 +00001791}
1792
1793template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00001794DeclarationName
Douglas Gregor81499bb2009-09-03 22:13:48 +00001795TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
Douglas Gregordd62b152009-10-19 22:04:39 +00001796 SourceLocation Loc,
1797 QualType ObjectType) {
Douglas Gregor81499bb2009-09-03 22:13:48 +00001798 if (!Name)
1799 return Name;
1800
1801 switch (Name.getNameKind()) {
1802 case DeclarationName::Identifier:
1803 case DeclarationName::ObjCZeroArgSelector:
1804 case DeclarationName::ObjCOneArgSelector:
1805 case DeclarationName::ObjCMultiArgSelector:
1806 case DeclarationName::CXXOperatorName:
1807 case DeclarationName::CXXUsingDirective:
1808 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001809
Douglas Gregor81499bb2009-09-03 22:13:48 +00001810 case DeclarationName::CXXConstructorName:
1811 case DeclarationName::CXXDestructorName:
1812 case DeclarationName::CXXConversionFunctionName: {
1813 TemporaryBase Rebase(*this, Loc, Name);
Douglas Gregordd62b152009-10-19 22:04:39 +00001814 QualType T;
1815 if (!ObjectType.isNull() &&
1816 isa<TemplateSpecializationType>(Name.getCXXNameType())) {
1817 TemplateSpecializationType *SpecType
1818 = cast<TemplateSpecializationType>(Name.getCXXNameType());
1819 T = TransformTemplateSpecializationType(SpecType, ObjectType);
1820 } else
1821 T = getDerived().TransformType(Name.getCXXNameType());
Douglas Gregor81499bb2009-09-03 22:13:48 +00001822 if (T.isNull())
1823 return DeclarationName();
Mike Stump1eb44332009-09-09 15:08:12 +00001824
Douglas Gregor81499bb2009-09-03 22:13:48 +00001825 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
Mike Stump1eb44332009-09-09 15:08:12 +00001826 Name.getNameKind(),
Douglas Gregor81499bb2009-09-03 22:13:48 +00001827 SemaRef.Context.getCanonicalType(T));
Douglas Gregor81499bb2009-09-03 22:13:48 +00001828 }
Mike Stump1eb44332009-09-09 15:08:12 +00001829 }
1830
Douglas Gregor81499bb2009-09-03 22:13:48 +00001831 return DeclarationName();
1832}
1833
1834template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00001835TemplateName
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001836TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
1837 QualType ObjectType) {
Douglas Gregord1067e52009-08-06 06:41:21 +00001838 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001839 NestedNameSpecifier *NNS
Douglas Gregord1067e52009-08-06 06:41:21 +00001840 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1841 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1842 if (!NNS)
1843 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001844
Douglas Gregord1067e52009-08-06 06:41:21 +00001845 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001846 TemplateDecl *TransTemplate
Douglas Gregord1067e52009-08-06 06:41:21 +00001847 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1848 if (!TransTemplate)
1849 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001850
Douglas Gregord1067e52009-08-06 06:41:21 +00001851 if (!getDerived().AlwaysRebuild() &&
1852 NNS == QTN->getQualifier() &&
1853 TransTemplate == Template)
1854 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001855
Douglas Gregord1067e52009-08-06 06:41:21 +00001856 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1857 TransTemplate);
1858 }
Mike Stump1eb44332009-09-09 15:08:12 +00001859
Douglas Gregord1067e52009-08-06 06:41:21 +00001860 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1861 assert(Ovl && "Not a template name or an overload set?");
Mike Stump1eb44332009-09-09 15:08:12 +00001862 OverloadedFunctionDecl *TransOvl
Douglas Gregord1067e52009-08-06 06:41:21 +00001863 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1864 if (!TransOvl)
1865 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001866
Douglas Gregord1067e52009-08-06 06:41:21 +00001867 if (!getDerived().AlwaysRebuild() &&
1868 NNS == QTN->getQualifier() &&
1869 TransOvl == Ovl)
1870 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001871
Douglas Gregord1067e52009-08-06 06:41:21 +00001872 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1873 TransOvl);
1874 }
Mike Stump1eb44332009-09-09 15:08:12 +00001875
Douglas Gregord1067e52009-08-06 06:41:21 +00001876 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001877 NestedNameSpecifier *NNS
Douglas Gregord1067e52009-08-06 06:41:21 +00001878 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1879 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001880 if (!NNS && DTN->getQualifier())
Douglas Gregord1067e52009-08-06 06:41:21 +00001881 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001882
Douglas Gregord1067e52009-08-06 06:41:21 +00001883 if (!getDerived().AlwaysRebuild() &&
Douglas Gregordd62b152009-10-19 22:04:39 +00001884 NNS == DTN->getQualifier() &&
1885 ObjectType.isNull())
Douglas Gregord1067e52009-08-06 06:41:21 +00001886 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001887
Douglas Gregorca1bdd72009-11-04 00:56:37 +00001888 if (DTN->isIdentifier())
1889 return getDerived().RebuildTemplateName(NNS, *DTN->getIdentifier(),
1890 ObjectType);
1891
1892 return getDerived().RebuildTemplateName(NNS, DTN->getOperator(),
1893 ObjectType);
Douglas Gregord1067e52009-08-06 06:41:21 +00001894 }
Mike Stump1eb44332009-09-09 15:08:12 +00001895
Douglas Gregord1067e52009-08-06 06:41:21 +00001896 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001897 TemplateDecl *TransTemplate
Douglas Gregord1067e52009-08-06 06:41:21 +00001898 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1899 if (!TransTemplate)
1900 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001901
Douglas Gregord1067e52009-08-06 06:41:21 +00001902 if (!getDerived().AlwaysRebuild() &&
1903 TransTemplate == Template)
1904 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001905
Douglas Gregord1067e52009-08-06 06:41:21 +00001906 return TemplateName(TransTemplate);
1907 }
Mike Stump1eb44332009-09-09 15:08:12 +00001908
Douglas Gregord1067e52009-08-06 06:41:21 +00001909 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1910 assert(Ovl && "Not a template name or an overload set?");
Mike Stump1eb44332009-09-09 15:08:12 +00001911 OverloadedFunctionDecl *TransOvl
Douglas Gregord1067e52009-08-06 06:41:21 +00001912 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1913 if (!TransOvl)
1914 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001915
Douglas Gregord1067e52009-08-06 06:41:21 +00001916 if (!getDerived().AlwaysRebuild() &&
1917 TransOvl == Ovl)
1918 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001919
Douglas Gregord1067e52009-08-06 06:41:21 +00001920 return TemplateName(TransOvl);
1921}
1922
1923template<typename Derived>
John McCall833ca992009-10-29 08:12:44 +00001924void TreeTransform<Derived>::InventTemplateArgumentLoc(
1925 const TemplateArgument &Arg,
1926 TemplateArgumentLoc &Output) {
1927 SourceLocation Loc = getDerived().getBaseLocation();
1928 switch (Arg.getKind()) {
1929 case TemplateArgument::Null:
1930 llvm::llvm_unreachable("null template argument in TreeTransform");
1931 break;
1932
1933 case TemplateArgument::Type:
1934 Output = TemplateArgumentLoc(Arg,
1935 SemaRef.Context.getTrivialDeclaratorInfo(Arg.getAsType(), Loc));
1936
1937 break;
1938
Douglas Gregor788cd062009-11-11 01:00:40 +00001939 case TemplateArgument::Template:
1940 Output = TemplateArgumentLoc(Arg, SourceRange(), Loc);
1941 break;
1942
John McCall833ca992009-10-29 08:12:44 +00001943 case TemplateArgument::Expression:
1944 Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
1945 break;
1946
1947 case TemplateArgument::Declaration:
1948 case TemplateArgument::Integral:
1949 case TemplateArgument::Pack:
John McCall828bff22009-10-29 18:45:58 +00001950 Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
John McCall833ca992009-10-29 08:12:44 +00001951 break;
1952 }
1953}
1954
1955template<typename Derived>
1956bool TreeTransform<Derived>::TransformTemplateArgument(
1957 const TemplateArgumentLoc &Input,
1958 TemplateArgumentLoc &Output) {
1959 const TemplateArgument &Arg = Input.getArgument();
Douglas Gregor670444e2009-08-04 22:27:00 +00001960 switch (Arg.getKind()) {
1961 case TemplateArgument::Null:
1962 case TemplateArgument::Integral:
John McCall833ca992009-10-29 08:12:44 +00001963 Output = Input;
1964 return false;
Mike Stump1eb44332009-09-09 15:08:12 +00001965
Douglas Gregor670444e2009-08-04 22:27:00 +00001966 case TemplateArgument::Type: {
John McCall833ca992009-10-29 08:12:44 +00001967 DeclaratorInfo *DI = Input.getSourceDeclaratorInfo();
1968 if (DI == NULL)
1969 DI = InventDeclaratorInfo(Input.getArgument().getAsType());
1970
1971 DI = getDerived().TransformType(DI);
1972 if (!DI) return true;
1973
1974 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
1975 return false;
Douglas Gregor670444e2009-08-04 22:27:00 +00001976 }
Mike Stump1eb44332009-09-09 15:08:12 +00001977
Douglas Gregor670444e2009-08-04 22:27:00 +00001978 case TemplateArgument::Declaration: {
John McCall833ca992009-10-29 08:12:44 +00001979 // FIXME: we should never have to transform one of these.
Douglas Gregor972e6ce2009-10-27 06:26:26 +00001980 DeclarationName Name;
1981 if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
1982 Name = ND->getDeclName();
Douglas Gregor788cd062009-11-11 01:00:40 +00001983 TemporaryBase Rebase(*this, Input.getLocation(), Name);
Douglas Gregor670444e2009-08-04 22:27:00 +00001984 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
John McCall833ca992009-10-29 08:12:44 +00001985 if (!D) return true;
1986
John McCall828bff22009-10-29 18:45:58 +00001987 Expr *SourceExpr = Input.getSourceDeclExpression();
1988 if (SourceExpr) {
1989 EnterExpressionEvaluationContext Unevaluated(getSema(),
1990 Action::Unevaluated);
1991 Sema::OwningExprResult E = getDerived().TransformExpr(SourceExpr);
1992 if (E.isInvalid())
1993 SourceExpr = NULL;
1994 else {
1995 SourceExpr = E.takeAs<Expr>();
1996 SourceExpr->Retain();
1997 }
1998 }
1999
2000 Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr);
John McCall833ca992009-10-29 08:12:44 +00002001 return false;
Douglas Gregor670444e2009-08-04 22:27:00 +00002002 }
Mike Stump1eb44332009-09-09 15:08:12 +00002003
Douglas Gregor788cd062009-11-11 01:00:40 +00002004 case TemplateArgument::Template: {
2005 TemporaryBase Rebase(*this, Input.getLocation(), DeclarationName());
2006 TemplateName Template
2007 = getDerived().TransformTemplateName(Arg.getAsTemplate());
2008 if (Template.isNull())
2009 return true;
2010
2011 Output = TemplateArgumentLoc(TemplateArgument(Template),
2012 Input.getTemplateQualifierRange(),
2013 Input.getTemplateNameLoc());
2014 return false;
2015 }
2016
Douglas Gregor670444e2009-08-04 22:27:00 +00002017 case TemplateArgument::Expression: {
2018 // Template argument expressions are not potentially evaluated.
Mike Stump1eb44332009-09-09 15:08:12 +00002019 EnterExpressionEvaluationContext Unevaluated(getSema(),
Douglas Gregor670444e2009-08-04 22:27:00 +00002020 Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00002021
John McCall833ca992009-10-29 08:12:44 +00002022 Expr *InputExpr = Input.getSourceExpression();
2023 if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
2024
2025 Sema::OwningExprResult E
2026 = getDerived().TransformExpr(InputExpr);
2027 if (E.isInvalid()) return true;
2028
2029 Expr *ETaken = E.takeAs<Expr>();
John McCall828bff22009-10-29 18:45:58 +00002030 ETaken->Retain();
John McCall833ca992009-10-29 08:12:44 +00002031 Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
2032 return false;
Douglas Gregor670444e2009-08-04 22:27:00 +00002033 }
Mike Stump1eb44332009-09-09 15:08:12 +00002034
Douglas Gregor670444e2009-08-04 22:27:00 +00002035 case TemplateArgument::Pack: {
2036 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
2037 TransformedArgs.reserve(Arg.pack_size());
Mike Stump1eb44332009-09-09 15:08:12 +00002038 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
Douglas Gregor670444e2009-08-04 22:27:00 +00002039 AEnd = Arg.pack_end();
2040 A != AEnd; ++A) {
Mike Stump1eb44332009-09-09 15:08:12 +00002041
John McCall833ca992009-10-29 08:12:44 +00002042 // FIXME: preserve source information here when we start
2043 // caring about parameter packs.
2044
John McCall828bff22009-10-29 18:45:58 +00002045 TemplateArgumentLoc InputArg;
2046 TemplateArgumentLoc OutputArg;
2047 getDerived().InventTemplateArgumentLoc(*A, InputArg);
2048 if (getDerived().TransformTemplateArgument(InputArg, OutputArg))
John McCall833ca992009-10-29 08:12:44 +00002049 return true;
2050
John McCall828bff22009-10-29 18:45:58 +00002051 TransformedArgs.push_back(OutputArg.getArgument());
Douglas Gregor670444e2009-08-04 22:27:00 +00002052 }
2053 TemplateArgument Result;
Mike Stump1eb44332009-09-09 15:08:12 +00002054 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
Douglas Gregor670444e2009-08-04 22:27:00 +00002055 true);
John McCall828bff22009-10-29 18:45:58 +00002056 Output = TemplateArgumentLoc(Result, Input.getLocInfo());
John McCall833ca992009-10-29 08:12:44 +00002057 return false;
Douglas Gregor670444e2009-08-04 22:27:00 +00002058 }
2059 }
Mike Stump1eb44332009-09-09 15:08:12 +00002060
Douglas Gregor670444e2009-08-04 22:27:00 +00002061 // Work around bogus GCC warning
John McCall833ca992009-10-29 08:12:44 +00002062 return true;
Douglas Gregor670444e2009-08-04 22:27:00 +00002063}
2064
Douglas Gregor577f75a2009-08-04 16:50:30 +00002065//===----------------------------------------------------------------------===//
2066// Type transformation
2067//===----------------------------------------------------------------------===//
2068
2069template<typename Derived>
2070QualType TreeTransform<Derived>::TransformType(QualType T) {
2071 if (getDerived().AlreadyTransformed(T))
2072 return T;
Mike Stump1eb44332009-09-09 15:08:12 +00002073
John McCalla2becad2009-10-21 00:40:46 +00002074 // Temporary workaround. All of these transformations should
2075 // eventually turn into transformations on TypeLocs.
2076 DeclaratorInfo *DI = getSema().Context.CreateDeclaratorInfo(T);
John McCall4802a312009-10-21 00:44:26 +00002077 DI->getTypeLoc().initialize(getDerived().getBaseLocation());
John McCalla2becad2009-10-21 00:40:46 +00002078
2079 DeclaratorInfo *NewDI = getDerived().TransformType(DI);
John McCall0953e762009-09-24 19:53:00 +00002080
John McCalla2becad2009-10-21 00:40:46 +00002081 if (!NewDI)
2082 return QualType();
2083
2084 return NewDI->getType();
2085}
2086
2087template<typename Derived>
2088DeclaratorInfo *TreeTransform<Derived>::TransformType(DeclaratorInfo *DI) {
2089 if (getDerived().AlreadyTransformed(DI->getType()))
2090 return DI;
2091
2092 TypeLocBuilder TLB;
2093
2094 TypeLoc TL = DI->getTypeLoc();
2095 TLB.reserve(TL.getFullDataSize());
2096
2097 QualType Result = getDerived().TransformType(TLB, TL);
2098 if (Result.isNull())
2099 return 0;
2100
2101 return TLB.getDeclaratorInfo(SemaRef.Context, Result);
2102}
2103
2104template<typename Derived>
2105QualType
2106TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
2107 switch (T.getTypeLocClass()) {
2108#define ABSTRACT_TYPELOC(CLASS, PARENT)
2109#define TYPELOC(CLASS, PARENT) \
2110 case TypeLoc::CLASS: \
2111 return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T));
2112#include "clang/AST/TypeLocNodes.def"
Douglas Gregor577f75a2009-08-04 16:50:30 +00002113 }
Mike Stump1eb44332009-09-09 15:08:12 +00002114
John McCalla2becad2009-10-21 00:40:46 +00002115 llvm::llvm_unreachable("unhandled type loc!");
2116 return QualType();
2117}
2118
2119/// FIXME: By default, this routine adds type qualifiers only to types
2120/// that can have qualifiers, and silently suppresses those qualifiers
2121/// that are not permitted (e.g., qualifiers on reference or function
2122/// types). This is the right thing for template instantiation, but
2123/// probably not for other clients.
2124template<typename Derived>
2125QualType
2126TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
2127 QualifiedTypeLoc T) {
Douglas Gregora4923eb2009-11-16 21:35:15 +00002128 Qualifiers Quals = T.getType().getLocalQualifiers();
John McCalla2becad2009-10-21 00:40:46 +00002129
2130 QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
2131 if (Result.isNull())
2132 return QualType();
2133
2134 // Silently suppress qualifiers if the result type can't be qualified.
2135 // FIXME: this is the right thing for template instantiation, but
2136 // probably not for other clients.
2137 if (Result->isFunctionType() || Result->isReferenceType())
Douglas Gregor577f75a2009-08-04 16:50:30 +00002138 return Result;
Mike Stump1eb44332009-09-09 15:08:12 +00002139
John McCalla2becad2009-10-21 00:40:46 +00002140 Result = SemaRef.Context.getQualifiedType(Result, Quals);
2141
2142 TLB.push<QualifiedTypeLoc>(Result);
2143
2144 // No location information to preserve.
2145
2146 return Result;
2147}
2148
2149template <class TyLoc> static inline
2150QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
2151 TyLoc NewT = TLB.push<TyLoc>(T.getType());
2152 NewT.setNameLoc(T.getNameLoc());
2153 return T.getType();
2154}
2155
2156// Ugly metaprogramming macros because I couldn't be bothered to make
2157// the equivalent template version work.
2158#define TransformPointerLikeType(TypeClass) do { \
2159 QualType PointeeType \
2160 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2161 if (PointeeType.isNull()) \
2162 return QualType(); \
2163 \
2164 QualType Result = TL.getType(); \
2165 if (getDerived().AlwaysRebuild() || \
2166 PointeeType != TL.getPointeeLoc().getType()) { \
John McCall85737a72009-10-30 00:06:24 +00002167 Result = getDerived().Rebuild##TypeClass(PointeeType, \
2168 TL.getSigilLoc()); \
John McCalla2becad2009-10-21 00:40:46 +00002169 if (Result.isNull()) \
2170 return QualType(); \
2171 } \
2172 \
2173 TypeClass##Loc NewT = TLB.push<TypeClass##Loc>(Result); \
2174 NewT.setSigilLoc(TL.getSigilLoc()); \
2175 \
2176 return Result; \
2177} while(0)
2178
John McCalla2becad2009-10-21 00:40:46 +00002179template<typename Derived>
2180QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
2181 BuiltinTypeLoc T) {
2182 return TransformTypeSpecType(TLB, T);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002183}
Mike Stump1eb44332009-09-09 15:08:12 +00002184
Douglas Gregor577f75a2009-08-04 16:50:30 +00002185template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002186QualType
John McCalla2becad2009-10-21 00:40:46 +00002187TreeTransform<Derived>::TransformFixedWidthIntType(TypeLocBuilder &TLB,
2188 FixedWidthIntTypeLoc T) {
2189 return TransformTypeSpecType(TLB, T);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002190}
Argyrios Kyrtzidis1bb8a452009-08-19 01:28:17 +00002191
Douglas Gregor577f75a2009-08-04 16:50:30 +00002192template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002193QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
2194 ComplexTypeLoc T) {
2195 // FIXME: recurse?
2196 return TransformTypeSpecType(TLB, T);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002197}
Mike Stump1eb44332009-09-09 15:08:12 +00002198
Douglas Gregor577f75a2009-08-04 16:50:30 +00002199template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002200QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
2201 PointerTypeLoc TL) {
2202 TransformPointerLikeType(PointerType);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002203}
Mike Stump1eb44332009-09-09 15:08:12 +00002204
2205template<typename Derived>
2206QualType
John McCalla2becad2009-10-21 00:40:46 +00002207TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
2208 BlockPointerTypeLoc TL) {
2209 TransformPointerLikeType(BlockPointerType);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002210}
2211
John McCall85737a72009-10-30 00:06:24 +00002212/// Transforms a reference type. Note that somewhat paradoxically we
2213/// don't care whether the type itself is an l-value type or an r-value
2214/// type; we only care if the type was *written* as an l-value type
2215/// or an r-value type.
2216template<typename Derived>
2217QualType
2218TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
2219 ReferenceTypeLoc TL) {
2220 const ReferenceType *T = TL.getTypePtr();
2221
2222 // Note that this works with the pointee-as-written.
2223 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
2224 if (PointeeType.isNull())
2225 return QualType();
2226
2227 QualType Result = TL.getType();
2228 if (getDerived().AlwaysRebuild() ||
2229 PointeeType != T->getPointeeTypeAsWritten()) {
2230 Result = getDerived().RebuildReferenceType(PointeeType,
2231 T->isSpelledAsLValue(),
2232 TL.getSigilLoc());
2233 if (Result.isNull())
2234 return QualType();
2235 }
2236
2237 // r-value references can be rebuilt as l-value references.
2238 ReferenceTypeLoc NewTL;
2239 if (isa<LValueReferenceType>(Result))
2240 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
2241 else
2242 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
2243 NewTL.setSigilLoc(TL.getSigilLoc());
2244
2245 return Result;
2246}
2247
Mike Stump1eb44332009-09-09 15:08:12 +00002248template<typename Derived>
2249QualType
John McCalla2becad2009-10-21 00:40:46 +00002250TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
2251 LValueReferenceTypeLoc TL) {
John McCall85737a72009-10-30 00:06:24 +00002252 return TransformReferenceType(TLB, TL);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002253}
2254
Mike Stump1eb44332009-09-09 15:08:12 +00002255template<typename Derived>
2256QualType
John McCalla2becad2009-10-21 00:40:46 +00002257TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
2258 RValueReferenceTypeLoc TL) {
John McCall85737a72009-10-30 00:06:24 +00002259 return TransformReferenceType(TLB, TL);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002260}
Mike Stump1eb44332009-09-09 15:08:12 +00002261
Douglas Gregor577f75a2009-08-04 16:50:30 +00002262template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002263QualType
John McCalla2becad2009-10-21 00:40:46 +00002264TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
2265 MemberPointerTypeLoc TL) {
2266 MemberPointerType *T = TL.getTypePtr();
2267
2268 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002269 if (PointeeType.isNull())
2270 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002271
John McCalla2becad2009-10-21 00:40:46 +00002272 // TODO: preserve source information for this.
2273 QualType ClassType
2274 = getDerived().TransformType(QualType(T->getClass(), 0));
Douglas Gregor577f75a2009-08-04 16:50:30 +00002275 if (ClassType.isNull())
2276 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002277
John McCalla2becad2009-10-21 00:40:46 +00002278 QualType Result = TL.getType();
2279 if (getDerived().AlwaysRebuild() ||
2280 PointeeType != T->getPointeeType() ||
2281 ClassType != QualType(T->getClass(), 0)) {
John McCall85737a72009-10-30 00:06:24 +00002282 Result = getDerived().RebuildMemberPointerType(PointeeType, ClassType,
2283 TL.getStarLoc());
John McCalla2becad2009-10-21 00:40:46 +00002284 if (Result.isNull())
2285 return QualType();
2286 }
Douglas Gregor577f75a2009-08-04 16:50:30 +00002287
John McCalla2becad2009-10-21 00:40:46 +00002288 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
2289 NewTL.setSigilLoc(TL.getSigilLoc());
2290
2291 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002292}
2293
Mike Stump1eb44332009-09-09 15:08:12 +00002294template<typename Derived>
2295QualType
John McCalla2becad2009-10-21 00:40:46 +00002296TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
2297 ConstantArrayTypeLoc TL) {
2298 ConstantArrayType *T = TL.getTypePtr();
2299 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002300 if (ElementType.isNull())
2301 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002302
John McCalla2becad2009-10-21 00:40:46 +00002303 QualType Result = TL.getType();
2304 if (getDerived().AlwaysRebuild() ||
2305 ElementType != T->getElementType()) {
2306 Result = getDerived().RebuildConstantArrayType(ElementType,
2307 T->getSizeModifier(),
2308 T->getSize(),
John McCall85737a72009-10-30 00:06:24 +00002309 T->getIndexTypeCVRQualifiers(),
2310 TL.getBracketsRange());
John McCalla2becad2009-10-21 00:40:46 +00002311 if (Result.isNull())
2312 return QualType();
2313 }
2314
2315 ConstantArrayTypeLoc NewTL = TLB.push<ConstantArrayTypeLoc>(Result);
2316 NewTL.setLBracketLoc(TL.getLBracketLoc());
2317 NewTL.setRBracketLoc(TL.getRBracketLoc());
Mike Stump1eb44332009-09-09 15:08:12 +00002318
John McCalla2becad2009-10-21 00:40:46 +00002319 Expr *Size = TL.getSizeExpr();
2320 if (Size) {
2321 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2322 Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
2323 }
2324 NewTL.setSizeExpr(Size);
2325
2326 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002327}
Mike Stump1eb44332009-09-09 15:08:12 +00002328
Douglas Gregor577f75a2009-08-04 16:50:30 +00002329template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002330QualType TreeTransform<Derived>::TransformIncompleteArrayType(
John McCalla2becad2009-10-21 00:40:46 +00002331 TypeLocBuilder &TLB,
2332 IncompleteArrayTypeLoc TL) {
2333 IncompleteArrayType *T = TL.getTypePtr();
2334 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002335 if (ElementType.isNull())
2336 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002337
John McCalla2becad2009-10-21 00:40:46 +00002338 QualType Result = TL.getType();
2339 if (getDerived().AlwaysRebuild() ||
2340 ElementType != T->getElementType()) {
2341 Result = getDerived().RebuildIncompleteArrayType(ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00002342 T->getSizeModifier(),
John McCall85737a72009-10-30 00:06:24 +00002343 T->getIndexTypeCVRQualifiers(),
2344 TL.getBracketsRange());
John McCalla2becad2009-10-21 00:40:46 +00002345 if (Result.isNull())
2346 return QualType();
2347 }
2348
2349 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
2350 NewTL.setLBracketLoc(TL.getLBracketLoc());
2351 NewTL.setRBracketLoc(TL.getRBracketLoc());
2352 NewTL.setSizeExpr(0);
2353
2354 return Result;
2355}
2356
2357template<typename Derived>
2358QualType
2359TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
2360 VariableArrayTypeLoc TL) {
2361 VariableArrayType *T = TL.getTypePtr();
2362 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2363 if (ElementType.isNull())
2364 return QualType();
2365
2366 // Array bounds are not potentially evaluated contexts
2367 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2368
2369 Sema::OwningExprResult SizeResult
2370 = getDerived().TransformExpr(T->getSizeExpr());
2371 if (SizeResult.isInvalid())
2372 return QualType();
2373
2374 Expr *Size = static_cast<Expr*>(SizeResult.get());
2375
2376 QualType Result = TL.getType();
2377 if (getDerived().AlwaysRebuild() ||
2378 ElementType != T->getElementType() ||
2379 Size != T->getSizeExpr()) {
2380 Result = getDerived().RebuildVariableArrayType(ElementType,
2381 T->getSizeModifier(),
2382 move(SizeResult),
2383 T->getIndexTypeCVRQualifiers(),
John McCall85737a72009-10-30 00:06:24 +00002384 TL.getBracketsRange());
John McCalla2becad2009-10-21 00:40:46 +00002385 if (Result.isNull())
2386 return QualType();
2387 }
2388 else SizeResult.take();
2389
2390 VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
2391 NewTL.setLBracketLoc(TL.getLBracketLoc());
2392 NewTL.setRBracketLoc(TL.getRBracketLoc());
2393 NewTL.setSizeExpr(Size);
2394
2395 return Result;
2396}
2397
2398template<typename Derived>
2399QualType
2400TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
2401 DependentSizedArrayTypeLoc TL) {
2402 DependentSizedArrayType *T = TL.getTypePtr();
2403 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2404 if (ElementType.isNull())
2405 return QualType();
2406
2407 // Array bounds are not potentially evaluated contexts
2408 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2409
2410 Sema::OwningExprResult SizeResult
2411 = getDerived().TransformExpr(T->getSizeExpr());
2412 if (SizeResult.isInvalid())
2413 return QualType();
2414
2415 Expr *Size = static_cast<Expr*>(SizeResult.get());
2416
2417 QualType Result = TL.getType();
2418 if (getDerived().AlwaysRebuild() ||
2419 ElementType != T->getElementType() ||
2420 Size != T->getSizeExpr()) {
2421 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
2422 T->getSizeModifier(),
2423 move(SizeResult),
2424 T->getIndexTypeCVRQualifiers(),
John McCall85737a72009-10-30 00:06:24 +00002425 TL.getBracketsRange());
John McCalla2becad2009-10-21 00:40:46 +00002426 if (Result.isNull())
2427 return QualType();
2428 }
2429 else SizeResult.take();
2430
2431 // We might have any sort of array type now, but fortunately they
2432 // all have the same location layout.
2433 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
2434 NewTL.setLBracketLoc(TL.getLBracketLoc());
2435 NewTL.setRBracketLoc(TL.getRBracketLoc());
2436 NewTL.setSizeExpr(Size);
2437
2438 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002439}
Mike Stump1eb44332009-09-09 15:08:12 +00002440
2441template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002442QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
John McCalla2becad2009-10-21 00:40:46 +00002443 TypeLocBuilder &TLB,
2444 DependentSizedExtVectorTypeLoc TL) {
2445 DependentSizedExtVectorType *T = TL.getTypePtr();
2446
2447 // FIXME: ext vector locs should be nested
Douglas Gregor577f75a2009-08-04 16:50:30 +00002448 QualType ElementType = getDerived().TransformType(T->getElementType());
2449 if (ElementType.isNull())
2450 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002451
Douglas Gregor670444e2009-08-04 22:27:00 +00002452 // Vector sizes are not potentially evaluated contexts
2453 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2454
Douglas Gregor577f75a2009-08-04 16:50:30 +00002455 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2456 if (Size.isInvalid())
2457 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002458
John McCalla2becad2009-10-21 00:40:46 +00002459 QualType Result = TL.getType();
2460 if (getDerived().AlwaysRebuild() ||
John McCalleee91c32009-10-23 17:55:45 +00002461 ElementType != T->getElementType() ||
2462 Size.get() != T->getSizeExpr()) {
John McCalla2becad2009-10-21 00:40:46 +00002463 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00002464 move(Size),
2465 T->getAttributeLoc());
John McCalla2becad2009-10-21 00:40:46 +00002466 if (Result.isNull())
2467 return QualType();
2468 }
2469 else Size.take();
2470
2471 // Result might be dependent or not.
2472 if (isa<DependentSizedExtVectorType>(Result)) {
2473 DependentSizedExtVectorTypeLoc NewTL
2474 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
2475 NewTL.setNameLoc(TL.getNameLoc());
2476 } else {
2477 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2478 NewTL.setNameLoc(TL.getNameLoc());
2479 }
2480
2481 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002482}
Mike Stump1eb44332009-09-09 15:08:12 +00002483
2484template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002485QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
2486 VectorTypeLoc TL) {
2487 VectorType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002488 QualType ElementType = getDerived().TransformType(T->getElementType());
2489 if (ElementType.isNull())
2490 return QualType();
2491
John McCalla2becad2009-10-21 00:40:46 +00002492 QualType Result = TL.getType();
2493 if (getDerived().AlwaysRebuild() ||
2494 ElementType != T->getElementType()) {
2495 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements());
2496 if (Result.isNull())
2497 return QualType();
2498 }
2499
2500 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
2501 NewTL.setNameLoc(TL.getNameLoc());
Mike Stump1eb44332009-09-09 15:08:12 +00002502
John McCalla2becad2009-10-21 00:40:46 +00002503 return Result;
2504}
2505
2506template<typename Derived>
2507QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
2508 ExtVectorTypeLoc TL) {
2509 VectorType *T = TL.getTypePtr();
2510 QualType ElementType = getDerived().TransformType(T->getElementType());
2511 if (ElementType.isNull())
2512 return QualType();
2513
2514 QualType Result = TL.getType();
2515 if (getDerived().AlwaysRebuild() ||
2516 ElementType != T->getElementType()) {
2517 Result = getDerived().RebuildExtVectorType(ElementType,
2518 T->getNumElements(),
2519 /*FIXME*/ SourceLocation());
2520 if (Result.isNull())
2521 return QualType();
2522 }
2523
2524 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2525 NewTL.setNameLoc(TL.getNameLoc());
2526
2527 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002528}
Mike Stump1eb44332009-09-09 15:08:12 +00002529
2530template<typename Derived>
2531QualType
John McCalla2becad2009-10-21 00:40:46 +00002532TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
2533 FunctionProtoTypeLoc TL) {
2534 FunctionProtoType *T = TL.getTypePtr();
2535 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002536 if (ResultType.isNull())
2537 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002538
John McCalla2becad2009-10-21 00:40:46 +00002539 // Transform the parameters.
Douglas Gregor577f75a2009-08-04 16:50:30 +00002540 llvm::SmallVector<QualType, 4> ParamTypes;
John McCalla2becad2009-10-21 00:40:46 +00002541 llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
2542 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2543 ParmVarDecl *OldParm = TL.getArg(i);
Mike Stump1eb44332009-09-09 15:08:12 +00002544
John McCalla2becad2009-10-21 00:40:46 +00002545 QualType NewType;
2546 ParmVarDecl *NewParm;
2547
2548 if (OldParm) {
2549 DeclaratorInfo *OldDI = OldParm->getDeclaratorInfo();
2550 assert(OldDI->getType() == T->getArgType(i));
2551
2552 DeclaratorInfo *NewDI = getDerived().TransformType(OldDI);
2553 if (!NewDI)
2554 return QualType();
2555
2556 if (NewDI == OldDI)
2557 NewParm = OldParm;
2558 else
2559 NewParm = ParmVarDecl::Create(SemaRef.Context,
2560 OldParm->getDeclContext(),
2561 OldParm->getLocation(),
2562 OldParm->getIdentifier(),
2563 NewDI->getType(),
2564 NewDI,
2565 OldParm->getStorageClass(),
2566 /* DefArg */ NULL);
2567 NewType = NewParm->getType();
2568
2569 // Deal with the possibility that we don't have a parameter
2570 // declaration for this parameter.
2571 } else {
2572 NewParm = 0;
2573
2574 QualType OldType = T->getArgType(i);
2575 NewType = getDerived().TransformType(OldType);
2576 if (NewType.isNull())
2577 return QualType();
2578 }
2579
2580 ParamTypes.push_back(NewType);
2581 ParamDecls.push_back(NewParm);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002582 }
Mike Stump1eb44332009-09-09 15:08:12 +00002583
John McCalla2becad2009-10-21 00:40:46 +00002584 QualType Result = TL.getType();
2585 if (getDerived().AlwaysRebuild() ||
2586 ResultType != T->getResultType() ||
2587 !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
2588 Result = getDerived().RebuildFunctionProtoType(ResultType,
2589 ParamTypes.data(),
2590 ParamTypes.size(),
2591 T->isVariadic(),
2592 T->getTypeQuals());
2593 if (Result.isNull())
2594 return QualType();
2595 }
Mike Stump1eb44332009-09-09 15:08:12 +00002596
John McCalla2becad2009-10-21 00:40:46 +00002597 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
2598 NewTL.setLParenLoc(TL.getLParenLoc());
2599 NewTL.setRParenLoc(TL.getRParenLoc());
2600 for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
2601 NewTL.setArg(i, ParamDecls[i]);
2602
2603 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002604}
Mike Stump1eb44332009-09-09 15:08:12 +00002605
Douglas Gregor577f75a2009-08-04 16:50:30 +00002606template<typename Derived>
2607QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
John McCalla2becad2009-10-21 00:40:46 +00002608 TypeLocBuilder &TLB,
2609 FunctionNoProtoTypeLoc TL) {
2610 FunctionNoProtoType *T = TL.getTypePtr();
2611 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
2612 if (ResultType.isNull())
2613 return QualType();
2614
2615 QualType Result = TL.getType();
2616 if (getDerived().AlwaysRebuild() ||
2617 ResultType != T->getResultType())
2618 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
2619
2620 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
2621 NewTL.setLParenLoc(TL.getLParenLoc());
2622 NewTL.setRParenLoc(TL.getRParenLoc());
2623
2624 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002625}
Mike Stump1eb44332009-09-09 15:08:12 +00002626
Douglas Gregor577f75a2009-08-04 16:50:30 +00002627template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002628QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
2629 TypedefTypeLoc TL) {
2630 TypedefType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002631 TypedefDecl *Typedef
2632 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2633 if (!Typedef)
2634 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002635
John McCalla2becad2009-10-21 00:40:46 +00002636 QualType Result = TL.getType();
2637 if (getDerived().AlwaysRebuild() ||
2638 Typedef != T->getDecl()) {
2639 Result = getDerived().RebuildTypedefType(Typedef);
2640 if (Result.isNull())
2641 return QualType();
2642 }
Mike Stump1eb44332009-09-09 15:08:12 +00002643
John McCalla2becad2009-10-21 00:40:46 +00002644 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
2645 NewTL.setNameLoc(TL.getNameLoc());
2646
2647 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002648}
Mike Stump1eb44332009-09-09 15:08:12 +00002649
Douglas Gregor577f75a2009-08-04 16:50:30 +00002650template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002651QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
2652 TypeOfExprTypeLoc TL) {
2653 TypeOfExprType *T = TL.getTypePtr();
2654
Douglas Gregor670444e2009-08-04 22:27:00 +00002655 // typeof expressions are not potentially evaluated contexts
2656 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00002657
Douglas Gregor577f75a2009-08-04 16:50:30 +00002658 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2659 if (E.isInvalid())
2660 return QualType();
2661
John McCalla2becad2009-10-21 00:40:46 +00002662 QualType Result = TL.getType();
2663 if (getDerived().AlwaysRebuild() ||
2664 E.get() != T->getUnderlyingExpr()) {
2665 Result = getDerived().RebuildTypeOfExprType(move(E));
2666 if (Result.isNull())
2667 return QualType();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002668 }
John McCalla2becad2009-10-21 00:40:46 +00002669 else E.take();
Mike Stump1eb44332009-09-09 15:08:12 +00002670
John McCalla2becad2009-10-21 00:40:46 +00002671 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
2672 NewTL.setNameLoc(TL.getNameLoc());
2673
2674 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002675}
Mike Stump1eb44332009-09-09 15:08:12 +00002676
2677template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002678QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
2679 TypeOfTypeLoc TL) {
2680 TypeOfType *T = TL.getTypePtr();
2681
2682 // FIXME: should be an inner type, or at least have a DeclaratorInfo.
Douglas Gregor577f75a2009-08-04 16:50:30 +00002683 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2684 if (Underlying.isNull())
2685 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002686
John McCalla2becad2009-10-21 00:40:46 +00002687 QualType Result = TL.getType();
2688 if (getDerived().AlwaysRebuild() ||
2689 Underlying != T->getUnderlyingType()) {
2690 Result = getDerived().RebuildTypeOfType(Underlying);
2691 if (Result.isNull())
2692 return QualType();
2693 }
Mike Stump1eb44332009-09-09 15:08:12 +00002694
John McCalla2becad2009-10-21 00:40:46 +00002695 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
2696 NewTL.setNameLoc(TL.getNameLoc());
2697
2698 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002699}
Mike Stump1eb44332009-09-09 15:08:12 +00002700
2701template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002702QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
2703 DecltypeTypeLoc TL) {
2704 DecltypeType *T = TL.getTypePtr();
2705
Douglas Gregor670444e2009-08-04 22:27:00 +00002706 // decltype expressions are not potentially evaluated contexts
2707 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00002708
Douglas Gregor577f75a2009-08-04 16:50:30 +00002709 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2710 if (E.isInvalid())
2711 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002712
John McCalla2becad2009-10-21 00:40:46 +00002713 QualType Result = TL.getType();
2714 if (getDerived().AlwaysRebuild() ||
2715 E.get() != T->getUnderlyingExpr()) {
2716 Result = getDerived().RebuildDecltypeType(move(E));
2717 if (Result.isNull())
2718 return QualType();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002719 }
John McCalla2becad2009-10-21 00:40:46 +00002720 else E.take();
Mike Stump1eb44332009-09-09 15:08:12 +00002721
John McCalla2becad2009-10-21 00:40:46 +00002722 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
2723 NewTL.setNameLoc(TL.getNameLoc());
2724
2725 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002726}
2727
2728template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002729QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
2730 RecordTypeLoc TL) {
2731 RecordType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002732 RecordDecl *Record
John McCalla2becad2009-10-21 00:40:46 +00002733 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregor577f75a2009-08-04 16:50:30 +00002734 if (!Record)
2735 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002736
John McCalla2becad2009-10-21 00:40:46 +00002737 QualType Result = TL.getType();
2738 if (getDerived().AlwaysRebuild() ||
2739 Record != T->getDecl()) {
2740 Result = getDerived().RebuildRecordType(Record);
2741 if (Result.isNull())
2742 return QualType();
2743 }
Mike Stump1eb44332009-09-09 15:08:12 +00002744
John McCalla2becad2009-10-21 00:40:46 +00002745 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
2746 NewTL.setNameLoc(TL.getNameLoc());
2747
2748 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002749}
Mike Stump1eb44332009-09-09 15:08:12 +00002750
2751template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002752QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
2753 EnumTypeLoc TL) {
2754 EnumType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002755 EnumDecl *Enum
John McCalla2becad2009-10-21 00:40:46 +00002756 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregor577f75a2009-08-04 16:50:30 +00002757 if (!Enum)
2758 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002759
John McCalla2becad2009-10-21 00:40:46 +00002760 QualType Result = TL.getType();
2761 if (getDerived().AlwaysRebuild() ||
2762 Enum != T->getDecl()) {
2763 Result = getDerived().RebuildEnumType(Enum);
2764 if (Result.isNull())
2765 return QualType();
2766 }
Mike Stump1eb44332009-09-09 15:08:12 +00002767
John McCalla2becad2009-10-21 00:40:46 +00002768 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
2769 NewTL.setNameLoc(TL.getNameLoc());
2770
2771 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002772}
John McCall7da24312009-09-05 00:15:47 +00002773
2774template <typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002775QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
2776 ElaboratedTypeLoc TL) {
2777 ElaboratedType *T = TL.getTypePtr();
2778
2779 // FIXME: this should be a nested type.
John McCall7da24312009-09-05 00:15:47 +00002780 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2781 if (Underlying.isNull())
2782 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002783
John McCalla2becad2009-10-21 00:40:46 +00002784 QualType Result = TL.getType();
2785 if (getDerived().AlwaysRebuild() ||
2786 Underlying != T->getUnderlyingType()) {
2787 Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
2788 if (Result.isNull())
2789 return QualType();
2790 }
Mike Stump1eb44332009-09-09 15:08:12 +00002791
John McCalla2becad2009-10-21 00:40:46 +00002792 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
2793 NewTL.setNameLoc(TL.getNameLoc());
2794
2795 return Result;
John McCall7da24312009-09-05 00:15:47 +00002796}
Mike Stump1eb44332009-09-09 15:08:12 +00002797
2798
Douglas Gregor577f75a2009-08-04 16:50:30 +00002799template<typename Derived>
2800QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
John McCalla2becad2009-10-21 00:40:46 +00002801 TypeLocBuilder &TLB,
2802 TemplateTypeParmTypeLoc TL) {
2803 return TransformTypeSpecType(TLB, TL);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002804}
2805
Mike Stump1eb44332009-09-09 15:08:12 +00002806template<typename Derived>
John McCall49a832b2009-10-18 09:09:24 +00002807QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
John McCalla2becad2009-10-21 00:40:46 +00002808 TypeLocBuilder &TLB,
2809 SubstTemplateTypeParmTypeLoc TL) {
2810 return TransformTypeSpecType(TLB, TL);
John McCall49a832b2009-10-18 09:09:24 +00002811}
2812
2813template<typename Derived>
Douglas Gregordd62b152009-10-19 22:04:39 +00002814inline QualType
2815TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCalla2becad2009-10-21 00:40:46 +00002816 TypeLocBuilder &TLB,
2817 TemplateSpecializationTypeLoc TL) {
John McCall833ca992009-10-29 08:12:44 +00002818 return TransformTemplateSpecializationType(TLB, TL, QualType());
2819}
John McCalla2becad2009-10-21 00:40:46 +00002820
John McCall833ca992009-10-29 08:12:44 +00002821template<typename Derived>
2822QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
2823 const TemplateSpecializationType *TST,
2824 QualType ObjectType) {
2825 // FIXME: this entire method is a temporary workaround; callers
2826 // should be rewritten to provide real type locs.
John McCalla2becad2009-10-21 00:40:46 +00002827
John McCall833ca992009-10-29 08:12:44 +00002828 // Fake up a TemplateSpecializationTypeLoc.
2829 TypeLocBuilder TLB;
2830 TemplateSpecializationTypeLoc TL
2831 = TLB.push<TemplateSpecializationTypeLoc>(QualType(TST, 0));
2832
John McCall828bff22009-10-29 18:45:58 +00002833 SourceLocation BaseLoc = getDerived().getBaseLocation();
2834
2835 TL.setTemplateNameLoc(BaseLoc);
2836 TL.setLAngleLoc(BaseLoc);
2837 TL.setRAngleLoc(BaseLoc);
John McCall833ca992009-10-29 08:12:44 +00002838 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2839 const TemplateArgument &TA = TST->getArg(i);
2840 TemplateArgumentLoc TAL;
2841 getDerived().InventTemplateArgumentLoc(TA, TAL);
2842 TL.setArgLocInfo(i, TAL.getLocInfo());
2843 }
2844
2845 TypeLocBuilder IgnoredTLB;
2846 return TransformTemplateSpecializationType(IgnoredTLB, TL, ObjectType);
Douglas Gregordd62b152009-10-19 22:04:39 +00002847}
2848
2849template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002850QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall833ca992009-10-29 08:12:44 +00002851 TypeLocBuilder &TLB,
2852 TemplateSpecializationTypeLoc TL,
2853 QualType ObjectType) {
2854 const TemplateSpecializationType *T = TL.getTypePtr();
2855
Mike Stump1eb44332009-09-09 15:08:12 +00002856 TemplateName Template
Douglas Gregordd62b152009-10-19 22:04:39 +00002857 = getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002858 if (Template.isNull())
2859 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002860
John McCalld5532b62009-11-23 01:53:49 +00002861 TemplateArgumentListInfo NewTemplateArgs;
2862 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
2863 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
2864
2865 for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
2866 TemplateArgumentLoc Loc;
2867 if (getDerived().TransformTemplateArgument(TL.getArgLoc(i), Loc))
Douglas Gregor577f75a2009-08-04 16:50:30 +00002868 return QualType();
John McCalld5532b62009-11-23 01:53:49 +00002869 NewTemplateArgs.addArgument(Loc);
2870 }
Mike Stump1eb44332009-09-09 15:08:12 +00002871
John McCall833ca992009-10-29 08:12:44 +00002872 // FIXME: maybe don't rebuild if all the template arguments are the same.
2873
2874 QualType Result =
2875 getDerived().RebuildTemplateSpecializationType(Template,
2876 TL.getTemplateNameLoc(),
John McCalld5532b62009-11-23 01:53:49 +00002877 NewTemplateArgs);
John McCall833ca992009-10-29 08:12:44 +00002878
2879 if (!Result.isNull()) {
2880 TemplateSpecializationTypeLoc NewTL
2881 = TLB.push<TemplateSpecializationTypeLoc>(Result);
2882 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
2883 NewTL.setLAngleLoc(TL.getLAngleLoc());
2884 NewTL.setRAngleLoc(TL.getRAngleLoc());
2885 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
2886 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002887 }
Mike Stump1eb44332009-09-09 15:08:12 +00002888
John McCall833ca992009-10-29 08:12:44 +00002889 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002890}
Mike Stump1eb44332009-09-09 15:08:12 +00002891
2892template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002893QualType
2894TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
2895 QualifiedNameTypeLoc TL) {
2896 QualifiedNameType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002897 NestedNameSpecifier *NNS
2898 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2899 SourceRange());
2900 if (!NNS)
2901 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002902
Douglas Gregor577f75a2009-08-04 16:50:30 +00002903 QualType Named = getDerived().TransformType(T->getNamedType());
2904 if (Named.isNull())
2905 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002906
John McCalla2becad2009-10-21 00:40:46 +00002907 QualType Result = TL.getType();
2908 if (getDerived().AlwaysRebuild() ||
2909 NNS != T->getQualifier() ||
2910 Named != T->getNamedType()) {
2911 Result = getDerived().RebuildQualifiedNameType(NNS, Named);
2912 if (Result.isNull())
2913 return QualType();
2914 }
Douglas Gregor577f75a2009-08-04 16:50:30 +00002915
John McCalla2becad2009-10-21 00:40:46 +00002916 QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
2917 NewTL.setNameLoc(TL.getNameLoc());
2918
2919 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002920}
Mike Stump1eb44332009-09-09 15:08:12 +00002921
2922template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002923QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
2924 TypenameTypeLoc TL) {
2925 TypenameType *T = TL.getTypePtr();
John McCall833ca992009-10-29 08:12:44 +00002926
2927 /* FIXME: preserve source information better than this */
2928 SourceRange SR(TL.getNameLoc());
2929
Douglas Gregor577f75a2009-08-04 16:50:30 +00002930 NestedNameSpecifier *NNS
John McCall833ca992009-10-29 08:12:44 +00002931 = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002932 if (!NNS)
2933 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002934
John McCalla2becad2009-10-21 00:40:46 +00002935 QualType Result;
2936
Douglas Gregor577f75a2009-08-04 16:50:30 +00002937 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
Mike Stump1eb44332009-09-09 15:08:12 +00002938 QualType NewTemplateId
Douglas Gregor577f75a2009-08-04 16:50:30 +00002939 = getDerived().TransformType(QualType(TemplateId, 0));
2940 if (NewTemplateId.isNull())
2941 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002942
Douglas Gregor577f75a2009-08-04 16:50:30 +00002943 if (!getDerived().AlwaysRebuild() &&
2944 NNS == T->getQualifier() &&
2945 NewTemplateId == QualType(TemplateId, 0))
2946 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002947
John McCalla2becad2009-10-21 00:40:46 +00002948 Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
2949 } else {
John McCall833ca992009-10-29 08:12:44 +00002950 Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier(), SR);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002951 }
John McCalla2becad2009-10-21 00:40:46 +00002952 if (Result.isNull())
2953 return QualType();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002954
John McCalla2becad2009-10-21 00:40:46 +00002955 TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
2956 NewTL.setNameLoc(TL.getNameLoc());
2957
2958 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002959}
Mike Stump1eb44332009-09-09 15:08:12 +00002960
Douglas Gregor577f75a2009-08-04 16:50:30 +00002961template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002962QualType
2963TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
2964 ObjCInterfaceTypeLoc TL) {
John McCall54e14c42009-10-22 22:37:11 +00002965 assert(false && "TransformObjCInterfaceType unimplemented");
2966 return QualType();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002967}
Mike Stump1eb44332009-09-09 15:08:12 +00002968
2969template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002970QualType
2971TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
2972 ObjCObjectPointerTypeLoc TL) {
John McCall54e14c42009-10-22 22:37:11 +00002973 assert(false && "TransformObjCObjectPointerType unimplemented");
2974 return QualType();
Argyrios Kyrtzidis24fab412009-09-29 19:42:55 +00002975}
2976
Douglas Gregor577f75a2009-08-04 16:50:30 +00002977//===----------------------------------------------------------------------===//
Douglas Gregor43959a92009-08-20 07:17:43 +00002978// Statement transformation
2979//===----------------------------------------------------------------------===//
2980template<typename Derived>
2981Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002982TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2983 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00002984}
2985
2986template<typename Derived>
2987Sema::OwningStmtResult
2988TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2989 return getDerived().TransformCompoundStmt(S, false);
2990}
2991
2992template<typename Derived>
2993Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00002994TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
Douglas Gregor43959a92009-08-20 07:17:43 +00002995 bool IsStmtExpr) {
2996 bool SubStmtChanged = false;
2997 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2998 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2999 B != BEnd; ++B) {
3000 OwningStmtResult Result = getDerived().TransformStmt(*B);
3001 if (Result.isInvalid())
3002 return getSema().StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003003
Douglas Gregor43959a92009-08-20 07:17:43 +00003004 SubStmtChanged = SubStmtChanged || Result.get() != *B;
3005 Statements.push_back(Result.takeAs<Stmt>());
3006 }
Mike Stump1eb44332009-09-09 15:08:12 +00003007
Douglas Gregor43959a92009-08-20 07:17:43 +00003008 if (!getDerived().AlwaysRebuild() &&
3009 !SubStmtChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00003010 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003011
3012 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
3013 move_arg(Statements),
3014 S->getRBracLoc(),
3015 IsStmtExpr);
3016}
Mike Stump1eb44332009-09-09 15:08:12 +00003017
Douglas Gregor43959a92009-08-20 07:17:43 +00003018template<typename Derived>
3019Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003020TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
Eli Friedman264c1f82009-11-19 03:14:00 +00003021 OwningExprResult LHS(SemaRef), RHS(SemaRef);
3022 {
3023 // The case value expressions are not potentially evaluated.
3024 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00003025
Eli Friedman264c1f82009-11-19 03:14:00 +00003026 // Transform the left-hand case value.
3027 LHS = getDerived().TransformExpr(S->getLHS());
3028 if (LHS.isInvalid())
3029 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003030
Eli Friedman264c1f82009-11-19 03:14:00 +00003031 // Transform the right-hand case value (for the GNU case-range extension).
3032 RHS = getDerived().TransformExpr(S->getRHS());
3033 if (RHS.isInvalid())
3034 return SemaRef.StmtError();
3035 }
Mike Stump1eb44332009-09-09 15:08:12 +00003036
Douglas Gregor43959a92009-08-20 07:17:43 +00003037 // Build the case statement.
3038 // Case statements are always rebuilt so that they will attached to their
3039 // transformed switch statement.
3040 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
3041 move(LHS),
3042 S->getEllipsisLoc(),
3043 move(RHS),
3044 S->getColonLoc());
3045 if (Case.isInvalid())
3046 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003047
Douglas Gregor43959a92009-08-20 07:17:43 +00003048 // Transform the statement following the case
3049 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3050 if (SubStmt.isInvalid())
3051 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003052
Douglas Gregor43959a92009-08-20 07:17:43 +00003053 // Attach the body to the case statement
3054 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
3055}
3056
3057template<typename Derived>
3058Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003059TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003060 // Transform the statement following the default case
3061 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3062 if (SubStmt.isInvalid())
3063 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003064
Douglas Gregor43959a92009-08-20 07:17:43 +00003065 // Default statements are always rebuilt
3066 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
3067 move(SubStmt));
3068}
Mike Stump1eb44332009-09-09 15:08:12 +00003069
Douglas Gregor43959a92009-08-20 07:17:43 +00003070template<typename Derived>
3071Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003072TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003073 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3074 if (SubStmt.isInvalid())
3075 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003076
Douglas Gregor43959a92009-08-20 07:17:43 +00003077 // FIXME: Pass the real colon location in.
3078 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
3079 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
3080 move(SubStmt));
3081}
Mike Stump1eb44332009-09-09 15:08:12 +00003082
Douglas Gregor43959a92009-08-20 07:17:43 +00003083template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003084Sema::OwningStmtResult
3085TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003086 // Transform the condition
Douglas Gregor8cfe5a72009-11-23 23:44:04 +00003087 OwningExprResult Cond(SemaRef);
3088 VarDecl *ConditionVar = 0;
3089 if (S->getConditionVariable()) {
3090 ConditionVar
3091 = cast_or_null<VarDecl>(
3092 getDerived().TransformDefinition(S->getConditionVariable()));
3093 if (!ConditionVar)
3094 return SemaRef.StmtError();
3095
3096 Cond = getSema().CheckConditionVariable(ConditionVar);
3097 } else
3098 Cond = getDerived().TransformExpr(S->getCond());
3099
Douglas Gregor43959a92009-08-20 07:17:43 +00003100 if (Cond.isInvalid())
3101 return SemaRef.StmtError();
Douglas Gregor8cfe5a72009-11-23 23:44:04 +00003102
Douglas Gregor43959a92009-08-20 07:17:43 +00003103 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump1eb44332009-09-09 15:08:12 +00003104
Douglas Gregor43959a92009-08-20 07:17:43 +00003105 // Transform the "then" branch.
3106 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
3107 if (Then.isInvalid())
3108 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003109
Douglas Gregor43959a92009-08-20 07:17:43 +00003110 // Transform the "else" branch.
3111 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
3112 if (Else.isInvalid())
3113 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003114
Douglas Gregor43959a92009-08-20 07:17:43 +00003115 if (!getDerived().AlwaysRebuild() &&
3116 FullCond->get() == S->getCond() &&
3117 Then.get() == S->getThen() &&
3118 Else.get() == S->getElse())
Mike Stump1eb44332009-09-09 15:08:12 +00003119 return SemaRef.Owned(S->Retain());
3120
Douglas Gregor43959a92009-08-20 07:17:43 +00003121 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
Mike Stump1eb44332009-09-09 15:08:12 +00003122 S->getElseLoc(), move(Else));
Douglas Gregor43959a92009-08-20 07:17:43 +00003123}
3124
3125template<typename Derived>
3126Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003127TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003128 // Transform the condition.
Douglas Gregord3d53012009-11-24 17:07:59 +00003129 OwningExprResult Cond(SemaRef);
3130 VarDecl *ConditionVar = 0;
3131 if (S->getConditionVariable()) {
3132 ConditionVar
3133 = cast_or_null<VarDecl>(
3134 getDerived().TransformDefinition(S->getConditionVariable()));
3135 if (!ConditionVar)
3136 return SemaRef.StmtError();
3137
3138 Cond = getSema().CheckConditionVariable(ConditionVar);
3139 } else
3140 Cond = getDerived().TransformExpr(S->getCond());
Douglas Gregor43959a92009-08-20 07:17:43 +00003141 if (Cond.isInvalid())
3142 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003143
Douglas Gregor43959a92009-08-20 07:17:43 +00003144 // Rebuild the switch statement.
3145 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
3146 if (Switch.isInvalid())
3147 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003148
Douglas Gregor43959a92009-08-20 07:17:43 +00003149 // Transform the body of the switch statement.
3150 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3151 if (Body.isInvalid())
3152 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003153
Douglas Gregor43959a92009-08-20 07:17:43 +00003154 // Complete the switch statement.
3155 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
3156 move(Body));
3157}
Mike Stump1eb44332009-09-09 15:08:12 +00003158
Douglas Gregor43959a92009-08-20 07:17:43 +00003159template<typename Derived>
3160Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003161TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003162 // Transform the condition
3163 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3164 if (Cond.isInvalid())
3165 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003166
Douglas Gregor43959a92009-08-20 07:17:43 +00003167 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump1eb44332009-09-09 15:08:12 +00003168
Douglas Gregor43959a92009-08-20 07:17:43 +00003169 // Transform the body
3170 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3171 if (Body.isInvalid())
3172 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003173
Douglas Gregor43959a92009-08-20 07:17:43 +00003174 if (!getDerived().AlwaysRebuild() &&
3175 FullCond->get() == S->getCond() &&
3176 Body.get() == S->getBody())
Mike Stump1eb44332009-09-09 15:08:12 +00003177 return SemaRef.Owned(S->Retain());
3178
Douglas Gregor43959a92009-08-20 07:17:43 +00003179 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
3180}
Mike Stump1eb44332009-09-09 15:08:12 +00003181
Douglas Gregor43959a92009-08-20 07:17:43 +00003182template<typename Derived>
3183Sema::OwningStmtResult
3184TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
3185 // Transform the condition
3186 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3187 if (Cond.isInvalid())
3188 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003189
Douglas Gregor43959a92009-08-20 07:17:43 +00003190 // Transform the body
3191 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3192 if (Body.isInvalid())
3193 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003194
Douglas Gregor43959a92009-08-20 07:17:43 +00003195 if (!getDerived().AlwaysRebuild() &&
3196 Cond.get() == S->getCond() &&
3197 Body.get() == S->getBody())
Mike Stump1eb44332009-09-09 15:08:12 +00003198 return SemaRef.Owned(S->Retain());
3199
Douglas Gregor43959a92009-08-20 07:17:43 +00003200 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
3201 /*FIXME:*/S->getWhileLoc(), move(Cond),
3202 S->getRParenLoc());
3203}
Mike Stump1eb44332009-09-09 15:08:12 +00003204
Douglas Gregor43959a92009-08-20 07:17:43 +00003205template<typename Derived>
3206Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003207TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003208 // Transform the initialization statement
3209 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
3210 if (Init.isInvalid())
3211 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003212
Douglas Gregor43959a92009-08-20 07:17:43 +00003213 // Transform the condition
3214 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3215 if (Cond.isInvalid())
3216 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003217
Douglas Gregor43959a92009-08-20 07:17:43 +00003218 // Transform the increment
3219 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
3220 if (Inc.isInvalid())
3221 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003222
Douglas Gregor43959a92009-08-20 07:17:43 +00003223 // Transform the body
3224 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3225 if (Body.isInvalid())
3226 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003227
Douglas Gregor43959a92009-08-20 07:17:43 +00003228 if (!getDerived().AlwaysRebuild() &&
3229 Init.get() == S->getInit() &&
3230 Cond.get() == S->getCond() &&
3231 Inc.get() == S->getInc() &&
3232 Body.get() == S->getBody())
Mike Stump1eb44332009-09-09 15:08:12 +00003233 return SemaRef.Owned(S->Retain());
3234
Douglas Gregor43959a92009-08-20 07:17:43 +00003235 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
3236 move(Init), move(Cond), move(Inc),
3237 S->getRParenLoc(), move(Body));
3238}
3239
3240template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003241Sema::OwningStmtResult
3242TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003243 // Goto statements must always be rebuilt, to resolve the label.
Mike Stump1eb44332009-09-09 15:08:12 +00003244 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
Douglas Gregor43959a92009-08-20 07:17:43 +00003245 S->getLabel());
3246}
3247
3248template<typename Derived>
3249Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003250TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003251 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
3252 if (Target.isInvalid())
3253 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003254
Douglas Gregor43959a92009-08-20 07:17:43 +00003255 if (!getDerived().AlwaysRebuild() &&
3256 Target.get() == S->getTarget())
Mike Stump1eb44332009-09-09 15:08:12 +00003257 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003258
3259 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
3260 move(Target));
3261}
3262
3263template<typename Derived>
3264Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003265TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
3266 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003267}
Mike Stump1eb44332009-09-09 15:08:12 +00003268
Douglas Gregor43959a92009-08-20 07:17:43 +00003269template<typename Derived>
3270Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003271TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
3272 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003273}
Mike Stump1eb44332009-09-09 15:08:12 +00003274
Douglas Gregor43959a92009-08-20 07:17:43 +00003275template<typename Derived>
3276Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003277TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003278 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
3279 if (Result.isInvalid())
3280 return SemaRef.StmtError();
3281
Mike Stump1eb44332009-09-09 15:08:12 +00003282 // FIXME: We always rebuild the return statement because there is no way
Douglas Gregor43959a92009-08-20 07:17:43 +00003283 // to tell whether the return type of the function has changed.
3284 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
3285}
Mike Stump1eb44332009-09-09 15:08:12 +00003286
Douglas Gregor43959a92009-08-20 07:17:43 +00003287template<typename Derived>
3288Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003289TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003290 bool DeclChanged = false;
3291 llvm::SmallVector<Decl *, 4> Decls;
3292 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
3293 D != DEnd; ++D) {
3294 Decl *Transformed = getDerived().TransformDefinition(*D);
3295 if (!Transformed)
3296 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003297
Douglas Gregor43959a92009-08-20 07:17:43 +00003298 if (Transformed != *D)
3299 DeclChanged = true;
Mike Stump1eb44332009-09-09 15:08:12 +00003300
Douglas Gregor43959a92009-08-20 07:17:43 +00003301 Decls.push_back(Transformed);
3302 }
Mike Stump1eb44332009-09-09 15:08:12 +00003303
Douglas Gregor43959a92009-08-20 07:17:43 +00003304 if (!getDerived().AlwaysRebuild() && !DeclChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00003305 return SemaRef.Owned(S->Retain());
3306
3307 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
Douglas Gregor43959a92009-08-20 07:17:43 +00003308 S->getStartLoc(), S->getEndLoc());
3309}
Mike Stump1eb44332009-09-09 15:08:12 +00003310
Douglas Gregor43959a92009-08-20 07:17:43 +00003311template<typename Derived>
3312Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003313TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003314 assert(false && "SwitchCase is abstract and cannot be transformed");
Mike Stump1eb44332009-09-09 15:08:12 +00003315 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003316}
3317
3318template<typename Derived>
3319Sema::OwningStmtResult
3320TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
3321 // FIXME: Implement!
3322 assert(false && "Inline assembly cannot be transformed");
Mike Stump1eb44332009-09-09 15:08:12 +00003323 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003324}
3325
3326
3327template<typename Derived>
3328Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003329TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003330 // FIXME: Implement this
3331 assert(false && "Cannot transform an Objective-C @try statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003332 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003333}
Mike Stump1eb44332009-09-09 15:08:12 +00003334
Douglas Gregor43959a92009-08-20 07:17:43 +00003335template<typename Derived>
3336Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003337TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003338 // FIXME: Implement this
3339 assert(false && "Cannot transform an Objective-C @catch statement");
3340 return SemaRef.Owned(S->Retain());
3341}
Mike Stump1eb44332009-09-09 15:08:12 +00003342
Douglas Gregor43959a92009-08-20 07:17:43 +00003343template<typename Derived>
3344Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003345TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003346 // FIXME: Implement this
3347 assert(false && "Cannot transform an Objective-C @finally statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003348 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003349}
Mike Stump1eb44332009-09-09 15:08:12 +00003350
Douglas Gregor43959a92009-08-20 07:17:43 +00003351template<typename Derived>
3352Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003353TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003354 // FIXME: Implement this
3355 assert(false && "Cannot transform an Objective-C @throw statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003356 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003357}
Mike Stump1eb44332009-09-09 15:08:12 +00003358
Douglas Gregor43959a92009-08-20 07:17:43 +00003359template<typename Derived>
3360Sema::OwningStmtResult
3361TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
Mike Stump1eb44332009-09-09 15:08:12 +00003362 ObjCAtSynchronizedStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003363 // FIXME: Implement this
3364 assert(false && "Cannot transform an Objective-C @synchronized statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003365 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003366}
3367
3368template<typename Derived>
3369Sema::OwningStmtResult
3370TreeTransform<Derived>::TransformObjCForCollectionStmt(
Mike Stump1eb44332009-09-09 15:08:12 +00003371 ObjCForCollectionStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003372 // FIXME: Implement this
3373 assert(false && "Cannot transform an Objective-C for-each statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003374 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003375}
3376
3377
3378template<typename Derived>
3379Sema::OwningStmtResult
3380TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
3381 // Transform the exception declaration, if any.
3382 VarDecl *Var = 0;
3383 if (S->getExceptionDecl()) {
3384 VarDecl *ExceptionDecl = S->getExceptionDecl();
3385 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
3386 ExceptionDecl->getDeclName());
3387
3388 QualType T = getDerived().TransformType(ExceptionDecl->getType());
3389 if (T.isNull())
3390 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003391
Douglas Gregor43959a92009-08-20 07:17:43 +00003392 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
3393 T,
3394 ExceptionDecl->getDeclaratorInfo(),
3395 ExceptionDecl->getIdentifier(),
3396 ExceptionDecl->getLocation(),
3397 /*FIXME: Inaccurate*/
3398 SourceRange(ExceptionDecl->getLocation()));
3399 if (!Var || Var->isInvalidDecl()) {
3400 if (Var)
3401 Var->Destroy(SemaRef.Context);
3402 return SemaRef.StmtError();
3403 }
3404 }
Mike Stump1eb44332009-09-09 15:08:12 +00003405
Douglas Gregor43959a92009-08-20 07:17:43 +00003406 // Transform the actual exception handler.
3407 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
3408 if (Handler.isInvalid()) {
3409 if (Var)
3410 Var->Destroy(SemaRef.Context);
3411 return SemaRef.StmtError();
3412 }
Mike Stump1eb44332009-09-09 15:08:12 +00003413
Douglas Gregor43959a92009-08-20 07:17:43 +00003414 if (!getDerived().AlwaysRebuild() &&
3415 !Var &&
3416 Handler.get() == S->getHandlerBlock())
Mike Stump1eb44332009-09-09 15:08:12 +00003417 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003418
3419 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
3420 Var,
3421 move(Handler));
3422}
Mike Stump1eb44332009-09-09 15:08:12 +00003423
Douglas Gregor43959a92009-08-20 07:17:43 +00003424template<typename Derived>
3425Sema::OwningStmtResult
3426TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
3427 // Transform the try block itself.
Mike Stump1eb44332009-09-09 15:08:12 +00003428 OwningStmtResult TryBlock
Douglas Gregor43959a92009-08-20 07:17:43 +00003429 = getDerived().TransformCompoundStmt(S->getTryBlock());
3430 if (TryBlock.isInvalid())
3431 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003432
Douglas Gregor43959a92009-08-20 07:17:43 +00003433 // Transform the handlers.
3434 bool HandlerChanged = false;
3435 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
3436 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
Mike Stump1eb44332009-09-09 15:08:12 +00003437 OwningStmtResult Handler
Douglas Gregor43959a92009-08-20 07:17:43 +00003438 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
3439 if (Handler.isInvalid())
3440 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003441
Douglas Gregor43959a92009-08-20 07:17:43 +00003442 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
3443 Handlers.push_back(Handler.takeAs<Stmt>());
3444 }
Mike Stump1eb44332009-09-09 15:08:12 +00003445
Douglas Gregor43959a92009-08-20 07:17:43 +00003446 if (!getDerived().AlwaysRebuild() &&
3447 TryBlock.get() == S->getTryBlock() &&
3448 !HandlerChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00003449 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003450
3451 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
Mike Stump1eb44332009-09-09 15:08:12 +00003452 move_arg(Handlers));
Douglas Gregor43959a92009-08-20 07:17:43 +00003453}
Mike Stump1eb44332009-09-09 15:08:12 +00003454
Douglas Gregor43959a92009-08-20 07:17:43 +00003455//===----------------------------------------------------------------------===//
Douglas Gregorb98b1992009-08-11 05:31:07 +00003456// Expression transformation
3457//===----------------------------------------------------------------------===//
Mike Stump1eb44332009-09-09 15:08:12 +00003458template<typename Derived>
3459Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003460TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E,
3461 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003462 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003463}
Mike Stump1eb44332009-09-09 15:08:12 +00003464
3465template<typename Derived>
3466Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003467TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E,
3468 bool isAddressOfOperand) {
Douglas Gregora2813ce2009-10-23 18:54:35 +00003469 NestedNameSpecifier *Qualifier = 0;
3470 if (E->getQualifier()) {
3471 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3472 E->getQualifierRange());
3473 if (!Qualifier)
3474 return SemaRef.ExprError();
3475 }
3476
Mike Stump1eb44332009-09-09 15:08:12 +00003477 NamedDecl *ND
Douglas Gregorb98b1992009-08-11 05:31:07 +00003478 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3479 if (!ND)
3480 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003481
Douglas Gregora2813ce2009-10-23 18:54:35 +00003482 if (!getDerived().AlwaysRebuild() &&
3483 Qualifier == E->getQualifier() &&
3484 ND == E->getDecl() &&
3485 !E->hasExplicitTemplateArgumentList())
Mike Stump1eb44332009-09-09 15:08:12 +00003486 return SemaRef.Owned(E->Retain());
3487
Douglas Gregora2813ce2009-10-23 18:54:35 +00003488 // FIXME: We're losing the explicit template arguments in this transformation.
3489
John McCall833ca992009-10-29 08:12:44 +00003490 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregora2813ce2009-10-23 18:54:35 +00003491 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall833ca992009-10-29 08:12:44 +00003492 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
3493 TransArgs[I]))
Douglas Gregora2813ce2009-10-23 18:54:35 +00003494 return SemaRef.ExprError();
Douglas Gregora2813ce2009-10-23 18:54:35 +00003495 }
3496
3497 // FIXME: Pass the qualifier/qualifier range along.
3498 return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003499 ND, E->getLocation(),
3500 isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003501}
Mike Stump1eb44332009-09-09 15:08:12 +00003502
Douglas Gregorb98b1992009-08-11 05:31:07 +00003503template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003504Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003505TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E,
3506 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003507 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003508}
Mike Stump1eb44332009-09-09 15:08:12 +00003509
Douglas Gregorb98b1992009-08-11 05:31:07 +00003510template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003511Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003512TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E,
3513 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003514 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003515}
Mike Stump1eb44332009-09-09 15:08:12 +00003516
Douglas Gregorb98b1992009-08-11 05:31:07 +00003517template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003518Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003519TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E,
3520 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003521 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003522}
Mike Stump1eb44332009-09-09 15:08:12 +00003523
Douglas Gregorb98b1992009-08-11 05:31:07 +00003524template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003525Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003526TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E,
3527 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003528 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003529}
Mike Stump1eb44332009-09-09 15:08:12 +00003530
Douglas Gregorb98b1992009-08-11 05:31:07 +00003531template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003532Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003533TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E,
3534 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003535 return SemaRef.Owned(E->Retain());
3536}
3537
3538template<typename Derived>
3539Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003540TreeTransform<Derived>::TransformParenExpr(ParenExpr *E,
3541 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003542 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3543 if (SubExpr.isInvalid())
3544 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003545
Douglas Gregorb98b1992009-08-11 05:31:07 +00003546 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003547 return SemaRef.Owned(E->Retain());
3548
3549 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003550 E->getRParen());
3551}
3552
Mike Stump1eb44332009-09-09 15:08:12 +00003553template<typename Derived>
3554Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003555TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E,
3556 bool isAddressOfOperand) {
3557 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr(),
3558 E->getOpcode() == UnaryOperator::AddrOf);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003559 if (SubExpr.isInvalid())
3560 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003561
Douglas Gregorb98b1992009-08-11 05:31:07 +00003562 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003563 return SemaRef.Owned(E->Retain());
3564
Douglas Gregorb98b1992009-08-11 05:31:07 +00003565 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
3566 E->getOpcode(),
3567 move(SubExpr));
3568}
Mike Stump1eb44332009-09-09 15:08:12 +00003569
Douglas Gregorb98b1992009-08-11 05:31:07 +00003570template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003571Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003572TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
3573 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003574 if (E->isArgumentType()) {
John McCall5ab75172009-11-04 07:28:41 +00003575 DeclaratorInfo *OldT = E->getArgumentTypeInfo();
Douglas Gregor5557b252009-10-28 00:29:27 +00003576
John McCall5ab75172009-11-04 07:28:41 +00003577 DeclaratorInfo *NewT = getDerived().TransformType(OldT);
3578 if (!NewT)
Douglas Gregorb98b1992009-08-11 05:31:07 +00003579 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003580
John McCall5ab75172009-11-04 07:28:41 +00003581 if (!getDerived().AlwaysRebuild() && OldT == NewT)
Douglas Gregorb98b1992009-08-11 05:31:07 +00003582 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003583
John McCall5ab75172009-11-04 07:28:41 +00003584 return getDerived().RebuildSizeOfAlignOf(NewT, E->getOperatorLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00003585 E->isSizeOf(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003586 E->getSourceRange());
3587 }
Mike Stump1eb44332009-09-09 15:08:12 +00003588
Douglas Gregorb98b1992009-08-11 05:31:07 +00003589 Sema::OwningExprResult SubExpr(SemaRef);
Mike Stump1eb44332009-09-09 15:08:12 +00003590 {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003591 // C++0x [expr.sizeof]p1:
3592 // The operand is either an expression, which is an unevaluated operand
3593 // [...]
3594 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00003595
Douglas Gregorb98b1992009-08-11 05:31:07 +00003596 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
3597 if (SubExpr.isInvalid())
3598 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003599
Douglas Gregorb98b1992009-08-11 05:31:07 +00003600 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
3601 return SemaRef.Owned(E->Retain());
3602 }
Mike Stump1eb44332009-09-09 15:08:12 +00003603
Douglas Gregorb98b1992009-08-11 05:31:07 +00003604 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
3605 E->isSizeOf(),
3606 E->getSourceRange());
3607}
Mike Stump1eb44332009-09-09 15:08:12 +00003608
Douglas Gregorb98b1992009-08-11 05:31:07 +00003609template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003610Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003611TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E,
3612 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003613 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3614 if (LHS.isInvalid())
3615 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003616
Douglas Gregorb98b1992009-08-11 05:31:07 +00003617 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3618 if (RHS.isInvalid())
3619 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003620
3621
Douglas Gregorb98b1992009-08-11 05:31:07 +00003622 if (!getDerived().AlwaysRebuild() &&
3623 LHS.get() == E->getLHS() &&
3624 RHS.get() == E->getRHS())
3625 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003626
Douglas Gregorb98b1992009-08-11 05:31:07 +00003627 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3628 /*FIXME:*/E->getLHS()->getLocStart(),
3629 move(RHS),
3630 E->getRBracketLoc());
3631}
Mike Stump1eb44332009-09-09 15:08:12 +00003632
3633template<typename Derived>
3634Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003635TreeTransform<Derived>::TransformCallExpr(CallExpr *E,
3636 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003637 // Transform the callee.
3638 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3639 if (Callee.isInvalid())
3640 return SemaRef.ExprError();
3641
3642 // Transform arguments.
3643 bool ArgChanged = false;
3644 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3645 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3646 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3647 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3648 if (Arg.isInvalid())
3649 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003650
Douglas Gregorb98b1992009-08-11 05:31:07 +00003651 // FIXME: Wrong source location information for the ','.
3652 FakeCommaLocs.push_back(
3653 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
Mike Stump1eb44332009-09-09 15:08:12 +00003654
3655 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003656 Args.push_back(Arg.takeAs<Expr>());
3657 }
Mike Stump1eb44332009-09-09 15:08:12 +00003658
Douglas Gregorb98b1992009-08-11 05:31:07 +00003659 if (!getDerived().AlwaysRebuild() &&
3660 Callee.get() == E->getCallee() &&
3661 !ArgChanged)
3662 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003663
Douglas Gregorb98b1992009-08-11 05:31:07 +00003664 // FIXME: Wrong source location information for the '('.
Mike Stump1eb44332009-09-09 15:08:12 +00003665 SourceLocation FakeLParenLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003666 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3667 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3668 move_arg(Args),
3669 FakeCommaLocs.data(),
3670 E->getRParenLoc());
3671}
Mike Stump1eb44332009-09-09 15:08:12 +00003672
3673template<typename Derived>
3674Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003675TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E,
3676 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003677 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3678 if (Base.isInvalid())
3679 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003680
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003681 NestedNameSpecifier *Qualifier = 0;
3682 if (E->hasQualifier()) {
Mike Stump1eb44332009-09-09 15:08:12 +00003683 Qualifier
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003684 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3685 E->getQualifierRange());
Douglas Gregorc4bf26f2009-09-01 00:37:14 +00003686 if (Qualifier == 0)
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003687 return SemaRef.ExprError();
3688 }
Mike Stump1eb44332009-09-09 15:08:12 +00003689
3690 NamedDecl *Member
Douglas Gregorb98b1992009-08-11 05:31:07 +00003691 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3692 if (!Member)
3693 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003694
Douglas Gregorb98b1992009-08-11 05:31:07 +00003695 if (!getDerived().AlwaysRebuild() &&
3696 Base.get() == E->getBase() &&
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003697 Qualifier == E->getQualifier() &&
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003698 Member == E->getMemberDecl() &&
3699 !E->hasExplicitTemplateArgumentList())
Mike Stump1eb44332009-09-09 15:08:12 +00003700 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003701
John McCalld5532b62009-11-23 01:53:49 +00003702 TemplateArgumentListInfo TransArgs;
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003703 if (E->hasExplicitTemplateArgumentList()) {
John McCalld5532b62009-11-23 01:53:49 +00003704 TransArgs.setLAngleLoc(E->getLAngleLoc());
3705 TransArgs.setRAngleLoc(E->getRAngleLoc());
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003706 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCalld5532b62009-11-23 01:53:49 +00003707 TemplateArgumentLoc Loc;
3708 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003709 return SemaRef.ExprError();
John McCalld5532b62009-11-23 01:53:49 +00003710 TransArgs.addArgument(Loc);
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003711 }
3712 }
3713
Douglas Gregorb98b1992009-08-11 05:31:07 +00003714 // FIXME: Bogus source location for the operator
3715 SourceLocation FakeOperatorLoc
3716 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3717
3718 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3719 E->isArrow(),
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003720 Qualifier,
3721 E->getQualifierRange(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003722 E->getMemberLoc(),
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003723 Member,
John McCalld5532b62009-11-23 01:53:49 +00003724 (E->hasExplicitTemplateArgumentList()
3725 ? &TransArgs : 0),
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003726 0);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003727}
Mike Stump1eb44332009-09-09 15:08:12 +00003728
Douglas Gregorb98b1992009-08-11 05:31:07 +00003729template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00003730Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003731TreeTransform<Derived>::TransformCastExpr(CastExpr *E,
3732 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003733 assert(false && "Cannot transform abstract class");
3734 return SemaRef.Owned(E->Retain());
3735}
3736
3737template<typename Derived>
3738Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003739TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E,
3740 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003741 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3742 if (LHS.isInvalid())
3743 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003744
Douglas Gregorb98b1992009-08-11 05:31:07 +00003745 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3746 if (RHS.isInvalid())
3747 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003748
Douglas Gregorb98b1992009-08-11 05:31:07 +00003749 if (!getDerived().AlwaysRebuild() &&
3750 LHS.get() == E->getLHS() &&
3751 RHS.get() == E->getRHS())
Mike Stump1eb44332009-09-09 15:08:12 +00003752 return SemaRef.Owned(E->Retain());
3753
Douglas Gregorb98b1992009-08-11 05:31:07 +00003754 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3755 move(LHS), move(RHS));
3756}
3757
Mike Stump1eb44332009-09-09 15:08:12 +00003758template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00003759Sema::OwningExprResult
3760TreeTransform<Derived>::TransformCompoundAssignOperator(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003761 CompoundAssignOperator *E,
3762 bool isAddressOfOperand) {
3763 return getDerived().TransformBinaryOperator(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003764}
Mike Stump1eb44332009-09-09 15:08:12 +00003765
Douglas Gregorb98b1992009-08-11 05:31:07 +00003766template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003767Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003768TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E,
3769 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003770 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3771 if (Cond.isInvalid())
3772 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003773
Douglas Gregorb98b1992009-08-11 05:31:07 +00003774 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3775 if (LHS.isInvalid())
3776 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003777
Douglas Gregorb98b1992009-08-11 05:31:07 +00003778 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3779 if (RHS.isInvalid())
3780 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003781
Douglas Gregorb98b1992009-08-11 05:31:07 +00003782 if (!getDerived().AlwaysRebuild() &&
3783 Cond.get() == E->getCond() &&
3784 LHS.get() == E->getLHS() &&
3785 RHS.get() == E->getRHS())
3786 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003787
3788 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor47e1f7c2009-08-26 14:37:04 +00003789 E->getQuestionLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00003790 move(LHS),
Douglas Gregor47e1f7c2009-08-26 14:37:04 +00003791 E->getColonLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003792 move(RHS));
3793}
Mike Stump1eb44332009-09-09 15:08:12 +00003794
3795template<typename Derived>
3796Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003797TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E,
3798 bool isAddressOfOperand) {
Douglas Gregor5557b252009-10-28 00:29:27 +00003799 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3800
3801 // FIXME: Will we ever have type information here? It seems like we won't,
3802 // so do we even need to transform the type?
Douglas Gregorb98b1992009-08-11 05:31:07 +00003803 QualType T = getDerived().TransformType(E->getType());
3804 if (T.isNull())
3805 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003806
Douglas Gregorb98b1992009-08-11 05:31:07 +00003807 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3808 if (SubExpr.isInvalid())
3809 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003810
Douglas Gregorb98b1992009-08-11 05:31:07 +00003811 if (!getDerived().AlwaysRebuild() &&
3812 T == E->getType() &&
3813 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003814 return SemaRef.Owned(E->Retain());
3815
Douglas Gregorb98b1992009-08-11 05:31:07 +00003816 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
Mike Stump1eb44332009-09-09 15:08:12 +00003817 move(SubExpr),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003818 E->isLvalueCast());
3819}
Mike Stump1eb44332009-09-09 15:08:12 +00003820
Douglas Gregorb98b1992009-08-11 05:31:07 +00003821template<typename Derived>
3822Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003823TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E,
3824 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003825 assert(false && "Cannot transform abstract class");
3826 return SemaRef.Owned(E->Retain());
3827}
3828
3829template<typename Derived>
3830Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003831TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E,
3832 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003833 QualType T;
3834 {
3835 // FIXME: Source location isn't quite accurate.
Mike Stump1eb44332009-09-09 15:08:12 +00003836 SourceLocation TypeStartLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003837 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3838 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003839
Douglas Gregorb98b1992009-08-11 05:31:07 +00003840 T = getDerived().TransformType(E->getTypeAsWritten());
3841 if (T.isNull())
3842 return SemaRef.ExprError();
3843 }
Mike Stump1eb44332009-09-09 15:08:12 +00003844
Douglas Gregorb98b1992009-08-11 05:31:07 +00003845 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3846 if (SubExpr.isInvalid())
3847 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003848
Douglas Gregorb98b1992009-08-11 05:31:07 +00003849 if (!getDerived().AlwaysRebuild() &&
3850 T == E->getTypeAsWritten() &&
3851 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003852 return SemaRef.Owned(E->Retain());
3853
Douglas Gregorb98b1992009-08-11 05:31:07 +00003854 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3855 E->getRParenLoc(),
3856 move(SubExpr));
3857}
Mike Stump1eb44332009-09-09 15:08:12 +00003858
Douglas Gregorb98b1992009-08-11 05:31:07 +00003859template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003860Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003861TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E,
3862 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003863 QualType T;
3864 {
3865 // FIXME: Source location isn't quite accurate.
Mike Stump1eb44332009-09-09 15:08:12 +00003866 SourceLocation FakeTypeLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003867 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3868 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003869
Douglas Gregorb98b1992009-08-11 05:31:07 +00003870 T = getDerived().TransformType(E->getType());
3871 if (T.isNull())
3872 return SemaRef.ExprError();
3873 }
Mike Stump1eb44332009-09-09 15:08:12 +00003874
Douglas Gregorb98b1992009-08-11 05:31:07 +00003875 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3876 if (Init.isInvalid())
3877 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003878
Douglas Gregorb98b1992009-08-11 05:31:07 +00003879 if (!getDerived().AlwaysRebuild() &&
3880 T == E->getType() &&
3881 Init.get() == E->getInitializer())
Mike Stump1eb44332009-09-09 15:08:12 +00003882 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003883
3884 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3885 /*FIXME:*/E->getInitializer()->getLocEnd(),
3886 move(Init));
3887}
Mike Stump1eb44332009-09-09 15:08:12 +00003888
Douglas Gregorb98b1992009-08-11 05:31:07 +00003889template<typename Derived>
3890Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003891TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E,
3892 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003893 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3894 if (Base.isInvalid())
3895 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003896
Douglas Gregorb98b1992009-08-11 05:31:07 +00003897 if (!getDerived().AlwaysRebuild() &&
3898 Base.get() == E->getBase())
Mike Stump1eb44332009-09-09 15:08:12 +00003899 return SemaRef.Owned(E->Retain());
3900
Douglas Gregorb98b1992009-08-11 05:31:07 +00003901 // FIXME: Bad source location
Mike Stump1eb44332009-09-09 15:08:12 +00003902 SourceLocation FakeOperatorLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003903 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3904 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3905 E->getAccessorLoc(),
3906 E->getAccessor());
3907}
Mike Stump1eb44332009-09-09 15:08:12 +00003908
Douglas Gregorb98b1992009-08-11 05:31:07 +00003909template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003910Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003911TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E,
3912 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003913 bool InitChanged = false;
Mike Stump1eb44332009-09-09 15:08:12 +00003914
Douglas Gregorb98b1992009-08-11 05:31:07 +00003915 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3916 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3917 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3918 if (Init.isInvalid())
3919 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003920
Douglas Gregorb98b1992009-08-11 05:31:07 +00003921 InitChanged = InitChanged || Init.get() != E->getInit(I);
3922 Inits.push_back(Init.takeAs<Expr>());
3923 }
Mike Stump1eb44332009-09-09 15:08:12 +00003924
Douglas Gregorb98b1992009-08-11 05:31:07 +00003925 if (!getDerived().AlwaysRebuild() && !InitChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00003926 return SemaRef.Owned(E->Retain());
3927
Douglas Gregorb98b1992009-08-11 05:31:07 +00003928 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
Douglas Gregore48319a2009-11-09 17:16:50 +00003929 E->getRBraceLoc(), E->getType());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003930}
Mike Stump1eb44332009-09-09 15:08:12 +00003931
Douglas Gregorb98b1992009-08-11 05:31:07 +00003932template<typename Derived>
3933Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003934TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E,
3935 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003936 Designation Desig;
Mike Stump1eb44332009-09-09 15:08:12 +00003937
Douglas Gregor43959a92009-08-20 07:17:43 +00003938 // transform the initializer value
Douglas Gregorb98b1992009-08-11 05:31:07 +00003939 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3940 if (Init.isInvalid())
3941 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003942
Douglas Gregor43959a92009-08-20 07:17:43 +00003943 // transform the designators.
Douglas Gregorb98b1992009-08-11 05:31:07 +00003944 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3945 bool ExprChanged = false;
3946 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3947 DEnd = E->designators_end();
3948 D != DEnd; ++D) {
3949 if (D->isFieldDesignator()) {
3950 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3951 D->getDotLoc(),
3952 D->getFieldLoc()));
3953 continue;
3954 }
Mike Stump1eb44332009-09-09 15:08:12 +00003955
Douglas Gregorb98b1992009-08-11 05:31:07 +00003956 if (D->isArrayDesignator()) {
3957 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3958 if (Index.isInvalid())
3959 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003960
3961 Desig.AddDesignator(Designator::getArray(Index.get(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003962 D->getLBracketLoc()));
Mike Stump1eb44332009-09-09 15:08:12 +00003963
Douglas Gregorb98b1992009-08-11 05:31:07 +00003964 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3965 ArrayExprs.push_back(Index.release());
3966 continue;
3967 }
Mike Stump1eb44332009-09-09 15:08:12 +00003968
Douglas Gregorb98b1992009-08-11 05:31:07 +00003969 assert(D->isArrayRangeDesignator() && "New kind of designator?");
Mike Stump1eb44332009-09-09 15:08:12 +00003970 OwningExprResult Start
Douglas Gregorb98b1992009-08-11 05:31:07 +00003971 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3972 if (Start.isInvalid())
3973 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003974
Douglas Gregorb98b1992009-08-11 05:31:07 +00003975 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3976 if (End.isInvalid())
3977 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003978
3979 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003980 End.get(),
3981 D->getLBracketLoc(),
3982 D->getEllipsisLoc()));
Mike Stump1eb44332009-09-09 15:08:12 +00003983
Douglas Gregorb98b1992009-08-11 05:31:07 +00003984 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3985 End.get() != E->getArrayRangeEnd(*D);
Mike Stump1eb44332009-09-09 15:08:12 +00003986
Douglas Gregorb98b1992009-08-11 05:31:07 +00003987 ArrayExprs.push_back(Start.release());
3988 ArrayExprs.push_back(End.release());
3989 }
Mike Stump1eb44332009-09-09 15:08:12 +00003990
Douglas Gregorb98b1992009-08-11 05:31:07 +00003991 if (!getDerived().AlwaysRebuild() &&
3992 Init.get() == E->getInit() &&
3993 !ExprChanged)
3994 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003995
Douglas Gregorb98b1992009-08-11 05:31:07 +00003996 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3997 E->getEqualOrColonLoc(),
3998 E->usesGNUSyntax(), move(Init));
3999}
Mike Stump1eb44332009-09-09 15:08:12 +00004000
Douglas Gregorb98b1992009-08-11 05:31:07 +00004001template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004002Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00004003TreeTransform<Derived>::TransformImplicitValueInitExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004004 ImplicitValueInitExpr *E,
4005 bool isAddressOfOperand) {
Douglas Gregor5557b252009-10-28 00:29:27 +00004006 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
4007
4008 // FIXME: Will we ever have proper type location here? Will we actually
4009 // need to transform the type?
Douglas Gregorb98b1992009-08-11 05:31:07 +00004010 QualType T = getDerived().TransformType(E->getType());
4011 if (T.isNull())
4012 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004013
Douglas Gregorb98b1992009-08-11 05:31:07 +00004014 if (!getDerived().AlwaysRebuild() &&
4015 T == E->getType())
Mike Stump1eb44332009-09-09 15:08:12 +00004016 return SemaRef.Owned(E->Retain());
4017
Douglas Gregorb98b1992009-08-11 05:31:07 +00004018 return getDerived().RebuildImplicitValueInitExpr(T);
4019}
Mike Stump1eb44332009-09-09 15:08:12 +00004020
Douglas Gregorb98b1992009-08-11 05:31:07 +00004021template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004022Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004023TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E,
4024 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004025 // FIXME: Do we want the type as written?
4026 QualType T;
Mike Stump1eb44332009-09-09 15:08:12 +00004027
Douglas Gregorb98b1992009-08-11 05:31:07 +00004028 {
4029 // FIXME: Source location isn't quite accurate.
4030 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
4031 T = getDerived().TransformType(E->getType());
4032 if (T.isNull())
4033 return SemaRef.ExprError();
4034 }
Mike Stump1eb44332009-09-09 15:08:12 +00004035
Douglas Gregorb98b1992009-08-11 05:31:07 +00004036 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4037 if (SubExpr.isInvalid())
4038 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004039
Douglas Gregorb98b1992009-08-11 05:31:07 +00004040 if (!getDerived().AlwaysRebuild() &&
4041 T == E->getType() &&
4042 SubExpr.get() == E->getSubExpr())
4043 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004044
Douglas Gregorb98b1992009-08-11 05:31:07 +00004045 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
4046 T, E->getRParenLoc());
4047}
4048
4049template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004050Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004051TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E,
4052 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004053 bool ArgumentChanged = false;
4054 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
4055 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
4056 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
4057 if (Init.isInvalid())
4058 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004059
Douglas Gregorb98b1992009-08-11 05:31:07 +00004060 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
4061 Inits.push_back(Init.takeAs<Expr>());
4062 }
Mike Stump1eb44332009-09-09 15:08:12 +00004063
Douglas Gregorb98b1992009-08-11 05:31:07 +00004064 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
4065 move_arg(Inits),
4066 E->getRParenLoc());
4067}
Mike Stump1eb44332009-09-09 15:08:12 +00004068
Douglas Gregorb98b1992009-08-11 05:31:07 +00004069/// \brief Transform an address-of-label expression.
4070///
4071/// By default, the transformation of an address-of-label expression always
4072/// rebuilds the expression, so that the label identifier can be resolved to
4073/// the corresponding label statement by semantic analysis.
4074template<typename Derived>
4075Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004076TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E,
4077 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004078 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
4079 E->getLabel());
4080}
Mike Stump1eb44332009-09-09 15:08:12 +00004081
4082template<typename Derived>
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004083Sema::OwningExprResult
4084TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E,
4085 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004086 OwningStmtResult SubStmt
Douglas Gregorb98b1992009-08-11 05:31:07 +00004087 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
4088 if (SubStmt.isInvalid())
4089 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004090
Douglas Gregorb98b1992009-08-11 05:31:07 +00004091 if (!getDerived().AlwaysRebuild() &&
4092 SubStmt.get() == E->getSubStmt())
4093 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004094
4095 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004096 move(SubStmt),
4097 E->getRParenLoc());
4098}
Mike Stump1eb44332009-09-09 15:08:12 +00004099
Douglas Gregorb98b1992009-08-11 05:31:07 +00004100template<typename Derived>
4101Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004102TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E,
4103 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004104 QualType T1, T2;
4105 {
4106 // FIXME: Source location isn't quite accurate.
4107 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004108
Douglas Gregorb98b1992009-08-11 05:31:07 +00004109 T1 = getDerived().TransformType(E->getArgType1());
4110 if (T1.isNull())
4111 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004112
Douglas Gregorb98b1992009-08-11 05:31:07 +00004113 T2 = getDerived().TransformType(E->getArgType2());
4114 if (T2.isNull())
4115 return SemaRef.ExprError();
4116 }
4117
4118 if (!getDerived().AlwaysRebuild() &&
4119 T1 == E->getArgType1() &&
4120 T2 == E->getArgType2())
Mike Stump1eb44332009-09-09 15:08:12 +00004121 return SemaRef.Owned(E->Retain());
4122
Douglas Gregorb98b1992009-08-11 05:31:07 +00004123 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
4124 T1, T2, E->getRParenLoc());
4125}
Mike Stump1eb44332009-09-09 15:08:12 +00004126
Douglas Gregorb98b1992009-08-11 05:31:07 +00004127template<typename Derived>
4128Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004129TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E,
4130 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004131 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
4132 if (Cond.isInvalid())
4133 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004134
Douglas Gregorb98b1992009-08-11 05:31:07 +00004135 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
4136 if (LHS.isInvalid())
4137 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004138
Douglas Gregorb98b1992009-08-11 05:31:07 +00004139 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
4140 if (RHS.isInvalid())
4141 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004142
Douglas Gregorb98b1992009-08-11 05:31:07 +00004143 if (!getDerived().AlwaysRebuild() &&
4144 Cond.get() == E->getCond() &&
4145 LHS.get() == E->getLHS() &&
4146 RHS.get() == E->getRHS())
Mike Stump1eb44332009-09-09 15:08:12 +00004147 return SemaRef.Owned(E->Retain());
4148
Douglas Gregorb98b1992009-08-11 05:31:07 +00004149 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
4150 move(Cond), move(LHS), move(RHS),
4151 E->getRParenLoc());
4152}
Mike Stump1eb44332009-09-09 15:08:12 +00004153
Douglas Gregorb98b1992009-08-11 05:31:07 +00004154template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004155Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004156TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E,
4157 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004158 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004159}
4160
4161template<typename Derived>
4162Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004163TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E,
4164 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004165 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
4166 if (Callee.isInvalid())
4167 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004168
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004169 OwningExprResult First
4170 = getDerived().TransformExpr(E->getArg(0),
4171 E->getNumArgs() == 1 && E->getOperator() == OO_Amp);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004172 if (First.isInvalid())
4173 return SemaRef.ExprError();
4174
4175 OwningExprResult Second(SemaRef);
4176 if (E->getNumArgs() == 2) {
4177 Second = getDerived().TransformExpr(E->getArg(1));
4178 if (Second.isInvalid())
4179 return SemaRef.ExprError();
4180 }
Mike Stump1eb44332009-09-09 15:08:12 +00004181
Douglas Gregorb98b1992009-08-11 05:31:07 +00004182 if (!getDerived().AlwaysRebuild() &&
4183 Callee.get() == E->getCallee() &&
4184 First.get() == E->getArg(0) &&
Mike Stump1eb44332009-09-09 15:08:12 +00004185 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
4186 return SemaRef.Owned(E->Retain());
4187
Douglas Gregorb98b1992009-08-11 05:31:07 +00004188 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
4189 E->getOperatorLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00004190 move(Callee),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004191 move(First),
4192 move(Second));
4193}
Mike Stump1eb44332009-09-09 15:08:12 +00004194
Douglas Gregorb98b1992009-08-11 05:31:07 +00004195template<typename Derived>
4196Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004197TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E,
4198 bool isAddressOfOperand) {
4199 return getDerived().TransformCallExpr(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004200}
Mike Stump1eb44332009-09-09 15:08:12 +00004201
Douglas Gregorb98b1992009-08-11 05:31:07 +00004202template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004203Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004204TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E,
4205 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004206 QualType ExplicitTy;
4207 {
4208 // FIXME: Source location isn't quite accurate.
Mike Stump1eb44332009-09-09 15:08:12 +00004209 SourceLocation TypeStartLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00004210 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4211 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004212
Douglas Gregorb98b1992009-08-11 05:31:07 +00004213 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4214 if (ExplicitTy.isNull())
4215 return SemaRef.ExprError();
4216 }
Mike Stump1eb44332009-09-09 15:08:12 +00004217
Douglas Gregorb98b1992009-08-11 05:31:07 +00004218 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4219 if (SubExpr.isInvalid())
4220 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004221
Douglas Gregorb98b1992009-08-11 05:31:07 +00004222 if (!getDerived().AlwaysRebuild() &&
4223 ExplicitTy == E->getTypeAsWritten() &&
4224 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00004225 return SemaRef.Owned(E->Retain());
4226
Douglas Gregorb98b1992009-08-11 05:31:07 +00004227 // FIXME: Poor source location information here.
Mike Stump1eb44332009-09-09 15:08:12 +00004228 SourceLocation FakeLAngleLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00004229 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4230 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
4231 SourceLocation FakeRParenLoc
4232 = SemaRef.PP.getLocForEndOfToken(
4233 E->getSubExpr()->getSourceRange().getEnd());
4234 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00004235 E->getStmtClass(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004236 FakeLAngleLoc,
4237 ExplicitTy,
4238 FakeRAngleLoc,
4239 FakeRAngleLoc,
4240 move(SubExpr),
4241 FakeRParenLoc);
4242}
Mike Stump1eb44332009-09-09 15:08:12 +00004243
Douglas Gregorb98b1992009-08-11 05:31:07 +00004244template<typename Derived>
4245Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004246TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E,
4247 bool isAddressOfOperand) {
4248 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004249}
Mike Stump1eb44332009-09-09 15:08:12 +00004250
4251template<typename Derived>
4252Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004253TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E,
4254 bool isAddressOfOperand) {
4255 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Mike Stump1eb44332009-09-09 15:08:12 +00004256}
4257
Douglas Gregorb98b1992009-08-11 05:31:07 +00004258template<typename Derived>
4259Sema::OwningExprResult
4260TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004261 CXXReinterpretCastExpr *E,
4262 bool isAddressOfOperand) {
4263 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004264}
Mike Stump1eb44332009-09-09 15:08:12 +00004265
Douglas Gregorb98b1992009-08-11 05:31:07 +00004266template<typename Derived>
4267Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004268TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E,
4269 bool isAddressOfOperand) {
4270 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004271}
Mike Stump1eb44332009-09-09 15:08:12 +00004272
Douglas Gregorb98b1992009-08-11 05:31:07 +00004273template<typename Derived>
4274Sema::OwningExprResult
4275TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004276 CXXFunctionalCastExpr *E,
4277 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004278 QualType ExplicitTy;
4279 {
4280 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004281
Douglas Gregorb98b1992009-08-11 05:31:07 +00004282 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4283 if (ExplicitTy.isNull())
4284 return SemaRef.ExprError();
4285 }
Mike Stump1eb44332009-09-09 15:08:12 +00004286
Douglas Gregorb98b1992009-08-11 05:31:07 +00004287 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4288 if (SubExpr.isInvalid())
4289 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004290
Douglas Gregorb98b1992009-08-11 05:31:07 +00004291 if (!getDerived().AlwaysRebuild() &&
4292 ExplicitTy == E->getTypeAsWritten() &&
4293 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00004294 return SemaRef.Owned(E->Retain());
4295
Douglas Gregorb98b1992009-08-11 05:31:07 +00004296 // FIXME: The end of the type's source range is wrong
4297 return getDerived().RebuildCXXFunctionalCastExpr(
4298 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
4299 ExplicitTy,
4300 /*FIXME:*/E->getSubExpr()->getLocStart(),
4301 move(SubExpr),
4302 E->getRParenLoc());
4303}
Mike Stump1eb44332009-09-09 15:08:12 +00004304
Douglas Gregorb98b1992009-08-11 05:31:07 +00004305template<typename Derived>
4306Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004307TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E,
4308 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004309 if (E->isTypeOperand()) {
4310 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004311
Douglas Gregorb98b1992009-08-11 05:31:07 +00004312 QualType T = getDerived().TransformType(E->getTypeOperand());
4313 if (T.isNull())
4314 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004315
Douglas Gregorb98b1992009-08-11 05:31:07 +00004316 if (!getDerived().AlwaysRebuild() &&
4317 T == E->getTypeOperand())
4318 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004319
Douglas Gregorb98b1992009-08-11 05:31:07 +00004320 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4321 /*FIXME:*/E->getLocStart(),
4322 T,
4323 E->getLocEnd());
4324 }
Mike Stump1eb44332009-09-09 15:08:12 +00004325
Douglas Gregorb98b1992009-08-11 05:31:07 +00004326 // We don't know whether the expression is potentially evaluated until
4327 // after we perform semantic analysis, so the expression is potentially
4328 // potentially evaluated.
Mike Stump1eb44332009-09-09 15:08:12 +00004329 EnterExpressionEvaluationContext Unevaluated(SemaRef,
Douglas Gregorb98b1992009-08-11 05:31:07 +00004330 Action::PotentiallyPotentiallyEvaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00004331
Douglas Gregorb98b1992009-08-11 05:31:07 +00004332 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
4333 if (SubExpr.isInvalid())
4334 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004335
Douglas Gregorb98b1992009-08-11 05:31:07 +00004336 if (!getDerived().AlwaysRebuild() &&
4337 SubExpr.get() == E->getExprOperand())
Mike Stump1eb44332009-09-09 15:08:12 +00004338 return SemaRef.Owned(E->Retain());
4339
Douglas Gregorb98b1992009-08-11 05:31:07 +00004340 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4341 /*FIXME:*/E->getLocStart(),
4342 move(SubExpr),
4343 E->getLocEnd());
4344}
4345
4346template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004347Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004348TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E,
4349 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004350 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004351}
Mike Stump1eb44332009-09-09 15:08:12 +00004352
Douglas Gregorb98b1992009-08-11 05:31:07 +00004353template<typename Derived>
4354Sema::OwningExprResult
4355TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004356 CXXNullPtrLiteralExpr *E,
4357 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004358 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004359}
Mike Stump1eb44332009-09-09 15:08:12 +00004360
Douglas Gregorb98b1992009-08-11 05:31:07 +00004361template<typename Derived>
4362Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004363TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E,
4364 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004365 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004366
Douglas Gregorb98b1992009-08-11 05:31:07 +00004367 QualType T = getDerived().TransformType(E->getType());
4368 if (T.isNull())
4369 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004370
Douglas Gregorb98b1992009-08-11 05:31:07 +00004371 if (!getDerived().AlwaysRebuild() &&
4372 T == E->getType())
4373 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004374
Douglas Gregorb98b1992009-08-11 05:31:07 +00004375 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
4376}
Mike Stump1eb44332009-09-09 15:08:12 +00004377
Douglas Gregorb98b1992009-08-11 05:31:07 +00004378template<typename Derived>
4379Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004380TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E,
4381 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004382 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4383 if (SubExpr.isInvalid())
4384 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004385
Douglas Gregorb98b1992009-08-11 05:31:07 +00004386 if (!getDerived().AlwaysRebuild() &&
4387 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00004388 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004389
4390 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
4391}
Mike Stump1eb44332009-09-09 15:08:12 +00004392
Douglas Gregorb98b1992009-08-11 05:31:07 +00004393template<typename Derived>
4394Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004395TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E,
4396 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004397 ParmVarDecl *Param
Douglas Gregorb98b1992009-08-11 05:31:07 +00004398 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
4399 if (!Param)
4400 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004401
Douglas Gregorb98b1992009-08-11 05:31:07 +00004402 if (getDerived().AlwaysRebuild() &&
4403 Param == E->getParam())
4404 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004405
Douglas Gregorb98b1992009-08-11 05:31:07 +00004406 return getDerived().RebuildCXXDefaultArgExpr(Param);
4407}
Mike Stump1eb44332009-09-09 15:08:12 +00004408
Douglas Gregorb98b1992009-08-11 05:31:07 +00004409template<typename Derived>
4410Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004411TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E,
4412 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004413 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4414
4415 QualType T = getDerived().TransformType(E->getType());
4416 if (T.isNull())
4417 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004418
Douglas Gregorb98b1992009-08-11 05:31:07 +00004419 if (!getDerived().AlwaysRebuild() &&
4420 T == E->getType())
Mike Stump1eb44332009-09-09 15:08:12 +00004421 return SemaRef.Owned(E->Retain());
4422
4423 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004424 /*FIXME:*/E->getTypeBeginLoc(),
4425 T,
4426 E->getRParenLoc());
4427}
Mike Stump1eb44332009-09-09 15:08:12 +00004428
Douglas Gregorb98b1992009-08-11 05:31:07 +00004429template<typename Derived>
4430Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004431TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E,
4432 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004433 VarDecl *Var
Douglas Gregor43959a92009-08-20 07:17:43 +00004434 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregorb98b1992009-08-11 05:31:07 +00004435 if (!Var)
4436 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004437
Douglas Gregorb98b1992009-08-11 05:31:07 +00004438 if (!getDerived().AlwaysRebuild() &&
Mike Stump1eb44332009-09-09 15:08:12 +00004439 Var == E->getVarDecl())
Douglas Gregorb98b1992009-08-11 05:31:07 +00004440 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004441
4442 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004443 /*FIXME:*/E->getStartLoc(),
4444 Var);
4445}
Mike Stump1eb44332009-09-09 15:08:12 +00004446
Douglas Gregorb98b1992009-08-11 05:31:07 +00004447template<typename Derived>
4448Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004449TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E,
4450 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004451 // Transform the type that we're allocating
4452 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
4453 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
4454 if (AllocType.isNull())
4455 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004456
Douglas Gregorb98b1992009-08-11 05:31:07 +00004457 // Transform the size of the array we're allocating (if any).
4458 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
4459 if (ArraySize.isInvalid())
4460 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004461
Douglas Gregorb98b1992009-08-11 05:31:07 +00004462 // Transform the placement arguments (if any).
4463 bool ArgumentChanged = false;
4464 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
4465 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
4466 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
4467 if (Arg.isInvalid())
4468 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004469
Douglas Gregorb98b1992009-08-11 05:31:07 +00004470 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
4471 PlacementArgs.push_back(Arg.take());
4472 }
Mike Stump1eb44332009-09-09 15:08:12 +00004473
Douglas Gregor43959a92009-08-20 07:17:43 +00004474 // transform the constructor arguments (if any).
Douglas Gregorb98b1992009-08-11 05:31:07 +00004475 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
4476 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
4477 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
4478 if (Arg.isInvalid())
4479 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004480
Douglas Gregorb98b1992009-08-11 05:31:07 +00004481 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
4482 ConstructorArgs.push_back(Arg.take());
4483 }
Mike Stump1eb44332009-09-09 15:08:12 +00004484
Douglas Gregorb98b1992009-08-11 05:31:07 +00004485 if (!getDerived().AlwaysRebuild() &&
4486 AllocType == E->getAllocatedType() &&
4487 ArraySize.get() == E->getArraySize() &&
4488 !ArgumentChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00004489 return SemaRef.Owned(E->Retain());
4490
Douglas Gregorb98b1992009-08-11 05:31:07 +00004491 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
4492 E->isGlobalNew(),
4493 /*FIXME:*/E->getLocStart(),
4494 move_arg(PlacementArgs),
4495 /*FIXME:*/E->getLocStart(),
4496 E->isParenTypeId(),
4497 AllocType,
4498 /*FIXME:*/E->getLocStart(),
4499 /*FIXME:*/SourceRange(),
4500 move(ArraySize),
4501 /*FIXME:*/E->getLocStart(),
4502 move_arg(ConstructorArgs),
Mike Stump1eb44332009-09-09 15:08:12 +00004503 E->getLocEnd());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004504}
Mike Stump1eb44332009-09-09 15:08:12 +00004505
Douglas Gregorb98b1992009-08-11 05:31:07 +00004506template<typename Derived>
4507Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004508TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E,
4509 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004510 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
4511 if (Operand.isInvalid())
4512 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004513
Douglas Gregorb98b1992009-08-11 05:31:07 +00004514 if (!getDerived().AlwaysRebuild() &&
Mike Stump1eb44332009-09-09 15:08:12 +00004515 Operand.get() == E->getArgument())
4516 return SemaRef.Owned(E->Retain());
4517
Douglas Gregorb98b1992009-08-11 05:31:07 +00004518 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
4519 E->isGlobalDelete(),
4520 E->isArrayForm(),
4521 move(Operand));
4522}
Mike Stump1eb44332009-09-09 15:08:12 +00004523
Douglas Gregorb98b1992009-08-11 05:31:07 +00004524template<typename Derived>
4525Sema::OwningExprResult
Douglas Gregora71d8192009-09-04 17:36:40 +00004526TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004527 CXXPseudoDestructorExpr *E,
4528 bool isAddressOfOperand) {
Douglas Gregora71d8192009-09-04 17:36:40 +00004529 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4530 if (Base.isInvalid())
4531 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004532
Douglas Gregora71d8192009-09-04 17:36:40 +00004533 NestedNameSpecifier *Qualifier
4534 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4535 E->getQualifierRange());
4536 if (E->getQualifier() && !Qualifier)
4537 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004538
Douglas Gregora71d8192009-09-04 17:36:40 +00004539 QualType DestroyedType;
4540 {
4541 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
4542 DestroyedType = getDerived().TransformType(E->getDestroyedType());
4543 if (DestroyedType.isNull())
4544 return SemaRef.ExprError();
4545 }
Mike Stump1eb44332009-09-09 15:08:12 +00004546
Douglas Gregora71d8192009-09-04 17:36:40 +00004547 if (!getDerived().AlwaysRebuild() &&
4548 Base.get() == E->getBase() &&
4549 Qualifier == E->getQualifier() &&
4550 DestroyedType == E->getDestroyedType())
4551 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004552
Douglas Gregora71d8192009-09-04 17:36:40 +00004553 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
4554 E->getOperatorLoc(),
4555 E->isArrow(),
4556 E->getDestroyedTypeLoc(),
4557 DestroyedType,
4558 Qualifier,
4559 E->getQualifierRange());
4560}
Mike Stump1eb44332009-09-09 15:08:12 +00004561
Douglas Gregora71d8192009-09-04 17:36:40 +00004562template<typename Derived>
4563Sema::OwningExprResult
John McCallba135432009-11-21 08:51:07 +00004564TreeTransform<Derived>::TransformUnresolvedLookupExpr(
4565 UnresolvedLookupExpr *E,
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004566 bool isAddressOfOperand) {
John McCallba135432009-11-21 08:51:07 +00004567 // There is no transformation we can apply to an unresolved lookup.
Mike Stump1eb44332009-09-09 15:08:12 +00004568 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004569}
Mike Stump1eb44332009-09-09 15:08:12 +00004570
Douglas Gregorb98b1992009-08-11 05:31:07 +00004571template<typename Derived>
4572Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004573TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E,
4574 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004575 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004576
Douglas Gregorb98b1992009-08-11 05:31:07 +00004577 QualType T = getDerived().TransformType(E->getQueriedType());
4578 if (T.isNull())
4579 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004580
Douglas Gregorb98b1992009-08-11 05:31:07 +00004581 if (!getDerived().AlwaysRebuild() &&
4582 T == E->getQueriedType())
4583 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004584
Douglas Gregorb98b1992009-08-11 05:31:07 +00004585 // FIXME: Bad location information
4586 SourceLocation FakeLParenLoc
4587 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
Mike Stump1eb44332009-09-09 15:08:12 +00004588
4589 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004590 E->getLocStart(),
4591 /*FIXME:*/FakeLParenLoc,
4592 T,
4593 E->getLocEnd());
4594}
Mike Stump1eb44332009-09-09 15:08:12 +00004595
Douglas Gregorb98b1992009-08-11 05:31:07 +00004596template<typename Derived>
4597Sema::OwningExprResult
John McCall865d4472009-11-19 22:55:06 +00004598TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
4599 DependentScopeDeclRefExpr *E,
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004600 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004601 NestedNameSpecifier *NNS
Douglas Gregorf17bb742009-10-22 17:20:55 +00004602 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4603 E->getQualifierRange());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004604 if (!NNS)
4605 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004606
4607 DeclarationName Name
Douglas Gregor81499bb2009-09-03 22:13:48 +00004608 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
4609 if (!Name)
4610 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004611
4612 if (!getDerived().AlwaysRebuild() &&
Douglas Gregorb98b1992009-08-11 05:31:07 +00004613 NNS == E->getQualifier() &&
4614 Name == E->getDeclName())
Mike Stump1eb44332009-09-09 15:08:12 +00004615 return SemaRef.Owned(E->Retain());
4616
John McCall865d4472009-11-19 22:55:06 +00004617 return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
Douglas Gregorb98b1992009-08-11 05:31:07 +00004618 E->getQualifierRange(),
4619 Name,
4620 E->getLocation(),
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004621 isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004622}
4623
4624template<typename Derived>
4625Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004626TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E,
4627 bool isAddressOfOperand) {
Douglas Gregorfd2300e2009-10-29 17:56:10 +00004628 TemporaryBase Rebase(*this, E->getTemplateNameLoc(), DeclarationName());
4629
Mike Stump1eb44332009-09-09 15:08:12 +00004630 TemplateName Template
Douglas Gregorb98b1992009-08-11 05:31:07 +00004631 = getDerived().TransformTemplateName(E->getTemplateName());
4632 if (Template.isNull())
4633 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004634
Douglas Gregorf17bb742009-10-22 17:20:55 +00004635 NestedNameSpecifier *Qualifier = 0;
4636 if (E->getQualifier()) {
4637 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4638 E->getQualifierRange());
4639 if (!Qualifier)
4640 return SemaRef.ExprError();
4641 }
John McCalld5532b62009-11-23 01:53:49 +00004642
4643 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004644 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCalld5532b62009-11-23 01:53:49 +00004645 TemplateArgumentLoc Loc;
4646 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
Douglas Gregorb98b1992009-08-11 05:31:07 +00004647 return SemaRef.ExprError();
John McCalld5532b62009-11-23 01:53:49 +00004648 TransArgs.addArgument(Loc);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004649 }
4650
4651 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
4652 // compare template arguments (yet).
Mike Stump1eb44332009-09-09 15:08:12 +00004653
4654 // FIXME: It's possible that we'll find out now that the template name
Douglas Gregorb98b1992009-08-11 05:31:07 +00004655 // actually refers to a type, in which case the caller is actually dealing
4656 // with a functional cast. Give a reasonable error message!
Douglas Gregorf17bb742009-10-22 17:20:55 +00004657 return getDerived().RebuildTemplateIdExpr(Qualifier, E->getQualifierRange(),
4658 Template, E->getTemplateNameLoc(),
John McCalld5532b62009-11-23 01:53:49 +00004659 TransArgs);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004660}
4661
4662template<typename Derived>
4663Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004664TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E,
4665 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004666 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4667
4668 QualType T = getDerived().TransformType(E->getType());
4669 if (T.isNull())
4670 return SemaRef.ExprError();
4671
4672 CXXConstructorDecl *Constructor
4673 = cast_or_null<CXXConstructorDecl>(
4674 getDerived().TransformDecl(E->getConstructor()));
4675 if (!Constructor)
4676 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004677
Douglas Gregorb98b1992009-08-11 05:31:07 +00004678 bool ArgumentChanged = false;
4679 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
Mike Stump1eb44332009-09-09 15:08:12 +00004680 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004681 ArgEnd = E->arg_end();
4682 Arg != ArgEnd; ++Arg) {
4683 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4684 if (TransArg.isInvalid())
4685 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004686
Douglas Gregorb98b1992009-08-11 05:31:07 +00004687 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4688 Args.push_back(TransArg.takeAs<Expr>());
4689 }
4690
4691 if (!getDerived().AlwaysRebuild() &&
4692 T == E->getType() &&
4693 Constructor == E->getConstructor() &&
4694 !ArgumentChanged)
4695 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004696
Douglas Gregorb98b1992009-08-11 05:31:07 +00004697 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4698 move_arg(Args));
4699}
Mike Stump1eb44332009-09-09 15:08:12 +00004700
Douglas Gregorb98b1992009-08-11 05:31:07 +00004701/// \brief Transform a C++ temporary-binding expression.
4702///
Mike Stump1eb44332009-09-09 15:08:12 +00004703/// The transformation of a temporary-binding expression always attempts to
4704/// bind a new temporary variable to its subexpression, even if the
Douglas Gregorb98b1992009-08-11 05:31:07 +00004705/// subexpression itself did not change, because the temporary variable itself
4706/// must be unique.
4707template<typename Derived>
4708Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004709TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E,
4710 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004711 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4712 if (SubExpr.isInvalid())
4713 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004714
Douglas Gregorb98b1992009-08-11 05:31:07 +00004715 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4716}
Mike Stump1eb44332009-09-09 15:08:12 +00004717
4718/// \brief Transform a C++ expression that contains temporaries that should
Douglas Gregorb98b1992009-08-11 05:31:07 +00004719/// be destroyed after the expression is evaluated.
4720///
Mike Stump1eb44332009-09-09 15:08:12 +00004721/// The transformation of a full expression always attempts to build a new
4722/// CXXExprWithTemporaries expression, even if the
Douglas Gregorb98b1992009-08-11 05:31:07 +00004723/// subexpression itself did not change, because it will need to capture the
4724/// the new temporary variables introduced in the subexpression.
4725template<typename Derived>
4726Sema::OwningExprResult
4727TreeTransform<Derived>::TransformCXXExprWithTemporaries(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004728 CXXExprWithTemporaries *E,
4729 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004730 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4731 if (SubExpr.isInvalid())
4732 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004733
Douglas Gregorb98b1992009-08-11 05:31:07 +00004734 return SemaRef.Owned(
4735 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4736 E->shouldDestroyTemporaries()));
4737}
Mike Stump1eb44332009-09-09 15:08:12 +00004738
Douglas Gregorb98b1992009-08-11 05:31:07 +00004739template<typename Derived>
4740Sema::OwningExprResult
4741TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004742 CXXTemporaryObjectExpr *E,
4743 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004744 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4745 QualType T = getDerived().TransformType(E->getType());
4746 if (T.isNull())
4747 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004748
Douglas Gregorb98b1992009-08-11 05:31:07 +00004749 CXXConstructorDecl *Constructor
4750 = cast_or_null<CXXConstructorDecl>(
4751 getDerived().TransformDecl(E->getConstructor()));
4752 if (!Constructor)
4753 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004754
Douglas Gregorb98b1992009-08-11 05:31:07 +00004755 bool ArgumentChanged = false;
4756 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4757 Args.reserve(E->getNumArgs());
Mike Stump1eb44332009-09-09 15:08:12 +00004758 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004759 ArgEnd = E->arg_end();
4760 Arg != ArgEnd; ++Arg) {
4761 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4762 if (TransArg.isInvalid())
4763 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004764
Douglas Gregorb98b1992009-08-11 05:31:07 +00004765 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4766 Args.push_back((Expr *)TransArg.release());
4767 }
Mike Stump1eb44332009-09-09 15:08:12 +00004768
Douglas Gregorb98b1992009-08-11 05:31:07 +00004769 if (!getDerived().AlwaysRebuild() &&
4770 T == E->getType() &&
4771 Constructor == E->getConstructor() &&
4772 !ArgumentChanged)
4773 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004774
Douglas Gregorb98b1992009-08-11 05:31:07 +00004775 // FIXME: Bogus location information
4776 SourceLocation CommaLoc;
4777 if (Args.size() > 1) {
4778 Expr *First = (Expr *)Args[0];
Mike Stump1eb44332009-09-09 15:08:12 +00004779 CommaLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00004780 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4781 }
4782 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4783 T,
4784 /*FIXME:*/E->getTypeBeginLoc(),
4785 move_arg(Args),
4786 &CommaLoc,
4787 E->getLocEnd());
4788}
Mike Stump1eb44332009-09-09 15:08:12 +00004789
Douglas Gregorb98b1992009-08-11 05:31:07 +00004790template<typename Derived>
4791Sema::OwningExprResult
4792TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004793 CXXUnresolvedConstructExpr *E,
4794 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004795 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4796 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4797 if (T.isNull())
4798 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004799
Douglas Gregorb98b1992009-08-11 05:31:07 +00004800 bool ArgumentChanged = false;
4801 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4802 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4803 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4804 ArgEnd = E->arg_end();
4805 Arg != ArgEnd; ++Arg) {
4806 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4807 if (TransArg.isInvalid())
4808 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004809
Douglas Gregorb98b1992009-08-11 05:31:07 +00004810 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4811 FakeCommaLocs.push_back(
4812 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4813 Args.push_back(TransArg.takeAs<Expr>());
4814 }
Mike Stump1eb44332009-09-09 15:08:12 +00004815
Douglas Gregorb98b1992009-08-11 05:31:07 +00004816 if (!getDerived().AlwaysRebuild() &&
4817 T == E->getTypeAsWritten() &&
4818 !ArgumentChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00004819 return SemaRef.Owned(E->Retain());
4820
Douglas Gregorb98b1992009-08-11 05:31:07 +00004821 // FIXME: we're faking the locations of the commas
4822 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4823 T,
4824 E->getLParenLoc(),
4825 move_arg(Args),
4826 FakeCommaLocs.data(),
4827 E->getRParenLoc());
4828}
Mike Stump1eb44332009-09-09 15:08:12 +00004829
Douglas Gregorb98b1992009-08-11 05:31:07 +00004830template<typename Derived>
4831Sema::OwningExprResult
John McCall865d4472009-11-19 22:55:06 +00004832TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
4833 CXXDependentScopeMemberExpr *E,
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004834 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004835 // Transform the base of the expression.
4836 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4837 if (Base.isInvalid())
4838 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004839
Douglas Gregor6cd21982009-10-20 05:58:46 +00004840 // Start the member reference and compute the object's type.
Douglas Gregora38c6872009-09-03 16:14:30 +00004841 Sema::TypeTy *ObjectType = 0;
Mike Stump1eb44332009-09-09 15:08:12 +00004842 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
Douglas Gregora38c6872009-09-03 16:14:30 +00004843 E->getOperatorLoc(),
4844 E->isArrow()? tok::arrow : tok::period,
4845 ObjectType);
4846 if (Base.isInvalid())
4847 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004848
Douglas Gregor6cd21982009-10-20 05:58:46 +00004849 // Transform the first part of the nested-name-specifier that qualifies
4850 // the member name.
Douglas Gregorc68afe22009-09-03 21:38:09 +00004851 NamedDecl *FirstQualifierInScope
Douglas Gregor6cd21982009-10-20 05:58:46 +00004852 = getDerived().TransformFirstQualifierInScope(
4853 E->getFirstQualifierFoundInScope(),
4854 E->getQualifierRange().getBegin());
Mike Stump1eb44332009-09-09 15:08:12 +00004855
Douglas Gregora38c6872009-09-03 16:14:30 +00004856 NestedNameSpecifier *Qualifier = 0;
4857 if (E->getQualifier()) {
4858 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4859 E->getQualifierRange(),
Douglas Gregorc68afe22009-09-03 21:38:09 +00004860 QualType::getFromOpaquePtr(ObjectType),
4861 FirstQualifierInScope);
Douglas Gregora38c6872009-09-03 16:14:30 +00004862 if (!Qualifier)
4863 return SemaRef.ExprError();
4864 }
Mike Stump1eb44332009-09-09 15:08:12 +00004865
4866 DeclarationName Name
Douglas Gregordd62b152009-10-19 22:04:39 +00004867 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
4868 QualType::getFromOpaquePtr(ObjectType));
Douglas Gregor81499bb2009-09-03 22:13:48 +00004869 if (!Name)
4870 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004871
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004872 if (!E->hasExplicitTemplateArgumentList()) {
4873 // This is a reference to a member without an explicitly-specified
4874 // template argument list. Optimize for this common case.
4875 if (!getDerived().AlwaysRebuild() &&
4876 Base.get() == E->getBase() &&
4877 Qualifier == E->getQualifier() &&
4878 Name == E->getMember() &&
4879 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
Mike Stump1eb44332009-09-09 15:08:12 +00004880 return SemaRef.Owned(E->Retain());
4881
John McCall865d4472009-11-19 22:55:06 +00004882 return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004883 E->isArrow(),
4884 E->getOperatorLoc(),
4885 Qualifier,
4886 E->getQualifierRange(),
4887 Name,
4888 E->getMemberLoc(),
4889 FirstQualifierInScope);
4890 }
4891
4892 // FIXME: This is an ugly hack, which forces the same template name to
4893 // be looked up multiple times. Yuck!
Douglas Gregorca1bdd72009-11-04 00:56:37 +00004894 TemporaryBase Rebase(*this, E->getMemberLoc(), DeclarationName());
4895 TemplateName OrigTemplateName;
4896 if (const IdentifierInfo *II = Name.getAsIdentifierInfo())
4897 OrigTemplateName = SemaRef.Context.getDependentTemplateName(0, II);
4898 else
4899 OrigTemplateName
4900 = SemaRef.Context.getDependentTemplateName(0,
4901 Name.getCXXOverloadedOperator());
Mike Stump1eb44332009-09-09 15:08:12 +00004902
4903 TemplateName Template
4904 = getDerived().TransformTemplateName(OrigTemplateName,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004905 QualType::getFromOpaquePtr(ObjectType));
4906 if (Template.isNull())
4907 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004908
John McCalld5532b62009-11-23 01:53:49 +00004909 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004910 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCalld5532b62009-11-23 01:53:49 +00004911 TemplateArgumentLoc Loc;
4912 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I], Loc))
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004913 return SemaRef.ExprError();
John McCalld5532b62009-11-23 01:53:49 +00004914 TransArgs.addArgument(Loc);
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004915 }
Mike Stump1eb44332009-09-09 15:08:12 +00004916
John McCall865d4472009-11-19 22:55:06 +00004917 return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004918 E->isArrow(),
4919 E->getOperatorLoc(),
Douglas Gregora38c6872009-09-03 16:14:30 +00004920 Qualifier,
4921 E->getQualifierRange(),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004922 Template,
Douglas Gregorc68afe22009-09-03 21:38:09 +00004923 E->getMemberLoc(),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004924 FirstQualifierInScope,
John McCalld5532b62009-11-23 01:53:49 +00004925 TransArgs);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004926}
4927
4928template<typename Derived>
4929Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004930TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E,
4931 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004932 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004933}
4934
Mike Stump1eb44332009-09-09 15:08:12 +00004935template<typename Derived>
4936Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004937TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E,
4938 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004939 // FIXME: poor source location
4940 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4941 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4942 if (EncodedType.isNull())
4943 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004944
Douglas Gregorb98b1992009-08-11 05:31:07 +00004945 if (!getDerived().AlwaysRebuild() &&
4946 EncodedType == E->getEncodedType())
Mike Stump1eb44332009-09-09 15:08:12 +00004947 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004948
4949 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4950 EncodedType,
4951 E->getRParenLoc());
4952}
Mike Stump1eb44332009-09-09 15:08:12 +00004953
Douglas Gregorb98b1992009-08-11 05:31:07 +00004954template<typename Derived>
4955Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004956TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E,
4957 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004958 // FIXME: Implement this!
4959 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00004960 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004961}
4962
Mike Stump1eb44332009-09-09 15:08:12 +00004963template<typename Derived>
4964Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004965TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E,
4966 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004967 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004968}
4969
Mike Stump1eb44332009-09-09 15:08:12 +00004970template<typename Derived>
4971Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004972TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E,
4973 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004974 ObjCProtocolDecl *Protocol
Douglas Gregorb98b1992009-08-11 05:31:07 +00004975 = cast_or_null<ObjCProtocolDecl>(
4976 getDerived().TransformDecl(E->getProtocol()));
4977 if (!Protocol)
4978 return SemaRef.ExprError();
4979
4980 if (!getDerived().AlwaysRebuild() &&
4981 Protocol == E->getProtocol())
Mike Stump1eb44332009-09-09 15:08:12 +00004982 return SemaRef.Owned(E->Retain());
4983
Douglas Gregorb98b1992009-08-11 05:31:07 +00004984 return getDerived().RebuildObjCProtocolExpr(Protocol,
4985 E->getAtLoc(),
4986 /*FIXME:*/E->getAtLoc(),
4987 /*FIXME:*/E->getAtLoc(),
4988 E->getRParenLoc());
Mike Stump1eb44332009-09-09 15:08:12 +00004989
Douglas Gregorb98b1992009-08-11 05:31:07 +00004990}
4991
Mike Stump1eb44332009-09-09 15:08:12 +00004992template<typename Derived>
4993Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004994TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E,
4995 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004996 // FIXME: Implement this!
4997 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00004998 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004999}
5000
Mike Stump1eb44332009-09-09 15:08:12 +00005001template<typename Derived>
5002Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005003TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E,
5004 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005005 // FIXME: Implement this!
5006 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005007 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005008}
5009
Mike Stump1eb44332009-09-09 15:08:12 +00005010template<typename Derived>
5011Sema::OwningExprResult
Fariborz Jahanian09105f52009-08-20 17:02:02 +00005012TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005013 ObjCImplicitSetterGetterRefExpr *E,
5014 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005015 // FIXME: Implement this!
5016 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005017 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005018}
5019
Mike Stump1eb44332009-09-09 15:08:12 +00005020template<typename Derived>
5021Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005022TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E,
5023 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005024 // FIXME: Implement this!
5025 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005026 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005027}
5028
Mike Stump1eb44332009-09-09 15:08:12 +00005029template<typename Derived>
5030Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005031TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E,
5032 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005033 // FIXME: Implement this!
5034 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005035 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005036}
5037
Mike Stump1eb44332009-09-09 15:08:12 +00005038template<typename Derived>
5039Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005040TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E,
5041 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005042 bool ArgumentChanged = false;
5043 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
5044 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
5045 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
5046 if (SubExpr.isInvalid())
5047 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00005048
Douglas Gregorb98b1992009-08-11 05:31:07 +00005049 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
5050 SubExprs.push_back(SubExpr.takeAs<Expr>());
5051 }
Mike Stump1eb44332009-09-09 15:08:12 +00005052
Douglas Gregorb98b1992009-08-11 05:31:07 +00005053 if (!getDerived().AlwaysRebuild() &&
5054 !ArgumentChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00005055 return SemaRef.Owned(E->Retain());
5056
Douglas Gregorb98b1992009-08-11 05:31:07 +00005057 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
5058 move_arg(SubExprs),
5059 E->getRParenLoc());
5060}
5061
Mike Stump1eb44332009-09-09 15:08:12 +00005062template<typename Derived>
5063Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005064TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E,
5065 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005066 // FIXME: Implement this!
5067 assert(false && "Cannot transform block expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005068 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005069}
5070
Mike Stump1eb44332009-09-09 15:08:12 +00005071template<typename Derived>
5072Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005073TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E,
5074 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005075 // FIXME: Implement this!
5076 assert(false && "Cannot transform block-related expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005077 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005078}
Mike Stump1eb44332009-09-09 15:08:12 +00005079
Douglas Gregorb98b1992009-08-11 05:31:07 +00005080//===----------------------------------------------------------------------===//
Douglas Gregor577f75a2009-08-04 16:50:30 +00005081// Type reconstruction
5082//===----------------------------------------------------------------------===//
5083
Mike Stump1eb44332009-09-09 15:08:12 +00005084template<typename Derived>
John McCall85737a72009-10-30 00:06:24 +00005085QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
5086 SourceLocation Star) {
5087 return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Star,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005088 getDerived().getBaseEntity());
5089}
5090
Mike Stump1eb44332009-09-09 15:08:12 +00005091template<typename Derived>
John McCall85737a72009-10-30 00:06:24 +00005092QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
5093 SourceLocation Star) {
5094 return SemaRef.BuildBlockPointerType(PointeeType, Qualifiers(), Star,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005095 getDerived().getBaseEntity());
5096}
5097
Mike Stump1eb44332009-09-09 15:08:12 +00005098template<typename Derived>
5099QualType
John McCall85737a72009-10-30 00:06:24 +00005100TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
5101 bool WrittenAsLValue,
5102 SourceLocation Sigil) {
5103 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue, Qualifiers(),
5104 Sigil, getDerived().getBaseEntity());
Douglas Gregor577f75a2009-08-04 16:50:30 +00005105}
5106
5107template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005108QualType
John McCall85737a72009-10-30 00:06:24 +00005109TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
5110 QualType ClassType,
5111 SourceLocation Sigil) {
John McCall0953e762009-09-24 19:53:00 +00005112 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Qualifiers(),
John McCall85737a72009-10-30 00:06:24 +00005113 Sigil, getDerived().getBaseEntity());
Douglas Gregor577f75a2009-08-04 16:50:30 +00005114}
5115
5116template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005117QualType
John McCall85737a72009-10-30 00:06:24 +00005118TreeTransform<Derived>::RebuildObjCObjectPointerType(QualType PointeeType,
5119 SourceLocation Sigil) {
5120 return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Sigil,
John McCalla2becad2009-10-21 00:40:46 +00005121 getDerived().getBaseEntity());
5122}
5123
5124template<typename Derived>
5125QualType
Douglas Gregor577f75a2009-08-04 16:50:30 +00005126TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
5127 ArrayType::ArraySizeModifier SizeMod,
5128 const llvm::APInt *Size,
5129 Expr *SizeExpr,
5130 unsigned IndexTypeQuals,
5131 SourceRange BracketsRange) {
5132 if (SizeExpr || !Size)
5133 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
5134 IndexTypeQuals, BracketsRange,
5135 getDerived().getBaseEntity());
Mike Stump1eb44332009-09-09 15:08:12 +00005136
5137 QualType Types[] = {
5138 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
5139 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
5140 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
Douglas Gregor577f75a2009-08-04 16:50:30 +00005141 };
5142 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
5143 QualType SizeType;
5144 for (unsigned I = 0; I != NumTypes; ++I)
5145 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
5146 SizeType = Types[I];
5147 break;
5148 }
Mike Stump1eb44332009-09-09 15:08:12 +00005149
Douglas Gregor577f75a2009-08-04 16:50:30 +00005150 if (SizeType.isNull())
5151 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
Mike Stump1eb44332009-09-09 15:08:12 +00005152
Douglas Gregor577f75a2009-08-04 16:50:30 +00005153 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
Mike Stump1eb44332009-09-09 15:08:12 +00005154 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005155 IndexTypeQuals, BracketsRange,
Mike Stump1eb44332009-09-09 15:08:12 +00005156 getDerived().getBaseEntity());
Douglas Gregor577f75a2009-08-04 16:50:30 +00005157}
Mike Stump1eb44332009-09-09 15:08:12 +00005158
Douglas Gregor577f75a2009-08-04 16:50:30 +00005159template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005160QualType
5161TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005162 ArrayType::ArraySizeModifier SizeMod,
5163 const llvm::APInt &Size,
John McCall85737a72009-10-30 00:06:24 +00005164 unsigned IndexTypeQuals,
5165 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00005166 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
John McCall85737a72009-10-30 00:06:24 +00005167 IndexTypeQuals, BracketsRange);
Douglas Gregor577f75a2009-08-04 16:50:30 +00005168}
5169
5170template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005171QualType
Mike Stump1eb44332009-09-09 15:08:12 +00005172TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005173 ArrayType::ArraySizeModifier SizeMod,
John McCall85737a72009-10-30 00:06:24 +00005174 unsigned IndexTypeQuals,
5175 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00005176 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
John McCall85737a72009-10-30 00:06:24 +00005177 IndexTypeQuals, BracketsRange);
Douglas Gregor577f75a2009-08-04 16:50:30 +00005178}
Mike Stump1eb44332009-09-09 15:08:12 +00005179
Douglas Gregor577f75a2009-08-04 16:50:30 +00005180template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005181QualType
5182TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005183 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +00005184 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005185 unsigned IndexTypeQuals,
5186 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00005187 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005188 SizeExpr.takeAs<Expr>(),
5189 IndexTypeQuals, BracketsRange);
5190}
5191
5192template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005193QualType
5194TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005195 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +00005196 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005197 unsigned IndexTypeQuals,
5198 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00005199 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005200 SizeExpr.takeAs<Expr>(),
5201 IndexTypeQuals, BracketsRange);
5202}
5203
5204template<typename Derived>
5205QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
5206 unsigned NumElements) {
5207 // FIXME: semantic checking!
5208 return SemaRef.Context.getVectorType(ElementType, NumElements);
5209}
Mike Stump1eb44332009-09-09 15:08:12 +00005210
Douglas Gregor577f75a2009-08-04 16:50:30 +00005211template<typename Derived>
5212QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
5213 unsigned NumElements,
5214 SourceLocation AttributeLoc) {
5215 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
5216 NumElements, true);
5217 IntegerLiteral *VectorSize
Mike Stump1eb44332009-09-09 15:08:12 +00005218 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005219 AttributeLoc);
5220 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
5221 AttributeLoc);
5222}
Mike Stump1eb44332009-09-09 15:08:12 +00005223
Douglas Gregor577f75a2009-08-04 16:50:30 +00005224template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005225QualType
5226TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregorb98b1992009-08-11 05:31:07 +00005227 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005228 SourceLocation AttributeLoc) {
5229 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
5230}
Mike Stump1eb44332009-09-09 15:08:12 +00005231
Douglas Gregor577f75a2009-08-04 16:50:30 +00005232template<typename Derived>
5233QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
Mike Stump1eb44332009-09-09 15:08:12 +00005234 QualType *ParamTypes,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005235 unsigned NumParamTypes,
Mike Stump1eb44332009-09-09 15:08:12 +00005236 bool Variadic,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005237 unsigned Quals) {
Mike Stump1eb44332009-09-09 15:08:12 +00005238 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005239 Quals,
5240 getDerived().getBaseLocation(),
5241 getDerived().getBaseEntity());
5242}
Mike Stump1eb44332009-09-09 15:08:12 +00005243
Douglas Gregor577f75a2009-08-04 16:50:30 +00005244template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00005245QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
5246 return SemaRef.Context.getFunctionNoProtoType(T);
5247}
5248
5249template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00005250QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00005251 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
5252}
5253
5254template<typename Derived>
5255QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
5256 return SemaRef.Context.getTypeOfType(Underlying);
5257}
5258
5259template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00005260QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00005261 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
5262}
5263
5264template<typename Derived>
5265QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
John McCall833ca992009-10-29 08:12:44 +00005266 TemplateName Template,
5267 SourceLocation TemplateNameLoc,
John McCalld5532b62009-11-23 01:53:49 +00005268 const TemplateArgumentListInfo &TemplateArgs) {
5269 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
Douglas Gregor577f75a2009-08-04 16:50:30 +00005270}
Mike Stump1eb44332009-09-09 15:08:12 +00005271
Douglas Gregordcee1a12009-08-06 05:28:30 +00005272template<typename Derived>
5273NestedNameSpecifier *
5274TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5275 SourceRange Range,
Douglas Gregora38c6872009-09-03 16:14:30 +00005276 IdentifierInfo &II,
Douglas Gregorc68afe22009-09-03 21:38:09 +00005277 QualType ObjectType,
John McCalld5532b62009-11-23 01:53:49 +00005278 NamedDecl *FirstQualifierInScope) {
Douglas Gregordcee1a12009-08-06 05:28:30 +00005279 CXXScopeSpec SS;
5280 // FIXME: The source location information is all wrong.
5281 SS.setRange(Range);
5282 SS.setScopeRep(Prefix);
5283 return static_cast<NestedNameSpecifier *>(
Mike Stump1eb44332009-09-09 15:08:12 +00005284 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregor495c35d2009-08-25 22:51:20 +00005285 Range.getEnd(), II,
Douglas Gregorc68afe22009-09-03 21:38:09 +00005286 ObjectType,
5287 FirstQualifierInScope,
Douglas Gregor495c35d2009-08-25 22:51:20 +00005288 false));
Douglas Gregordcee1a12009-08-06 05:28:30 +00005289}
5290
5291template<typename Derived>
5292NestedNameSpecifier *
5293TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5294 SourceRange Range,
5295 NamespaceDecl *NS) {
5296 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
5297}
5298
5299template<typename Derived>
5300NestedNameSpecifier *
5301TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5302 SourceRange Range,
5303 bool TemplateKW,
5304 QualType T) {
5305 if (T->isDependentType() || T->isRecordType() ||
5306 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
Douglas Gregora4923eb2009-11-16 21:35:15 +00005307 assert(!T.hasLocalQualifiers() && "Can't get cv-qualifiers here");
Douglas Gregordcee1a12009-08-06 05:28:30 +00005308 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
5309 T.getTypePtr());
5310 }
Mike Stump1eb44332009-09-09 15:08:12 +00005311
Douglas Gregordcee1a12009-08-06 05:28:30 +00005312 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
5313 return 0;
5314}
Mike Stump1eb44332009-09-09 15:08:12 +00005315
Douglas Gregord1067e52009-08-06 06:41:21 +00005316template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005317TemplateName
Douglas Gregord1067e52009-08-06 06:41:21 +00005318TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5319 bool TemplateKW,
5320 TemplateDecl *Template) {
Mike Stump1eb44332009-09-09 15:08:12 +00005321 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
Douglas Gregord1067e52009-08-06 06:41:21 +00005322 Template);
5323}
5324
5325template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005326TemplateName
Douglas Gregord1067e52009-08-06 06:41:21 +00005327TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5328 bool TemplateKW,
5329 OverloadedFunctionDecl *Ovl) {
5330 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
5331}
5332
5333template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005334TemplateName
Douglas Gregord1067e52009-08-06 06:41:21 +00005335TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00005336 const IdentifierInfo &II,
5337 QualType ObjectType) {
Douglas Gregord1067e52009-08-06 06:41:21 +00005338 CXXScopeSpec SS;
5339 SS.setRange(SourceRange(getDerived().getBaseLocation()));
Mike Stump1eb44332009-09-09 15:08:12 +00005340 SS.setScopeRep(Qualifier);
Douglas Gregor014e88d2009-11-03 23:16:33 +00005341 UnqualifiedId Name;
5342 Name.setIdentifier(&II, /*FIXME:*/getDerived().getBaseLocation());
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00005343 return getSema().ActOnDependentTemplateName(
5344 /*FIXME:*/getDerived().getBaseLocation(),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00005345 SS,
Douglas Gregor014e88d2009-11-03 23:16:33 +00005346 Name,
Douglas Gregora481edb2009-11-20 23:39:24 +00005347 ObjectType.getAsOpaquePtr(),
5348 /*EnteringContext=*/false)
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00005349 .template getAsVal<TemplateName>();
Douglas Gregord1067e52009-08-06 06:41:21 +00005350}
Mike Stump1eb44332009-09-09 15:08:12 +00005351
Douglas Gregorb98b1992009-08-11 05:31:07 +00005352template<typename Derived>
Douglas Gregorca1bdd72009-11-04 00:56:37 +00005353TemplateName
5354TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5355 OverloadedOperatorKind Operator,
5356 QualType ObjectType) {
5357 CXXScopeSpec SS;
5358 SS.setRange(SourceRange(getDerived().getBaseLocation()));
5359 SS.setScopeRep(Qualifier);
5360 UnqualifiedId Name;
5361 SourceLocation SymbolLocations[3]; // FIXME: Bogus location information.
5362 Name.setOperatorFunctionId(/*FIXME:*/getDerived().getBaseLocation(),
5363 Operator, SymbolLocations);
5364 return getSema().ActOnDependentTemplateName(
5365 /*FIXME:*/getDerived().getBaseLocation(),
5366 SS,
5367 Name,
Douglas Gregora481edb2009-11-20 23:39:24 +00005368 ObjectType.getAsOpaquePtr(),
5369 /*EnteringContext=*/false)
Douglas Gregorca1bdd72009-11-04 00:56:37 +00005370 .template getAsVal<TemplateName>();
5371}
5372
5373template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005374Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00005375TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
5376 SourceLocation OpLoc,
5377 ExprArg Callee,
5378 ExprArg First,
5379 ExprArg Second) {
5380 Expr *FirstExpr = (Expr *)First.get();
5381 Expr *SecondExpr = (Expr *)Second.get();
John McCallba135432009-11-21 08:51:07 +00005382 Expr *CalleeExpr = ((Expr *)Callee.get())->IgnoreParenCasts();
Douglas Gregorb98b1992009-08-11 05:31:07 +00005383 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
Mike Stump1eb44332009-09-09 15:08:12 +00005384
Douglas Gregorb98b1992009-08-11 05:31:07 +00005385 // Determine whether this should be a builtin operation.
Sebastian Redlf322ed62009-10-29 20:17:01 +00005386 if (Op == OO_Subscript) {
5387 if (!FirstExpr->getType()->isOverloadableType() &&
5388 !SecondExpr->getType()->isOverloadableType())
5389 return getSema().CreateBuiltinArraySubscriptExpr(move(First),
John McCallba135432009-11-21 08:51:07 +00005390 CalleeExpr->getLocStart(),
Sebastian Redlf322ed62009-10-29 20:17:01 +00005391 move(Second), OpLoc);
Eli Friedman1a3c75f2009-11-16 19:13:03 +00005392 } else if (Op == OO_Arrow) {
5393 // -> is never a builtin operation.
5394 return SemaRef.BuildOverloadedArrowExpr(0, move(First), OpLoc);
Sebastian Redlf322ed62009-10-29 20:17:01 +00005395 } else if (SecondExpr == 0 || isPostIncDec) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005396 if (!FirstExpr->getType()->isOverloadableType()) {
5397 // The argument is not of overloadable type, so try to create a
5398 // built-in unary operation.
Mike Stump1eb44332009-09-09 15:08:12 +00005399 UnaryOperator::Opcode Opc
Douglas Gregorb98b1992009-08-11 05:31:07 +00005400 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
Mike Stump1eb44332009-09-09 15:08:12 +00005401
Douglas Gregorb98b1992009-08-11 05:31:07 +00005402 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
5403 }
5404 } else {
Mike Stump1eb44332009-09-09 15:08:12 +00005405 if (!FirstExpr->getType()->isOverloadableType() &&
Douglas Gregorb98b1992009-08-11 05:31:07 +00005406 !SecondExpr->getType()->isOverloadableType()) {
5407 // Neither of the arguments is an overloadable type, so try to
5408 // create a built-in binary operation.
5409 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
Mike Stump1eb44332009-09-09 15:08:12 +00005410 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +00005411 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
5412 if (Result.isInvalid())
5413 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00005414
Douglas Gregorb98b1992009-08-11 05:31:07 +00005415 First.release();
5416 Second.release();
5417 return move(Result);
5418 }
5419 }
Mike Stump1eb44332009-09-09 15:08:12 +00005420
5421 // Compute the transformed set of functions (and function templates) to be
Douglas Gregorb98b1992009-08-11 05:31:07 +00005422 // used during overload resolution.
5423 Sema::FunctionSet Functions;
Mike Stump1eb44332009-09-09 15:08:12 +00005424
John McCallba135432009-11-21 08:51:07 +00005425 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(CalleeExpr)) {
5426 assert(ULE->requiresADL());
5427
5428 // FIXME: Do we have to check
5429 // IsAcceptableNonMemberOperatorCandidate for each of these?
5430 for (UnresolvedLookupExpr::decls_iterator I = ULE->decls_begin(),
5431 E = ULE->decls_end(); I != E; ++I)
5432 Functions.insert(AnyFunctionDecl::getFromNamedDecl(*I));
5433 } else {
5434 Functions.insert(AnyFunctionDecl::getFromNamedDecl(
5435 cast<DeclRefExpr>(CalleeExpr)->getDecl()));
5436 }
Mike Stump1eb44332009-09-09 15:08:12 +00005437
Douglas Gregorb98b1992009-08-11 05:31:07 +00005438 // Add any functions found via argument-dependent lookup.
5439 Expr *Args[2] = { FirstExpr, SecondExpr };
5440 unsigned NumArgs = 1 + (SecondExpr != 0);
Mike Stump1eb44332009-09-09 15:08:12 +00005441 DeclarationName OpName
Douglas Gregorb98b1992009-08-11 05:31:07 +00005442 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
Sebastian Redl644be852009-10-23 19:23:15 +00005443 SemaRef.ArgumentDependentLookup(OpName, /*Operator*/true, Args, NumArgs,
5444 Functions);
Mike Stump1eb44332009-09-09 15:08:12 +00005445
Douglas Gregorb98b1992009-08-11 05:31:07 +00005446 // Create the overloaded operator invocation for unary operators.
5447 if (NumArgs == 1 || isPostIncDec) {
Mike Stump1eb44332009-09-09 15:08:12 +00005448 UnaryOperator::Opcode Opc
Douglas Gregorb98b1992009-08-11 05:31:07 +00005449 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
5450 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
5451 }
Mike Stump1eb44332009-09-09 15:08:12 +00005452
Sebastian Redlf322ed62009-10-29 20:17:01 +00005453 if (Op == OO_Subscript)
John McCallba135432009-11-21 08:51:07 +00005454 return SemaRef.CreateOverloadedArraySubscriptExpr(CalleeExpr->getLocStart(),
5455 OpLoc,
5456 move(First),
5457 move(Second));
Sebastian Redlf322ed62009-10-29 20:17:01 +00005458
Douglas Gregorb98b1992009-08-11 05:31:07 +00005459 // Create the overloaded operator invocation for binary operators.
Mike Stump1eb44332009-09-09 15:08:12 +00005460 BinaryOperator::Opcode Opc =
Douglas Gregorb98b1992009-08-11 05:31:07 +00005461 BinaryOperator::getOverloadedOpcode(Op);
Mike Stump1eb44332009-09-09 15:08:12 +00005462 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +00005463 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
5464 if (Result.isInvalid())
5465 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00005466
Douglas Gregorb98b1992009-08-11 05:31:07 +00005467 First.release();
5468 Second.release();
Mike Stump1eb44332009-09-09 15:08:12 +00005469 return move(Result);
Douglas Gregorb98b1992009-08-11 05:31:07 +00005470}
Mike Stump1eb44332009-09-09 15:08:12 +00005471
Douglas Gregor577f75a2009-08-04 16:50:30 +00005472} // end namespace clang
5473
5474#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H