blob: 579937ead7695a13ef4e9993ea37a912de842fad [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,
506 SourceLocation LAngleLoc,
507 const TemplateArgumentLoc *Args,
508 unsigned NumArgs,
509 SourceLocation RAngleLoc);
Mike Stump1eb44332009-09-09 15:08:12 +0000510
Douglas Gregor577f75a2009-08-04 16:50:30 +0000511 /// \brief Build a new qualified name type.
512 ///
Mike Stump1eb44332009-09-09 15:08:12 +0000513 /// By default, builds a new QualifiedNameType type from the
514 /// nested-name-specifier and the named type. Subclasses may override
Douglas Gregor577f75a2009-08-04 16:50:30 +0000515 /// this routine to provide different behavior.
516 QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
517 return SemaRef.Context.getQualifiedNameType(NNS, Named);
Mike Stump1eb44332009-09-09 15:08:12 +0000518 }
Douglas Gregor577f75a2009-08-04 16:50:30 +0000519
520 /// \brief Build a new typename type that refers to a template-id.
521 ///
522 /// By default, builds a new TypenameType type from the nested-name-specifier
Mike Stump1eb44332009-09-09 15:08:12 +0000523 /// and the given type. Subclasses may override this routine to provide
Douglas Gregor577f75a2009-08-04 16:50:30 +0000524 /// different behavior.
525 QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
526 if (NNS->isDependent())
Mike Stump1eb44332009-09-09 15:08:12 +0000527 return SemaRef.Context.getTypenameType(NNS,
Douglas Gregor577f75a2009-08-04 16:50:30 +0000528 cast<TemplateSpecializationType>(T));
Mike Stump1eb44332009-09-09 15:08:12 +0000529
Douglas Gregor577f75a2009-08-04 16:50:30 +0000530 return SemaRef.Context.getQualifiedNameType(NNS, T);
Mike Stump1eb44332009-09-09 15:08:12 +0000531 }
Douglas Gregor577f75a2009-08-04 16:50:30 +0000532
533 /// \brief Build a new typename type that refers to an identifier.
534 ///
535 /// By default, performs semantic analysis when building the typename type
Mike Stump1eb44332009-09-09 15:08:12 +0000536 /// (or qualified name type). Subclasses may override this routine to provide
Douglas Gregor577f75a2009-08-04 16:50:30 +0000537 /// different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000538 QualType RebuildTypenameType(NestedNameSpecifier *NNS,
John McCall833ca992009-10-29 08:12:44 +0000539 const IdentifierInfo *Id,
540 SourceRange SR) {
541 return SemaRef.CheckTypenameType(NNS, *Id, SR);
Douglas Gregordcee1a12009-08-06 05:28:30 +0000542 }
Mike Stump1eb44332009-09-09 15:08:12 +0000543
Douglas Gregordcee1a12009-08-06 05:28:30 +0000544 /// \brief Build a new nested-name-specifier given the prefix and an
545 /// identifier that names the next step in the nested-name-specifier.
546 ///
547 /// By default, performs semantic analysis when building the new
548 /// nested-name-specifier. Subclasses may override this routine to provide
549 /// different behavior.
550 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
551 SourceRange Range,
Douglas Gregora38c6872009-09-03 16:14:30 +0000552 IdentifierInfo &II,
Douglas Gregorc68afe22009-09-03 21:38:09 +0000553 QualType ObjectType,
554 NamedDecl *FirstQualifierInScope);
Douglas Gregordcee1a12009-08-06 05:28:30 +0000555
556 /// \brief Build a new nested-name-specifier given the prefix and the
557 /// namespace named in the next step in the nested-name-specifier.
558 ///
559 /// By default, performs semantic analysis when building the new
560 /// nested-name-specifier. Subclasses may override this routine to provide
561 /// different behavior.
562 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
563 SourceRange Range,
564 NamespaceDecl *NS);
565
566 /// \brief Build a new nested-name-specifier given the prefix and the
567 /// type named in the next step in the nested-name-specifier.
568 ///
569 /// By default, performs semantic analysis when building the new
570 /// nested-name-specifier. Subclasses may override this routine to provide
571 /// different behavior.
572 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
573 SourceRange Range,
574 bool TemplateKW,
575 QualType T);
Douglas Gregord1067e52009-08-06 06:41:21 +0000576
577 /// \brief Build a new template name given a nested name specifier, a flag
578 /// indicating whether the "template" keyword was provided, and the template
579 /// that the template name refers to.
580 ///
581 /// By default, builds the new template name directly. Subclasses may override
582 /// this routine to provide different behavior.
583 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
584 bool TemplateKW,
585 TemplateDecl *Template);
586
587 /// \brief Build a new template name given a nested name specifier, a flag
588 /// indicating whether the "template" keyword was provided, and a set of
589 /// overloaded function templates.
590 ///
591 /// By default, builds the new template name directly. Subclasses may override
592 /// this routine to provide different behavior.
593 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
594 bool TemplateKW,
595 OverloadedFunctionDecl *Ovl);
Mike Stump1eb44332009-09-09 15:08:12 +0000596
Douglas Gregord1067e52009-08-06 06:41:21 +0000597 /// \brief Build a new template name given a nested name specifier and the
598 /// name that is referred to as a template.
599 ///
600 /// By default, performs semantic analysis to determine whether the name can
601 /// be resolved to a specific template, then builds the appropriate kind of
602 /// template name. Subclasses may override this routine to provide different
603 /// behavior.
604 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +0000605 const IdentifierInfo &II,
606 QualType ObjectType);
Mike Stump1eb44332009-09-09 15:08:12 +0000607
Douglas Gregorca1bdd72009-11-04 00:56:37 +0000608 /// \brief Build a new template name given a nested name specifier and the
609 /// overloaded operator name that is referred to as a template.
610 ///
611 /// By default, performs semantic analysis to determine whether the name can
612 /// be resolved to a specific template, then builds the appropriate kind of
613 /// template name. Subclasses may override this routine to provide different
614 /// behavior.
615 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
616 OverloadedOperatorKind Operator,
617 QualType ObjectType);
618
Douglas Gregor43959a92009-08-20 07:17:43 +0000619 /// \brief Build a new compound statement.
620 ///
621 /// By default, performs semantic analysis to build the new statement.
622 /// Subclasses may override this routine to provide different behavior.
623 OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
624 MultiStmtArg Statements,
625 SourceLocation RBraceLoc,
626 bool IsStmtExpr) {
627 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
628 IsStmtExpr);
629 }
630
631 /// \brief Build a new case statement.
632 ///
633 /// By default, performs semantic analysis to build the new statement.
634 /// Subclasses may override this routine to provide different behavior.
635 OwningStmtResult RebuildCaseStmt(SourceLocation CaseLoc,
636 ExprArg LHS,
637 SourceLocation EllipsisLoc,
638 ExprArg RHS,
639 SourceLocation ColonLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +0000640 return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
Douglas Gregor43959a92009-08-20 07:17:43 +0000641 ColonLoc);
642 }
Mike Stump1eb44332009-09-09 15:08:12 +0000643
Douglas Gregor43959a92009-08-20 07:17:43 +0000644 /// \brief Attach the body to a new case statement.
645 ///
646 /// By default, performs semantic analysis to build the new statement.
647 /// Subclasses may override this routine to provide different behavior.
648 OwningStmtResult RebuildCaseStmtBody(StmtArg S, StmtArg Body) {
649 getSema().ActOnCaseStmtBody(S.get(), move(Body));
650 return move(S);
651 }
Mike Stump1eb44332009-09-09 15:08:12 +0000652
Douglas Gregor43959a92009-08-20 07:17:43 +0000653 /// \brief Build a new default statement.
654 ///
655 /// By default, performs semantic analysis to build the new statement.
656 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000657 OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000658 SourceLocation ColonLoc,
659 StmtArg SubStmt) {
Mike Stump1eb44332009-09-09 15:08:12 +0000660 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
Douglas Gregor43959a92009-08-20 07:17:43 +0000661 /*CurScope=*/0);
662 }
Mike Stump1eb44332009-09-09 15:08:12 +0000663
Douglas Gregor43959a92009-08-20 07:17:43 +0000664 /// \brief Build a new label statement.
665 ///
666 /// By default, performs semantic analysis to build the new statement.
667 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000668 OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000669 IdentifierInfo *Id,
670 SourceLocation ColonLoc,
671 StmtArg SubStmt) {
672 return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
673 }
Mike Stump1eb44332009-09-09 15:08:12 +0000674
Douglas Gregor43959a92009-08-20 07:17:43 +0000675 /// \brief Build a new "if" statement.
676 ///
677 /// By default, performs semantic analysis to build the new statement.
678 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000679 OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
680 StmtArg Then, SourceLocation ElseLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000681 StmtArg Else) {
682 return getSema().ActOnIfStmt(IfLoc, Cond, move(Then), ElseLoc, move(Else));
683 }
Mike Stump1eb44332009-09-09 15:08:12 +0000684
Douglas Gregor43959a92009-08-20 07:17:43 +0000685 /// \brief Start building a new switch statement.
686 ///
687 /// By default, performs semantic analysis to build the new statement.
688 /// Subclasses may override this routine to provide different behavior.
689 OwningStmtResult RebuildSwitchStmtStart(ExprArg Cond) {
690 return getSema().ActOnStartOfSwitchStmt(move(Cond));
691 }
Mike Stump1eb44332009-09-09 15:08:12 +0000692
Douglas Gregor43959a92009-08-20 07:17:43 +0000693 /// \brief Attach the body to the switch statement.
694 ///
695 /// By default, performs semantic analysis to build the new statement.
696 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000697 OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000698 StmtArg Switch, StmtArg Body) {
699 return getSema().ActOnFinishSwitchStmt(SwitchLoc, move(Switch),
700 move(Body));
701 }
702
703 /// \brief Build a new while statement.
704 ///
705 /// By default, performs semantic analysis to build the new statement.
706 /// Subclasses may override this routine to provide different behavior.
707 OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc,
708 Sema::FullExprArg Cond,
709 StmtArg Body) {
710 return getSema().ActOnWhileStmt(WhileLoc, Cond, move(Body));
711 }
Mike Stump1eb44332009-09-09 15:08:12 +0000712
Douglas Gregor43959a92009-08-20 07:17:43 +0000713 /// \brief Build a new do-while statement.
714 ///
715 /// By default, performs semantic analysis to build the new statement.
716 /// Subclasses may override this routine to provide different behavior.
717 OwningStmtResult RebuildDoStmt(SourceLocation DoLoc, StmtArg Body,
718 SourceLocation WhileLoc,
719 SourceLocation LParenLoc,
720 ExprArg Cond,
721 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +0000722 return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000723 move(Cond), RParenLoc);
724 }
725
726 /// \brief Build a new for statement.
727 ///
728 /// By default, performs semantic analysis to build the new statement.
729 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000730 OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000731 SourceLocation LParenLoc,
732 StmtArg Init, ExprArg Cond, ExprArg Inc,
733 SourceLocation RParenLoc, StmtArg Body) {
Mike Stump1eb44332009-09-09 15:08:12 +0000734 return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), move(Cond),
Douglas Gregor43959a92009-08-20 07:17:43 +0000735 move(Inc), RParenLoc, move(Body));
736 }
Mike Stump1eb44332009-09-09 15:08:12 +0000737
Douglas Gregor43959a92009-08-20 07:17:43 +0000738 /// \brief Build a new goto statement.
739 ///
740 /// By default, performs semantic analysis to build the new statement.
741 /// Subclasses may override this routine to provide different behavior.
742 OwningStmtResult RebuildGotoStmt(SourceLocation GotoLoc,
743 SourceLocation LabelLoc,
744 LabelStmt *Label) {
745 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
746 }
747
748 /// \brief Build a new indirect goto statement.
749 ///
750 /// By default, performs semantic analysis to build the new statement.
751 /// Subclasses may override this routine to provide different behavior.
752 OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
753 SourceLocation StarLoc,
754 ExprArg Target) {
755 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
756 }
Mike Stump1eb44332009-09-09 15:08:12 +0000757
Douglas Gregor43959a92009-08-20 07:17:43 +0000758 /// \brief Build a new return statement.
759 ///
760 /// By default, performs semantic analysis to build the new statement.
761 /// Subclasses may override this routine to provide different behavior.
762 OwningStmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
763 ExprArg Result) {
Mike Stump1eb44332009-09-09 15:08:12 +0000764
Douglas Gregor43959a92009-08-20 07:17:43 +0000765 return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
766 }
Mike Stump1eb44332009-09-09 15:08:12 +0000767
Douglas Gregor43959a92009-08-20 07:17:43 +0000768 /// \brief Build a new declaration statement.
769 ///
770 /// By default, performs semantic analysis to build the new statement.
771 /// Subclasses may override this routine to provide different behavior.
772 OwningStmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
Mike Stump1eb44332009-09-09 15:08:12 +0000773 SourceLocation StartLoc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000774 SourceLocation EndLoc) {
775 return getSema().Owned(
776 new (getSema().Context) DeclStmt(
777 DeclGroupRef::Create(getSema().Context,
778 Decls, NumDecls),
779 StartLoc, EndLoc));
780 }
Mike Stump1eb44332009-09-09 15:08:12 +0000781
Douglas Gregor43959a92009-08-20 07:17:43 +0000782 /// \brief Build a new C++ exception declaration.
783 ///
784 /// By default, performs semantic analysis to build the new decaration.
785 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000786 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
Douglas Gregor43959a92009-08-20 07:17:43 +0000787 DeclaratorInfo *Declarator,
788 IdentifierInfo *Name,
789 SourceLocation Loc,
790 SourceRange TypeRange) {
Mike Stump1eb44332009-09-09 15:08:12 +0000791 return getSema().BuildExceptionDeclaration(0, T, Declarator, Name, Loc,
Douglas Gregor43959a92009-08-20 07:17:43 +0000792 TypeRange);
793 }
794
795 /// \brief Build a new C++ catch statement.
796 ///
797 /// By default, performs semantic analysis to build the new statement.
798 /// Subclasses may override this routine to provide different behavior.
799 OwningStmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
800 VarDecl *ExceptionDecl,
801 StmtArg Handler) {
802 return getSema().Owned(
Mike Stump1eb44332009-09-09 15:08:12 +0000803 new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
Douglas Gregor43959a92009-08-20 07:17:43 +0000804 Handler.takeAs<Stmt>()));
805 }
Mike Stump1eb44332009-09-09 15:08:12 +0000806
Douglas Gregor43959a92009-08-20 07:17:43 +0000807 /// \brief Build a new C++ try statement.
808 ///
809 /// By default, performs semantic analysis to build the new statement.
810 /// Subclasses may override this routine to provide different behavior.
811 OwningStmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
812 StmtArg TryBlock,
813 MultiStmtArg Handlers) {
814 return getSema().ActOnCXXTryBlock(TryLoc, move(TryBlock), move(Handlers));
815 }
Mike Stump1eb44332009-09-09 15:08:12 +0000816
Douglas Gregorb98b1992009-08-11 05:31:07 +0000817 /// \brief Build a new expression that references a declaration.
818 ///
819 /// By default, performs semantic analysis to build the new expression.
820 /// Subclasses may override this routine to provide different behavior.
Douglas Gregora2813ce2009-10-23 18:54:35 +0000821 OwningExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
822 SourceRange QualifierRange,
Douglas Gregorc86a6e92009-11-04 07:01:15 +0000823 NamedDecl *ND, SourceLocation Loc,
824 bool isAddressOfOperand) {
Douglas Gregora2813ce2009-10-23 18:54:35 +0000825 CXXScopeSpec SS;
826 SS.setScopeRep(Qualifier);
827 SS.setRange(QualifierRange);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000828 return getSema().BuildDeclarationNameExpr(Loc, ND,
829 /*FIXME:*/false,
Douglas Gregora2813ce2009-10-23 18:54:35 +0000830 &SS,
Douglas Gregorc86a6e92009-11-04 07:01:15 +0000831 isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000832 }
Mike Stump1eb44332009-09-09 15:08:12 +0000833
Douglas Gregorb98b1992009-08-11 05:31:07 +0000834 /// \brief Build a new expression in parentheses.
Mike Stump1eb44332009-09-09 15:08:12 +0000835 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000836 /// By default, performs semantic analysis to build the new expression.
837 /// Subclasses may override this routine to provide different behavior.
838 OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
839 SourceLocation RParen) {
840 return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
841 }
842
Douglas Gregora71d8192009-09-04 17:36:40 +0000843 /// \brief Build a new pseudo-destructor expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000844 ///
Douglas Gregora71d8192009-09-04 17:36:40 +0000845 /// By default, performs semantic analysis to build the new expression.
846 /// Subclasses may override this routine to provide different behavior.
847 OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
848 SourceLocation OperatorLoc,
849 bool isArrow,
850 SourceLocation DestroyedTypeLoc,
851 QualType DestroyedType,
852 NestedNameSpecifier *Qualifier,
853 SourceRange QualifierRange) {
854 CXXScopeSpec SS;
855 if (Qualifier) {
856 SS.setRange(QualifierRange);
857 SS.setScopeRep(Qualifier);
858 }
859
Mike Stump1eb44332009-09-09 15:08:12 +0000860 DeclarationName Name
Douglas Gregora71d8192009-09-04 17:36:40 +0000861 = SemaRef.Context.DeclarationNames.getCXXDestructorName(
862 SemaRef.Context.getCanonicalType(DestroyedType));
Mike Stump1eb44332009-09-09 15:08:12 +0000863
864 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregora71d8192009-09-04 17:36:40 +0000865 OperatorLoc,
866 isArrow? tok::arrow : tok::period,
867 DestroyedTypeLoc,
868 Name,
869 Sema::DeclPtrTy::make((Decl *)0),
870 &SS);
Mike Stump1eb44332009-09-09 15:08:12 +0000871 }
872
Douglas Gregorb98b1992009-08-11 05:31:07 +0000873 /// \brief Build a new unary operator expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000874 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000875 /// By default, performs semantic analysis to build the new expression.
876 /// Subclasses may override this routine to provide different behavior.
877 OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
878 UnaryOperator::Opcode Opc,
879 ExprArg SubExpr) {
Douglas Gregor6ca7cfb2009-11-05 00:51:44 +0000880 return getSema().BuildUnaryOp(/*Scope=*/0, OpLoc, Opc, move(SubExpr));
Douglas Gregorb98b1992009-08-11 05:31:07 +0000881 }
Mike Stump1eb44332009-09-09 15:08:12 +0000882
Douglas Gregorb98b1992009-08-11 05:31:07 +0000883 /// \brief Build a new sizeof or alignof expression with a type argument.
Mike Stump1eb44332009-09-09 15:08:12 +0000884 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000885 /// By default, performs semantic analysis to build the new expression.
886 /// Subclasses may override this routine to provide different behavior.
John McCall5ab75172009-11-04 07:28:41 +0000887 OwningExprResult RebuildSizeOfAlignOf(DeclaratorInfo *DInfo,
888 SourceLocation OpLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000889 bool isSizeOf, SourceRange R) {
John McCall5ab75172009-11-04 07:28:41 +0000890 return getSema().CreateSizeOfAlignOfExpr(DInfo, OpLoc, isSizeOf, R);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000891 }
892
Mike Stump1eb44332009-09-09 15:08:12 +0000893 /// \brief Build a new sizeof or alignof expression with an expression
Douglas Gregorb98b1992009-08-11 05:31:07 +0000894 /// argument.
Mike Stump1eb44332009-09-09 15:08:12 +0000895 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000896 /// By default, performs semantic analysis to build the new expression.
897 /// Subclasses may override this routine to provide different behavior.
898 OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
899 bool isSizeOf, SourceRange R) {
Mike Stump1eb44332009-09-09 15:08:12 +0000900 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +0000901 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
902 OpLoc, isSizeOf, R);
903 if (Result.isInvalid())
904 return getSema().ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +0000905
Douglas Gregorb98b1992009-08-11 05:31:07 +0000906 SubExpr.release();
907 return move(Result);
908 }
Mike Stump1eb44332009-09-09 15:08:12 +0000909
Douglas Gregorb98b1992009-08-11 05:31:07 +0000910 /// \brief Build a new array subscript expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000911 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000912 /// By default, performs semantic analysis to build the new expression.
913 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +0000914 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000915 SourceLocation LBracketLoc,
916 ExprArg RHS,
917 SourceLocation RBracketLoc) {
918 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
Mike Stump1eb44332009-09-09 15:08:12 +0000919 LBracketLoc, move(RHS),
Douglas Gregorb98b1992009-08-11 05:31:07 +0000920 RBracketLoc);
921 }
922
923 /// \brief Build a new call expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000924 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000925 /// By default, performs semantic analysis to build the new expression.
926 /// Subclasses may override this routine to provide different behavior.
927 OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
928 MultiExprArg Args,
929 SourceLocation *CommaLocs,
930 SourceLocation RParenLoc) {
931 return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
932 move(Args), CommaLocs, RParenLoc);
933 }
934
935 /// \brief Build a new member access expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000936 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000937 /// By default, performs semantic analysis to build the new expression.
938 /// Subclasses may override this routine to provide different behavior.
939 OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
Mike Stump1eb44332009-09-09 15:08:12 +0000940 bool isArrow,
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000941 NestedNameSpecifier *Qualifier,
942 SourceRange QualifierRange,
943 SourceLocation MemberLoc,
Douglas Gregor8a4386b2009-11-04 23:20:05 +0000944 NamedDecl *Member,
945 bool HasExplicitTemplateArgs,
946 SourceLocation LAngleLoc,
947 const TemplateArgumentLoc *ExplicitTemplateArgs,
948 unsigned NumExplicitTemplateArgs,
949 SourceLocation RAngleLoc,
950 NamedDecl *FirstQualifierInScope) {
Anders Carlssond8b285f2009-09-01 04:26:58 +0000951 if (!Member->getDeclName()) {
952 // We have a reference to an unnamed field.
953 assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
Mike Stump1eb44332009-09-09 15:08:12 +0000954
955 MemberExpr *ME =
Anders Carlssond8b285f2009-09-01 04:26:58 +0000956 new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
957 Member, MemberLoc,
958 cast<FieldDecl>(Member)->getType());
959 return getSema().Owned(ME);
960 }
Mike Stump1eb44332009-09-09 15:08:12 +0000961
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000962 CXXScopeSpec SS;
963 if (Qualifier) {
964 SS.setRange(QualifierRange);
965 SS.setScopeRep(Qualifier);
966 }
967
Douglas Gregor017dde52009-08-31 20:00:26 +0000968 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +0000969 isArrow? tok::arrow : tok::period,
970 MemberLoc,
Douglas Gregor017dde52009-08-31 20:00:26 +0000971 Member->getDeclName(),
Douglas Gregor8a4386b2009-11-04 23:20:05 +0000972 HasExplicitTemplateArgs,
973 LAngleLoc,
974 ExplicitTemplateArgs,
975 NumExplicitTemplateArgs,
976 RAngleLoc,
Douglas Gregor83f6faf2009-08-31 23:41:50 +0000977 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregor8a4386b2009-11-04 23:20:05 +0000978 &SS,
979 FirstQualifierInScope);
Douglas Gregorb98b1992009-08-11 05:31:07 +0000980 }
Mike Stump1eb44332009-09-09 15:08:12 +0000981
Douglas Gregorb98b1992009-08-11 05:31:07 +0000982 /// \brief Build a new binary 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 RebuildBinaryOperator(SourceLocation OpLoc,
987 BinaryOperator::Opcode Opc,
988 ExprArg LHS, ExprArg RHS) {
Douglas Gregor6ca7cfb2009-11-05 00:51:44 +0000989 return getSema().BuildBinOp(/*Scope=*/0, OpLoc, Opc,
990 LHS.takeAs<Expr>(), RHS.takeAs<Expr>());
Douglas Gregorb98b1992009-08-11 05:31:07 +0000991 }
992
993 /// \brief Build a new conditional operator expression.
Mike Stump1eb44332009-09-09 15:08:12 +0000994 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +0000995 /// By default, performs semantic analysis to build the new expression.
996 /// Subclasses may override this routine to provide different behavior.
997 OwningExprResult RebuildConditionalOperator(ExprArg Cond,
998 SourceLocation QuestionLoc,
999 ExprArg LHS,
1000 SourceLocation ColonLoc,
1001 ExprArg RHS) {
Mike Stump1eb44332009-09-09 15:08:12 +00001002 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001003 move(LHS), move(RHS));
1004 }
1005
1006 /// \brief Build a new implicit cast expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001007 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001008 /// By default, builds a new implicit cast without any semantic analysis.
1009 /// Subclasses may override this routine to provide different behavior.
1010 OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
1011 ExprArg SubExpr, bool isLvalue) {
1012 ImplicitCastExpr *ICE
Mike Stump1eb44332009-09-09 15:08:12 +00001013 = new (getSema().Context) ImplicitCastExpr(T, Kind,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001014 (Expr *)SubExpr.release(),
1015 isLvalue);
1016 return getSema().Owned(ICE);
1017 }
1018
1019 /// \brief Build a new C-style cast expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001020 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001021 /// By default, performs semantic analysis to build the new expression.
1022 /// Subclasses may override this routine to provide different behavior.
1023 OwningExprResult RebuildCStyleCaseExpr(SourceLocation LParenLoc,
1024 QualType ExplicitTy,
1025 SourceLocation RParenLoc,
1026 ExprArg SubExpr) {
1027 return getSema().ActOnCastExpr(/*Scope=*/0,
1028 LParenLoc,
1029 ExplicitTy.getAsOpaquePtr(),
1030 RParenLoc,
1031 move(SubExpr));
1032 }
Mike Stump1eb44332009-09-09 15:08:12 +00001033
Douglas Gregorb98b1992009-08-11 05:31:07 +00001034 /// \brief Build a new compound literal expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001035 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001036 /// By default, performs semantic analysis to build the new expression.
1037 /// Subclasses may override this routine to provide different behavior.
1038 OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
1039 QualType T,
1040 SourceLocation RParenLoc,
1041 ExprArg Init) {
1042 return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
1043 RParenLoc, move(Init));
1044 }
Mike Stump1eb44332009-09-09 15:08:12 +00001045
Douglas Gregorb98b1992009-08-11 05:31:07 +00001046 /// \brief Build a new extended vector element access expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001047 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001048 /// By default, performs semantic analysis to build the new expression.
1049 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001050 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001051 SourceLocation OpLoc,
1052 SourceLocation AccessorLoc,
1053 IdentifierInfo &Accessor) {
Douglas Gregor2d1c2142009-11-03 19:44:04 +00001054 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001055 tok::period, AccessorLoc,
Douglas Gregor2d1c2142009-11-03 19:44:04 +00001056 DeclarationName(&Accessor),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001057 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
1058 }
Mike Stump1eb44332009-09-09 15:08:12 +00001059
Douglas Gregorb98b1992009-08-11 05:31:07 +00001060 /// \brief Build a new initializer list expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001061 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001062 /// By default, performs semantic analysis to build the new expression.
1063 /// Subclasses may override this routine to provide different behavior.
1064 OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
1065 MultiExprArg Inits,
Douglas Gregore48319a2009-11-09 17:16:50 +00001066 SourceLocation RBraceLoc,
1067 QualType ResultTy) {
1068 OwningExprResult Result
1069 = SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
1070 if (Result.isInvalid() || ResultTy->isDependentType())
1071 return move(Result);
1072
1073 // Patch in the result type we were given, which may have been computed
1074 // when the initial InitListExpr was built.
1075 InitListExpr *ILE = cast<InitListExpr>((Expr *)Result.get());
1076 ILE->setType(ResultTy);
1077 return move(Result);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001078 }
Mike Stump1eb44332009-09-09 15:08:12 +00001079
Douglas Gregorb98b1992009-08-11 05:31:07 +00001080 /// \brief Build a new designated initializer expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001081 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001082 /// By default, performs semantic analysis to build the new expression.
1083 /// Subclasses may override this routine to provide different behavior.
1084 OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
1085 MultiExprArg ArrayExprs,
1086 SourceLocation EqualOrColonLoc,
1087 bool GNUSyntax,
1088 ExprArg Init) {
1089 OwningExprResult Result
1090 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1091 move(Init));
1092 if (Result.isInvalid())
1093 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00001094
Douglas Gregorb98b1992009-08-11 05:31:07 +00001095 ArrayExprs.release();
1096 return move(Result);
1097 }
Mike Stump1eb44332009-09-09 15:08:12 +00001098
Douglas Gregorb98b1992009-08-11 05:31:07 +00001099 /// \brief Build a new value-initialized expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001100 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001101 /// By default, builds the implicit value initialization without performing
1102 /// any semantic analysis. Subclasses may override this routine to provide
1103 /// different behavior.
1104 OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
1105 return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1106 }
Mike Stump1eb44332009-09-09 15:08:12 +00001107
Douglas Gregorb98b1992009-08-11 05:31:07 +00001108 /// \brief Build a new \c va_arg expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001109 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001110 /// By default, performs semantic analysis to build the new expression.
1111 /// Subclasses may override this routine to provide different behavior.
1112 OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
1113 QualType T, SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001114 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001115 RParenLoc);
1116 }
1117
1118 /// \brief Build a new expression list in parentheses.
Mike Stump1eb44332009-09-09 15:08:12 +00001119 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001120 /// By default, performs semantic analysis to build the new expression.
1121 /// Subclasses may override this routine to provide different behavior.
1122 OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1123 MultiExprArg SubExprs,
1124 SourceLocation RParenLoc) {
1125 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
1126 }
Mike Stump1eb44332009-09-09 15:08:12 +00001127
Douglas Gregorb98b1992009-08-11 05:31:07 +00001128 /// \brief Build a new address-of-label expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001129 ///
1130 /// By default, performs semantic analysis, using the name of the label
Douglas Gregorb98b1992009-08-11 05:31:07 +00001131 /// rather than attempting to map the label statement itself.
1132 /// Subclasses may override this routine to provide different behavior.
1133 OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1134 SourceLocation LabelLoc,
1135 LabelStmt *Label) {
1136 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
1137 }
Mike Stump1eb44332009-09-09 15:08:12 +00001138
Douglas Gregorb98b1992009-08-11 05:31:07 +00001139 /// \brief Build a new GNU statement expression.
Mike Stump1eb44332009-09-09 15:08:12 +00001140 ///
Douglas Gregorb98b1992009-08-11 05:31:07 +00001141 /// By default, performs semantic analysis to build the new expression.
1142 /// Subclasses may override this routine to provide different behavior.
1143 OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
1144 StmtArg SubStmt,
1145 SourceLocation RParenLoc) {
1146 return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
1147 }
Mike Stump1eb44332009-09-09 15:08:12 +00001148
Douglas Gregorb98b1992009-08-11 05:31:07 +00001149 /// \brief Build a new __builtin_types_compatible_p expression.
1150 ///
1151 /// By default, performs semantic analysis to build the new expression.
1152 /// Subclasses may override this routine to provide different behavior.
1153 OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
1154 QualType T1, QualType T2,
1155 SourceLocation RParenLoc) {
1156 return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
1157 T1.getAsOpaquePtr(),
1158 T2.getAsOpaquePtr(),
1159 RParenLoc);
1160 }
Mike Stump1eb44332009-09-09 15:08:12 +00001161
Douglas Gregorb98b1992009-08-11 05:31:07 +00001162 /// \brief Build a new __builtin_choose_expr expression.
1163 ///
1164 /// By default, performs semantic analysis to build the new expression.
1165 /// Subclasses may override this routine to provide different behavior.
1166 OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1167 ExprArg Cond, ExprArg LHS, ExprArg RHS,
1168 SourceLocation RParenLoc) {
1169 return SemaRef.ActOnChooseExpr(BuiltinLoc,
1170 move(Cond), move(LHS), move(RHS),
1171 RParenLoc);
1172 }
Mike Stump1eb44332009-09-09 15:08:12 +00001173
Douglas Gregorb98b1992009-08-11 05:31:07 +00001174 /// \brief Build a new overloaded operator call expression.
1175 ///
1176 /// By default, performs semantic analysis to build the new expression.
1177 /// The semantic analysis provides the behavior of template instantiation,
1178 /// copying with transformations that turn what looks like an overloaded
Mike Stump1eb44332009-09-09 15:08:12 +00001179 /// operator call into a use of a builtin operator, performing
Douglas Gregorb98b1992009-08-11 05:31:07 +00001180 /// argument-dependent lookup, etc. Subclasses may override this routine to
1181 /// provide different behavior.
1182 OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1183 SourceLocation OpLoc,
1184 ExprArg Callee,
1185 ExprArg First,
1186 ExprArg Second);
Mike Stump1eb44332009-09-09 15:08:12 +00001187
1188 /// \brief Build a new C++ "named" cast expression, such as static_cast or
Douglas Gregorb98b1992009-08-11 05:31:07 +00001189 /// reinterpret_cast.
1190 ///
1191 /// By default, this routine dispatches to one of the more-specific routines
Mike Stump1eb44332009-09-09 15:08:12 +00001192 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
Douglas Gregorb98b1992009-08-11 05:31:07 +00001193 /// Subclasses may override this routine to provide different behavior.
1194 OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1195 Stmt::StmtClass Class,
1196 SourceLocation LAngleLoc,
1197 QualType T,
1198 SourceLocation RAngleLoc,
1199 SourceLocation LParenLoc,
1200 ExprArg SubExpr,
1201 SourceLocation RParenLoc) {
1202 switch (Class) {
1203 case Stmt::CXXStaticCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001204 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1205 RAngleLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001206 move(SubExpr), RParenLoc);
1207
1208 case Stmt::CXXDynamicCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001209 return getDerived().RebuildCXXDynamicCastExpr(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 case Stmt::CXXReinterpretCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001214 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1215 RAngleLoc, LParenLoc,
1216 move(SubExpr),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001217 RParenLoc);
Mike Stump1eb44332009-09-09 15:08:12 +00001218
Douglas Gregorb98b1992009-08-11 05:31:07 +00001219 case Stmt::CXXConstCastExprClass:
Mike Stump1eb44332009-09-09 15:08:12 +00001220 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1221 RAngleLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001222 move(SubExpr), RParenLoc);
Mike Stump1eb44332009-09-09 15:08:12 +00001223
Douglas Gregorb98b1992009-08-11 05:31:07 +00001224 default:
1225 assert(false && "Invalid C++ named cast");
1226 break;
1227 }
Mike Stump1eb44332009-09-09 15:08:12 +00001228
Douglas Gregorb98b1992009-08-11 05:31:07 +00001229 return getSema().ExprError();
1230 }
Mike Stump1eb44332009-09-09 15:08:12 +00001231
Douglas Gregorb98b1992009-08-11 05:31:07 +00001232 /// \brief Build a new C++ static_cast expression.
1233 ///
1234 /// By default, performs semantic analysis to build the new expression.
1235 /// Subclasses may override this routine to provide different behavior.
1236 OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1237 SourceLocation LAngleLoc,
1238 QualType T,
1239 SourceLocation RAngleLoc,
1240 SourceLocation LParenLoc,
1241 ExprArg SubExpr,
1242 SourceLocation RParenLoc) {
1243 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
Mike Stump1eb44332009-09-09 15:08:12 +00001244 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001245 LParenLoc, move(SubExpr), RParenLoc);
1246 }
1247
1248 /// \brief Build a new C++ dynamic_cast expression.
1249 ///
1250 /// By default, performs semantic analysis to build the new expression.
1251 /// Subclasses may override this routine to provide different behavior.
1252 OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1253 SourceLocation LAngleLoc,
1254 QualType T,
1255 SourceLocation RAngleLoc,
1256 SourceLocation LParenLoc,
1257 ExprArg SubExpr,
1258 SourceLocation RParenLoc) {
1259 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
Mike Stump1eb44332009-09-09 15:08:12 +00001260 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001261 LParenLoc, move(SubExpr), RParenLoc);
1262 }
1263
1264 /// \brief Build a new C++ reinterpret_cast expression.
1265 ///
1266 /// By default, performs semantic analysis to build the new expression.
1267 /// Subclasses may override this routine to provide different behavior.
1268 OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1269 SourceLocation LAngleLoc,
1270 QualType T,
1271 SourceLocation RAngleLoc,
1272 SourceLocation LParenLoc,
1273 ExprArg SubExpr,
1274 SourceLocation RParenLoc) {
1275 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1276 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1277 LParenLoc, move(SubExpr), RParenLoc);
1278 }
1279
1280 /// \brief Build a new C++ const_cast expression.
1281 ///
1282 /// By default, performs semantic analysis to build the new expression.
1283 /// Subclasses may override this routine to provide different behavior.
1284 OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1285 SourceLocation LAngleLoc,
1286 QualType T,
1287 SourceLocation RAngleLoc,
1288 SourceLocation LParenLoc,
1289 ExprArg SubExpr,
1290 SourceLocation RParenLoc) {
1291 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
Mike Stump1eb44332009-09-09 15:08:12 +00001292 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001293 LParenLoc, move(SubExpr), RParenLoc);
1294 }
Mike Stump1eb44332009-09-09 15:08:12 +00001295
Douglas Gregorb98b1992009-08-11 05:31:07 +00001296 /// \brief Build a new C++ functional-style cast expression.
1297 ///
1298 /// By default, performs semantic analysis to build the new expression.
1299 /// Subclasses may override this routine to provide different behavior.
1300 OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
1301 QualType T,
1302 SourceLocation LParenLoc,
1303 ExprArg SubExpr,
1304 SourceLocation RParenLoc) {
Chris Lattner88650c32009-08-24 05:19:01 +00001305 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregorb98b1992009-08-11 05:31:07 +00001306 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1307 T.getAsOpaquePtr(),
1308 LParenLoc,
Chris Lattner88650c32009-08-24 05:19:01 +00001309 Sema::MultiExprArg(getSema(), &Sub, 1),
Mike Stump1eb44332009-09-09 15:08:12 +00001310 /*CommaLocs=*/0,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001311 RParenLoc);
1312 }
Mike Stump1eb44332009-09-09 15:08:12 +00001313
Douglas Gregorb98b1992009-08-11 05:31:07 +00001314 /// \brief Build a new C++ typeid(type) expression.
1315 ///
1316 /// By default, performs semantic analysis to build the new expression.
1317 /// Subclasses may override this routine to provide different behavior.
1318 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1319 SourceLocation LParenLoc,
1320 QualType T,
1321 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001322 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001323 T.getAsOpaquePtr(), RParenLoc);
1324 }
Mike Stump1eb44332009-09-09 15:08:12 +00001325
Douglas Gregorb98b1992009-08-11 05:31:07 +00001326 /// \brief Build a new C++ typeid(expr) expression.
1327 ///
1328 /// By default, performs semantic analysis to build the new expression.
1329 /// Subclasses may override this routine to provide different behavior.
1330 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1331 SourceLocation LParenLoc,
1332 ExprArg Operand,
1333 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001334 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +00001335 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1336 RParenLoc);
1337 if (Result.isInvalid())
1338 return getSema().ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00001339
Douglas Gregorb98b1992009-08-11 05:31:07 +00001340 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1341 return move(Result);
Mike Stump1eb44332009-09-09 15:08:12 +00001342 }
1343
Douglas Gregorb98b1992009-08-11 05:31:07 +00001344 /// \brief Build a new C++ "this" expression.
1345 ///
1346 /// By default, builds a new "this" expression without performing any
Mike Stump1eb44332009-09-09 15:08:12 +00001347 /// semantic analysis. Subclasses may override this routine to provide
Douglas Gregorb98b1992009-08-11 05:31:07 +00001348 /// different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001349 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001350 QualType ThisType) {
1351 return getSema().Owned(
1352 new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
1353 }
1354
1355 /// \brief Build a new C++ throw expression.
1356 ///
1357 /// By default, performs semantic analysis to build the new expression.
1358 /// Subclasses may override this routine to provide different behavior.
1359 OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
1360 return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
1361 }
1362
1363 /// \brief Build a new C++ default-argument expression.
1364 ///
1365 /// By default, builds a new default-argument expression, which does not
1366 /// require any semantic analysis. Subclasses may override this routine to
1367 /// provide different behavior.
1368 OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
Anders Carlssonf1480ee2009-08-14 18:30:22 +00001369 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001370 }
1371
1372 /// \brief Build a new C++ zero-initialization expression.
1373 ///
1374 /// By default, performs semantic analysis to build the new expression.
1375 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001376 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001377 SourceLocation LParenLoc,
1378 QualType T,
1379 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001380 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1381 T.getAsOpaquePtr(), LParenLoc,
1382 MultiExprArg(getSema(), 0, 0),
Douglas Gregorb98b1992009-08-11 05:31:07 +00001383 0, RParenLoc);
1384 }
Mike Stump1eb44332009-09-09 15:08:12 +00001385
Douglas Gregorb98b1992009-08-11 05:31:07 +00001386 /// \brief Build a new C++ conditional declaration expression.
1387 ///
1388 /// By default, performs semantic analysis to build the new expression.
1389 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001390 OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001391 SourceLocation EqLoc,
1392 VarDecl *Var) {
1393 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(StartLoc,
1394 EqLoc,
1395 Var));
1396 }
Mike Stump1eb44332009-09-09 15:08:12 +00001397
Douglas Gregorb98b1992009-08-11 05:31:07 +00001398 /// \brief Build a new C++ "new" expression.
1399 ///
1400 /// By default, performs semantic analysis to build the new expression.
1401 /// Subclasses may override this routine to provide different behavior.
Mike Stump1eb44332009-09-09 15:08:12 +00001402 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001403 bool UseGlobal,
1404 SourceLocation PlacementLParen,
1405 MultiExprArg PlacementArgs,
1406 SourceLocation PlacementRParen,
Mike Stump1eb44332009-09-09 15:08:12 +00001407 bool ParenTypeId,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001408 QualType AllocType,
1409 SourceLocation TypeLoc,
1410 SourceRange TypeRange,
1411 ExprArg ArraySize,
1412 SourceLocation ConstructorLParen,
1413 MultiExprArg ConstructorArgs,
1414 SourceLocation ConstructorRParen) {
Mike Stump1eb44332009-09-09 15:08:12 +00001415 return getSema().BuildCXXNew(StartLoc, UseGlobal,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001416 PlacementLParen,
1417 move(PlacementArgs),
1418 PlacementRParen,
1419 ParenTypeId,
1420 AllocType,
1421 TypeLoc,
1422 TypeRange,
1423 move(ArraySize),
1424 ConstructorLParen,
1425 move(ConstructorArgs),
1426 ConstructorRParen);
1427 }
Mike Stump1eb44332009-09-09 15:08:12 +00001428
Douglas Gregorb98b1992009-08-11 05:31:07 +00001429 /// \brief Build a new C++ "delete" expression.
1430 ///
1431 /// By default, performs semantic analysis to build the new expression.
1432 /// Subclasses may override this routine to provide different behavior.
1433 OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
1434 bool IsGlobalDelete,
1435 bool IsArrayForm,
1436 ExprArg Operand) {
1437 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
1438 move(Operand));
1439 }
Mike Stump1eb44332009-09-09 15:08:12 +00001440
Douglas Gregorb98b1992009-08-11 05:31:07 +00001441 /// \brief Build a new unary type trait expression.
1442 ///
1443 /// By default, performs semantic analysis to build the new expression.
1444 /// Subclasses may override this routine to provide different behavior.
1445 OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
1446 SourceLocation StartLoc,
1447 SourceLocation LParenLoc,
1448 QualType T,
1449 SourceLocation RParenLoc) {
Mike Stump1eb44332009-09-09 15:08:12 +00001450 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001451 T.getAsOpaquePtr(), RParenLoc);
1452 }
1453
Mike Stump1eb44332009-09-09 15:08:12 +00001454 /// \brief Build a new (previously unresolved) declaration reference
Douglas Gregorb98b1992009-08-11 05:31:07 +00001455 /// expression.
1456 ///
1457 /// By default, performs semantic analysis to build the new expression.
1458 /// Subclasses may override this routine to provide different behavior.
John McCall865d4472009-11-19 22:55:06 +00001459 OwningExprResult RebuildDependentScopeDeclRefExpr(NestedNameSpecifier *NNS,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001460 SourceRange QualifierRange,
1461 DeclarationName Name,
1462 SourceLocation Location,
1463 bool IsAddressOfOperand) {
1464 CXXScopeSpec SS;
1465 SS.setRange(QualifierRange);
1466 SS.setScopeRep(NNS);
Mike Stump1eb44332009-09-09 15:08:12 +00001467 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001468 Location,
1469 Name,
1470 /*Trailing lparen=*/false,
1471 &SS,
1472 IsAddressOfOperand);
1473 }
1474
1475 /// \brief Build a new template-id expression.
1476 ///
1477 /// By default, performs semantic analysis to build the new expression.
1478 /// Subclasses may override this routine to provide different behavior.
Douglas Gregorf17bb742009-10-22 17:20:55 +00001479 OwningExprResult RebuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
1480 SourceRange QualifierRange,
1481 TemplateName Template,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001482 SourceLocation TemplateLoc,
1483 SourceLocation LAngleLoc,
John McCall833ca992009-10-29 08:12:44 +00001484 TemplateArgumentLoc *TemplateArgs,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001485 unsigned NumTemplateArgs,
1486 SourceLocation RAngleLoc) {
Douglas Gregorf17bb742009-10-22 17:20:55 +00001487 return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
1488 Template, TemplateLoc,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001489 LAngleLoc,
1490 TemplateArgs, NumTemplateArgs,
1491 RAngleLoc);
1492 }
1493
1494 /// \brief Build a new object-construction expression.
1495 ///
1496 /// By default, performs semantic analysis to build the new expression.
1497 /// Subclasses may override this routine to provide different behavior.
1498 OwningExprResult RebuildCXXConstructExpr(QualType T,
1499 CXXConstructorDecl *Constructor,
1500 bool IsElidable,
1501 MultiExprArg Args) {
Anders Carlssonec8e5ea2009-09-05 07:40:38 +00001502 return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/
1503 SourceLocation(),
1504 T, Constructor, IsElidable,
Anders Carlssonf47511a2009-09-07 22:23:31 +00001505 move(Args));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001506 }
1507
1508 /// \brief Build a new object-construction expression.
1509 ///
1510 /// By default, performs semantic analysis to build the new expression.
1511 /// Subclasses may override this routine to provide different behavior.
1512 OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
1513 QualType T,
1514 SourceLocation LParenLoc,
1515 MultiExprArg Args,
1516 SourceLocation *Commas,
1517 SourceLocation RParenLoc) {
1518 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
1519 T.getAsOpaquePtr(),
1520 LParenLoc,
1521 move(Args),
1522 Commas,
1523 RParenLoc);
1524 }
1525
1526 /// \brief Build a new object-construction expression.
1527 ///
1528 /// By default, performs semantic analysis to build the new expression.
1529 /// Subclasses may override this routine to provide different behavior.
1530 OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
1531 QualType T,
1532 SourceLocation LParenLoc,
1533 MultiExprArg Args,
1534 SourceLocation *Commas,
1535 SourceLocation RParenLoc) {
1536 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
1537 /*FIXME*/LParenLoc),
1538 T.getAsOpaquePtr(),
1539 LParenLoc,
1540 move(Args),
1541 Commas,
1542 RParenLoc);
1543 }
Mike Stump1eb44332009-09-09 15:08:12 +00001544
Douglas Gregorb98b1992009-08-11 05:31:07 +00001545 /// \brief Build a new member reference expression.
1546 ///
1547 /// By default, performs semantic analysis to build the new expression.
1548 /// Subclasses may override this routine to provide different behavior.
John McCall865d4472009-11-19 22:55:06 +00001549 OwningExprResult RebuildCXXDependentScopeMemberExpr(ExprArg BaseE,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001550 bool IsArrow,
1551 SourceLocation OperatorLoc,
Douglas Gregora38c6872009-09-03 16:14:30 +00001552 NestedNameSpecifier *Qualifier,
1553 SourceRange QualifierRange,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001554 DeclarationName Name,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001555 SourceLocation MemberLoc,
1556 NamedDecl *FirstQualifierInScope) {
Douglas Gregor0dec56d2009-08-11 15:56:57 +00001557 OwningExprResult Base = move(BaseE);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001558 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregora38c6872009-09-03 16:14:30 +00001559
Douglas Gregorb98b1992009-08-11 05:31:07 +00001560 CXXScopeSpec SS;
Douglas Gregora38c6872009-09-03 16:14:30 +00001561 SS.setRange(QualifierRange);
1562 SS.setScopeRep(Qualifier);
Mike Stump1eb44332009-09-09 15:08:12 +00001563
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001564 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregorb98b1992009-08-11 05:31:07 +00001565 move(Base), OperatorLoc, OpKind,
Douglas Gregor017dde52009-08-31 20:00:26 +00001566 MemberLoc,
1567 Name,
Douglas Gregora38c6872009-09-03 16:14:30 +00001568 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregorc68afe22009-09-03 21:38:09 +00001569 &SS,
1570 FirstQualifierInScope);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001571 }
1572
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001573 /// \brief Build a new member reference expression with explicit template
1574 /// arguments.
1575 ///
1576 /// By default, performs semantic analysis to build the new expression.
1577 /// Subclasses may override this routine to provide different behavior.
John McCall865d4472009-11-19 22:55:06 +00001578 OwningExprResult RebuildCXXDependentScopeMemberExpr(ExprArg BaseE,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001579 bool IsArrow,
1580 SourceLocation OperatorLoc,
1581 NestedNameSpecifier *Qualifier,
1582 SourceRange QualifierRange,
1583 TemplateName Template,
1584 SourceLocation TemplateNameLoc,
1585 NamedDecl *FirstQualifierInScope,
1586 SourceLocation LAngleLoc,
John McCall833ca992009-10-29 08:12:44 +00001587 const TemplateArgumentLoc *TemplateArgs,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001588 unsigned NumTemplateArgs,
1589 SourceLocation RAngleLoc) {
1590 OwningExprResult Base = move(BaseE);
1591 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Mike Stump1eb44332009-09-09 15:08:12 +00001592
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001593 CXXScopeSpec SS;
1594 SS.setRange(QualifierRange);
1595 SS.setScopeRep(Qualifier);
Mike Stump1eb44332009-09-09 15:08:12 +00001596
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001597 // FIXME: We're going to end up looking up the template based on its name,
Douglas Gregor2d1c2142009-11-03 19:44:04 +00001598 // twice! Also, duplicates part of Sema::BuildMemberAccessExpr.
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001599 DeclarationName Name;
1600 if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
1601 Name = ActualTemplate->getDeclName();
Mike Stump1eb44332009-09-09 15:08:12 +00001602 else if (OverloadedFunctionDecl *Ovl
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001603 = Template.getAsOverloadedFunctionDecl())
1604 Name = Ovl->getDeclName();
Douglas Gregorca1bdd72009-11-04 00:56:37 +00001605 else {
1606 DependentTemplateName *DTN = Template.getAsDependentTemplateName();
1607 if (DTN->isIdentifier())
1608 Name = DTN->getIdentifier();
1609 else
1610 Name = SemaRef.Context.DeclarationNames.getCXXOperatorName(
1611 DTN->getOperator());
1612 }
Mike Stump1eb44332009-09-09 15:08:12 +00001613 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001614 OperatorLoc, OpKind,
1615 TemplateNameLoc, Name, true,
1616 LAngleLoc, TemplateArgs,
1617 NumTemplateArgs, RAngleLoc,
1618 Sema::DeclPtrTy(), &SS);
1619 }
Mike Stump1eb44332009-09-09 15:08:12 +00001620
Douglas Gregorb98b1992009-08-11 05:31:07 +00001621 /// \brief Build a new Objective-C @encode expression.
1622 ///
1623 /// By default, performs semantic analysis to build the new expression.
1624 /// Subclasses may override this routine to provide different behavior.
1625 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1626 QualType T,
1627 SourceLocation RParenLoc) {
1628 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1629 RParenLoc));
Mike Stump1eb44332009-09-09 15:08:12 +00001630 }
Douglas Gregorb98b1992009-08-11 05:31:07 +00001631
1632 /// \brief Build a new Objective-C protocol expression.
1633 ///
1634 /// By default, performs semantic analysis to build the new expression.
1635 /// Subclasses may override this routine to provide different behavior.
1636 OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1637 SourceLocation AtLoc,
1638 SourceLocation ProtoLoc,
1639 SourceLocation LParenLoc,
1640 SourceLocation RParenLoc) {
1641 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1642 Protocol->getIdentifier(),
1643 AtLoc,
1644 ProtoLoc,
1645 LParenLoc,
Mike Stump1eb44332009-09-09 15:08:12 +00001646 RParenLoc));
Douglas Gregorb98b1992009-08-11 05:31:07 +00001647 }
Mike Stump1eb44332009-09-09 15:08:12 +00001648
Douglas Gregorb98b1992009-08-11 05:31:07 +00001649 /// \brief Build a new shuffle vector expression.
1650 ///
1651 /// By default, performs semantic analysis to build the new expression.
1652 /// Subclasses may override this routine to provide different behavior.
1653 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1654 MultiExprArg SubExprs,
1655 SourceLocation RParenLoc) {
1656 // Find the declaration for __builtin_shufflevector
Mike Stump1eb44332009-09-09 15:08:12 +00001657 const IdentifierInfo &Name
Douglas Gregorb98b1992009-08-11 05:31:07 +00001658 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1659 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1660 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1661 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
Mike Stump1eb44332009-09-09 15:08:12 +00001662
Douglas Gregorb98b1992009-08-11 05:31:07 +00001663 // Build a reference to the __builtin_shufflevector builtin
1664 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Mike Stump1eb44332009-09-09 15:08:12 +00001665 Expr *Callee
Douglas Gregorb98b1992009-08-11 05:31:07 +00001666 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1667 BuiltinLoc, false, false);
1668 SemaRef.UsualUnaryConversions(Callee);
Mike Stump1eb44332009-09-09 15:08:12 +00001669
1670 // Build the CallExpr
Douglas Gregorb98b1992009-08-11 05:31:07 +00001671 unsigned NumSubExprs = SubExprs.size();
1672 Expr **Subs = (Expr **)SubExprs.release();
1673 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1674 Subs, NumSubExprs,
1675 Builtin->getResultType(),
1676 RParenLoc);
1677 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
Mike Stump1eb44332009-09-09 15:08:12 +00001678
Douglas Gregorb98b1992009-08-11 05:31:07 +00001679 // Type-check the __builtin_shufflevector expression.
1680 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1681 if (Result.isInvalid())
1682 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00001683
Douglas Gregorb98b1992009-08-11 05:31:07 +00001684 OwnedCall.release();
Mike Stump1eb44332009-09-09 15:08:12 +00001685 return move(Result);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001686 }
Douglas Gregor577f75a2009-08-04 16:50:30 +00001687};
Douglas Gregorb98b1992009-08-11 05:31:07 +00001688
Douglas Gregor43959a92009-08-20 07:17:43 +00001689template<typename Derived>
1690Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1691 if (!S)
1692 return SemaRef.Owned(S);
Mike Stump1eb44332009-09-09 15:08:12 +00001693
Douglas Gregor43959a92009-08-20 07:17:43 +00001694 switch (S->getStmtClass()) {
1695 case Stmt::NoStmtClass: break;
Mike Stump1eb44332009-09-09 15:08:12 +00001696
Douglas Gregor43959a92009-08-20 07:17:43 +00001697 // Transform individual statement nodes
1698#define STMT(Node, Parent) \
1699 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1700#define EXPR(Node, Parent)
1701#include "clang/AST/StmtNodes.def"
Mike Stump1eb44332009-09-09 15:08:12 +00001702
Douglas Gregor43959a92009-08-20 07:17:43 +00001703 // Transform expressions by calling TransformExpr.
1704#define STMT(Node, Parent)
1705#define EXPR(Node, Parent) case Stmt::Node##Class:
1706#include "clang/AST/StmtNodes.def"
1707 {
1708 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1709 if (E.isInvalid())
1710 return getSema().StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00001711
Douglas Gregorafe7ec22009-11-13 18:34:26 +00001712 return getSema().ActOnExprStmt(getSema().FullExpr(E));
Douglas Gregor43959a92009-08-20 07:17:43 +00001713 }
Mike Stump1eb44332009-09-09 15:08:12 +00001714 }
1715
Douglas Gregor43959a92009-08-20 07:17:43 +00001716 return SemaRef.Owned(S->Retain());
1717}
Mike Stump1eb44332009-09-09 15:08:12 +00001718
1719
Douglas Gregor670444e2009-08-04 22:27:00 +00001720template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00001721Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1722 bool isAddressOfOperand) {
1723 if (!E)
1724 return SemaRef.Owned(E);
1725
1726 switch (E->getStmtClass()) {
1727 case Stmt::NoStmtClass: break;
1728#define STMT(Node, Parent) case Stmt::Node##Class: break;
1729#define EXPR(Node, Parent) \
Douglas Gregorc86a6e92009-11-04 07:01:15 +00001730 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E), \
1731 isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00001732#include "clang/AST/StmtNodes.def"
Mike Stump1eb44332009-09-09 15:08:12 +00001733 }
1734
Douglas Gregorb98b1992009-08-11 05:31:07 +00001735 return SemaRef.Owned(E->Retain());
Douglas Gregor657c1ac2009-08-06 22:17:10 +00001736}
1737
1738template<typename Derived>
Douglas Gregordcee1a12009-08-06 05:28:30 +00001739NestedNameSpecifier *
1740TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregora38c6872009-09-03 16:14:30 +00001741 SourceRange Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001742 QualType ObjectType,
1743 NamedDecl *FirstQualifierInScope) {
Douglas Gregor0979c802009-08-31 21:41:48 +00001744 if (!NNS)
1745 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001746
Douglas Gregor43959a92009-08-20 07:17:43 +00001747 // Transform the prefix of this nested name specifier.
Douglas Gregordcee1a12009-08-06 05:28:30 +00001748 NestedNameSpecifier *Prefix = NNS->getPrefix();
1749 if (Prefix) {
Mike Stump1eb44332009-09-09 15:08:12 +00001750 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregorc68afe22009-09-03 21:38:09 +00001751 ObjectType,
1752 FirstQualifierInScope);
Douglas Gregordcee1a12009-08-06 05:28:30 +00001753 if (!Prefix)
1754 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001755
1756 // Clear out the object type and the first qualifier in scope; they only
Douglas Gregorc68afe22009-09-03 21:38:09 +00001757 // apply to the first element in the nested-name-specifier.
Douglas Gregora38c6872009-09-03 16:14:30 +00001758 ObjectType = QualType();
Douglas Gregorc68afe22009-09-03 21:38:09 +00001759 FirstQualifierInScope = 0;
Douglas Gregordcee1a12009-08-06 05:28:30 +00001760 }
Mike Stump1eb44332009-09-09 15:08:12 +00001761
Douglas Gregordcee1a12009-08-06 05:28:30 +00001762 switch (NNS->getKind()) {
1763 case NestedNameSpecifier::Identifier:
Mike Stump1eb44332009-09-09 15:08:12 +00001764 assert((Prefix || !ObjectType.isNull()) &&
Douglas Gregora38c6872009-09-03 16:14:30 +00001765 "Identifier nested-name-specifier with no prefix or object type");
1766 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
1767 ObjectType.isNull())
Douglas Gregordcee1a12009-08-06 05:28:30 +00001768 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001769
1770 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregora38c6872009-09-03 16:14:30 +00001771 *NNS->getAsIdentifier(),
Douglas Gregorc68afe22009-09-03 21:38:09 +00001772 ObjectType,
1773 FirstQualifierInScope);
Mike Stump1eb44332009-09-09 15:08:12 +00001774
Douglas Gregordcee1a12009-08-06 05:28:30 +00001775 case NestedNameSpecifier::Namespace: {
Mike Stump1eb44332009-09-09 15:08:12 +00001776 NamespaceDecl *NS
Douglas Gregordcee1a12009-08-06 05:28:30 +00001777 = cast_or_null<NamespaceDecl>(
1778 getDerived().TransformDecl(NNS->getAsNamespace()));
Mike Stump1eb44332009-09-09 15:08:12 +00001779 if (!getDerived().AlwaysRebuild() &&
Douglas Gregordcee1a12009-08-06 05:28:30 +00001780 Prefix == NNS->getPrefix() &&
1781 NS == NNS->getAsNamespace())
1782 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001783
Douglas Gregordcee1a12009-08-06 05:28:30 +00001784 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1785 }
Mike Stump1eb44332009-09-09 15:08:12 +00001786
Douglas Gregordcee1a12009-08-06 05:28:30 +00001787 case NestedNameSpecifier::Global:
1788 // There is no meaningful transformation that one could perform on the
1789 // global scope.
1790 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001791
Douglas Gregordcee1a12009-08-06 05:28:30 +00001792 case NestedNameSpecifier::TypeSpecWithTemplate:
1793 case NestedNameSpecifier::TypeSpec: {
Douglas Gregorfbf2c942009-10-29 22:21:39 +00001794 TemporaryBase Rebase(*this, Range.getBegin(), DeclarationName());
Douglas Gregordcee1a12009-08-06 05:28:30 +00001795 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregord1067e52009-08-06 06:41:21 +00001796 if (T.isNull())
1797 return 0;
Mike Stump1eb44332009-09-09 15:08:12 +00001798
Douglas Gregordcee1a12009-08-06 05:28:30 +00001799 if (!getDerived().AlwaysRebuild() &&
1800 Prefix == NNS->getPrefix() &&
1801 T == QualType(NNS->getAsType(), 0))
1802 return NNS;
Mike Stump1eb44332009-09-09 15:08:12 +00001803
1804 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1805 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
Douglas Gregordcee1a12009-08-06 05:28:30 +00001806 T);
1807 }
1808 }
Mike Stump1eb44332009-09-09 15:08:12 +00001809
Douglas Gregordcee1a12009-08-06 05:28:30 +00001810 // Required to silence a GCC warning
Mike Stump1eb44332009-09-09 15:08:12 +00001811 return 0;
Douglas Gregordcee1a12009-08-06 05:28:30 +00001812}
1813
1814template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00001815DeclarationName
Douglas Gregor81499bb2009-09-03 22:13:48 +00001816TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
Douglas Gregordd62b152009-10-19 22:04:39 +00001817 SourceLocation Loc,
1818 QualType ObjectType) {
Douglas Gregor81499bb2009-09-03 22:13:48 +00001819 if (!Name)
1820 return Name;
1821
1822 switch (Name.getNameKind()) {
1823 case DeclarationName::Identifier:
1824 case DeclarationName::ObjCZeroArgSelector:
1825 case DeclarationName::ObjCOneArgSelector:
1826 case DeclarationName::ObjCMultiArgSelector:
1827 case DeclarationName::CXXOperatorName:
1828 case DeclarationName::CXXUsingDirective:
1829 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001830
Douglas Gregor81499bb2009-09-03 22:13:48 +00001831 case DeclarationName::CXXConstructorName:
1832 case DeclarationName::CXXDestructorName:
1833 case DeclarationName::CXXConversionFunctionName: {
1834 TemporaryBase Rebase(*this, Loc, Name);
Douglas Gregordd62b152009-10-19 22:04:39 +00001835 QualType T;
1836 if (!ObjectType.isNull() &&
1837 isa<TemplateSpecializationType>(Name.getCXXNameType())) {
1838 TemplateSpecializationType *SpecType
1839 = cast<TemplateSpecializationType>(Name.getCXXNameType());
1840 T = TransformTemplateSpecializationType(SpecType, ObjectType);
1841 } else
1842 T = getDerived().TransformType(Name.getCXXNameType());
Douglas Gregor81499bb2009-09-03 22:13:48 +00001843 if (T.isNull())
1844 return DeclarationName();
Mike Stump1eb44332009-09-09 15:08:12 +00001845
Douglas Gregor81499bb2009-09-03 22:13:48 +00001846 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
Mike Stump1eb44332009-09-09 15:08:12 +00001847 Name.getNameKind(),
Douglas Gregor81499bb2009-09-03 22:13:48 +00001848 SemaRef.Context.getCanonicalType(T));
Douglas Gregor81499bb2009-09-03 22:13:48 +00001849 }
Mike Stump1eb44332009-09-09 15:08:12 +00001850 }
1851
Douglas Gregor81499bb2009-09-03 22:13:48 +00001852 return DeclarationName();
1853}
1854
1855template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00001856TemplateName
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001857TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
1858 QualType ObjectType) {
Douglas Gregord1067e52009-08-06 06:41:21 +00001859 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001860 NestedNameSpecifier *NNS
Douglas Gregord1067e52009-08-06 06:41:21 +00001861 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1862 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1863 if (!NNS)
1864 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001865
Douglas Gregord1067e52009-08-06 06:41:21 +00001866 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001867 TemplateDecl *TransTemplate
Douglas Gregord1067e52009-08-06 06:41:21 +00001868 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1869 if (!TransTemplate)
1870 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001871
Douglas Gregord1067e52009-08-06 06:41:21 +00001872 if (!getDerived().AlwaysRebuild() &&
1873 NNS == QTN->getQualifier() &&
1874 TransTemplate == Template)
1875 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001876
Douglas Gregord1067e52009-08-06 06:41:21 +00001877 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1878 TransTemplate);
1879 }
Mike Stump1eb44332009-09-09 15:08:12 +00001880
Douglas Gregord1067e52009-08-06 06:41:21 +00001881 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1882 assert(Ovl && "Not a template name or an overload set?");
Mike Stump1eb44332009-09-09 15:08:12 +00001883 OverloadedFunctionDecl *TransOvl
Douglas Gregord1067e52009-08-06 06:41:21 +00001884 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1885 if (!TransOvl)
1886 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001887
Douglas Gregord1067e52009-08-06 06:41:21 +00001888 if (!getDerived().AlwaysRebuild() &&
1889 NNS == QTN->getQualifier() &&
1890 TransOvl == Ovl)
1891 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001892
Douglas Gregord1067e52009-08-06 06:41:21 +00001893 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1894 TransOvl);
1895 }
Mike Stump1eb44332009-09-09 15:08:12 +00001896
Douglas Gregord1067e52009-08-06 06:41:21 +00001897 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001898 NestedNameSpecifier *NNS
Douglas Gregord1067e52009-08-06 06:41:21 +00001899 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1900 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00001901 if (!NNS && DTN->getQualifier())
Douglas Gregord1067e52009-08-06 06:41:21 +00001902 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001903
Douglas Gregord1067e52009-08-06 06:41:21 +00001904 if (!getDerived().AlwaysRebuild() &&
Douglas Gregordd62b152009-10-19 22:04:39 +00001905 NNS == DTN->getQualifier() &&
1906 ObjectType.isNull())
Douglas Gregord1067e52009-08-06 06:41:21 +00001907 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001908
Douglas Gregorca1bdd72009-11-04 00:56:37 +00001909 if (DTN->isIdentifier())
1910 return getDerived().RebuildTemplateName(NNS, *DTN->getIdentifier(),
1911 ObjectType);
1912
1913 return getDerived().RebuildTemplateName(NNS, DTN->getOperator(),
1914 ObjectType);
Douglas Gregord1067e52009-08-06 06:41:21 +00001915 }
Mike Stump1eb44332009-09-09 15:08:12 +00001916
Douglas Gregord1067e52009-08-06 06:41:21 +00001917 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
Mike Stump1eb44332009-09-09 15:08:12 +00001918 TemplateDecl *TransTemplate
Douglas Gregord1067e52009-08-06 06:41:21 +00001919 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1920 if (!TransTemplate)
1921 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001922
Douglas Gregord1067e52009-08-06 06:41:21 +00001923 if (!getDerived().AlwaysRebuild() &&
1924 TransTemplate == Template)
1925 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001926
Douglas Gregord1067e52009-08-06 06:41:21 +00001927 return TemplateName(TransTemplate);
1928 }
Mike Stump1eb44332009-09-09 15:08:12 +00001929
Douglas Gregord1067e52009-08-06 06:41:21 +00001930 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1931 assert(Ovl && "Not a template name or an overload set?");
Mike Stump1eb44332009-09-09 15:08:12 +00001932 OverloadedFunctionDecl *TransOvl
Douglas Gregord1067e52009-08-06 06:41:21 +00001933 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1934 if (!TransOvl)
1935 return TemplateName();
Mike Stump1eb44332009-09-09 15:08:12 +00001936
Douglas Gregord1067e52009-08-06 06:41:21 +00001937 if (!getDerived().AlwaysRebuild() &&
1938 TransOvl == Ovl)
1939 return Name;
Mike Stump1eb44332009-09-09 15:08:12 +00001940
Douglas Gregord1067e52009-08-06 06:41:21 +00001941 return TemplateName(TransOvl);
1942}
1943
1944template<typename Derived>
John McCall833ca992009-10-29 08:12:44 +00001945void TreeTransform<Derived>::InventTemplateArgumentLoc(
1946 const TemplateArgument &Arg,
1947 TemplateArgumentLoc &Output) {
1948 SourceLocation Loc = getDerived().getBaseLocation();
1949 switch (Arg.getKind()) {
1950 case TemplateArgument::Null:
1951 llvm::llvm_unreachable("null template argument in TreeTransform");
1952 break;
1953
1954 case TemplateArgument::Type:
1955 Output = TemplateArgumentLoc(Arg,
1956 SemaRef.Context.getTrivialDeclaratorInfo(Arg.getAsType(), Loc));
1957
1958 break;
1959
Douglas Gregor788cd062009-11-11 01:00:40 +00001960 case TemplateArgument::Template:
1961 Output = TemplateArgumentLoc(Arg, SourceRange(), Loc);
1962 break;
1963
John McCall833ca992009-10-29 08:12:44 +00001964 case TemplateArgument::Expression:
1965 Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
1966 break;
1967
1968 case TemplateArgument::Declaration:
1969 case TemplateArgument::Integral:
1970 case TemplateArgument::Pack:
John McCall828bff22009-10-29 18:45:58 +00001971 Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
John McCall833ca992009-10-29 08:12:44 +00001972 break;
1973 }
1974}
1975
1976template<typename Derived>
1977bool TreeTransform<Derived>::TransformTemplateArgument(
1978 const TemplateArgumentLoc &Input,
1979 TemplateArgumentLoc &Output) {
1980 const TemplateArgument &Arg = Input.getArgument();
Douglas Gregor670444e2009-08-04 22:27:00 +00001981 switch (Arg.getKind()) {
1982 case TemplateArgument::Null:
1983 case TemplateArgument::Integral:
John McCall833ca992009-10-29 08:12:44 +00001984 Output = Input;
1985 return false;
Mike Stump1eb44332009-09-09 15:08:12 +00001986
Douglas Gregor670444e2009-08-04 22:27:00 +00001987 case TemplateArgument::Type: {
John McCall833ca992009-10-29 08:12:44 +00001988 DeclaratorInfo *DI = Input.getSourceDeclaratorInfo();
1989 if (DI == NULL)
1990 DI = InventDeclaratorInfo(Input.getArgument().getAsType());
1991
1992 DI = getDerived().TransformType(DI);
1993 if (!DI) return true;
1994
1995 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
1996 return false;
Douglas Gregor670444e2009-08-04 22:27:00 +00001997 }
Mike Stump1eb44332009-09-09 15:08:12 +00001998
Douglas Gregor670444e2009-08-04 22:27:00 +00001999 case TemplateArgument::Declaration: {
John McCall833ca992009-10-29 08:12:44 +00002000 // FIXME: we should never have to transform one of these.
Douglas Gregor972e6ce2009-10-27 06:26:26 +00002001 DeclarationName Name;
2002 if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
2003 Name = ND->getDeclName();
Douglas Gregor788cd062009-11-11 01:00:40 +00002004 TemporaryBase Rebase(*this, Input.getLocation(), Name);
Douglas Gregor670444e2009-08-04 22:27:00 +00002005 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
John McCall833ca992009-10-29 08:12:44 +00002006 if (!D) return true;
2007
John McCall828bff22009-10-29 18:45:58 +00002008 Expr *SourceExpr = Input.getSourceDeclExpression();
2009 if (SourceExpr) {
2010 EnterExpressionEvaluationContext Unevaluated(getSema(),
2011 Action::Unevaluated);
2012 Sema::OwningExprResult E = getDerived().TransformExpr(SourceExpr);
2013 if (E.isInvalid())
2014 SourceExpr = NULL;
2015 else {
2016 SourceExpr = E.takeAs<Expr>();
2017 SourceExpr->Retain();
2018 }
2019 }
2020
2021 Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr);
John McCall833ca992009-10-29 08:12:44 +00002022 return false;
Douglas Gregor670444e2009-08-04 22:27:00 +00002023 }
Mike Stump1eb44332009-09-09 15:08:12 +00002024
Douglas Gregor788cd062009-11-11 01:00:40 +00002025 case TemplateArgument::Template: {
2026 TemporaryBase Rebase(*this, Input.getLocation(), DeclarationName());
2027 TemplateName Template
2028 = getDerived().TransformTemplateName(Arg.getAsTemplate());
2029 if (Template.isNull())
2030 return true;
2031
2032 Output = TemplateArgumentLoc(TemplateArgument(Template),
2033 Input.getTemplateQualifierRange(),
2034 Input.getTemplateNameLoc());
2035 return false;
2036 }
2037
Douglas Gregor670444e2009-08-04 22:27:00 +00002038 case TemplateArgument::Expression: {
2039 // Template argument expressions are not potentially evaluated.
Mike Stump1eb44332009-09-09 15:08:12 +00002040 EnterExpressionEvaluationContext Unevaluated(getSema(),
Douglas Gregor670444e2009-08-04 22:27:00 +00002041 Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00002042
John McCall833ca992009-10-29 08:12:44 +00002043 Expr *InputExpr = Input.getSourceExpression();
2044 if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
2045
2046 Sema::OwningExprResult E
2047 = getDerived().TransformExpr(InputExpr);
2048 if (E.isInvalid()) return true;
2049
2050 Expr *ETaken = E.takeAs<Expr>();
John McCall828bff22009-10-29 18:45:58 +00002051 ETaken->Retain();
John McCall833ca992009-10-29 08:12:44 +00002052 Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
2053 return false;
Douglas Gregor670444e2009-08-04 22:27:00 +00002054 }
Mike Stump1eb44332009-09-09 15:08:12 +00002055
Douglas Gregor670444e2009-08-04 22:27:00 +00002056 case TemplateArgument::Pack: {
2057 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
2058 TransformedArgs.reserve(Arg.pack_size());
Mike Stump1eb44332009-09-09 15:08:12 +00002059 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
Douglas Gregor670444e2009-08-04 22:27:00 +00002060 AEnd = Arg.pack_end();
2061 A != AEnd; ++A) {
Mike Stump1eb44332009-09-09 15:08:12 +00002062
John McCall833ca992009-10-29 08:12:44 +00002063 // FIXME: preserve source information here when we start
2064 // caring about parameter packs.
2065
John McCall828bff22009-10-29 18:45:58 +00002066 TemplateArgumentLoc InputArg;
2067 TemplateArgumentLoc OutputArg;
2068 getDerived().InventTemplateArgumentLoc(*A, InputArg);
2069 if (getDerived().TransformTemplateArgument(InputArg, OutputArg))
John McCall833ca992009-10-29 08:12:44 +00002070 return true;
2071
John McCall828bff22009-10-29 18:45:58 +00002072 TransformedArgs.push_back(OutputArg.getArgument());
Douglas Gregor670444e2009-08-04 22:27:00 +00002073 }
2074 TemplateArgument Result;
Mike Stump1eb44332009-09-09 15:08:12 +00002075 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
Douglas Gregor670444e2009-08-04 22:27:00 +00002076 true);
John McCall828bff22009-10-29 18:45:58 +00002077 Output = TemplateArgumentLoc(Result, Input.getLocInfo());
John McCall833ca992009-10-29 08:12:44 +00002078 return false;
Douglas Gregor670444e2009-08-04 22:27:00 +00002079 }
2080 }
Mike Stump1eb44332009-09-09 15:08:12 +00002081
Douglas Gregor670444e2009-08-04 22:27:00 +00002082 // Work around bogus GCC warning
John McCall833ca992009-10-29 08:12:44 +00002083 return true;
Douglas Gregor670444e2009-08-04 22:27:00 +00002084}
2085
Douglas Gregor577f75a2009-08-04 16:50:30 +00002086//===----------------------------------------------------------------------===//
2087// Type transformation
2088//===----------------------------------------------------------------------===//
2089
2090template<typename Derived>
2091QualType TreeTransform<Derived>::TransformType(QualType T) {
2092 if (getDerived().AlreadyTransformed(T))
2093 return T;
Mike Stump1eb44332009-09-09 15:08:12 +00002094
John McCalla2becad2009-10-21 00:40:46 +00002095 // Temporary workaround. All of these transformations should
2096 // eventually turn into transformations on TypeLocs.
2097 DeclaratorInfo *DI = getSema().Context.CreateDeclaratorInfo(T);
John McCall4802a312009-10-21 00:44:26 +00002098 DI->getTypeLoc().initialize(getDerived().getBaseLocation());
John McCalla2becad2009-10-21 00:40:46 +00002099
2100 DeclaratorInfo *NewDI = getDerived().TransformType(DI);
John McCall0953e762009-09-24 19:53:00 +00002101
John McCalla2becad2009-10-21 00:40:46 +00002102 if (!NewDI)
2103 return QualType();
2104
2105 return NewDI->getType();
2106}
2107
2108template<typename Derived>
2109DeclaratorInfo *TreeTransform<Derived>::TransformType(DeclaratorInfo *DI) {
2110 if (getDerived().AlreadyTransformed(DI->getType()))
2111 return DI;
2112
2113 TypeLocBuilder TLB;
2114
2115 TypeLoc TL = DI->getTypeLoc();
2116 TLB.reserve(TL.getFullDataSize());
2117
2118 QualType Result = getDerived().TransformType(TLB, TL);
2119 if (Result.isNull())
2120 return 0;
2121
2122 return TLB.getDeclaratorInfo(SemaRef.Context, Result);
2123}
2124
2125template<typename Derived>
2126QualType
2127TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
2128 switch (T.getTypeLocClass()) {
2129#define ABSTRACT_TYPELOC(CLASS, PARENT)
2130#define TYPELOC(CLASS, PARENT) \
2131 case TypeLoc::CLASS: \
2132 return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T));
2133#include "clang/AST/TypeLocNodes.def"
Douglas Gregor577f75a2009-08-04 16:50:30 +00002134 }
Mike Stump1eb44332009-09-09 15:08:12 +00002135
John McCalla2becad2009-10-21 00:40:46 +00002136 llvm::llvm_unreachable("unhandled type loc!");
2137 return QualType();
2138}
2139
2140/// FIXME: By default, this routine adds type qualifiers only to types
2141/// that can have qualifiers, and silently suppresses those qualifiers
2142/// that are not permitted (e.g., qualifiers on reference or function
2143/// types). This is the right thing for template instantiation, but
2144/// probably not for other clients.
2145template<typename Derived>
2146QualType
2147TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
2148 QualifiedTypeLoc T) {
Douglas Gregora4923eb2009-11-16 21:35:15 +00002149 Qualifiers Quals = T.getType().getLocalQualifiers();
John McCalla2becad2009-10-21 00:40:46 +00002150
2151 QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
2152 if (Result.isNull())
2153 return QualType();
2154
2155 // Silently suppress qualifiers if the result type can't be qualified.
2156 // FIXME: this is the right thing for template instantiation, but
2157 // probably not for other clients.
2158 if (Result->isFunctionType() || Result->isReferenceType())
Douglas Gregor577f75a2009-08-04 16:50:30 +00002159 return Result;
Mike Stump1eb44332009-09-09 15:08:12 +00002160
John McCalla2becad2009-10-21 00:40:46 +00002161 Result = SemaRef.Context.getQualifiedType(Result, Quals);
2162
2163 TLB.push<QualifiedTypeLoc>(Result);
2164
2165 // No location information to preserve.
2166
2167 return Result;
2168}
2169
2170template <class TyLoc> static inline
2171QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
2172 TyLoc NewT = TLB.push<TyLoc>(T.getType());
2173 NewT.setNameLoc(T.getNameLoc());
2174 return T.getType();
2175}
2176
2177// Ugly metaprogramming macros because I couldn't be bothered to make
2178// the equivalent template version work.
2179#define TransformPointerLikeType(TypeClass) do { \
2180 QualType PointeeType \
2181 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2182 if (PointeeType.isNull()) \
2183 return QualType(); \
2184 \
2185 QualType Result = TL.getType(); \
2186 if (getDerived().AlwaysRebuild() || \
2187 PointeeType != TL.getPointeeLoc().getType()) { \
John McCall85737a72009-10-30 00:06:24 +00002188 Result = getDerived().Rebuild##TypeClass(PointeeType, \
2189 TL.getSigilLoc()); \
John McCalla2becad2009-10-21 00:40:46 +00002190 if (Result.isNull()) \
2191 return QualType(); \
2192 } \
2193 \
2194 TypeClass##Loc NewT = TLB.push<TypeClass##Loc>(Result); \
2195 NewT.setSigilLoc(TL.getSigilLoc()); \
2196 \
2197 return Result; \
2198} while(0)
2199
John McCalla2becad2009-10-21 00:40:46 +00002200template<typename Derived>
2201QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
2202 BuiltinTypeLoc T) {
2203 return TransformTypeSpecType(TLB, T);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002204}
Mike Stump1eb44332009-09-09 15:08:12 +00002205
Douglas Gregor577f75a2009-08-04 16:50:30 +00002206template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002207QualType
John McCalla2becad2009-10-21 00:40:46 +00002208TreeTransform<Derived>::TransformFixedWidthIntType(TypeLocBuilder &TLB,
2209 FixedWidthIntTypeLoc T) {
2210 return TransformTypeSpecType(TLB, T);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002211}
Argyrios Kyrtzidis1bb8a452009-08-19 01:28:17 +00002212
Douglas Gregor577f75a2009-08-04 16:50:30 +00002213template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002214QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
2215 ComplexTypeLoc T) {
2216 // FIXME: recurse?
2217 return TransformTypeSpecType(TLB, T);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002218}
Mike Stump1eb44332009-09-09 15:08:12 +00002219
Douglas Gregor577f75a2009-08-04 16:50:30 +00002220template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002221QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
2222 PointerTypeLoc TL) {
2223 TransformPointerLikeType(PointerType);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002224}
Mike Stump1eb44332009-09-09 15:08:12 +00002225
2226template<typename Derived>
2227QualType
John McCalla2becad2009-10-21 00:40:46 +00002228TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
2229 BlockPointerTypeLoc TL) {
2230 TransformPointerLikeType(BlockPointerType);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002231}
2232
John McCall85737a72009-10-30 00:06:24 +00002233/// Transforms a reference type. Note that somewhat paradoxically we
2234/// don't care whether the type itself is an l-value type or an r-value
2235/// type; we only care if the type was *written* as an l-value type
2236/// or an r-value type.
2237template<typename Derived>
2238QualType
2239TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
2240 ReferenceTypeLoc TL) {
2241 const ReferenceType *T = TL.getTypePtr();
2242
2243 // Note that this works with the pointee-as-written.
2244 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
2245 if (PointeeType.isNull())
2246 return QualType();
2247
2248 QualType Result = TL.getType();
2249 if (getDerived().AlwaysRebuild() ||
2250 PointeeType != T->getPointeeTypeAsWritten()) {
2251 Result = getDerived().RebuildReferenceType(PointeeType,
2252 T->isSpelledAsLValue(),
2253 TL.getSigilLoc());
2254 if (Result.isNull())
2255 return QualType();
2256 }
2257
2258 // r-value references can be rebuilt as l-value references.
2259 ReferenceTypeLoc NewTL;
2260 if (isa<LValueReferenceType>(Result))
2261 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
2262 else
2263 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
2264 NewTL.setSigilLoc(TL.getSigilLoc());
2265
2266 return Result;
2267}
2268
Mike Stump1eb44332009-09-09 15:08:12 +00002269template<typename Derived>
2270QualType
John McCalla2becad2009-10-21 00:40:46 +00002271TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
2272 LValueReferenceTypeLoc TL) {
John McCall85737a72009-10-30 00:06:24 +00002273 return TransformReferenceType(TLB, TL);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002274}
2275
Mike Stump1eb44332009-09-09 15:08:12 +00002276template<typename Derived>
2277QualType
John McCalla2becad2009-10-21 00:40:46 +00002278TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
2279 RValueReferenceTypeLoc TL) {
John McCall85737a72009-10-30 00:06:24 +00002280 return TransformReferenceType(TLB, TL);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002281}
Mike Stump1eb44332009-09-09 15:08:12 +00002282
Douglas Gregor577f75a2009-08-04 16:50:30 +00002283template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00002284QualType
John McCalla2becad2009-10-21 00:40:46 +00002285TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
2286 MemberPointerTypeLoc TL) {
2287 MemberPointerType *T = TL.getTypePtr();
2288
2289 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002290 if (PointeeType.isNull())
2291 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002292
John McCalla2becad2009-10-21 00:40:46 +00002293 // TODO: preserve source information for this.
2294 QualType ClassType
2295 = getDerived().TransformType(QualType(T->getClass(), 0));
Douglas Gregor577f75a2009-08-04 16:50:30 +00002296 if (ClassType.isNull())
2297 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002298
John McCalla2becad2009-10-21 00:40:46 +00002299 QualType Result = TL.getType();
2300 if (getDerived().AlwaysRebuild() ||
2301 PointeeType != T->getPointeeType() ||
2302 ClassType != QualType(T->getClass(), 0)) {
John McCall85737a72009-10-30 00:06:24 +00002303 Result = getDerived().RebuildMemberPointerType(PointeeType, ClassType,
2304 TL.getStarLoc());
John McCalla2becad2009-10-21 00:40:46 +00002305 if (Result.isNull())
2306 return QualType();
2307 }
Douglas Gregor577f75a2009-08-04 16:50:30 +00002308
John McCalla2becad2009-10-21 00:40:46 +00002309 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
2310 NewTL.setSigilLoc(TL.getSigilLoc());
2311
2312 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002313}
2314
Mike Stump1eb44332009-09-09 15:08:12 +00002315template<typename Derived>
2316QualType
John McCalla2becad2009-10-21 00:40:46 +00002317TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
2318 ConstantArrayTypeLoc TL) {
2319 ConstantArrayType *T = TL.getTypePtr();
2320 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002321 if (ElementType.isNull())
2322 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002323
John McCalla2becad2009-10-21 00:40:46 +00002324 QualType Result = TL.getType();
2325 if (getDerived().AlwaysRebuild() ||
2326 ElementType != T->getElementType()) {
2327 Result = getDerived().RebuildConstantArrayType(ElementType,
2328 T->getSizeModifier(),
2329 T->getSize(),
John McCall85737a72009-10-30 00:06:24 +00002330 T->getIndexTypeCVRQualifiers(),
2331 TL.getBracketsRange());
John McCalla2becad2009-10-21 00:40:46 +00002332 if (Result.isNull())
2333 return QualType();
2334 }
2335
2336 ConstantArrayTypeLoc NewTL = TLB.push<ConstantArrayTypeLoc>(Result);
2337 NewTL.setLBracketLoc(TL.getLBracketLoc());
2338 NewTL.setRBracketLoc(TL.getRBracketLoc());
Mike Stump1eb44332009-09-09 15:08:12 +00002339
John McCalla2becad2009-10-21 00:40:46 +00002340 Expr *Size = TL.getSizeExpr();
2341 if (Size) {
2342 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2343 Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
2344 }
2345 NewTL.setSizeExpr(Size);
2346
2347 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002348}
Mike Stump1eb44332009-09-09 15:08:12 +00002349
Douglas Gregor577f75a2009-08-04 16:50:30 +00002350template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002351QualType TreeTransform<Derived>::TransformIncompleteArrayType(
John McCalla2becad2009-10-21 00:40:46 +00002352 TypeLocBuilder &TLB,
2353 IncompleteArrayTypeLoc TL) {
2354 IncompleteArrayType *T = TL.getTypePtr();
2355 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002356 if (ElementType.isNull())
2357 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002358
John McCalla2becad2009-10-21 00:40:46 +00002359 QualType Result = TL.getType();
2360 if (getDerived().AlwaysRebuild() ||
2361 ElementType != T->getElementType()) {
2362 Result = getDerived().RebuildIncompleteArrayType(ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00002363 T->getSizeModifier(),
John McCall85737a72009-10-30 00:06:24 +00002364 T->getIndexTypeCVRQualifiers(),
2365 TL.getBracketsRange());
John McCalla2becad2009-10-21 00:40:46 +00002366 if (Result.isNull())
2367 return QualType();
2368 }
2369
2370 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
2371 NewTL.setLBracketLoc(TL.getLBracketLoc());
2372 NewTL.setRBracketLoc(TL.getRBracketLoc());
2373 NewTL.setSizeExpr(0);
2374
2375 return Result;
2376}
2377
2378template<typename Derived>
2379QualType
2380TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
2381 VariableArrayTypeLoc TL) {
2382 VariableArrayType *T = TL.getTypePtr();
2383 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2384 if (ElementType.isNull())
2385 return QualType();
2386
2387 // Array bounds are not potentially evaluated contexts
2388 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2389
2390 Sema::OwningExprResult SizeResult
2391 = getDerived().TransformExpr(T->getSizeExpr());
2392 if (SizeResult.isInvalid())
2393 return QualType();
2394
2395 Expr *Size = static_cast<Expr*>(SizeResult.get());
2396
2397 QualType Result = TL.getType();
2398 if (getDerived().AlwaysRebuild() ||
2399 ElementType != T->getElementType() ||
2400 Size != T->getSizeExpr()) {
2401 Result = getDerived().RebuildVariableArrayType(ElementType,
2402 T->getSizeModifier(),
2403 move(SizeResult),
2404 T->getIndexTypeCVRQualifiers(),
John McCall85737a72009-10-30 00:06:24 +00002405 TL.getBracketsRange());
John McCalla2becad2009-10-21 00:40:46 +00002406 if (Result.isNull())
2407 return QualType();
2408 }
2409 else SizeResult.take();
2410
2411 VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
2412 NewTL.setLBracketLoc(TL.getLBracketLoc());
2413 NewTL.setRBracketLoc(TL.getRBracketLoc());
2414 NewTL.setSizeExpr(Size);
2415
2416 return Result;
2417}
2418
2419template<typename Derived>
2420QualType
2421TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
2422 DependentSizedArrayTypeLoc TL) {
2423 DependentSizedArrayType *T = TL.getTypePtr();
2424 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2425 if (ElementType.isNull())
2426 return QualType();
2427
2428 // Array bounds are not potentially evaluated contexts
2429 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2430
2431 Sema::OwningExprResult SizeResult
2432 = getDerived().TransformExpr(T->getSizeExpr());
2433 if (SizeResult.isInvalid())
2434 return QualType();
2435
2436 Expr *Size = static_cast<Expr*>(SizeResult.get());
2437
2438 QualType Result = TL.getType();
2439 if (getDerived().AlwaysRebuild() ||
2440 ElementType != T->getElementType() ||
2441 Size != T->getSizeExpr()) {
2442 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
2443 T->getSizeModifier(),
2444 move(SizeResult),
2445 T->getIndexTypeCVRQualifiers(),
John McCall85737a72009-10-30 00:06:24 +00002446 TL.getBracketsRange());
John McCalla2becad2009-10-21 00:40:46 +00002447 if (Result.isNull())
2448 return QualType();
2449 }
2450 else SizeResult.take();
2451
2452 // We might have any sort of array type now, but fortunately they
2453 // all have the same location layout.
2454 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
2455 NewTL.setLBracketLoc(TL.getLBracketLoc());
2456 NewTL.setRBracketLoc(TL.getRBracketLoc());
2457 NewTL.setSizeExpr(Size);
2458
2459 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002460}
Mike Stump1eb44332009-09-09 15:08:12 +00002461
2462template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002463QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
John McCalla2becad2009-10-21 00:40:46 +00002464 TypeLocBuilder &TLB,
2465 DependentSizedExtVectorTypeLoc TL) {
2466 DependentSizedExtVectorType *T = TL.getTypePtr();
2467
2468 // FIXME: ext vector locs should be nested
Douglas Gregor577f75a2009-08-04 16:50:30 +00002469 QualType ElementType = getDerived().TransformType(T->getElementType());
2470 if (ElementType.isNull())
2471 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002472
Douglas Gregor670444e2009-08-04 22:27:00 +00002473 // Vector sizes are not potentially evaluated contexts
2474 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2475
Douglas Gregor577f75a2009-08-04 16:50:30 +00002476 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2477 if (Size.isInvalid())
2478 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002479
John McCalla2becad2009-10-21 00:40:46 +00002480 QualType Result = TL.getType();
2481 if (getDerived().AlwaysRebuild() ||
John McCalleee91c32009-10-23 17:55:45 +00002482 ElementType != T->getElementType() ||
2483 Size.get() != T->getSizeExpr()) {
John McCalla2becad2009-10-21 00:40:46 +00002484 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00002485 move(Size),
2486 T->getAttributeLoc());
John McCalla2becad2009-10-21 00:40:46 +00002487 if (Result.isNull())
2488 return QualType();
2489 }
2490 else Size.take();
2491
2492 // Result might be dependent or not.
2493 if (isa<DependentSizedExtVectorType>(Result)) {
2494 DependentSizedExtVectorTypeLoc NewTL
2495 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
2496 NewTL.setNameLoc(TL.getNameLoc());
2497 } else {
2498 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2499 NewTL.setNameLoc(TL.getNameLoc());
2500 }
2501
2502 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002503}
Mike Stump1eb44332009-09-09 15:08:12 +00002504
2505template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002506QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
2507 VectorTypeLoc TL) {
2508 VectorType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002509 QualType ElementType = getDerived().TransformType(T->getElementType());
2510 if (ElementType.isNull())
2511 return QualType();
2512
John McCalla2becad2009-10-21 00:40:46 +00002513 QualType Result = TL.getType();
2514 if (getDerived().AlwaysRebuild() ||
2515 ElementType != T->getElementType()) {
2516 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements());
2517 if (Result.isNull())
2518 return QualType();
2519 }
2520
2521 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
2522 NewTL.setNameLoc(TL.getNameLoc());
Mike Stump1eb44332009-09-09 15:08:12 +00002523
John McCalla2becad2009-10-21 00:40:46 +00002524 return Result;
2525}
2526
2527template<typename Derived>
2528QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
2529 ExtVectorTypeLoc TL) {
2530 VectorType *T = TL.getTypePtr();
2531 QualType ElementType = getDerived().TransformType(T->getElementType());
2532 if (ElementType.isNull())
2533 return QualType();
2534
2535 QualType Result = TL.getType();
2536 if (getDerived().AlwaysRebuild() ||
2537 ElementType != T->getElementType()) {
2538 Result = getDerived().RebuildExtVectorType(ElementType,
2539 T->getNumElements(),
2540 /*FIXME*/ SourceLocation());
2541 if (Result.isNull())
2542 return QualType();
2543 }
2544
2545 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2546 NewTL.setNameLoc(TL.getNameLoc());
2547
2548 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002549}
Mike Stump1eb44332009-09-09 15:08:12 +00002550
2551template<typename Derived>
2552QualType
John McCalla2becad2009-10-21 00:40:46 +00002553TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
2554 FunctionProtoTypeLoc TL) {
2555 FunctionProtoType *T = TL.getTypePtr();
2556 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002557 if (ResultType.isNull())
2558 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002559
John McCalla2becad2009-10-21 00:40:46 +00002560 // Transform the parameters.
Douglas Gregor577f75a2009-08-04 16:50:30 +00002561 llvm::SmallVector<QualType, 4> ParamTypes;
John McCalla2becad2009-10-21 00:40:46 +00002562 llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
2563 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2564 ParmVarDecl *OldParm = TL.getArg(i);
Mike Stump1eb44332009-09-09 15:08:12 +00002565
John McCalla2becad2009-10-21 00:40:46 +00002566 QualType NewType;
2567 ParmVarDecl *NewParm;
2568
2569 if (OldParm) {
2570 DeclaratorInfo *OldDI = OldParm->getDeclaratorInfo();
2571 assert(OldDI->getType() == T->getArgType(i));
2572
2573 DeclaratorInfo *NewDI = getDerived().TransformType(OldDI);
2574 if (!NewDI)
2575 return QualType();
2576
2577 if (NewDI == OldDI)
2578 NewParm = OldParm;
2579 else
2580 NewParm = ParmVarDecl::Create(SemaRef.Context,
2581 OldParm->getDeclContext(),
2582 OldParm->getLocation(),
2583 OldParm->getIdentifier(),
2584 NewDI->getType(),
2585 NewDI,
2586 OldParm->getStorageClass(),
2587 /* DefArg */ NULL);
2588 NewType = NewParm->getType();
2589
2590 // Deal with the possibility that we don't have a parameter
2591 // declaration for this parameter.
2592 } else {
2593 NewParm = 0;
2594
2595 QualType OldType = T->getArgType(i);
2596 NewType = getDerived().TransformType(OldType);
2597 if (NewType.isNull())
2598 return QualType();
2599 }
2600
2601 ParamTypes.push_back(NewType);
2602 ParamDecls.push_back(NewParm);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002603 }
Mike Stump1eb44332009-09-09 15:08:12 +00002604
John McCalla2becad2009-10-21 00:40:46 +00002605 QualType Result = TL.getType();
2606 if (getDerived().AlwaysRebuild() ||
2607 ResultType != T->getResultType() ||
2608 !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
2609 Result = getDerived().RebuildFunctionProtoType(ResultType,
2610 ParamTypes.data(),
2611 ParamTypes.size(),
2612 T->isVariadic(),
2613 T->getTypeQuals());
2614 if (Result.isNull())
2615 return QualType();
2616 }
Mike Stump1eb44332009-09-09 15:08:12 +00002617
John McCalla2becad2009-10-21 00:40:46 +00002618 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
2619 NewTL.setLParenLoc(TL.getLParenLoc());
2620 NewTL.setRParenLoc(TL.getRParenLoc());
2621 for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
2622 NewTL.setArg(i, ParamDecls[i]);
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>
2628QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
John McCalla2becad2009-10-21 00:40:46 +00002629 TypeLocBuilder &TLB,
2630 FunctionNoProtoTypeLoc TL) {
2631 FunctionNoProtoType *T = TL.getTypePtr();
2632 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
2633 if (ResultType.isNull())
2634 return QualType();
2635
2636 QualType Result = TL.getType();
2637 if (getDerived().AlwaysRebuild() ||
2638 ResultType != T->getResultType())
2639 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
2640
2641 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
2642 NewTL.setLParenLoc(TL.getLParenLoc());
2643 NewTL.setRParenLoc(TL.getRParenLoc());
2644
2645 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002646}
Mike Stump1eb44332009-09-09 15:08:12 +00002647
Douglas Gregor577f75a2009-08-04 16:50:30 +00002648template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002649QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
2650 TypedefTypeLoc TL) {
2651 TypedefType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002652 TypedefDecl *Typedef
2653 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2654 if (!Typedef)
2655 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002656
John McCalla2becad2009-10-21 00:40:46 +00002657 QualType Result = TL.getType();
2658 if (getDerived().AlwaysRebuild() ||
2659 Typedef != T->getDecl()) {
2660 Result = getDerived().RebuildTypedefType(Typedef);
2661 if (Result.isNull())
2662 return QualType();
2663 }
Mike Stump1eb44332009-09-09 15:08:12 +00002664
John McCalla2becad2009-10-21 00:40:46 +00002665 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
2666 NewTL.setNameLoc(TL.getNameLoc());
2667
2668 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002669}
Mike Stump1eb44332009-09-09 15:08:12 +00002670
Douglas Gregor577f75a2009-08-04 16:50:30 +00002671template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002672QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
2673 TypeOfExprTypeLoc TL) {
2674 TypeOfExprType *T = TL.getTypePtr();
2675
Douglas Gregor670444e2009-08-04 22:27:00 +00002676 // typeof expressions are not potentially evaluated contexts
2677 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00002678
Douglas Gregor577f75a2009-08-04 16:50:30 +00002679 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2680 if (E.isInvalid())
2681 return QualType();
2682
John McCalla2becad2009-10-21 00:40:46 +00002683 QualType Result = TL.getType();
2684 if (getDerived().AlwaysRebuild() ||
2685 E.get() != T->getUnderlyingExpr()) {
2686 Result = getDerived().RebuildTypeOfExprType(move(E));
2687 if (Result.isNull())
2688 return QualType();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002689 }
John McCalla2becad2009-10-21 00:40:46 +00002690 else E.take();
Mike Stump1eb44332009-09-09 15:08:12 +00002691
John McCalla2becad2009-10-21 00:40:46 +00002692 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
2693 NewTL.setNameLoc(TL.getNameLoc());
2694
2695 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002696}
Mike Stump1eb44332009-09-09 15:08:12 +00002697
2698template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002699QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
2700 TypeOfTypeLoc TL) {
2701 TypeOfType *T = TL.getTypePtr();
2702
2703 // FIXME: should be an inner type, or at least have a DeclaratorInfo.
Douglas Gregor577f75a2009-08-04 16:50:30 +00002704 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2705 if (Underlying.isNull())
2706 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002707
John McCalla2becad2009-10-21 00:40:46 +00002708 QualType Result = TL.getType();
2709 if (getDerived().AlwaysRebuild() ||
2710 Underlying != T->getUnderlyingType()) {
2711 Result = getDerived().RebuildTypeOfType(Underlying);
2712 if (Result.isNull())
2713 return QualType();
2714 }
Mike Stump1eb44332009-09-09 15:08:12 +00002715
John McCalla2becad2009-10-21 00:40:46 +00002716 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
2717 NewTL.setNameLoc(TL.getNameLoc());
2718
2719 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002720}
Mike Stump1eb44332009-09-09 15:08:12 +00002721
2722template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002723QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
2724 DecltypeTypeLoc TL) {
2725 DecltypeType *T = TL.getTypePtr();
2726
Douglas Gregor670444e2009-08-04 22:27:00 +00002727 // decltype expressions are not potentially evaluated contexts
2728 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00002729
Douglas Gregor577f75a2009-08-04 16:50:30 +00002730 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2731 if (E.isInvalid())
2732 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002733
John McCalla2becad2009-10-21 00:40:46 +00002734 QualType Result = TL.getType();
2735 if (getDerived().AlwaysRebuild() ||
2736 E.get() != T->getUnderlyingExpr()) {
2737 Result = getDerived().RebuildDecltypeType(move(E));
2738 if (Result.isNull())
2739 return QualType();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002740 }
John McCalla2becad2009-10-21 00:40:46 +00002741 else E.take();
Mike Stump1eb44332009-09-09 15:08:12 +00002742
John McCalla2becad2009-10-21 00:40:46 +00002743 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
2744 NewTL.setNameLoc(TL.getNameLoc());
2745
2746 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002747}
2748
2749template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002750QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
2751 RecordTypeLoc TL) {
2752 RecordType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002753 RecordDecl *Record
John McCalla2becad2009-10-21 00:40:46 +00002754 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregor577f75a2009-08-04 16:50:30 +00002755 if (!Record)
2756 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002757
John McCalla2becad2009-10-21 00:40:46 +00002758 QualType Result = TL.getType();
2759 if (getDerived().AlwaysRebuild() ||
2760 Record != T->getDecl()) {
2761 Result = getDerived().RebuildRecordType(Record);
2762 if (Result.isNull())
2763 return QualType();
2764 }
Mike Stump1eb44332009-09-09 15:08:12 +00002765
John McCalla2becad2009-10-21 00:40:46 +00002766 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
2767 NewTL.setNameLoc(TL.getNameLoc());
2768
2769 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002770}
Mike Stump1eb44332009-09-09 15:08:12 +00002771
2772template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002773QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
2774 EnumTypeLoc TL) {
2775 EnumType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002776 EnumDecl *Enum
John McCalla2becad2009-10-21 00:40:46 +00002777 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregor577f75a2009-08-04 16:50:30 +00002778 if (!Enum)
2779 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002780
John McCalla2becad2009-10-21 00:40:46 +00002781 QualType Result = TL.getType();
2782 if (getDerived().AlwaysRebuild() ||
2783 Enum != T->getDecl()) {
2784 Result = getDerived().RebuildEnumType(Enum);
2785 if (Result.isNull())
2786 return QualType();
2787 }
Mike Stump1eb44332009-09-09 15:08:12 +00002788
John McCalla2becad2009-10-21 00:40:46 +00002789 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
2790 NewTL.setNameLoc(TL.getNameLoc());
2791
2792 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002793}
John McCall7da24312009-09-05 00:15:47 +00002794
2795template <typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002796QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
2797 ElaboratedTypeLoc TL) {
2798 ElaboratedType *T = TL.getTypePtr();
2799
2800 // FIXME: this should be a nested type.
John McCall7da24312009-09-05 00:15:47 +00002801 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2802 if (Underlying.isNull())
2803 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002804
John McCalla2becad2009-10-21 00:40:46 +00002805 QualType Result = TL.getType();
2806 if (getDerived().AlwaysRebuild() ||
2807 Underlying != T->getUnderlyingType()) {
2808 Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
2809 if (Result.isNull())
2810 return QualType();
2811 }
Mike Stump1eb44332009-09-09 15:08:12 +00002812
John McCalla2becad2009-10-21 00:40:46 +00002813 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
2814 NewTL.setNameLoc(TL.getNameLoc());
2815
2816 return Result;
John McCall7da24312009-09-05 00:15:47 +00002817}
Mike Stump1eb44332009-09-09 15:08:12 +00002818
2819
Douglas Gregor577f75a2009-08-04 16:50:30 +00002820template<typename Derived>
2821QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
John McCalla2becad2009-10-21 00:40:46 +00002822 TypeLocBuilder &TLB,
2823 TemplateTypeParmTypeLoc TL) {
2824 return TransformTypeSpecType(TLB, TL);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002825}
2826
Mike Stump1eb44332009-09-09 15:08:12 +00002827template<typename Derived>
John McCall49a832b2009-10-18 09:09:24 +00002828QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
John McCalla2becad2009-10-21 00:40:46 +00002829 TypeLocBuilder &TLB,
2830 SubstTemplateTypeParmTypeLoc TL) {
2831 return TransformTypeSpecType(TLB, TL);
John McCall49a832b2009-10-18 09:09:24 +00002832}
2833
2834template<typename Derived>
Douglas Gregordd62b152009-10-19 22:04:39 +00002835inline QualType
2836TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCalla2becad2009-10-21 00:40:46 +00002837 TypeLocBuilder &TLB,
2838 TemplateSpecializationTypeLoc TL) {
John McCall833ca992009-10-29 08:12:44 +00002839 return TransformTemplateSpecializationType(TLB, TL, QualType());
2840}
John McCalla2becad2009-10-21 00:40:46 +00002841
John McCall833ca992009-10-29 08:12:44 +00002842template<typename Derived>
2843QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
2844 const TemplateSpecializationType *TST,
2845 QualType ObjectType) {
2846 // FIXME: this entire method is a temporary workaround; callers
2847 // should be rewritten to provide real type locs.
John McCalla2becad2009-10-21 00:40:46 +00002848
John McCall833ca992009-10-29 08:12:44 +00002849 // Fake up a TemplateSpecializationTypeLoc.
2850 TypeLocBuilder TLB;
2851 TemplateSpecializationTypeLoc TL
2852 = TLB.push<TemplateSpecializationTypeLoc>(QualType(TST, 0));
2853
John McCall828bff22009-10-29 18:45:58 +00002854 SourceLocation BaseLoc = getDerived().getBaseLocation();
2855
2856 TL.setTemplateNameLoc(BaseLoc);
2857 TL.setLAngleLoc(BaseLoc);
2858 TL.setRAngleLoc(BaseLoc);
John McCall833ca992009-10-29 08:12:44 +00002859 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2860 const TemplateArgument &TA = TST->getArg(i);
2861 TemplateArgumentLoc TAL;
2862 getDerived().InventTemplateArgumentLoc(TA, TAL);
2863 TL.setArgLocInfo(i, TAL.getLocInfo());
2864 }
2865
2866 TypeLocBuilder IgnoredTLB;
2867 return TransformTemplateSpecializationType(IgnoredTLB, TL, ObjectType);
Douglas Gregordd62b152009-10-19 22:04:39 +00002868}
2869
2870template<typename Derived>
Douglas Gregor577f75a2009-08-04 16:50:30 +00002871QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall833ca992009-10-29 08:12:44 +00002872 TypeLocBuilder &TLB,
2873 TemplateSpecializationTypeLoc TL,
2874 QualType ObjectType) {
2875 const TemplateSpecializationType *T = TL.getTypePtr();
2876
Mike Stump1eb44332009-09-09 15:08:12 +00002877 TemplateName Template
Douglas Gregordd62b152009-10-19 22:04:39 +00002878 = getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002879 if (Template.isNull())
2880 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002881
John McCall833ca992009-10-29 08:12:44 +00002882 llvm::SmallVector<TemplateArgumentLoc, 4> NewTemplateArgs(T->getNumArgs());
2883 for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i)
2884 if (getDerived().TransformTemplateArgument(TL.getArgLoc(i),
2885 NewTemplateArgs[i]))
Douglas Gregor577f75a2009-08-04 16:50:30 +00002886 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002887
John McCall833ca992009-10-29 08:12:44 +00002888 // FIXME: maybe don't rebuild if all the template arguments are the same.
2889
2890 QualType Result =
2891 getDerived().RebuildTemplateSpecializationType(Template,
2892 TL.getTemplateNameLoc(),
2893 TL.getLAngleLoc(),
2894 NewTemplateArgs.data(),
2895 NewTemplateArgs.size(),
2896 TL.getRAngleLoc());
2897
2898 if (!Result.isNull()) {
2899 TemplateSpecializationTypeLoc NewTL
2900 = TLB.push<TemplateSpecializationTypeLoc>(Result);
2901 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
2902 NewTL.setLAngleLoc(TL.getLAngleLoc());
2903 NewTL.setRAngleLoc(TL.getRAngleLoc());
2904 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
2905 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
Douglas Gregor577f75a2009-08-04 16:50:30 +00002906 }
Mike Stump1eb44332009-09-09 15:08:12 +00002907
John McCall833ca992009-10-29 08:12:44 +00002908 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002909}
Mike Stump1eb44332009-09-09 15:08:12 +00002910
2911template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002912QualType
2913TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
2914 QualifiedNameTypeLoc TL) {
2915 QualifiedNameType *T = TL.getTypePtr();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002916 NestedNameSpecifier *NNS
2917 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2918 SourceRange());
2919 if (!NNS)
2920 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002921
Douglas Gregor577f75a2009-08-04 16:50:30 +00002922 QualType Named = getDerived().TransformType(T->getNamedType());
2923 if (Named.isNull())
2924 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002925
John McCalla2becad2009-10-21 00:40:46 +00002926 QualType Result = TL.getType();
2927 if (getDerived().AlwaysRebuild() ||
2928 NNS != T->getQualifier() ||
2929 Named != T->getNamedType()) {
2930 Result = getDerived().RebuildQualifiedNameType(NNS, Named);
2931 if (Result.isNull())
2932 return QualType();
2933 }
Douglas Gregor577f75a2009-08-04 16:50:30 +00002934
John McCalla2becad2009-10-21 00:40:46 +00002935 QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
2936 NewTL.setNameLoc(TL.getNameLoc());
2937
2938 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002939}
Mike Stump1eb44332009-09-09 15:08:12 +00002940
2941template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002942QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
2943 TypenameTypeLoc TL) {
2944 TypenameType *T = TL.getTypePtr();
John McCall833ca992009-10-29 08:12:44 +00002945
2946 /* FIXME: preserve source information better than this */
2947 SourceRange SR(TL.getNameLoc());
2948
Douglas Gregor577f75a2009-08-04 16:50:30 +00002949 NestedNameSpecifier *NNS
John McCall833ca992009-10-29 08:12:44 +00002950 = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002951 if (!NNS)
2952 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002953
John McCalla2becad2009-10-21 00:40:46 +00002954 QualType Result;
2955
Douglas Gregor577f75a2009-08-04 16:50:30 +00002956 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
Mike Stump1eb44332009-09-09 15:08:12 +00002957 QualType NewTemplateId
Douglas Gregor577f75a2009-08-04 16:50:30 +00002958 = getDerived().TransformType(QualType(TemplateId, 0));
2959 if (NewTemplateId.isNull())
2960 return QualType();
Mike Stump1eb44332009-09-09 15:08:12 +00002961
Douglas Gregor577f75a2009-08-04 16:50:30 +00002962 if (!getDerived().AlwaysRebuild() &&
2963 NNS == T->getQualifier() &&
2964 NewTemplateId == QualType(TemplateId, 0))
2965 return QualType(T, 0);
Mike Stump1eb44332009-09-09 15:08:12 +00002966
John McCalla2becad2009-10-21 00:40:46 +00002967 Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
2968 } else {
John McCall833ca992009-10-29 08:12:44 +00002969 Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier(), SR);
Douglas Gregor577f75a2009-08-04 16:50:30 +00002970 }
John McCalla2becad2009-10-21 00:40:46 +00002971 if (Result.isNull())
2972 return QualType();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002973
John McCalla2becad2009-10-21 00:40:46 +00002974 TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
2975 NewTL.setNameLoc(TL.getNameLoc());
2976
2977 return Result;
Douglas Gregor577f75a2009-08-04 16:50:30 +00002978}
Mike Stump1eb44332009-09-09 15:08:12 +00002979
Douglas Gregor577f75a2009-08-04 16:50:30 +00002980template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002981QualType
2982TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
2983 ObjCInterfaceTypeLoc TL) {
John McCall54e14c42009-10-22 22:37:11 +00002984 assert(false && "TransformObjCInterfaceType unimplemented");
2985 return QualType();
Douglas Gregor577f75a2009-08-04 16:50:30 +00002986}
Mike Stump1eb44332009-09-09 15:08:12 +00002987
2988template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00002989QualType
2990TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
2991 ObjCObjectPointerTypeLoc TL) {
John McCall54e14c42009-10-22 22:37:11 +00002992 assert(false && "TransformObjCObjectPointerType unimplemented");
2993 return QualType();
Argyrios Kyrtzidis24fab412009-09-29 19:42:55 +00002994}
2995
Douglas Gregor577f75a2009-08-04 16:50:30 +00002996//===----------------------------------------------------------------------===//
Douglas Gregor43959a92009-08-20 07:17:43 +00002997// Statement transformation
2998//===----------------------------------------------------------------------===//
2999template<typename Derived>
3000Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003001TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
3002 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003003}
3004
3005template<typename Derived>
3006Sema::OwningStmtResult
3007TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
3008 return getDerived().TransformCompoundStmt(S, false);
3009}
3010
3011template<typename Derived>
3012Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003013TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
Douglas Gregor43959a92009-08-20 07:17:43 +00003014 bool IsStmtExpr) {
3015 bool SubStmtChanged = false;
3016 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
3017 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
3018 B != BEnd; ++B) {
3019 OwningStmtResult Result = getDerived().TransformStmt(*B);
3020 if (Result.isInvalid())
3021 return getSema().StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003022
Douglas Gregor43959a92009-08-20 07:17:43 +00003023 SubStmtChanged = SubStmtChanged || Result.get() != *B;
3024 Statements.push_back(Result.takeAs<Stmt>());
3025 }
Mike Stump1eb44332009-09-09 15:08:12 +00003026
Douglas Gregor43959a92009-08-20 07:17:43 +00003027 if (!getDerived().AlwaysRebuild() &&
3028 !SubStmtChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00003029 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003030
3031 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
3032 move_arg(Statements),
3033 S->getRBracLoc(),
3034 IsStmtExpr);
3035}
Mike Stump1eb44332009-09-09 15:08:12 +00003036
Douglas Gregor43959a92009-08-20 07:17:43 +00003037template<typename Derived>
3038Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003039TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
Eli Friedman264c1f82009-11-19 03:14:00 +00003040 OwningExprResult LHS(SemaRef), RHS(SemaRef);
3041 {
3042 // The case value expressions are not potentially evaluated.
3043 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00003044
Eli Friedman264c1f82009-11-19 03:14:00 +00003045 // Transform the left-hand case value.
3046 LHS = getDerived().TransformExpr(S->getLHS());
3047 if (LHS.isInvalid())
3048 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003049
Eli Friedman264c1f82009-11-19 03:14:00 +00003050 // Transform the right-hand case value (for the GNU case-range extension).
3051 RHS = getDerived().TransformExpr(S->getRHS());
3052 if (RHS.isInvalid())
3053 return SemaRef.StmtError();
3054 }
Mike Stump1eb44332009-09-09 15:08:12 +00003055
Douglas Gregor43959a92009-08-20 07:17:43 +00003056 // Build the case statement.
3057 // Case statements are always rebuilt so that they will attached to their
3058 // transformed switch statement.
3059 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
3060 move(LHS),
3061 S->getEllipsisLoc(),
3062 move(RHS),
3063 S->getColonLoc());
3064 if (Case.isInvalid())
3065 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003066
Douglas Gregor43959a92009-08-20 07:17:43 +00003067 // Transform the statement following the case
3068 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3069 if (SubStmt.isInvalid())
3070 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003071
Douglas Gregor43959a92009-08-20 07:17:43 +00003072 // Attach the body to the case statement
3073 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
3074}
3075
3076template<typename Derived>
3077Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003078TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003079 // Transform the statement following the default case
3080 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3081 if (SubStmt.isInvalid())
3082 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003083
Douglas Gregor43959a92009-08-20 07:17:43 +00003084 // Default statements are always rebuilt
3085 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
3086 move(SubStmt));
3087}
Mike Stump1eb44332009-09-09 15:08:12 +00003088
Douglas Gregor43959a92009-08-20 07:17:43 +00003089template<typename Derived>
3090Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003091TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003092 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3093 if (SubStmt.isInvalid())
3094 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003095
Douglas Gregor43959a92009-08-20 07:17:43 +00003096 // FIXME: Pass the real colon location in.
3097 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
3098 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
3099 move(SubStmt));
3100}
Mike Stump1eb44332009-09-09 15:08:12 +00003101
Douglas Gregor43959a92009-08-20 07:17:43 +00003102template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003103Sema::OwningStmtResult
3104TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003105 // Transform the condition
3106 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3107 if (Cond.isInvalid())
3108 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003109
Douglas Gregor43959a92009-08-20 07:17:43 +00003110 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump1eb44332009-09-09 15:08:12 +00003111
Douglas Gregor43959a92009-08-20 07:17:43 +00003112 // Transform the "then" branch.
3113 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
3114 if (Then.isInvalid())
3115 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003116
Douglas Gregor43959a92009-08-20 07:17:43 +00003117 // Transform the "else" branch.
3118 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
3119 if (Else.isInvalid())
3120 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003121
Douglas Gregor43959a92009-08-20 07:17:43 +00003122 if (!getDerived().AlwaysRebuild() &&
3123 FullCond->get() == S->getCond() &&
3124 Then.get() == S->getThen() &&
3125 Else.get() == S->getElse())
Mike Stump1eb44332009-09-09 15:08:12 +00003126 return SemaRef.Owned(S->Retain());
3127
Douglas Gregor43959a92009-08-20 07:17:43 +00003128 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
Mike Stump1eb44332009-09-09 15:08:12 +00003129 S->getElseLoc(), move(Else));
Douglas Gregor43959a92009-08-20 07:17:43 +00003130}
3131
3132template<typename Derived>
3133Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003134TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003135 // Transform the condition.
3136 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3137 if (Cond.isInvalid())
3138 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003139
Douglas Gregor43959a92009-08-20 07:17:43 +00003140 // Rebuild the switch statement.
3141 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
3142 if (Switch.isInvalid())
3143 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003144
Douglas Gregor43959a92009-08-20 07:17:43 +00003145 // Transform the body of the switch statement.
3146 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3147 if (Body.isInvalid())
3148 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003149
Douglas Gregor43959a92009-08-20 07:17:43 +00003150 // Complete the switch statement.
3151 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
3152 move(Body));
3153}
Mike Stump1eb44332009-09-09 15:08:12 +00003154
Douglas Gregor43959a92009-08-20 07:17:43 +00003155template<typename Derived>
3156Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003157TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003158 // Transform the condition
3159 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3160 if (Cond.isInvalid())
3161 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003162
Douglas Gregor43959a92009-08-20 07:17:43 +00003163 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump1eb44332009-09-09 15:08:12 +00003164
Douglas Gregor43959a92009-08-20 07:17:43 +00003165 // Transform the body
3166 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3167 if (Body.isInvalid())
3168 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003169
Douglas Gregor43959a92009-08-20 07:17:43 +00003170 if (!getDerived().AlwaysRebuild() &&
3171 FullCond->get() == S->getCond() &&
3172 Body.get() == S->getBody())
Mike Stump1eb44332009-09-09 15:08:12 +00003173 return SemaRef.Owned(S->Retain());
3174
Douglas Gregor43959a92009-08-20 07:17:43 +00003175 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
3176}
Mike Stump1eb44332009-09-09 15:08:12 +00003177
Douglas Gregor43959a92009-08-20 07:17:43 +00003178template<typename Derived>
3179Sema::OwningStmtResult
3180TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
3181 // Transform the condition
3182 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3183 if (Cond.isInvalid())
3184 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003185
Douglas Gregor43959a92009-08-20 07:17:43 +00003186 // Transform the body
3187 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3188 if (Body.isInvalid())
3189 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003190
Douglas Gregor43959a92009-08-20 07:17:43 +00003191 if (!getDerived().AlwaysRebuild() &&
3192 Cond.get() == S->getCond() &&
3193 Body.get() == S->getBody())
Mike Stump1eb44332009-09-09 15:08:12 +00003194 return SemaRef.Owned(S->Retain());
3195
Douglas Gregor43959a92009-08-20 07:17:43 +00003196 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
3197 /*FIXME:*/S->getWhileLoc(), move(Cond),
3198 S->getRParenLoc());
3199}
Mike Stump1eb44332009-09-09 15:08:12 +00003200
Douglas Gregor43959a92009-08-20 07:17:43 +00003201template<typename Derived>
3202Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003203TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003204 // Transform the initialization statement
3205 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
3206 if (Init.isInvalid())
3207 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003208
Douglas Gregor43959a92009-08-20 07:17:43 +00003209 // Transform the condition
3210 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3211 if (Cond.isInvalid())
3212 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003213
Douglas Gregor43959a92009-08-20 07:17:43 +00003214 // Transform the increment
3215 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
3216 if (Inc.isInvalid())
3217 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003218
Douglas Gregor43959a92009-08-20 07:17:43 +00003219 // Transform the body
3220 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3221 if (Body.isInvalid())
3222 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003223
Douglas Gregor43959a92009-08-20 07:17:43 +00003224 if (!getDerived().AlwaysRebuild() &&
3225 Init.get() == S->getInit() &&
3226 Cond.get() == S->getCond() &&
3227 Inc.get() == S->getInc() &&
3228 Body.get() == S->getBody())
Mike Stump1eb44332009-09-09 15:08:12 +00003229 return SemaRef.Owned(S->Retain());
3230
Douglas Gregor43959a92009-08-20 07:17:43 +00003231 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
3232 move(Init), move(Cond), move(Inc),
3233 S->getRParenLoc(), move(Body));
3234}
3235
3236template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003237Sema::OwningStmtResult
3238TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003239 // Goto statements must always be rebuilt, to resolve the label.
Mike Stump1eb44332009-09-09 15:08:12 +00003240 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
Douglas Gregor43959a92009-08-20 07:17:43 +00003241 S->getLabel());
3242}
3243
3244template<typename Derived>
3245Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003246TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003247 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
3248 if (Target.isInvalid())
3249 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003250
Douglas Gregor43959a92009-08-20 07:17:43 +00003251 if (!getDerived().AlwaysRebuild() &&
3252 Target.get() == S->getTarget())
Mike Stump1eb44332009-09-09 15:08:12 +00003253 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003254
3255 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
3256 move(Target));
3257}
3258
3259template<typename Derived>
3260Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003261TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
3262 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003263}
Mike Stump1eb44332009-09-09 15:08:12 +00003264
Douglas Gregor43959a92009-08-20 07:17:43 +00003265template<typename Derived>
3266Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003267TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
3268 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003269}
Mike Stump1eb44332009-09-09 15:08:12 +00003270
Douglas Gregor43959a92009-08-20 07:17:43 +00003271template<typename Derived>
3272Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003273TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003274 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
3275 if (Result.isInvalid())
3276 return SemaRef.StmtError();
3277
Mike Stump1eb44332009-09-09 15:08:12 +00003278 // FIXME: We always rebuild the return statement because there is no way
Douglas Gregor43959a92009-08-20 07:17:43 +00003279 // to tell whether the return type of the function has changed.
3280 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
3281}
Mike Stump1eb44332009-09-09 15:08:12 +00003282
Douglas Gregor43959a92009-08-20 07:17:43 +00003283template<typename Derived>
3284Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003285TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003286 bool DeclChanged = false;
3287 llvm::SmallVector<Decl *, 4> Decls;
3288 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
3289 D != DEnd; ++D) {
3290 Decl *Transformed = getDerived().TransformDefinition(*D);
3291 if (!Transformed)
3292 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003293
Douglas Gregor43959a92009-08-20 07:17:43 +00003294 if (Transformed != *D)
3295 DeclChanged = true;
Mike Stump1eb44332009-09-09 15:08:12 +00003296
Douglas Gregor43959a92009-08-20 07:17:43 +00003297 Decls.push_back(Transformed);
3298 }
Mike Stump1eb44332009-09-09 15:08:12 +00003299
Douglas Gregor43959a92009-08-20 07:17:43 +00003300 if (!getDerived().AlwaysRebuild() && !DeclChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00003301 return SemaRef.Owned(S->Retain());
3302
3303 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
Douglas Gregor43959a92009-08-20 07:17:43 +00003304 S->getStartLoc(), S->getEndLoc());
3305}
Mike Stump1eb44332009-09-09 15:08:12 +00003306
Douglas Gregor43959a92009-08-20 07:17:43 +00003307template<typename Derived>
3308Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003309TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003310 assert(false && "SwitchCase is abstract and cannot be transformed");
Mike Stump1eb44332009-09-09 15:08:12 +00003311 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003312}
3313
3314template<typename Derived>
3315Sema::OwningStmtResult
3316TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
3317 // FIXME: Implement!
3318 assert(false && "Inline assembly cannot be transformed");
Mike Stump1eb44332009-09-09 15:08:12 +00003319 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003320}
3321
3322
3323template<typename Derived>
3324Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003325TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003326 // FIXME: Implement this
3327 assert(false && "Cannot transform an Objective-C @try statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003328 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003329}
Mike Stump1eb44332009-09-09 15:08:12 +00003330
Douglas Gregor43959a92009-08-20 07:17:43 +00003331template<typename Derived>
3332Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003333TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003334 // FIXME: Implement this
3335 assert(false && "Cannot transform an Objective-C @catch statement");
3336 return SemaRef.Owned(S->Retain());
3337}
Mike Stump1eb44332009-09-09 15:08:12 +00003338
Douglas Gregor43959a92009-08-20 07:17:43 +00003339template<typename Derived>
3340Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003341TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003342 // FIXME: Implement this
3343 assert(false && "Cannot transform an Objective-C @finally statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003344 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003345}
Mike Stump1eb44332009-09-09 15:08:12 +00003346
Douglas Gregor43959a92009-08-20 07:17:43 +00003347template<typename Derived>
3348Sema::OwningStmtResult
Mike Stump1eb44332009-09-09 15:08:12 +00003349TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003350 // FIXME: Implement this
3351 assert(false && "Cannot transform an Objective-C @throw statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003352 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003353}
Mike Stump1eb44332009-09-09 15:08:12 +00003354
Douglas Gregor43959a92009-08-20 07:17:43 +00003355template<typename Derived>
3356Sema::OwningStmtResult
3357TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
Mike Stump1eb44332009-09-09 15:08:12 +00003358 ObjCAtSynchronizedStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003359 // FIXME: Implement this
3360 assert(false && "Cannot transform an Objective-C @synchronized statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003361 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003362}
3363
3364template<typename Derived>
3365Sema::OwningStmtResult
3366TreeTransform<Derived>::TransformObjCForCollectionStmt(
Mike Stump1eb44332009-09-09 15:08:12 +00003367 ObjCForCollectionStmt *S) {
Douglas Gregor43959a92009-08-20 07:17:43 +00003368 // FIXME: Implement this
3369 assert(false && "Cannot transform an Objective-C for-each statement");
Mike Stump1eb44332009-09-09 15:08:12 +00003370 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003371}
3372
3373
3374template<typename Derived>
3375Sema::OwningStmtResult
3376TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
3377 // Transform the exception declaration, if any.
3378 VarDecl *Var = 0;
3379 if (S->getExceptionDecl()) {
3380 VarDecl *ExceptionDecl = S->getExceptionDecl();
3381 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
3382 ExceptionDecl->getDeclName());
3383
3384 QualType T = getDerived().TransformType(ExceptionDecl->getType());
3385 if (T.isNull())
3386 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003387
Douglas Gregor43959a92009-08-20 07:17:43 +00003388 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
3389 T,
3390 ExceptionDecl->getDeclaratorInfo(),
3391 ExceptionDecl->getIdentifier(),
3392 ExceptionDecl->getLocation(),
3393 /*FIXME: Inaccurate*/
3394 SourceRange(ExceptionDecl->getLocation()));
3395 if (!Var || Var->isInvalidDecl()) {
3396 if (Var)
3397 Var->Destroy(SemaRef.Context);
3398 return SemaRef.StmtError();
3399 }
3400 }
Mike Stump1eb44332009-09-09 15:08:12 +00003401
Douglas Gregor43959a92009-08-20 07:17:43 +00003402 // Transform the actual exception handler.
3403 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
3404 if (Handler.isInvalid()) {
3405 if (Var)
3406 Var->Destroy(SemaRef.Context);
3407 return SemaRef.StmtError();
3408 }
Mike Stump1eb44332009-09-09 15:08:12 +00003409
Douglas Gregor43959a92009-08-20 07:17:43 +00003410 if (!getDerived().AlwaysRebuild() &&
3411 !Var &&
3412 Handler.get() == S->getHandlerBlock())
Mike Stump1eb44332009-09-09 15:08:12 +00003413 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003414
3415 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
3416 Var,
3417 move(Handler));
3418}
Mike Stump1eb44332009-09-09 15:08:12 +00003419
Douglas Gregor43959a92009-08-20 07:17:43 +00003420template<typename Derived>
3421Sema::OwningStmtResult
3422TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
3423 // Transform the try block itself.
Mike Stump1eb44332009-09-09 15:08:12 +00003424 OwningStmtResult TryBlock
Douglas Gregor43959a92009-08-20 07:17:43 +00003425 = getDerived().TransformCompoundStmt(S->getTryBlock());
3426 if (TryBlock.isInvalid())
3427 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003428
Douglas Gregor43959a92009-08-20 07:17:43 +00003429 // Transform the handlers.
3430 bool HandlerChanged = false;
3431 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
3432 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
Mike Stump1eb44332009-09-09 15:08:12 +00003433 OwningStmtResult Handler
Douglas Gregor43959a92009-08-20 07:17:43 +00003434 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
3435 if (Handler.isInvalid())
3436 return SemaRef.StmtError();
Mike Stump1eb44332009-09-09 15:08:12 +00003437
Douglas Gregor43959a92009-08-20 07:17:43 +00003438 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
3439 Handlers.push_back(Handler.takeAs<Stmt>());
3440 }
Mike Stump1eb44332009-09-09 15:08:12 +00003441
Douglas Gregor43959a92009-08-20 07:17:43 +00003442 if (!getDerived().AlwaysRebuild() &&
3443 TryBlock.get() == S->getTryBlock() &&
3444 !HandlerChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00003445 return SemaRef.Owned(S->Retain());
Douglas Gregor43959a92009-08-20 07:17:43 +00003446
3447 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
Mike Stump1eb44332009-09-09 15:08:12 +00003448 move_arg(Handlers));
Douglas Gregor43959a92009-08-20 07:17:43 +00003449}
Mike Stump1eb44332009-09-09 15:08:12 +00003450
Douglas Gregor43959a92009-08-20 07:17:43 +00003451//===----------------------------------------------------------------------===//
Douglas Gregorb98b1992009-08-11 05:31:07 +00003452// Expression transformation
3453//===----------------------------------------------------------------------===//
Mike Stump1eb44332009-09-09 15:08:12 +00003454template<typename Derived>
3455Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003456TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E,
3457 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003458 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003459}
Mike Stump1eb44332009-09-09 15:08:12 +00003460
3461template<typename Derived>
3462Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003463TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E,
3464 bool isAddressOfOperand) {
Douglas Gregora2813ce2009-10-23 18:54:35 +00003465 NestedNameSpecifier *Qualifier = 0;
3466 if (E->getQualifier()) {
3467 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3468 E->getQualifierRange());
3469 if (!Qualifier)
3470 return SemaRef.ExprError();
3471 }
3472
Mike Stump1eb44332009-09-09 15:08:12 +00003473 NamedDecl *ND
Douglas Gregorb98b1992009-08-11 05:31:07 +00003474 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3475 if (!ND)
3476 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003477
Douglas Gregora2813ce2009-10-23 18:54:35 +00003478 if (!getDerived().AlwaysRebuild() &&
3479 Qualifier == E->getQualifier() &&
3480 ND == E->getDecl() &&
3481 !E->hasExplicitTemplateArgumentList())
Mike Stump1eb44332009-09-09 15:08:12 +00003482 return SemaRef.Owned(E->Retain());
3483
Douglas Gregora2813ce2009-10-23 18:54:35 +00003484 // FIXME: We're losing the explicit template arguments in this transformation.
3485
John McCall833ca992009-10-29 08:12:44 +00003486 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregora2813ce2009-10-23 18:54:35 +00003487 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall833ca992009-10-29 08:12:44 +00003488 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
3489 TransArgs[I]))
Douglas Gregora2813ce2009-10-23 18:54:35 +00003490 return SemaRef.ExprError();
Douglas Gregora2813ce2009-10-23 18:54:35 +00003491 }
3492
3493 // FIXME: Pass the qualifier/qualifier range along.
3494 return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003495 ND, E->getLocation(),
3496 isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003497}
Mike Stump1eb44332009-09-09 15:08:12 +00003498
Douglas Gregorb98b1992009-08-11 05:31:07 +00003499template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003500Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003501TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E,
3502 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003503 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003504}
Mike Stump1eb44332009-09-09 15:08:12 +00003505
Douglas Gregorb98b1992009-08-11 05:31:07 +00003506template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003507Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003508TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E,
3509 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003510 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003511}
Mike Stump1eb44332009-09-09 15:08:12 +00003512
Douglas Gregorb98b1992009-08-11 05:31:07 +00003513template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003514Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003515TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E,
3516 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003517 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003518}
Mike Stump1eb44332009-09-09 15:08:12 +00003519
Douglas Gregorb98b1992009-08-11 05:31:07 +00003520template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003521Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003522TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E,
3523 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003524 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003525}
Mike Stump1eb44332009-09-09 15:08:12 +00003526
Douglas Gregorb98b1992009-08-11 05:31:07 +00003527template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003528Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003529TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E,
3530 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003531 return SemaRef.Owned(E->Retain());
3532}
3533
3534template<typename Derived>
3535Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003536TreeTransform<Derived>::TransformParenExpr(ParenExpr *E,
3537 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003538 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3539 if (SubExpr.isInvalid())
3540 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003541
Douglas Gregorb98b1992009-08-11 05:31:07 +00003542 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003543 return SemaRef.Owned(E->Retain());
3544
3545 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003546 E->getRParen());
3547}
3548
Mike Stump1eb44332009-09-09 15:08:12 +00003549template<typename Derived>
3550Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003551TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E,
3552 bool isAddressOfOperand) {
3553 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr(),
3554 E->getOpcode() == UnaryOperator::AddrOf);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003555 if (SubExpr.isInvalid())
3556 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003557
Douglas Gregorb98b1992009-08-11 05:31:07 +00003558 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003559 return SemaRef.Owned(E->Retain());
3560
Douglas Gregorb98b1992009-08-11 05:31:07 +00003561 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
3562 E->getOpcode(),
3563 move(SubExpr));
3564}
Mike Stump1eb44332009-09-09 15:08:12 +00003565
Douglas Gregorb98b1992009-08-11 05:31:07 +00003566template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003567Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003568TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E,
3569 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003570 if (E->isArgumentType()) {
John McCall5ab75172009-11-04 07:28:41 +00003571 DeclaratorInfo *OldT = E->getArgumentTypeInfo();
Douglas Gregor5557b252009-10-28 00:29:27 +00003572
John McCall5ab75172009-11-04 07:28:41 +00003573 DeclaratorInfo *NewT = getDerived().TransformType(OldT);
3574 if (!NewT)
Douglas Gregorb98b1992009-08-11 05:31:07 +00003575 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003576
John McCall5ab75172009-11-04 07:28:41 +00003577 if (!getDerived().AlwaysRebuild() && OldT == NewT)
Douglas Gregorb98b1992009-08-11 05:31:07 +00003578 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003579
John McCall5ab75172009-11-04 07:28:41 +00003580 return getDerived().RebuildSizeOfAlignOf(NewT, E->getOperatorLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00003581 E->isSizeOf(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003582 E->getSourceRange());
3583 }
Mike Stump1eb44332009-09-09 15:08:12 +00003584
Douglas Gregorb98b1992009-08-11 05:31:07 +00003585 Sema::OwningExprResult SubExpr(SemaRef);
Mike Stump1eb44332009-09-09 15:08:12 +00003586 {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003587 // C++0x [expr.sizeof]p1:
3588 // The operand is either an expression, which is an unevaluated operand
3589 // [...]
3590 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00003591
Douglas Gregorb98b1992009-08-11 05:31:07 +00003592 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
3593 if (SubExpr.isInvalid())
3594 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003595
Douglas Gregorb98b1992009-08-11 05:31:07 +00003596 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
3597 return SemaRef.Owned(E->Retain());
3598 }
Mike Stump1eb44332009-09-09 15:08:12 +00003599
Douglas Gregorb98b1992009-08-11 05:31:07 +00003600 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
3601 E->isSizeOf(),
3602 E->getSourceRange());
3603}
Mike Stump1eb44332009-09-09 15:08:12 +00003604
Douglas Gregorb98b1992009-08-11 05:31:07 +00003605template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003606Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003607TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E,
3608 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003609 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3610 if (LHS.isInvalid())
3611 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003612
Douglas Gregorb98b1992009-08-11 05:31:07 +00003613 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3614 if (RHS.isInvalid())
3615 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003616
3617
Douglas Gregorb98b1992009-08-11 05:31:07 +00003618 if (!getDerived().AlwaysRebuild() &&
3619 LHS.get() == E->getLHS() &&
3620 RHS.get() == E->getRHS())
3621 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003622
Douglas Gregorb98b1992009-08-11 05:31:07 +00003623 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3624 /*FIXME:*/E->getLHS()->getLocStart(),
3625 move(RHS),
3626 E->getRBracketLoc());
3627}
Mike Stump1eb44332009-09-09 15:08:12 +00003628
3629template<typename Derived>
3630Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003631TreeTransform<Derived>::TransformCallExpr(CallExpr *E,
3632 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003633 // Transform the callee.
3634 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3635 if (Callee.isInvalid())
3636 return SemaRef.ExprError();
3637
3638 // Transform arguments.
3639 bool ArgChanged = false;
3640 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3641 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3642 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3643 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3644 if (Arg.isInvalid())
3645 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003646
Douglas Gregorb98b1992009-08-11 05:31:07 +00003647 // FIXME: Wrong source location information for the ','.
3648 FakeCommaLocs.push_back(
3649 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
Mike Stump1eb44332009-09-09 15:08:12 +00003650
3651 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003652 Args.push_back(Arg.takeAs<Expr>());
3653 }
Mike Stump1eb44332009-09-09 15:08:12 +00003654
Douglas Gregorb98b1992009-08-11 05:31:07 +00003655 if (!getDerived().AlwaysRebuild() &&
3656 Callee.get() == E->getCallee() &&
3657 !ArgChanged)
3658 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003659
Douglas Gregorb98b1992009-08-11 05:31:07 +00003660 // FIXME: Wrong source location information for the '('.
Mike Stump1eb44332009-09-09 15:08:12 +00003661 SourceLocation FakeLParenLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003662 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3663 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3664 move_arg(Args),
3665 FakeCommaLocs.data(),
3666 E->getRParenLoc());
3667}
Mike Stump1eb44332009-09-09 15:08:12 +00003668
3669template<typename Derived>
3670Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003671TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E,
3672 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003673 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3674 if (Base.isInvalid())
3675 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003676
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003677 NestedNameSpecifier *Qualifier = 0;
3678 if (E->hasQualifier()) {
Mike Stump1eb44332009-09-09 15:08:12 +00003679 Qualifier
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003680 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3681 E->getQualifierRange());
Douglas Gregorc4bf26f2009-09-01 00:37:14 +00003682 if (Qualifier == 0)
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003683 return SemaRef.ExprError();
3684 }
Mike Stump1eb44332009-09-09 15:08:12 +00003685
3686 NamedDecl *Member
Douglas Gregorb98b1992009-08-11 05:31:07 +00003687 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3688 if (!Member)
3689 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003690
Douglas Gregorb98b1992009-08-11 05:31:07 +00003691 if (!getDerived().AlwaysRebuild() &&
3692 Base.get() == E->getBase() &&
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003693 Qualifier == E->getQualifier() &&
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003694 Member == E->getMemberDecl() &&
3695 !E->hasExplicitTemplateArgumentList())
Mike Stump1eb44332009-09-09 15:08:12 +00003696 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003697
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003698 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs;
3699 if (E->hasExplicitTemplateArgumentList()) {
3700 TransArgs.resize(E->getNumTemplateArgs());
3701 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
3702 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
3703 TransArgs[I]))
3704 return SemaRef.ExprError();
3705 }
3706 }
3707
Douglas Gregorb98b1992009-08-11 05:31:07 +00003708 // FIXME: Bogus source location for the operator
3709 SourceLocation FakeOperatorLoc
3710 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3711
3712 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3713 E->isArrow(),
Douglas Gregor83f6faf2009-08-31 23:41:50 +00003714 Qualifier,
3715 E->getQualifierRange(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003716 E->getMemberLoc(),
Douglas Gregor8a4386b2009-11-04 23:20:05 +00003717 Member,
3718 E->hasExplicitTemplateArgumentList(),
3719 E->getLAngleLoc(),
3720 TransArgs.data(),
3721 TransArgs.size(),
3722 E->getRAngleLoc(),
3723 0);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003724}
Mike Stump1eb44332009-09-09 15:08:12 +00003725
Douglas Gregorb98b1992009-08-11 05:31:07 +00003726template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00003727Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003728TreeTransform<Derived>::TransformCastExpr(CastExpr *E,
3729 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003730 assert(false && "Cannot transform abstract class");
3731 return SemaRef.Owned(E->Retain());
3732}
3733
3734template<typename Derived>
3735Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003736TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E,
3737 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003738 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3739 if (LHS.isInvalid())
3740 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003741
Douglas Gregorb98b1992009-08-11 05:31:07 +00003742 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3743 if (RHS.isInvalid())
3744 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003745
Douglas Gregorb98b1992009-08-11 05:31:07 +00003746 if (!getDerived().AlwaysRebuild() &&
3747 LHS.get() == E->getLHS() &&
3748 RHS.get() == E->getRHS())
Mike Stump1eb44332009-09-09 15:08:12 +00003749 return SemaRef.Owned(E->Retain());
3750
Douglas Gregorb98b1992009-08-11 05:31:07 +00003751 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3752 move(LHS), move(RHS));
3753}
3754
Mike Stump1eb44332009-09-09 15:08:12 +00003755template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00003756Sema::OwningExprResult
3757TreeTransform<Derived>::TransformCompoundAssignOperator(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003758 CompoundAssignOperator *E,
3759 bool isAddressOfOperand) {
3760 return getDerived().TransformBinaryOperator(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00003761}
Mike Stump1eb44332009-09-09 15:08:12 +00003762
Douglas Gregorb98b1992009-08-11 05:31:07 +00003763template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003764Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003765TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E,
3766 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003767 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3768 if (Cond.isInvalid())
3769 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003770
Douglas Gregorb98b1992009-08-11 05:31:07 +00003771 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3772 if (LHS.isInvalid())
3773 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003774
Douglas Gregorb98b1992009-08-11 05:31:07 +00003775 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3776 if (RHS.isInvalid())
3777 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003778
Douglas Gregorb98b1992009-08-11 05:31:07 +00003779 if (!getDerived().AlwaysRebuild() &&
3780 Cond.get() == E->getCond() &&
3781 LHS.get() == E->getLHS() &&
3782 RHS.get() == E->getRHS())
3783 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003784
3785 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor47e1f7c2009-08-26 14:37:04 +00003786 E->getQuestionLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00003787 move(LHS),
Douglas Gregor47e1f7c2009-08-26 14:37:04 +00003788 E->getColonLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003789 move(RHS));
3790}
Mike Stump1eb44332009-09-09 15:08:12 +00003791
3792template<typename Derived>
3793Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003794TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E,
3795 bool isAddressOfOperand) {
Douglas Gregor5557b252009-10-28 00:29:27 +00003796 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3797
3798 // FIXME: Will we ever have type information here? It seems like we won't,
3799 // so do we even need to transform the type?
Douglas Gregorb98b1992009-08-11 05:31:07 +00003800 QualType T = getDerived().TransformType(E->getType());
3801 if (T.isNull())
3802 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003803
Douglas Gregorb98b1992009-08-11 05:31:07 +00003804 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3805 if (SubExpr.isInvalid())
3806 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003807
Douglas Gregorb98b1992009-08-11 05:31:07 +00003808 if (!getDerived().AlwaysRebuild() &&
3809 T == E->getType() &&
3810 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003811 return SemaRef.Owned(E->Retain());
3812
Douglas Gregorb98b1992009-08-11 05:31:07 +00003813 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
Mike Stump1eb44332009-09-09 15:08:12 +00003814 move(SubExpr),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003815 E->isLvalueCast());
3816}
Mike Stump1eb44332009-09-09 15:08:12 +00003817
Douglas Gregorb98b1992009-08-11 05:31:07 +00003818template<typename Derived>
3819Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003820TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E,
3821 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00003822 assert(false && "Cannot transform abstract class");
3823 return SemaRef.Owned(E->Retain());
3824}
3825
3826template<typename Derived>
3827Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003828TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E,
3829 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003830 QualType T;
3831 {
3832 // FIXME: Source location isn't quite accurate.
Mike Stump1eb44332009-09-09 15:08:12 +00003833 SourceLocation TypeStartLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003834 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3835 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003836
Douglas Gregorb98b1992009-08-11 05:31:07 +00003837 T = getDerived().TransformType(E->getTypeAsWritten());
3838 if (T.isNull())
3839 return SemaRef.ExprError();
3840 }
Mike Stump1eb44332009-09-09 15:08:12 +00003841
Douglas Gregorb98b1992009-08-11 05:31:07 +00003842 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3843 if (SubExpr.isInvalid())
3844 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003845
Douglas Gregorb98b1992009-08-11 05:31:07 +00003846 if (!getDerived().AlwaysRebuild() &&
3847 T == E->getTypeAsWritten() &&
3848 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00003849 return SemaRef.Owned(E->Retain());
3850
Douglas Gregorb98b1992009-08-11 05:31:07 +00003851 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3852 E->getRParenLoc(),
3853 move(SubExpr));
3854}
Mike Stump1eb44332009-09-09 15:08:12 +00003855
Douglas Gregorb98b1992009-08-11 05:31:07 +00003856template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003857Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003858TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E,
3859 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003860 QualType T;
3861 {
3862 // FIXME: Source location isn't quite accurate.
Mike Stump1eb44332009-09-09 15:08:12 +00003863 SourceLocation FakeTypeLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003864 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3865 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00003866
Douglas Gregorb98b1992009-08-11 05:31:07 +00003867 T = getDerived().TransformType(E->getType());
3868 if (T.isNull())
3869 return SemaRef.ExprError();
3870 }
Mike Stump1eb44332009-09-09 15:08:12 +00003871
Douglas Gregorb98b1992009-08-11 05:31:07 +00003872 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3873 if (Init.isInvalid())
3874 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003875
Douglas Gregorb98b1992009-08-11 05:31:07 +00003876 if (!getDerived().AlwaysRebuild() &&
3877 T == E->getType() &&
3878 Init.get() == E->getInitializer())
Mike Stump1eb44332009-09-09 15:08:12 +00003879 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003880
3881 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3882 /*FIXME:*/E->getInitializer()->getLocEnd(),
3883 move(Init));
3884}
Mike Stump1eb44332009-09-09 15:08:12 +00003885
Douglas Gregorb98b1992009-08-11 05:31:07 +00003886template<typename Derived>
3887Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003888TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E,
3889 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003890 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3891 if (Base.isInvalid())
3892 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003893
Douglas Gregorb98b1992009-08-11 05:31:07 +00003894 if (!getDerived().AlwaysRebuild() &&
3895 Base.get() == E->getBase())
Mike Stump1eb44332009-09-09 15:08:12 +00003896 return SemaRef.Owned(E->Retain());
3897
Douglas Gregorb98b1992009-08-11 05:31:07 +00003898 // FIXME: Bad source location
Mike Stump1eb44332009-09-09 15:08:12 +00003899 SourceLocation FakeOperatorLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00003900 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3901 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3902 E->getAccessorLoc(),
3903 E->getAccessor());
3904}
Mike Stump1eb44332009-09-09 15:08:12 +00003905
Douglas Gregorb98b1992009-08-11 05:31:07 +00003906template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003907Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003908TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E,
3909 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003910 bool InitChanged = false;
Mike Stump1eb44332009-09-09 15:08:12 +00003911
Douglas Gregorb98b1992009-08-11 05:31:07 +00003912 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3913 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3914 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3915 if (Init.isInvalid())
3916 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003917
Douglas Gregorb98b1992009-08-11 05:31:07 +00003918 InitChanged = InitChanged || Init.get() != E->getInit(I);
3919 Inits.push_back(Init.takeAs<Expr>());
3920 }
Mike Stump1eb44332009-09-09 15:08:12 +00003921
Douglas Gregorb98b1992009-08-11 05:31:07 +00003922 if (!getDerived().AlwaysRebuild() && !InitChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00003923 return SemaRef.Owned(E->Retain());
3924
Douglas Gregorb98b1992009-08-11 05:31:07 +00003925 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
Douglas Gregore48319a2009-11-09 17:16:50 +00003926 E->getRBraceLoc(), E->getType());
Douglas Gregorb98b1992009-08-11 05:31:07 +00003927}
Mike Stump1eb44332009-09-09 15:08:12 +00003928
Douglas Gregorb98b1992009-08-11 05:31:07 +00003929template<typename Derived>
3930Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00003931TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E,
3932 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00003933 Designation Desig;
Mike Stump1eb44332009-09-09 15:08:12 +00003934
Douglas Gregor43959a92009-08-20 07:17:43 +00003935 // transform the initializer value
Douglas Gregorb98b1992009-08-11 05:31:07 +00003936 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3937 if (Init.isInvalid())
3938 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003939
Douglas Gregor43959a92009-08-20 07:17:43 +00003940 // transform the designators.
Douglas Gregorb98b1992009-08-11 05:31:07 +00003941 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3942 bool ExprChanged = false;
3943 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3944 DEnd = E->designators_end();
3945 D != DEnd; ++D) {
3946 if (D->isFieldDesignator()) {
3947 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3948 D->getDotLoc(),
3949 D->getFieldLoc()));
3950 continue;
3951 }
Mike Stump1eb44332009-09-09 15:08:12 +00003952
Douglas Gregorb98b1992009-08-11 05:31:07 +00003953 if (D->isArrayDesignator()) {
3954 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3955 if (Index.isInvalid())
3956 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003957
3958 Desig.AddDesignator(Designator::getArray(Index.get(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003959 D->getLBracketLoc()));
Mike Stump1eb44332009-09-09 15:08:12 +00003960
Douglas Gregorb98b1992009-08-11 05:31:07 +00003961 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3962 ArrayExprs.push_back(Index.release());
3963 continue;
3964 }
Mike Stump1eb44332009-09-09 15:08:12 +00003965
Douglas Gregorb98b1992009-08-11 05:31:07 +00003966 assert(D->isArrayRangeDesignator() && "New kind of designator?");
Mike Stump1eb44332009-09-09 15:08:12 +00003967 OwningExprResult Start
Douglas Gregorb98b1992009-08-11 05:31:07 +00003968 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3969 if (Start.isInvalid())
3970 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003971
Douglas Gregorb98b1992009-08-11 05:31:07 +00003972 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3973 if (End.isInvalid())
3974 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00003975
3976 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00003977 End.get(),
3978 D->getLBracketLoc(),
3979 D->getEllipsisLoc()));
Mike Stump1eb44332009-09-09 15:08:12 +00003980
Douglas Gregorb98b1992009-08-11 05:31:07 +00003981 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3982 End.get() != E->getArrayRangeEnd(*D);
Mike Stump1eb44332009-09-09 15:08:12 +00003983
Douglas Gregorb98b1992009-08-11 05:31:07 +00003984 ArrayExprs.push_back(Start.release());
3985 ArrayExprs.push_back(End.release());
3986 }
Mike Stump1eb44332009-09-09 15:08:12 +00003987
Douglas Gregorb98b1992009-08-11 05:31:07 +00003988 if (!getDerived().AlwaysRebuild() &&
3989 Init.get() == E->getInit() &&
3990 !ExprChanged)
3991 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00003992
Douglas Gregorb98b1992009-08-11 05:31:07 +00003993 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3994 E->getEqualOrColonLoc(),
3995 E->usesGNUSyntax(), move(Init));
3996}
Mike Stump1eb44332009-09-09 15:08:12 +00003997
Douglas Gregorb98b1992009-08-11 05:31:07 +00003998template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00003999Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00004000TreeTransform<Derived>::TransformImplicitValueInitExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004001 ImplicitValueInitExpr *E,
4002 bool isAddressOfOperand) {
Douglas Gregor5557b252009-10-28 00:29:27 +00004003 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
4004
4005 // FIXME: Will we ever have proper type location here? Will we actually
4006 // need to transform the type?
Douglas Gregorb98b1992009-08-11 05:31:07 +00004007 QualType T = getDerived().TransformType(E->getType());
4008 if (T.isNull())
4009 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004010
Douglas Gregorb98b1992009-08-11 05:31:07 +00004011 if (!getDerived().AlwaysRebuild() &&
4012 T == E->getType())
Mike Stump1eb44332009-09-09 15:08:12 +00004013 return SemaRef.Owned(E->Retain());
4014
Douglas Gregorb98b1992009-08-11 05:31:07 +00004015 return getDerived().RebuildImplicitValueInitExpr(T);
4016}
Mike Stump1eb44332009-09-09 15:08:12 +00004017
Douglas Gregorb98b1992009-08-11 05:31:07 +00004018template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004019Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004020TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E,
4021 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004022 // FIXME: Do we want the type as written?
4023 QualType T;
Mike Stump1eb44332009-09-09 15:08:12 +00004024
Douglas Gregorb98b1992009-08-11 05:31:07 +00004025 {
4026 // FIXME: Source location isn't quite accurate.
4027 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
4028 T = getDerived().TransformType(E->getType());
4029 if (T.isNull())
4030 return SemaRef.ExprError();
4031 }
Mike Stump1eb44332009-09-09 15:08:12 +00004032
Douglas Gregorb98b1992009-08-11 05:31:07 +00004033 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4034 if (SubExpr.isInvalid())
4035 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004036
Douglas Gregorb98b1992009-08-11 05:31:07 +00004037 if (!getDerived().AlwaysRebuild() &&
4038 T == E->getType() &&
4039 SubExpr.get() == E->getSubExpr())
4040 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004041
Douglas Gregorb98b1992009-08-11 05:31:07 +00004042 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
4043 T, E->getRParenLoc());
4044}
4045
4046template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004047Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004048TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E,
4049 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004050 bool ArgumentChanged = false;
4051 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
4052 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
4053 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
4054 if (Init.isInvalid())
4055 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004056
Douglas Gregorb98b1992009-08-11 05:31:07 +00004057 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
4058 Inits.push_back(Init.takeAs<Expr>());
4059 }
Mike Stump1eb44332009-09-09 15:08:12 +00004060
Douglas Gregorb98b1992009-08-11 05:31:07 +00004061 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
4062 move_arg(Inits),
4063 E->getRParenLoc());
4064}
Mike Stump1eb44332009-09-09 15:08:12 +00004065
Douglas Gregorb98b1992009-08-11 05:31:07 +00004066/// \brief Transform an address-of-label expression.
4067///
4068/// By default, the transformation of an address-of-label expression always
4069/// rebuilds the expression, so that the label identifier can be resolved to
4070/// the corresponding label statement by semantic analysis.
4071template<typename Derived>
4072Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004073TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E,
4074 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004075 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
4076 E->getLabel());
4077}
Mike Stump1eb44332009-09-09 15:08:12 +00004078
4079template<typename Derived>
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004080Sema::OwningExprResult
4081TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E,
4082 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004083 OwningStmtResult SubStmt
Douglas Gregorb98b1992009-08-11 05:31:07 +00004084 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
4085 if (SubStmt.isInvalid())
4086 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004087
Douglas Gregorb98b1992009-08-11 05:31:07 +00004088 if (!getDerived().AlwaysRebuild() &&
4089 SubStmt.get() == E->getSubStmt())
4090 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004091
4092 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004093 move(SubStmt),
4094 E->getRParenLoc());
4095}
Mike Stump1eb44332009-09-09 15:08:12 +00004096
Douglas Gregorb98b1992009-08-11 05:31:07 +00004097template<typename Derived>
4098Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004099TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E,
4100 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004101 QualType T1, T2;
4102 {
4103 // FIXME: Source location isn't quite accurate.
4104 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004105
Douglas Gregorb98b1992009-08-11 05:31:07 +00004106 T1 = getDerived().TransformType(E->getArgType1());
4107 if (T1.isNull())
4108 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004109
Douglas Gregorb98b1992009-08-11 05:31:07 +00004110 T2 = getDerived().TransformType(E->getArgType2());
4111 if (T2.isNull())
4112 return SemaRef.ExprError();
4113 }
4114
4115 if (!getDerived().AlwaysRebuild() &&
4116 T1 == E->getArgType1() &&
4117 T2 == E->getArgType2())
Mike Stump1eb44332009-09-09 15:08:12 +00004118 return SemaRef.Owned(E->Retain());
4119
Douglas Gregorb98b1992009-08-11 05:31:07 +00004120 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
4121 T1, T2, E->getRParenLoc());
4122}
Mike Stump1eb44332009-09-09 15:08:12 +00004123
Douglas Gregorb98b1992009-08-11 05:31:07 +00004124template<typename Derived>
4125Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004126TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E,
4127 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004128 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
4129 if (Cond.isInvalid())
4130 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004131
Douglas Gregorb98b1992009-08-11 05:31:07 +00004132 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
4133 if (LHS.isInvalid())
4134 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004135
Douglas Gregorb98b1992009-08-11 05:31:07 +00004136 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
4137 if (RHS.isInvalid())
4138 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004139
Douglas Gregorb98b1992009-08-11 05:31:07 +00004140 if (!getDerived().AlwaysRebuild() &&
4141 Cond.get() == E->getCond() &&
4142 LHS.get() == E->getLHS() &&
4143 RHS.get() == E->getRHS())
Mike Stump1eb44332009-09-09 15:08:12 +00004144 return SemaRef.Owned(E->Retain());
4145
Douglas Gregorb98b1992009-08-11 05:31:07 +00004146 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
4147 move(Cond), move(LHS), move(RHS),
4148 E->getRParenLoc());
4149}
Mike Stump1eb44332009-09-09 15:08:12 +00004150
Douglas Gregorb98b1992009-08-11 05:31:07 +00004151template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004152Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004153TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E,
4154 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004155 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004156}
4157
4158template<typename Derived>
4159Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004160TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E,
4161 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004162 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
4163 if (Callee.isInvalid())
4164 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004165
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004166 OwningExprResult First
4167 = getDerived().TransformExpr(E->getArg(0),
4168 E->getNumArgs() == 1 && E->getOperator() == OO_Amp);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004169 if (First.isInvalid())
4170 return SemaRef.ExprError();
4171
4172 OwningExprResult Second(SemaRef);
4173 if (E->getNumArgs() == 2) {
4174 Second = getDerived().TransformExpr(E->getArg(1));
4175 if (Second.isInvalid())
4176 return SemaRef.ExprError();
4177 }
Mike Stump1eb44332009-09-09 15:08:12 +00004178
Douglas Gregorb98b1992009-08-11 05:31:07 +00004179 if (!getDerived().AlwaysRebuild() &&
4180 Callee.get() == E->getCallee() &&
4181 First.get() == E->getArg(0) &&
Mike Stump1eb44332009-09-09 15:08:12 +00004182 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
4183 return SemaRef.Owned(E->Retain());
4184
Douglas Gregorb98b1992009-08-11 05:31:07 +00004185 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
4186 E->getOperatorLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00004187 move(Callee),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004188 move(First),
4189 move(Second));
4190}
Mike Stump1eb44332009-09-09 15:08:12 +00004191
Douglas Gregorb98b1992009-08-11 05:31:07 +00004192template<typename Derived>
4193Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004194TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E,
4195 bool isAddressOfOperand) {
4196 return getDerived().TransformCallExpr(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004197}
Mike Stump1eb44332009-09-09 15:08:12 +00004198
Douglas Gregorb98b1992009-08-11 05:31:07 +00004199template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004200Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004201TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E,
4202 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004203 QualType ExplicitTy;
4204 {
4205 // FIXME: Source location isn't quite accurate.
Mike Stump1eb44332009-09-09 15:08:12 +00004206 SourceLocation TypeStartLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00004207 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4208 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004209
Douglas Gregorb98b1992009-08-11 05:31:07 +00004210 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4211 if (ExplicitTy.isNull())
4212 return SemaRef.ExprError();
4213 }
Mike Stump1eb44332009-09-09 15:08:12 +00004214
Douglas Gregorb98b1992009-08-11 05:31:07 +00004215 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4216 if (SubExpr.isInvalid())
4217 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004218
Douglas Gregorb98b1992009-08-11 05:31:07 +00004219 if (!getDerived().AlwaysRebuild() &&
4220 ExplicitTy == E->getTypeAsWritten() &&
4221 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00004222 return SemaRef.Owned(E->Retain());
4223
Douglas Gregorb98b1992009-08-11 05:31:07 +00004224 // FIXME: Poor source location information here.
Mike Stump1eb44332009-09-09 15:08:12 +00004225 SourceLocation FakeLAngleLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00004226 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4227 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
4228 SourceLocation FakeRParenLoc
4229 = SemaRef.PP.getLocForEndOfToken(
4230 E->getSubExpr()->getSourceRange().getEnd());
4231 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
Mike Stump1eb44332009-09-09 15:08:12 +00004232 E->getStmtClass(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004233 FakeLAngleLoc,
4234 ExplicitTy,
4235 FakeRAngleLoc,
4236 FakeRAngleLoc,
4237 move(SubExpr),
4238 FakeRParenLoc);
4239}
Mike Stump1eb44332009-09-09 15:08:12 +00004240
Douglas Gregorb98b1992009-08-11 05:31:07 +00004241template<typename Derived>
4242Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004243TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E,
4244 bool isAddressOfOperand) {
4245 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004246}
Mike Stump1eb44332009-09-09 15:08:12 +00004247
4248template<typename Derived>
4249Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004250TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E,
4251 bool isAddressOfOperand) {
4252 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Mike Stump1eb44332009-09-09 15:08:12 +00004253}
4254
Douglas Gregorb98b1992009-08-11 05:31:07 +00004255template<typename Derived>
4256Sema::OwningExprResult
4257TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004258 CXXReinterpretCastExpr *E,
4259 bool isAddressOfOperand) {
4260 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004261}
Mike Stump1eb44332009-09-09 15:08:12 +00004262
Douglas Gregorb98b1992009-08-11 05:31:07 +00004263template<typename Derived>
4264Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004265TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E,
4266 bool isAddressOfOperand) {
4267 return getDerived().TransformCXXNamedCastExpr(E, isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004268}
Mike Stump1eb44332009-09-09 15:08:12 +00004269
Douglas Gregorb98b1992009-08-11 05:31:07 +00004270template<typename Derived>
4271Sema::OwningExprResult
4272TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004273 CXXFunctionalCastExpr *E,
4274 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004275 QualType ExplicitTy;
4276 {
4277 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004278
Douglas Gregorb98b1992009-08-11 05:31:07 +00004279 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4280 if (ExplicitTy.isNull())
4281 return SemaRef.ExprError();
4282 }
Mike Stump1eb44332009-09-09 15:08:12 +00004283
Douglas Gregorb98b1992009-08-11 05:31:07 +00004284 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4285 if (SubExpr.isInvalid())
4286 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004287
Douglas Gregorb98b1992009-08-11 05:31:07 +00004288 if (!getDerived().AlwaysRebuild() &&
4289 ExplicitTy == E->getTypeAsWritten() &&
4290 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00004291 return SemaRef.Owned(E->Retain());
4292
Douglas Gregorb98b1992009-08-11 05:31:07 +00004293 // FIXME: The end of the type's source range is wrong
4294 return getDerived().RebuildCXXFunctionalCastExpr(
4295 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
4296 ExplicitTy,
4297 /*FIXME:*/E->getSubExpr()->getLocStart(),
4298 move(SubExpr),
4299 E->getRParenLoc());
4300}
Mike Stump1eb44332009-09-09 15:08:12 +00004301
Douglas Gregorb98b1992009-08-11 05:31:07 +00004302template<typename Derived>
4303Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004304TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E,
4305 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004306 if (E->isTypeOperand()) {
4307 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004308
Douglas Gregorb98b1992009-08-11 05:31:07 +00004309 QualType T = getDerived().TransformType(E->getTypeOperand());
4310 if (T.isNull())
4311 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004312
Douglas Gregorb98b1992009-08-11 05:31:07 +00004313 if (!getDerived().AlwaysRebuild() &&
4314 T == E->getTypeOperand())
4315 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004316
Douglas Gregorb98b1992009-08-11 05:31:07 +00004317 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4318 /*FIXME:*/E->getLocStart(),
4319 T,
4320 E->getLocEnd());
4321 }
Mike Stump1eb44332009-09-09 15:08:12 +00004322
Douglas Gregorb98b1992009-08-11 05:31:07 +00004323 // We don't know whether the expression is potentially evaluated until
4324 // after we perform semantic analysis, so the expression is potentially
4325 // potentially evaluated.
Mike Stump1eb44332009-09-09 15:08:12 +00004326 EnterExpressionEvaluationContext Unevaluated(SemaRef,
Douglas Gregorb98b1992009-08-11 05:31:07 +00004327 Action::PotentiallyPotentiallyEvaluated);
Mike Stump1eb44332009-09-09 15:08:12 +00004328
Douglas Gregorb98b1992009-08-11 05:31:07 +00004329 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
4330 if (SubExpr.isInvalid())
4331 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004332
Douglas Gregorb98b1992009-08-11 05:31:07 +00004333 if (!getDerived().AlwaysRebuild() &&
4334 SubExpr.get() == E->getExprOperand())
Mike Stump1eb44332009-09-09 15:08:12 +00004335 return SemaRef.Owned(E->Retain());
4336
Douglas Gregorb98b1992009-08-11 05:31:07 +00004337 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4338 /*FIXME:*/E->getLocStart(),
4339 move(SubExpr),
4340 E->getLocEnd());
4341}
4342
4343template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00004344Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004345TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E,
4346 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004347 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004348}
Mike Stump1eb44332009-09-09 15:08:12 +00004349
Douglas Gregorb98b1992009-08-11 05:31:07 +00004350template<typename Derived>
4351Sema::OwningExprResult
4352TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004353 CXXNullPtrLiteralExpr *E,
4354 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004355 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004356}
Mike Stump1eb44332009-09-09 15:08:12 +00004357
Douglas Gregorb98b1992009-08-11 05:31:07 +00004358template<typename Derived>
4359Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004360TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E,
4361 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004362 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004363
Douglas Gregorb98b1992009-08-11 05:31:07 +00004364 QualType T = getDerived().TransformType(E->getType());
4365 if (T.isNull())
4366 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004367
Douglas Gregorb98b1992009-08-11 05:31:07 +00004368 if (!getDerived().AlwaysRebuild() &&
4369 T == E->getType())
4370 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004371
Douglas Gregorb98b1992009-08-11 05:31:07 +00004372 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
4373}
Mike Stump1eb44332009-09-09 15:08:12 +00004374
Douglas Gregorb98b1992009-08-11 05:31:07 +00004375template<typename Derived>
4376Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004377TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E,
4378 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004379 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4380 if (SubExpr.isInvalid())
4381 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004382
Douglas Gregorb98b1992009-08-11 05:31:07 +00004383 if (!getDerived().AlwaysRebuild() &&
4384 SubExpr.get() == E->getSubExpr())
Mike Stump1eb44332009-09-09 15:08:12 +00004385 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004386
4387 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
4388}
Mike Stump1eb44332009-09-09 15:08:12 +00004389
Douglas Gregorb98b1992009-08-11 05:31:07 +00004390template<typename Derived>
4391Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004392TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E,
4393 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004394 ParmVarDecl *Param
Douglas Gregorb98b1992009-08-11 05:31:07 +00004395 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
4396 if (!Param)
4397 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004398
Douglas Gregorb98b1992009-08-11 05:31:07 +00004399 if (getDerived().AlwaysRebuild() &&
4400 Param == E->getParam())
4401 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004402
Douglas Gregorb98b1992009-08-11 05:31:07 +00004403 return getDerived().RebuildCXXDefaultArgExpr(Param);
4404}
Mike Stump1eb44332009-09-09 15:08:12 +00004405
Douglas Gregorb98b1992009-08-11 05:31:07 +00004406template<typename Derived>
4407Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004408TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E,
4409 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004410 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4411
4412 QualType T = getDerived().TransformType(E->getType());
4413 if (T.isNull())
4414 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004415
Douglas Gregorb98b1992009-08-11 05:31:07 +00004416 if (!getDerived().AlwaysRebuild() &&
4417 T == E->getType())
Mike Stump1eb44332009-09-09 15:08:12 +00004418 return SemaRef.Owned(E->Retain());
4419
4420 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004421 /*FIXME:*/E->getTypeBeginLoc(),
4422 T,
4423 E->getRParenLoc());
4424}
Mike Stump1eb44332009-09-09 15:08:12 +00004425
Douglas Gregorb98b1992009-08-11 05:31:07 +00004426template<typename Derived>
4427Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004428TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E,
4429 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004430 VarDecl *Var
Douglas Gregor43959a92009-08-20 07:17:43 +00004431 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregorb98b1992009-08-11 05:31:07 +00004432 if (!Var)
4433 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004434
Douglas Gregorb98b1992009-08-11 05:31:07 +00004435 if (!getDerived().AlwaysRebuild() &&
Mike Stump1eb44332009-09-09 15:08:12 +00004436 Var == E->getVarDecl())
Douglas Gregorb98b1992009-08-11 05:31:07 +00004437 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004438
4439 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004440 /*FIXME:*/E->getStartLoc(),
4441 Var);
4442}
Mike Stump1eb44332009-09-09 15:08:12 +00004443
Douglas Gregorb98b1992009-08-11 05:31:07 +00004444template<typename Derived>
4445Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004446TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E,
4447 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004448 // Transform the type that we're allocating
4449 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
4450 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
4451 if (AllocType.isNull())
4452 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004453
Douglas Gregorb98b1992009-08-11 05:31:07 +00004454 // Transform the size of the array we're allocating (if any).
4455 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
4456 if (ArraySize.isInvalid())
4457 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004458
Douglas Gregorb98b1992009-08-11 05:31:07 +00004459 // Transform the placement arguments (if any).
4460 bool ArgumentChanged = false;
4461 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
4462 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
4463 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
4464 if (Arg.isInvalid())
4465 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004466
Douglas Gregorb98b1992009-08-11 05:31:07 +00004467 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
4468 PlacementArgs.push_back(Arg.take());
4469 }
Mike Stump1eb44332009-09-09 15:08:12 +00004470
Douglas Gregor43959a92009-08-20 07:17:43 +00004471 // transform the constructor arguments (if any).
Douglas Gregorb98b1992009-08-11 05:31:07 +00004472 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
4473 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
4474 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
4475 if (Arg.isInvalid())
4476 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004477
Douglas Gregorb98b1992009-08-11 05:31:07 +00004478 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
4479 ConstructorArgs.push_back(Arg.take());
4480 }
Mike Stump1eb44332009-09-09 15:08:12 +00004481
Douglas Gregorb98b1992009-08-11 05:31:07 +00004482 if (!getDerived().AlwaysRebuild() &&
4483 AllocType == E->getAllocatedType() &&
4484 ArraySize.get() == E->getArraySize() &&
4485 !ArgumentChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00004486 return SemaRef.Owned(E->Retain());
4487
Douglas Gregorb98b1992009-08-11 05:31:07 +00004488 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
4489 E->isGlobalNew(),
4490 /*FIXME:*/E->getLocStart(),
4491 move_arg(PlacementArgs),
4492 /*FIXME:*/E->getLocStart(),
4493 E->isParenTypeId(),
4494 AllocType,
4495 /*FIXME:*/E->getLocStart(),
4496 /*FIXME:*/SourceRange(),
4497 move(ArraySize),
4498 /*FIXME:*/E->getLocStart(),
4499 move_arg(ConstructorArgs),
Mike Stump1eb44332009-09-09 15:08:12 +00004500 E->getLocEnd());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004501}
Mike Stump1eb44332009-09-09 15:08:12 +00004502
Douglas Gregorb98b1992009-08-11 05:31:07 +00004503template<typename Derived>
4504Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004505TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E,
4506 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004507 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
4508 if (Operand.isInvalid())
4509 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004510
Douglas Gregorb98b1992009-08-11 05:31:07 +00004511 if (!getDerived().AlwaysRebuild() &&
Mike Stump1eb44332009-09-09 15:08:12 +00004512 Operand.get() == E->getArgument())
4513 return SemaRef.Owned(E->Retain());
4514
Douglas Gregorb98b1992009-08-11 05:31:07 +00004515 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
4516 E->isGlobalDelete(),
4517 E->isArrayForm(),
4518 move(Operand));
4519}
Mike Stump1eb44332009-09-09 15:08:12 +00004520
Douglas Gregorb98b1992009-08-11 05:31:07 +00004521template<typename Derived>
4522Sema::OwningExprResult
Douglas Gregora71d8192009-09-04 17:36:40 +00004523TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004524 CXXPseudoDestructorExpr *E,
4525 bool isAddressOfOperand) {
Douglas Gregora71d8192009-09-04 17:36:40 +00004526 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4527 if (Base.isInvalid())
4528 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004529
Douglas Gregora71d8192009-09-04 17:36:40 +00004530 NestedNameSpecifier *Qualifier
4531 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4532 E->getQualifierRange());
4533 if (E->getQualifier() && !Qualifier)
4534 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004535
Douglas Gregora71d8192009-09-04 17:36:40 +00004536 QualType DestroyedType;
4537 {
4538 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
4539 DestroyedType = getDerived().TransformType(E->getDestroyedType());
4540 if (DestroyedType.isNull())
4541 return SemaRef.ExprError();
4542 }
Mike Stump1eb44332009-09-09 15:08:12 +00004543
Douglas Gregora71d8192009-09-04 17:36:40 +00004544 if (!getDerived().AlwaysRebuild() &&
4545 Base.get() == E->getBase() &&
4546 Qualifier == E->getQualifier() &&
4547 DestroyedType == E->getDestroyedType())
4548 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004549
Douglas Gregora71d8192009-09-04 17:36:40 +00004550 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
4551 E->getOperatorLoc(),
4552 E->isArrow(),
4553 E->getDestroyedTypeLoc(),
4554 DestroyedType,
4555 Qualifier,
4556 E->getQualifierRange());
4557}
Mike Stump1eb44332009-09-09 15:08:12 +00004558
Douglas Gregora71d8192009-09-04 17:36:40 +00004559template<typename Derived>
4560Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00004561TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004562 UnresolvedFunctionNameExpr *E,
4563 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004564 // There is no transformation we can apply to an unresolved function name.
Mike Stump1eb44332009-09-09 15:08:12 +00004565 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004566}
Mike Stump1eb44332009-09-09 15:08:12 +00004567
Douglas Gregorb98b1992009-08-11 05:31:07 +00004568template<typename Derived>
4569Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004570TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E,
4571 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004572 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump1eb44332009-09-09 15:08:12 +00004573
Douglas Gregorb98b1992009-08-11 05:31:07 +00004574 QualType T = getDerived().TransformType(E->getQueriedType());
4575 if (T.isNull())
4576 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004577
Douglas Gregorb98b1992009-08-11 05:31:07 +00004578 if (!getDerived().AlwaysRebuild() &&
4579 T == E->getQueriedType())
4580 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004581
Douglas Gregorb98b1992009-08-11 05:31:07 +00004582 // FIXME: Bad location information
4583 SourceLocation FakeLParenLoc
4584 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
Mike Stump1eb44332009-09-09 15:08:12 +00004585
4586 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004587 E->getLocStart(),
4588 /*FIXME:*/FakeLParenLoc,
4589 T,
4590 E->getLocEnd());
4591}
Mike Stump1eb44332009-09-09 15:08:12 +00004592
Douglas Gregorb98b1992009-08-11 05:31:07 +00004593template<typename Derived>
4594Sema::OwningExprResult
John McCall865d4472009-11-19 22:55:06 +00004595TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
4596 DependentScopeDeclRefExpr *E,
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004597 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004598 NestedNameSpecifier *NNS
Douglas Gregorf17bb742009-10-22 17:20:55 +00004599 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4600 E->getQualifierRange());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004601 if (!NNS)
4602 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004603
4604 DeclarationName Name
Douglas Gregor81499bb2009-09-03 22:13:48 +00004605 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
4606 if (!Name)
4607 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004608
4609 if (!getDerived().AlwaysRebuild() &&
Douglas Gregorb98b1992009-08-11 05:31:07 +00004610 NNS == E->getQualifier() &&
4611 Name == E->getDeclName())
Mike Stump1eb44332009-09-09 15:08:12 +00004612 return SemaRef.Owned(E->Retain());
4613
John McCall865d4472009-11-19 22:55:06 +00004614 return getDerived().RebuildDependentScopeDeclRefExpr(NNS,
Douglas Gregorb98b1992009-08-11 05:31:07 +00004615 E->getQualifierRange(),
4616 Name,
4617 E->getLocation(),
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004618 isAddressOfOperand);
Douglas Gregorb98b1992009-08-11 05:31:07 +00004619}
4620
4621template<typename Derived>
4622Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004623TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E,
4624 bool isAddressOfOperand) {
Douglas Gregorfd2300e2009-10-29 17:56:10 +00004625 TemporaryBase Rebase(*this, E->getTemplateNameLoc(), DeclarationName());
4626
Mike Stump1eb44332009-09-09 15:08:12 +00004627 TemplateName Template
Douglas Gregorb98b1992009-08-11 05:31:07 +00004628 = getDerived().TransformTemplateName(E->getTemplateName());
4629 if (Template.isNull())
4630 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004631
Douglas Gregorf17bb742009-10-22 17:20:55 +00004632 NestedNameSpecifier *Qualifier = 0;
4633 if (E->getQualifier()) {
4634 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4635 E->getQualifierRange());
4636 if (!Qualifier)
4637 return SemaRef.ExprError();
4638 }
4639
John McCall833ca992009-10-29 08:12:44 +00004640 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004641 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall833ca992009-10-29 08:12:44 +00004642 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
4643 TransArgs[I]))
Douglas Gregorb98b1992009-08-11 05:31:07 +00004644 return SemaRef.ExprError();
Douglas Gregorb98b1992009-08-11 05:31:07 +00004645 }
4646
4647 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
4648 // compare template arguments (yet).
Mike Stump1eb44332009-09-09 15:08:12 +00004649
4650 // FIXME: It's possible that we'll find out now that the template name
Douglas Gregorb98b1992009-08-11 05:31:07 +00004651 // actually refers to a type, in which case the caller is actually dealing
4652 // with a functional cast. Give a reasonable error message!
Douglas Gregorf17bb742009-10-22 17:20:55 +00004653 return getDerived().RebuildTemplateIdExpr(Qualifier, E->getQualifierRange(),
4654 Template, E->getTemplateNameLoc(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004655 E->getLAngleLoc(),
4656 TransArgs.data(),
4657 TransArgs.size(),
4658 E->getRAngleLoc());
4659}
4660
4661template<typename Derived>
4662Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004663TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E,
4664 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004665 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4666
4667 QualType T = getDerived().TransformType(E->getType());
4668 if (T.isNull())
4669 return SemaRef.ExprError();
4670
4671 CXXConstructorDecl *Constructor
4672 = cast_or_null<CXXConstructorDecl>(
4673 getDerived().TransformDecl(E->getConstructor()));
4674 if (!Constructor)
4675 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004676
Douglas Gregorb98b1992009-08-11 05:31:07 +00004677 bool ArgumentChanged = false;
4678 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
Mike Stump1eb44332009-09-09 15:08:12 +00004679 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004680 ArgEnd = E->arg_end();
4681 Arg != ArgEnd; ++Arg) {
4682 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4683 if (TransArg.isInvalid())
4684 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004685
Douglas Gregorb98b1992009-08-11 05:31:07 +00004686 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4687 Args.push_back(TransArg.takeAs<Expr>());
4688 }
4689
4690 if (!getDerived().AlwaysRebuild() &&
4691 T == E->getType() &&
4692 Constructor == E->getConstructor() &&
4693 !ArgumentChanged)
4694 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004695
Douglas Gregorb98b1992009-08-11 05:31:07 +00004696 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4697 move_arg(Args));
4698}
Mike Stump1eb44332009-09-09 15:08:12 +00004699
Douglas Gregorb98b1992009-08-11 05:31:07 +00004700/// \brief Transform a C++ temporary-binding expression.
4701///
Mike Stump1eb44332009-09-09 15:08:12 +00004702/// The transformation of a temporary-binding expression always attempts to
4703/// bind a new temporary variable to its subexpression, even if the
Douglas Gregorb98b1992009-08-11 05:31:07 +00004704/// subexpression itself did not change, because the temporary variable itself
4705/// must be unique.
4706template<typename Derived>
4707Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004708TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E,
4709 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004710 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4711 if (SubExpr.isInvalid())
4712 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004713
Douglas Gregorb98b1992009-08-11 05:31:07 +00004714 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4715}
Mike Stump1eb44332009-09-09 15:08:12 +00004716
4717/// \brief Transform a C++ expression that contains temporaries that should
Douglas Gregorb98b1992009-08-11 05:31:07 +00004718/// be destroyed after the expression is evaluated.
4719///
Mike Stump1eb44332009-09-09 15:08:12 +00004720/// The transformation of a full expression always attempts to build a new
4721/// CXXExprWithTemporaries expression, even if the
Douglas Gregorb98b1992009-08-11 05:31:07 +00004722/// subexpression itself did not change, because it will need to capture the
4723/// the new temporary variables introduced in the subexpression.
4724template<typename Derived>
4725Sema::OwningExprResult
4726TreeTransform<Derived>::TransformCXXExprWithTemporaries(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004727 CXXExprWithTemporaries *E,
4728 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004729 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4730 if (SubExpr.isInvalid())
4731 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004732
Douglas Gregorb98b1992009-08-11 05:31:07 +00004733 return SemaRef.Owned(
4734 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4735 E->shouldDestroyTemporaries()));
4736}
Mike Stump1eb44332009-09-09 15:08:12 +00004737
Douglas Gregorb98b1992009-08-11 05:31:07 +00004738template<typename Derived>
4739Sema::OwningExprResult
4740TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004741 CXXTemporaryObjectExpr *E,
4742 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004743 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4744 QualType T = getDerived().TransformType(E->getType());
4745 if (T.isNull())
4746 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004747
Douglas Gregorb98b1992009-08-11 05:31:07 +00004748 CXXConstructorDecl *Constructor
4749 = cast_or_null<CXXConstructorDecl>(
4750 getDerived().TransformDecl(E->getConstructor()));
4751 if (!Constructor)
4752 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004753
Douglas Gregorb98b1992009-08-11 05:31:07 +00004754 bool ArgumentChanged = false;
4755 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4756 Args.reserve(E->getNumArgs());
Mike Stump1eb44332009-09-09 15:08:12 +00004757 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004758 ArgEnd = E->arg_end();
4759 Arg != ArgEnd; ++Arg) {
4760 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4761 if (TransArg.isInvalid())
4762 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004763
Douglas Gregorb98b1992009-08-11 05:31:07 +00004764 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4765 Args.push_back((Expr *)TransArg.release());
4766 }
Mike Stump1eb44332009-09-09 15:08:12 +00004767
Douglas Gregorb98b1992009-08-11 05:31:07 +00004768 if (!getDerived().AlwaysRebuild() &&
4769 T == E->getType() &&
4770 Constructor == E->getConstructor() &&
4771 !ArgumentChanged)
4772 return SemaRef.Owned(E->Retain());
Mike Stump1eb44332009-09-09 15:08:12 +00004773
Douglas Gregorb98b1992009-08-11 05:31:07 +00004774 // FIXME: Bogus location information
4775 SourceLocation CommaLoc;
4776 if (Args.size() > 1) {
4777 Expr *First = (Expr *)Args[0];
Mike Stump1eb44332009-09-09 15:08:12 +00004778 CommaLoc
Douglas Gregorb98b1992009-08-11 05:31:07 +00004779 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4780 }
4781 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4782 T,
4783 /*FIXME:*/E->getTypeBeginLoc(),
4784 move_arg(Args),
4785 &CommaLoc,
4786 E->getLocEnd());
4787}
Mike Stump1eb44332009-09-09 15:08:12 +00004788
Douglas Gregorb98b1992009-08-11 05:31:07 +00004789template<typename Derived>
4790Sema::OwningExprResult
4791TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004792 CXXUnresolvedConstructExpr *E,
4793 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004794 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4795 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4796 if (T.isNull())
4797 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004798
Douglas Gregorb98b1992009-08-11 05:31:07 +00004799 bool ArgumentChanged = false;
4800 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4801 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4802 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4803 ArgEnd = E->arg_end();
4804 Arg != ArgEnd; ++Arg) {
4805 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4806 if (TransArg.isInvalid())
4807 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004808
Douglas Gregorb98b1992009-08-11 05:31:07 +00004809 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4810 FakeCommaLocs.push_back(
4811 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4812 Args.push_back(TransArg.takeAs<Expr>());
4813 }
Mike Stump1eb44332009-09-09 15:08:12 +00004814
Douglas Gregorb98b1992009-08-11 05:31:07 +00004815 if (!getDerived().AlwaysRebuild() &&
4816 T == E->getTypeAsWritten() &&
4817 !ArgumentChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00004818 return SemaRef.Owned(E->Retain());
4819
Douglas Gregorb98b1992009-08-11 05:31:07 +00004820 // FIXME: we're faking the locations of the commas
4821 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4822 T,
4823 E->getLParenLoc(),
4824 move_arg(Args),
4825 FakeCommaLocs.data(),
4826 E->getRParenLoc());
4827}
Mike Stump1eb44332009-09-09 15:08:12 +00004828
Douglas Gregorb98b1992009-08-11 05:31:07 +00004829template<typename Derived>
4830Sema::OwningExprResult
John McCall865d4472009-11-19 22:55:06 +00004831TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
4832 CXXDependentScopeMemberExpr *E,
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004833 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004834 // Transform the base of the expression.
4835 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4836 if (Base.isInvalid())
4837 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004838
Douglas Gregor6cd21982009-10-20 05:58:46 +00004839 // Start the member reference and compute the object's type.
Douglas Gregora38c6872009-09-03 16:14:30 +00004840 Sema::TypeTy *ObjectType = 0;
Mike Stump1eb44332009-09-09 15:08:12 +00004841 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
Douglas Gregora38c6872009-09-03 16:14:30 +00004842 E->getOperatorLoc(),
4843 E->isArrow()? tok::arrow : tok::period,
4844 ObjectType);
4845 if (Base.isInvalid())
4846 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004847
Douglas Gregor6cd21982009-10-20 05:58:46 +00004848 // Transform the first part of the nested-name-specifier that qualifies
4849 // the member name.
Douglas Gregorc68afe22009-09-03 21:38:09 +00004850 NamedDecl *FirstQualifierInScope
Douglas Gregor6cd21982009-10-20 05:58:46 +00004851 = getDerived().TransformFirstQualifierInScope(
4852 E->getFirstQualifierFoundInScope(),
4853 E->getQualifierRange().getBegin());
Mike Stump1eb44332009-09-09 15:08:12 +00004854
Douglas Gregora38c6872009-09-03 16:14:30 +00004855 NestedNameSpecifier *Qualifier = 0;
4856 if (E->getQualifier()) {
4857 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4858 E->getQualifierRange(),
Douglas Gregorc68afe22009-09-03 21:38:09 +00004859 QualType::getFromOpaquePtr(ObjectType),
4860 FirstQualifierInScope);
Douglas Gregora38c6872009-09-03 16:14:30 +00004861 if (!Qualifier)
4862 return SemaRef.ExprError();
4863 }
Mike Stump1eb44332009-09-09 15:08:12 +00004864
4865 DeclarationName Name
Douglas Gregordd62b152009-10-19 22:04:39 +00004866 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
4867 QualType::getFromOpaquePtr(ObjectType));
Douglas Gregor81499bb2009-09-03 22:13:48 +00004868 if (!Name)
4869 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004870
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004871 if (!E->hasExplicitTemplateArgumentList()) {
4872 // This is a reference to a member without an explicitly-specified
4873 // template argument list. Optimize for this common case.
4874 if (!getDerived().AlwaysRebuild() &&
4875 Base.get() == E->getBase() &&
4876 Qualifier == E->getQualifier() &&
4877 Name == E->getMember() &&
4878 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
Mike Stump1eb44332009-09-09 15:08:12 +00004879 return SemaRef.Owned(E->Retain());
4880
John McCall865d4472009-11-19 22:55:06 +00004881 return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004882 E->isArrow(),
4883 E->getOperatorLoc(),
4884 Qualifier,
4885 E->getQualifierRange(),
4886 Name,
4887 E->getMemberLoc(),
4888 FirstQualifierInScope);
4889 }
4890
4891 // FIXME: This is an ugly hack, which forces the same template name to
4892 // be looked up multiple times. Yuck!
Douglas Gregorca1bdd72009-11-04 00:56:37 +00004893 TemporaryBase Rebase(*this, E->getMemberLoc(), DeclarationName());
4894 TemplateName OrigTemplateName;
4895 if (const IdentifierInfo *II = Name.getAsIdentifierInfo())
4896 OrigTemplateName = SemaRef.Context.getDependentTemplateName(0, II);
4897 else
4898 OrigTemplateName
4899 = SemaRef.Context.getDependentTemplateName(0,
4900 Name.getCXXOverloadedOperator());
Mike Stump1eb44332009-09-09 15:08:12 +00004901
4902 TemplateName Template
4903 = getDerived().TransformTemplateName(OrigTemplateName,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004904 QualType::getFromOpaquePtr(ObjectType));
4905 if (Template.isNull())
4906 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004907
John McCall833ca992009-10-29 08:12:44 +00004908 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004909 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall833ca992009-10-29 08:12:44 +00004910 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
4911 TransArgs[I]))
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004912 return SemaRef.ExprError();
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004913 }
Mike Stump1eb44332009-09-09 15:08:12 +00004914
John McCall865d4472009-11-19 22:55:06 +00004915 return getDerived().RebuildCXXDependentScopeMemberExpr(move(Base),
Douglas Gregorb98b1992009-08-11 05:31:07 +00004916 E->isArrow(),
4917 E->getOperatorLoc(),
Douglas Gregora38c6872009-09-03 16:14:30 +00004918 Qualifier,
4919 E->getQualifierRange(),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004920 Template,
Douglas Gregorc68afe22009-09-03 21:38:09 +00004921 E->getMemberLoc(),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00004922 FirstQualifierInScope,
4923 E->getLAngleLoc(),
4924 TransArgs.data(),
4925 TransArgs.size(),
4926 E->getRAngleLoc());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004927}
4928
4929template<typename Derived>
4930Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004931TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E,
4932 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004933 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004934}
4935
Mike Stump1eb44332009-09-09 15:08:12 +00004936template<typename Derived>
4937Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004938TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E,
4939 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004940 // FIXME: poor source location
4941 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4942 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4943 if (EncodedType.isNull())
4944 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00004945
Douglas Gregorb98b1992009-08-11 05:31:07 +00004946 if (!getDerived().AlwaysRebuild() &&
4947 EncodedType == E->getEncodedType())
Mike Stump1eb44332009-09-09 15:08:12 +00004948 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004949
4950 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4951 EncodedType,
4952 E->getRParenLoc());
4953}
Mike Stump1eb44332009-09-09 15:08:12 +00004954
Douglas Gregorb98b1992009-08-11 05:31:07 +00004955template<typename Derived>
4956Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004957TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E,
4958 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004959 // FIXME: Implement this!
4960 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00004961 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004962}
4963
Mike Stump1eb44332009-09-09 15:08:12 +00004964template<typename Derived>
4965Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004966TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E,
4967 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004968 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00004969}
4970
Mike Stump1eb44332009-09-09 15:08:12 +00004971template<typename Derived>
4972Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004973TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E,
4974 bool isAddressOfOperand) {
Mike Stump1eb44332009-09-09 15:08:12 +00004975 ObjCProtocolDecl *Protocol
Douglas Gregorb98b1992009-08-11 05:31:07 +00004976 = cast_or_null<ObjCProtocolDecl>(
4977 getDerived().TransformDecl(E->getProtocol()));
4978 if (!Protocol)
4979 return SemaRef.ExprError();
4980
4981 if (!getDerived().AlwaysRebuild() &&
4982 Protocol == E->getProtocol())
Mike Stump1eb44332009-09-09 15:08:12 +00004983 return SemaRef.Owned(E->Retain());
4984
Douglas Gregorb98b1992009-08-11 05:31:07 +00004985 return getDerived().RebuildObjCProtocolExpr(Protocol,
4986 E->getAtLoc(),
4987 /*FIXME:*/E->getAtLoc(),
4988 /*FIXME:*/E->getAtLoc(),
4989 E->getRParenLoc());
Mike Stump1eb44332009-09-09 15:08:12 +00004990
Douglas Gregorb98b1992009-08-11 05:31:07 +00004991}
4992
Mike Stump1eb44332009-09-09 15:08:12 +00004993template<typename Derived>
4994Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00004995TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E,
4996 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00004997 // FIXME: Implement this!
4998 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00004999 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005000}
5001
Mike Stump1eb44332009-09-09 15:08:12 +00005002template<typename Derived>
5003Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005004TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E,
5005 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005006 // FIXME: Implement this!
5007 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005008 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005009}
5010
Mike Stump1eb44332009-09-09 15:08:12 +00005011template<typename Derived>
5012Sema::OwningExprResult
Fariborz Jahanian09105f52009-08-20 17:02:02 +00005013TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005014 ObjCImplicitSetterGetterRefExpr *E,
5015 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005016 // FIXME: Implement this!
5017 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005018 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005019}
5020
Mike Stump1eb44332009-09-09 15:08:12 +00005021template<typename Derived>
5022Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005023TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E,
5024 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005025 // FIXME: Implement this!
5026 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005027 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005028}
5029
Mike Stump1eb44332009-09-09 15:08:12 +00005030template<typename Derived>
5031Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005032TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E,
5033 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005034 // FIXME: Implement this!
5035 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005036 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005037}
5038
Mike Stump1eb44332009-09-09 15:08:12 +00005039template<typename Derived>
5040Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005041TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E,
5042 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005043 bool ArgumentChanged = false;
5044 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
5045 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
5046 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
5047 if (SubExpr.isInvalid())
5048 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00005049
Douglas Gregorb98b1992009-08-11 05:31:07 +00005050 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
5051 SubExprs.push_back(SubExpr.takeAs<Expr>());
5052 }
Mike Stump1eb44332009-09-09 15:08:12 +00005053
Douglas Gregorb98b1992009-08-11 05:31:07 +00005054 if (!getDerived().AlwaysRebuild() &&
5055 !ArgumentChanged)
Mike Stump1eb44332009-09-09 15:08:12 +00005056 return SemaRef.Owned(E->Retain());
5057
Douglas Gregorb98b1992009-08-11 05:31:07 +00005058 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
5059 move_arg(SubExprs),
5060 E->getRParenLoc());
5061}
5062
Mike Stump1eb44332009-09-09 15:08:12 +00005063template<typename Derived>
5064Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005065TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E,
5066 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005067 // FIXME: Implement this!
5068 assert(false && "Cannot transform block expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005069 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005070}
5071
Mike Stump1eb44332009-09-09 15:08:12 +00005072template<typename Derived>
5073Sema::OwningExprResult
Douglas Gregorc86a6e92009-11-04 07:01:15 +00005074TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E,
5075 bool isAddressOfOperand) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005076 // FIXME: Implement this!
5077 assert(false && "Cannot transform block-related expressions yet");
Mike Stump1eb44332009-09-09 15:08:12 +00005078 return SemaRef.Owned(E->Retain());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005079}
Mike Stump1eb44332009-09-09 15:08:12 +00005080
Douglas Gregorb98b1992009-08-11 05:31:07 +00005081//===----------------------------------------------------------------------===//
Douglas Gregor577f75a2009-08-04 16:50:30 +00005082// Type reconstruction
5083//===----------------------------------------------------------------------===//
5084
Mike Stump1eb44332009-09-09 15:08:12 +00005085template<typename Derived>
John McCall85737a72009-10-30 00:06:24 +00005086QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
5087 SourceLocation Star) {
5088 return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Star,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005089 getDerived().getBaseEntity());
5090}
5091
Mike Stump1eb44332009-09-09 15:08:12 +00005092template<typename Derived>
John McCall85737a72009-10-30 00:06:24 +00005093QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
5094 SourceLocation Star) {
5095 return SemaRef.BuildBlockPointerType(PointeeType, Qualifiers(), Star,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005096 getDerived().getBaseEntity());
5097}
5098
Mike Stump1eb44332009-09-09 15:08:12 +00005099template<typename Derived>
5100QualType
John McCall85737a72009-10-30 00:06:24 +00005101TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
5102 bool WrittenAsLValue,
5103 SourceLocation Sigil) {
5104 return SemaRef.BuildReferenceType(ReferentType, WrittenAsLValue, Qualifiers(),
5105 Sigil, getDerived().getBaseEntity());
Douglas Gregor577f75a2009-08-04 16:50:30 +00005106}
5107
5108template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005109QualType
John McCall85737a72009-10-30 00:06:24 +00005110TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
5111 QualType ClassType,
5112 SourceLocation Sigil) {
John McCall0953e762009-09-24 19:53:00 +00005113 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Qualifiers(),
John McCall85737a72009-10-30 00:06:24 +00005114 Sigil, getDerived().getBaseEntity());
Douglas Gregor577f75a2009-08-04 16:50:30 +00005115}
5116
5117template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005118QualType
John McCall85737a72009-10-30 00:06:24 +00005119TreeTransform<Derived>::RebuildObjCObjectPointerType(QualType PointeeType,
5120 SourceLocation Sigil) {
5121 return SemaRef.BuildPointerType(PointeeType, Qualifiers(), Sigil,
John McCalla2becad2009-10-21 00:40:46 +00005122 getDerived().getBaseEntity());
5123}
5124
5125template<typename Derived>
5126QualType
Douglas Gregor577f75a2009-08-04 16:50:30 +00005127TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
5128 ArrayType::ArraySizeModifier SizeMod,
5129 const llvm::APInt *Size,
5130 Expr *SizeExpr,
5131 unsigned IndexTypeQuals,
5132 SourceRange BracketsRange) {
5133 if (SizeExpr || !Size)
5134 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
5135 IndexTypeQuals, BracketsRange,
5136 getDerived().getBaseEntity());
Mike Stump1eb44332009-09-09 15:08:12 +00005137
5138 QualType Types[] = {
5139 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
5140 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
5141 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
Douglas Gregor577f75a2009-08-04 16:50:30 +00005142 };
5143 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
5144 QualType SizeType;
5145 for (unsigned I = 0; I != NumTypes; ++I)
5146 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
5147 SizeType = Types[I];
5148 break;
5149 }
Mike Stump1eb44332009-09-09 15:08:12 +00005150
Douglas Gregor577f75a2009-08-04 16:50:30 +00005151 if (SizeType.isNull())
5152 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
Mike Stump1eb44332009-09-09 15:08:12 +00005153
Douglas Gregor577f75a2009-08-04 16:50:30 +00005154 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
Mike Stump1eb44332009-09-09 15:08:12 +00005155 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005156 IndexTypeQuals, BracketsRange,
Mike Stump1eb44332009-09-09 15:08:12 +00005157 getDerived().getBaseEntity());
Douglas Gregor577f75a2009-08-04 16:50:30 +00005158}
Mike Stump1eb44332009-09-09 15:08:12 +00005159
Douglas Gregor577f75a2009-08-04 16:50:30 +00005160template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005161QualType
5162TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005163 ArrayType::ArraySizeModifier SizeMod,
5164 const llvm::APInt &Size,
John McCall85737a72009-10-30 00:06:24 +00005165 unsigned IndexTypeQuals,
5166 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00005167 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
John McCall85737a72009-10-30 00:06:24 +00005168 IndexTypeQuals, BracketsRange);
Douglas Gregor577f75a2009-08-04 16:50:30 +00005169}
5170
5171template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005172QualType
Mike Stump1eb44332009-09-09 15:08:12 +00005173TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005174 ArrayType::ArraySizeModifier SizeMod,
John McCall85737a72009-10-30 00:06:24 +00005175 unsigned IndexTypeQuals,
5176 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00005177 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
John McCall85737a72009-10-30 00:06:24 +00005178 IndexTypeQuals, BracketsRange);
Douglas Gregor577f75a2009-08-04 16:50:30 +00005179}
Mike Stump1eb44332009-09-09 15:08:12 +00005180
Douglas Gregor577f75a2009-08-04 16:50:30 +00005181template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005182QualType
5183TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005184 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +00005185 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005186 unsigned IndexTypeQuals,
5187 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00005188 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005189 SizeExpr.takeAs<Expr>(),
5190 IndexTypeQuals, BracketsRange);
5191}
5192
5193template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005194QualType
5195TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005196 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregorb98b1992009-08-11 05:31:07 +00005197 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005198 unsigned IndexTypeQuals,
5199 SourceRange BracketsRange) {
Mike Stump1eb44332009-09-09 15:08:12 +00005200 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005201 SizeExpr.takeAs<Expr>(),
5202 IndexTypeQuals, BracketsRange);
5203}
5204
5205template<typename Derived>
5206QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
5207 unsigned NumElements) {
5208 // FIXME: semantic checking!
5209 return SemaRef.Context.getVectorType(ElementType, NumElements);
5210}
Mike Stump1eb44332009-09-09 15:08:12 +00005211
Douglas Gregor577f75a2009-08-04 16:50:30 +00005212template<typename Derived>
5213QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
5214 unsigned NumElements,
5215 SourceLocation AttributeLoc) {
5216 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
5217 NumElements, true);
5218 IntegerLiteral *VectorSize
Mike Stump1eb44332009-09-09 15:08:12 +00005219 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005220 AttributeLoc);
5221 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
5222 AttributeLoc);
5223}
Mike Stump1eb44332009-09-09 15:08:12 +00005224
Douglas Gregor577f75a2009-08-04 16:50:30 +00005225template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005226QualType
5227TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregorb98b1992009-08-11 05:31:07 +00005228 ExprArg SizeExpr,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005229 SourceLocation AttributeLoc) {
5230 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
5231}
Mike Stump1eb44332009-09-09 15:08:12 +00005232
Douglas Gregor577f75a2009-08-04 16:50:30 +00005233template<typename Derived>
5234QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
Mike Stump1eb44332009-09-09 15:08:12 +00005235 QualType *ParamTypes,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005236 unsigned NumParamTypes,
Mike Stump1eb44332009-09-09 15:08:12 +00005237 bool Variadic,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005238 unsigned Quals) {
Mike Stump1eb44332009-09-09 15:08:12 +00005239 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
Douglas Gregor577f75a2009-08-04 16:50:30 +00005240 Quals,
5241 getDerived().getBaseLocation(),
5242 getDerived().getBaseEntity());
5243}
Mike Stump1eb44332009-09-09 15:08:12 +00005244
Douglas Gregor577f75a2009-08-04 16:50:30 +00005245template<typename Derived>
John McCalla2becad2009-10-21 00:40:46 +00005246QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
5247 return SemaRef.Context.getFunctionNoProtoType(T);
5248}
5249
5250template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00005251QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00005252 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
5253}
5254
5255template<typename Derived>
5256QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
5257 return SemaRef.Context.getTypeOfType(Underlying);
5258}
5259
5260template<typename Derived>
Douglas Gregorb98b1992009-08-11 05:31:07 +00005261QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregor577f75a2009-08-04 16:50:30 +00005262 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
5263}
5264
5265template<typename Derived>
5266QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
John McCall833ca992009-10-29 08:12:44 +00005267 TemplateName Template,
5268 SourceLocation TemplateNameLoc,
5269 SourceLocation LAngleLoc,
5270 const TemplateArgumentLoc *Args,
5271 unsigned NumArgs,
5272 SourceLocation RAngleLoc) {
5273 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, LAngleLoc,
5274 Args, NumArgs, RAngleLoc);
Douglas Gregor577f75a2009-08-04 16:50:30 +00005275}
Mike Stump1eb44332009-09-09 15:08:12 +00005276
Douglas Gregordcee1a12009-08-06 05:28:30 +00005277template<typename Derived>
5278NestedNameSpecifier *
5279TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5280 SourceRange Range,
Douglas Gregora38c6872009-09-03 16:14:30 +00005281 IdentifierInfo &II,
Douglas Gregorc68afe22009-09-03 21:38:09 +00005282 QualType ObjectType,
5283 NamedDecl *FirstQualifierInScope) {
Douglas Gregordcee1a12009-08-06 05:28:30 +00005284 CXXScopeSpec SS;
5285 // FIXME: The source location information is all wrong.
5286 SS.setRange(Range);
5287 SS.setScopeRep(Prefix);
5288 return static_cast<NestedNameSpecifier *>(
Mike Stump1eb44332009-09-09 15:08:12 +00005289 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregor495c35d2009-08-25 22:51:20 +00005290 Range.getEnd(), II,
Douglas Gregorc68afe22009-09-03 21:38:09 +00005291 ObjectType,
5292 FirstQualifierInScope,
Douglas Gregor495c35d2009-08-25 22:51:20 +00005293 false));
Douglas Gregordcee1a12009-08-06 05:28:30 +00005294}
5295
5296template<typename Derived>
5297NestedNameSpecifier *
5298TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5299 SourceRange Range,
5300 NamespaceDecl *NS) {
5301 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
5302}
5303
5304template<typename Derived>
5305NestedNameSpecifier *
5306TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5307 SourceRange Range,
5308 bool TemplateKW,
5309 QualType T) {
5310 if (T->isDependentType() || T->isRecordType() ||
5311 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
Douglas Gregora4923eb2009-11-16 21:35:15 +00005312 assert(!T.hasLocalQualifiers() && "Can't get cv-qualifiers here");
Douglas Gregordcee1a12009-08-06 05:28:30 +00005313 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
5314 T.getTypePtr());
5315 }
Mike Stump1eb44332009-09-09 15:08:12 +00005316
Douglas Gregordcee1a12009-08-06 05:28:30 +00005317 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
5318 return 0;
5319}
Mike Stump1eb44332009-09-09 15:08:12 +00005320
Douglas Gregord1067e52009-08-06 06:41:21 +00005321template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005322TemplateName
Douglas Gregord1067e52009-08-06 06:41:21 +00005323TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5324 bool TemplateKW,
5325 TemplateDecl *Template) {
Mike Stump1eb44332009-09-09 15:08:12 +00005326 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
Douglas Gregord1067e52009-08-06 06:41:21 +00005327 Template);
5328}
5329
5330template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005331TemplateName
Douglas Gregord1067e52009-08-06 06:41:21 +00005332TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5333 bool TemplateKW,
5334 OverloadedFunctionDecl *Ovl) {
5335 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
5336}
5337
5338template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005339TemplateName
Douglas Gregord1067e52009-08-06 06:41:21 +00005340TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00005341 const IdentifierInfo &II,
5342 QualType ObjectType) {
Douglas Gregord1067e52009-08-06 06:41:21 +00005343 CXXScopeSpec SS;
5344 SS.setRange(SourceRange(getDerived().getBaseLocation()));
Mike Stump1eb44332009-09-09 15:08:12 +00005345 SS.setScopeRep(Qualifier);
Douglas Gregor014e88d2009-11-03 23:16:33 +00005346 UnqualifiedId Name;
5347 Name.setIdentifier(&II, /*FIXME:*/getDerived().getBaseLocation());
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00005348 return getSema().ActOnDependentTemplateName(
5349 /*FIXME:*/getDerived().getBaseLocation(),
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00005350 SS,
Douglas Gregor014e88d2009-11-03 23:16:33 +00005351 Name,
Douglas Gregor3b6afbb2009-09-09 00:23:06 +00005352 ObjectType.getAsOpaquePtr())
5353 .template getAsVal<TemplateName>();
Douglas Gregord1067e52009-08-06 06:41:21 +00005354}
Mike Stump1eb44332009-09-09 15:08:12 +00005355
Douglas Gregorb98b1992009-08-11 05:31:07 +00005356template<typename Derived>
Douglas Gregorca1bdd72009-11-04 00:56:37 +00005357TemplateName
5358TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5359 OverloadedOperatorKind Operator,
5360 QualType ObjectType) {
5361 CXXScopeSpec SS;
5362 SS.setRange(SourceRange(getDerived().getBaseLocation()));
5363 SS.setScopeRep(Qualifier);
5364 UnqualifiedId Name;
5365 SourceLocation SymbolLocations[3]; // FIXME: Bogus location information.
5366 Name.setOperatorFunctionId(/*FIXME:*/getDerived().getBaseLocation(),
5367 Operator, SymbolLocations);
5368 return getSema().ActOnDependentTemplateName(
5369 /*FIXME:*/getDerived().getBaseLocation(),
5370 SS,
5371 Name,
5372 ObjectType.getAsOpaquePtr())
5373 .template getAsVal<TemplateName>();
5374}
5375
5376template<typename Derived>
Mike Stump1eb44332009-09-09 15:08:12 +00005377Sema::OwningExprResult
Douglas Gregorb98b1992009-08-11 05:31:07 +00005378TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
5379 SourceLocation OpLoc,
5380 ExprArg Callee,
5381 ExprArg First,
5382 ExprArg Second) {
5383 Expr *FirstExpr = (Expr *)First.get();
5384 Expr *SecondExpr = (Expr *)Second.get();
Sebastian Redlf322ed62009-10-29 20:17:01 +00005385 DeclRefExpr *DRE
5386 = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
Douglas Gregorb98b1992009-08-11 05:31:07 +00005387 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
Mike Stump1eb44332009-09-09 15:08:12 +00005388
Douglas Gregorb98b1992009-08-11 05:31:07 +00005389 // Determine whether this should be a builtin operation.
Sebastian Redlf322ed62009-10-29 20:17:01 +00005390 if (Op == OO_Subscript) {
5391 if (!FirstExpr->getType()->isOverloadableType() &&
5392 !SecondExpr->getType()->isOverloadableType())
5393 return getSema().CreateBuiltinArraySubscriptExpr(move(First),
5394 DRE->getLocStart(),
5395 move(Second), OpLoc);
Eli Friedman1a3c75f2009-11-16 19:13:03 +00005396 } else if (Op == OO_Arrow) {
5397 // -> is never a builtin operation.
5398 return SemaRef.BuildOverloadedArrowExpr(0, move(First), OpLoc);
Sebastian Redlf322ed62009-10-29 20:17:01 +00005399 } else if (SecondExpr == 0 || isPostIncDec) {
Douglas Gregorb98b1992009-08-11 05:31:07 +00005400 if (!FirstExpr->getType()->isOverloadableType()) {
5401 // The argument is not of overloadable type, so try to create a
5402 // built-in unary operation.
Mike Stump1eb44332009-09-09 15:08:12 +00005403 UnaryOperator::Opcode Opc
Douglas Gregorb98b1992009-08-11 05:31:07 +00005404 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
Mike Stump1eb44332009-09-09 15:08:12 +00005405
Douglas Gregorb98b1992009-08-11 05:31:07 +00005406 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
5407 }
5408 } else {
Mike Stump1eb44332009-09-09 15:08:12 +00005409 if (!FirstExpr->getType()->isOverloadableType() &&
Douglas Gregorb98b1992009-08-11 05:31:07 +00005410 !SecondExpr->getType()->isOverloadableType()) {
5411 // Neither of the arguments is an overloadable type, so try to
5412 // create a built-in binary operation.
5413 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
Mike Stump1eb44332009-09-09 15:08:12 +00005414 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +00005415 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
5416 if (Result.isInvalid())
5417 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00005418
Douglas Gregorb98b1992009-08-11 05:31:07 +00005419 First.release();
5420 Second.release();
5421 return move(Result);
5422 }
5423 }
Mike Stump1eb44332009-09-09 15:08:12 +00005424
5425 // Compute the transformed set of functions (and function templates) to be
Douglas Gregorb98b1992009-08-11 05:31:07 +00005426 // used during overload resolution.
5427 Sema::FunctionSet Functions;
Mike Stump1eb44332009-09-09 15:08:12 +00005428
Douglas Gregorb98b1992009-08-11 05:31:07 +00005429 // FIXME: Do we have to check
5430 // IsAcceptableNonMemberOperatorCandidate for each of these?
Douglas Gregor8f1d89e2009-09-01 16:58:52 +00005431 for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
Douglas Gregorb98b1992009-08-11 05:31:07 +00005432 Functions.insert(*F);
Mike Stump1eb44332009-09-09 15:08:12 +00005433
Douglas Gregorb98b1992009-08-11 05:31:07 +00005434 // Add any functions found via argument-dependent lookup.
5435 Expr *Args[2] = { FirstExpr, SecondExpr };
5436 unsigned NumArgs = 1 + (SecondExpr != 0);
Mike Stump1eb44332009-09-09 15:08:12 +00005437 DeclarationName OpName
Douglas Gregorb98b1992009-08-11 05:31:07 +00005438 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
Sebastian Redl644be852009-10-23 19:23:15 +00005439 SemaRef.ArgumentDependentLookup(OpName, /*Operator*/true, Args, NumArgs,
5440 Functions);
Mike Stump1eb44332009-09-09 15:08:12 +00005441
Douglas Gregorb98b1992009-08-11 05:31:07 +00005442 // Create the overloaded operator invocation for unary operators.
5443 if (NumArgs == 1 || isPostIncDec) {
Mike Stump1eb44332009-09-09 15:08:12 +00005444 UnaryOperator::Opcode Opc
Douglas Gregorb98b1992009-08-11 05:31:07 +00005445 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
5446 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
5447 }
Mike Stump1eb44332009-09-09 15:08:12 +00005448
Sebastian Redlf322ed62009-10-29 20:17:01 +00005449 if (Op == OO_Subscript)
5450 return SemaRef.CreateOverloadedArraySubscriptExpr(DRE->getLocStart(), OpLoc,
5451 move(First),move(Second));
5452
Douglas Gregorb98b1992009-08-11 05:31:07 +00005453 // Create the overloaded operator invocation for binary operators.
Mike Stump1eb44332009-09-09 15:08:12 +00005454 BinaryOperator::Opcode Opc =
Douglas Gregorb98b1992009-08-11 05:31:07 +00005455 BinaryOperator::getOverloadedOpcode(Op);
Mike Stump1eb44332009-09-09 15:08:12 +00005456 OwningExprResult Result
Douglas Gregorb98b1992009-08-11 05:31:07 +00005457 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
5458 if (Result.isInvalid())
5459 return SemaRef.ExprError();
Mike Stump1eb44332009-09-09 15:08:12 +00005460
Douglas Gregorb98b1992009-08-11 05:31:07 +00005461 First.release();
5462 Second.release();
Mike Stump1eb44332009-09-09 15:08:12 +00005463 return move(Result);
Douglas Gregorb98b1992009-08-11 05:31:07 +00005464}
Mike Stump1eb44332009-09-09 15:08:12 +00005465
Douglas Gregor577f75a2009-08-04 16:50:30 +00005466} // end namespace clang
5467
5468#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H