blob: e8956270d270c300672eab25c085fe6fe07ffe4f [file] [log] [blame]
John McCall550e0c22009-10-21 00:40:46 +00001//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===/
Douglas Gregord6ff3322009-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 Gregor1135c352009-08-06 05:28:30 +000017#include "clang/Sema/SemaDiagnostic.h"
Douglas Gregor2b6ca462009-09-03 21:38:09 +000018#include "clang/AST/Decl.h"
Douglas Gregor766b0bb2009-08-06 22:17:10 +000019#include "clang/AST/Expr.h"
Douglas Gregora16548e2009-08-11 05:31:07 +000020#include "clang/AST/ExprCXX.h"
21#include "clang/AST/ExprObjC.h"
Douglas Gregorebe10102009-08-20 07:17:43 +000022#include "clang/AST/Stmt.h"
23#include "clang/AST/StmtCXX.h"
24#include "clang/AST/StmtObjC.h"
John McCall550e0c22009-10-21 00:40:46 +000025#include "clang/AST/TypeLocBuilder.h"
Douglas Gregora16548e2009-08-11 05:31:07 +000026#include "clang/Parse/Ownership.h"
27#include "clang/Parse/Designator.h"
28#include "clang/Lex/Preprocessor.h"
John McCall550e0c22009-10-21 00:40:46 +000029#include "llvm/Support/ErrorHandling.h"
Douglas Gregord6ff3322009-08-04 16:50:30 +000030#include <algorithm>
31
32namespace clang {
Mike Stump11289f42009-09-09 15:08:12 +000033
Douglas Gregord6ff3322009-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 Stump11289f42009-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 Gregord6ff3322009-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 Stump11289f42009-09-09 15:08:12 +000047/// subclasses to customize any of its operations. Thus, a subclass can
Douglas Gregord6ff3322009-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 Stump11289f42009-09-09 15:08:12 +000062/// Subclasses can customize the transformation at various levels. The
Douglas Gregore922c772009-08-04 22:27:00 +000063/// most coarse-grained transformations involve replacing TransformType(),
Douglas Gregord6ff3322009-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 Gregorebe10102009-08-20 07:17:43 +000070/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
Douglas Gregord6ff3322009-08-04 16:50:30 +000071/// replacing TransformTemplateTypeParmType() allows template instantiation
Mike Stump11289f42009-09-09 15:08:12 +000072/// to substitute template arguments for their corresponding template
Douglas Gregord6ff3322009-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 Stump11289f42009-09-09 15:08:12 +000080/// to avoid traversing nodes that don't need any transformation
Douglas Gregord6ff3322009-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 Gregord6ff3322009-08-04 16:50:30 +000085template<typename Derived>
86class TreeTransform {
87protected:
88 Sema &SemaRef;
Mike Stump11289f42009-09-09 15:08:12 +000089
90public:
Douglas Gregora16548e2009-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 Gregorebe10102009-08-20 07:17:43 +000096 typedef Sema::MultiStmtArg MultiStmtArg;
Mike Stump11289f42009-09-09 15:08:12 +000097
Douglas Gregord6ff3322009-08-04 16:50:30 +000098 /// \brief Initializes a new tree transformer.
99 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
Mike Stump11289f42009-09-09 15:08:12 +0000100
Douglas Gregord6ff3322009-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 Stump11289f42009-09-09 15:08:12 +0000105 const Derived &getDerived() const {
106 return static_cast<const Derived&>(*this);
Douglas Gregord6ff3322009-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 Stump11289f42009-09-09 15:08:12 +0000112
Douglas Gregord6ff3322009-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 Stump11289f42009-09-09 15:08:12 +0000119
Douglas Gregord6ff3322009-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 Stump11289f42009-09-09 15:08:12 +0000123 /// By default, returns no source-location information. Subclasses can
Douglas Gregord6ff3322009-08-04 16:50:30 +0000124 /// provide an alternative implementation that provides better location
125 /// information.
126 SourceLocation getBaseLocation() { return SourceLocation(); }
Mike Stump11289f42009-09-09 15:08:12 +0000127
Douglas Gregord6ff3322009-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 Gregora16548e2009-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 Stump11289f42009-09-09 15:08:12 +0000141
Douglas Gregora16548e2009-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 Stump11289f42009-09-09 15:08:12 +0000148
Douglas Gregora16548e2009-08-11 05:31:07 +0000149 public:
150 TemporaryBase(TreeTransform &Self, SourceLocation Location,
Mike Stump11289f42009-09-09 15:08:12 +0000151 DeclarationName Entity) : Self(Self) {
Douglas Gregora16548e2009-08-11 05:31:07 +0000152 OldLocation = Self.getDerived().getBaseLocation();
153 OldEntity = Self.getDerived().getBaseEntity();
154 Self.getDerived().setBase(Location, Entity);
155 }
Mike Stump11289f42009-09-09 15:08:12 +0000156
Douglas Gregora16548e2009-08-11 05:31:07 +0000157 ~TemporaryBase() {
158 Self.getDerived().setBase(OldLocation, OldEntity);
159 }
160 };
Mike Stump11289f42009-09-09 15:08:12 +0000161
162 /// \brief Determine whether the given type \p T has already been
Douglas Gregord6ff3322009-08-04 16:50:30 +0000163 /// transformed.
164 ///
165 /// Subclasses can provide an alternative implementation of this routine
Mike Stump11289f42009-09-09 15:08:12 +0000166 /// to short-circuit evaluation when it is known that a given type will
Douglas Gregord6ff3322009-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 McCall550e0c22009-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 Gregord6ff3322009-08-04 16:50:30 +0000180 ///
181 /// \returns the transformed type.
182 QualType TransformType(QualType T);
Mike Stump11289f42009-09-09 15:08:12 +0000183
John McCall550e0c22009-10-21 00:40:46 +0000184 /// \brief Transforms the given type-with-location into a new
185 /// type-with-location.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000186 ///
John McCall550e0c22009-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 Stump11289f42009-09-09 15:08:12 +0000199
Douglas Gregor766b0bb2009-08-06 22:17:10 +0000200 /// \brief Transform the given statement.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000201 ///
Mike Stump11289f42009-09-09 15:08:12 +0000202 /// By default, this routine transforms a statement by delegating to the
Douglas Gregorebe10102009-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 Gregora16548e2009-08-11 05:31:07 +0000209 OwningStmtResult TransformStmt(Stmt *S);
Mike Stump11289f42009-09-09 15:08:12 +0000210
Douglas Gregor766b0bb2009-08-06 22:17:10 +0000211 /// \brief Transform the given expression.
212 ///
Douglas Gregora16548e2009-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 Stump11289f42009-09-09 15:08:12 +0000232
Douglas Gregord6ff3322009-08-04 16:50:30 +0000233 /// \brief Transform the given declaration, which is referenced from a type
234 /// or expression.
235 ///
Douglas Gregor1135c352009-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 Gregorebe10102009-08-20 07:17:43 +0000239
240 /// \brief Transform the definition of the given declaration.
241 ///
Mike Stump11289f42009-09-09 15:08:12 +0000242 /// By default, invokes TransformDecl() to transform the declaration.
Douglas Gregorebe10102009-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 Stump11289f42009-09-09 15:08:12 +0000245
Douglas Gregora5cb6da2009-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 Gregord6ff3322009-08-04 16:50:30 +0000259 /// \brief Transform the given nested-name-specifier.
260 ///
Mike Stump11289f42009-09-09 15:08:12 +0000261 /// By default, transforms all of the types and declarations within the
Douglas Gregor1135c352009-08-06 05:28:30 +0000262 /// nested-name-specifier. Subclasses may override this function to provide
263 /// alternate behavior.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000264 NestedNameSpecifier *TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregorc26e0f62009-09-03 16:14:30 +0000265 SourceRange Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +0000266 QualType ObjectType = QualType(),
267 NamedDecl *FirstQualifierInScope = 0);
Mike Stump11289f42009-09-09 15:08:12 +0000268
Douglas Gregorf816bd72009-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 Gregorc59e5612009-10-19 22:04:39 +0000276 SourceLocation Loc,
277 QualType ObjectType = QualType());
Mike Stump11289f42009-09-09 15:08:12 +0000278
Douglas Gregord6ff3322009-08-04 16:50:30 +0000279 /// \brief Transform the given template name.
Mike Stump11289f42009-09-09 15:08:12 +0000280 ///
Douglas Gregor71dc5092009-08-06 06:41:21 +0000281 /// By default, transforms the template name by transforming the declarations
Mike Stump11289f42009-09-09 15:08:12 +0000282 /// and nested-name-specifiers that occur within the template name.
Douglas Gregor71dc5092009-08-06 06:41:21 +0000283 /// Subclasses may override this function to provide alternate behavior.
Douglas Gregor308047d2009-09-09 00:23:06 +0000284 TemplateName TransformTemplateName(TemplateName Name,
285 QualType ObjectType = QualType());
Mike Stump11289f42009-09-09 15:08:12 +0000286
Douglas Gregord6ff3322009-08-04 16:50:30 +0000287 /// \brief Transform the given template argument.
288 ///
Mike Stump11289f42009-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 Gregore922c772009-08-04 22:27:00 +0000291 /// new template argument from the transformed result. Subclasses may
292 /// override this function to provide alternate behavior.
John McCall0ad16662009-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 Stump11289f42009-09-09 15:08:12 +0000307
John McCall550e0c22009-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 Gregord6ff3322009-08-04 16:50:30 +0000312
Douglas Gregorc59e5612009-10-19 22:04:39 +0000313 QualType
314 TransformTemplateSpecializationType(const TemplateSpecializationType *T,
315 QualType ObjectType);
John McCall0ad16662009-10-29 08:12:44 +0000316
317 QualType
318 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
319 TemplateSpecializationTypeLoc TL,
320 QualType ObjectType);
Douglas Gregorc59e5612009-10-19 22:04:39 +0000321
Douglas Gregorebe10102009-08-20 07:17:43 +0000322 OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
Mike Stump11289f42009-09-09 15:08:12 +0000323
Douglas Gregorebe10102009-08-20 07:17:43 +0000324#define STMT(Node, Parent) \
325 OwningStmtResult Transform##Node(Node *S);
Douglas Gregora16548e2009-08-11 05:31:07 +0000326#define EXPR(Node, Parent) \
327 OwningExprResult Transform##Node(Node *E);
328#define ABSTRACT_EXPR(Node, Parent)
329#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +0000330
Douglas Gregord6ff3322009-08-04 16:50:30 +0000331 /// \brief Build a new pointer type given its pointee type.
332 ///
333 /// By default, performs semantic analysis when building the pointer type.
334 /// Subclasses may override this routine to provide different behavior.
335 QualType RebuildPointerType(QualType PointeeType);
336
337 /// \brief Build a new block pointer type given its pointee type.
338 ///
Mike Stump11289f42009-09-09 15:08:12 +0000339 /// By default, performs semantic analysis when building the block pointer
Douglas Gregord6ff3322009-08-04 16:50:30 +0000340 /// type. Subclasses may override this routine to provide different behavior.
341 QualType RebuildBlockPointerType(QualType PointeeType);
342
343 /// \brief Build a new lvalue reference type given the type it references.
344 ///
345 /// By default, performs semantic analysis when building the lvalue reference
346 /// type. Subclasses may override this routine to provide different behavior.
347 QualType RebuildLValueReferenceType(QualType ReferentType);
348
349 /// \brief Build a new rvalue reference type given the type it references.
350 ///
351 /// By default, performs semantic analysis when building the rvalue reference
352 /// type. Subclasses may override this routine to provide different behavior.
353 QualType RebuildRValueReferenceType(QualType ReferentType);
Mike Stump11289f42009-09-09 15:08:12 +0000354
Douglas Gregord6ff3322009-08-04 16:50:30 +0000355 /// \brief Build a new member pointer type given the pointee type and the
356 /// class type it refers into.
357 ///
358 /// By default, performs semantic analysis when building the member pointer
359 /// type. Subclasses may override this routine to provide different behavior.
360 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType);
Mike Stump11289f42009-09-09 15:08:12 +0000361
John McCall550e0c22009-10-21 00:40:46 +0000362 /// \brief Build a new Objective C object pointer type.
363 QualType RebuildObjCObjectPointerType(QualType PointeeType);
364
Douglas Gregord6ff3322009-08-04 16:50:30 +0000365 /// \brief Build a new array type given the element type, size
366 /// modifier, size of the array (if known), size expression, and index type
367 /// qualifiers.
368 ///
369 /// By default, performs semantic analysis when building the array type.
370 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000371 /// Also by default, all of the other Rebuild*Array
Douglas Gregord6ff3322009-08-04 16:50:30 +0000372 QualType RebuildArrayType(QualType ElementType,
373 ArrayType::ArraySizeModifier SizeMod,
374 const llvm::APInt *Size,
375 Expr *SizeExpr,
376 unsigned IndexTypeQuals,
377 SourceRange BracketsRange);
Mike Stump11289f42009-09-09 15:08:12 +0000378
Douglas Gregord6ff3322009-08-04 16:50:30 +0000379 /// \brief Build a new constant array type given the element type, size
380 /// modifier, (known) size of the array, and index type qualifiers.
381 ///
382 /// By default, performs semantic analysis when building the array type.
383 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000384 QualType RebuildConstantArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000385 ArrayType::ArraySizeModifier SizeMod,
386 const llvm::APInt &Size,
387 unsigned IndexTypeQuals);
388
Douglas Gregord6ff3322009-08-04 16:50:30 +0000389 /// \brief Build a new incomplete array type given the element type, size
390 /// modifier, and index type qualifiers.
391 ///
392 /// By default, performs semantic analysis when building the array type.
393 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000394 QualType RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000395 ArrayType::ArraySizeModifier SizeMod,
396 unsigned IndexTypeQuals);
397
Mike Stump11289f42009-09-09 15:08:12 +0000398 /// \brief Build a new variable-length array type given the element type,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000399 /// size modifier, size expression, and index type qualifiers.
400 ///
401 /// By default, performs semantic analysis when building the array type.
402 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000403 QualType RebuildVariableArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000404 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +0000405 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000406 unsigned IndexTypeQuals,
407 SourceRange BracketsRange);
408
Mike Stump11289f42009-09-09 15:08:12 +0000409 /// \brief Build a new dependent-sized array type given the element type,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000410 /// size modifier, size expression, and index type qualifiers.
411 ///
412 /// By default, performs semantic analysis when building the array type.
413 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000414 QualType RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000415 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +0000416 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000417 unsigned IndexTypeQuals,
418 SourceRange BracketsRange);
419
420 /// \brief Build a new vector type given the element type and
421 /// number of elements.
422 ///
423 /// By default, performs semantic analysis when building the vector type.
424 /// Subclasses may override this routine to provide different behavior.
425 QualType RebuildVectorType(QualType ElementType, unsigned NumElements);
Mike Stump11289f42009-09-09 15:08:12 +0000426
Douglas Gregord6ff3322009-08-04 16:50:30 +0000427 /// \brief Build a new extended vector type given the element type and
428 /// number of elements.
429 ///
430 /// By default, performs semantic analysis when building the vector type.
431 /// Subclasses may override this routine to provide different behavior.
432 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
433 SourceLocation AttributeLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000434
435 /// \brief Build a new potentially dependently-sized extended vector type
Douglas Gregord6ff3322009-08-04 16:50:30 +0000436 /// given the element type and number of elements.
437 ///
438 /// By default, performs semantic analysis when building the vector type.
439 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000440 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregora16548e2009-08-11 05:31:07 +0000441 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000442 SourceLocation AttributeLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000443
Douglas Gregord6ff3322009-08-04 16:50:30 +0000444 /// \brief Build a new function type.
445 ///
446 /// By default, performs semantic analysis when building the function type.
447 /// Subclasses may override this routine to provide different behavior.
448 QualType RebuildFunctionProtoType(QualType T,
Mike Stump11289f42009-09-09 15:08:12 +0000449 QualType *ParamTypes,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000450 unsigned NumParamTypes,
451 bool Variadic, unsigned Quals);
Mike Stump11289f42009-09-09 15:08:12 +0000452
John McCall550e0c22009-10-21 00:40:46 +0000453 /// \brief Build a new unprototyped function type.
454 QualType RebuildFunctionNoProtoType(QualType ResultType);
455
Douglas Gregord6ff3322009-08-04 16:50:30 +0000456 /// \brief Build a new typedef type.
457 QualType RebuildTypedefType(TypedefDecl *Typedef) {
458 return SemaRef.Context.getTypeDeclType(Typedef);
459 }
460
461 /// \brief Build a new class/struct/union type.
462 QualType RebuildRecordType(RecordDecl *Record) {
463 return SemaRef.Context.getTypeDeclType(Record);
464 }
465
466 /// \brief Build a new Enum type.
467 QualType RebuildEnumType(EnumDecl *Enum) {
468 return SemaRef.Context.getTypeDeclType(Enum);
469 }
John McCallfcc33b02009-09-05 00:15:47 +0000470
471 /// \brief Build a new elaborated type.
472 QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag) {
473 return SemaRef.Context.getElaboratedType(T, Tag);
474 }
Mike Stump11289f42009-09-09 15:08:12 +0000475
476 /// \brief Build a new typeof(expr) type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000477 ///
478 /// By default, performs semantic analysis when building the typeof type.
479 /// Subclasses may override this routine to provide different behavior.
Douglas Gregora16548e2009-08-11 05:31:07 +0000480 QualType RebuildTypeOfExprType(ExprArg Underlying);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000481
Mike Stump11289f42009-09-09 15:08:12 +0000482 /// \brief Build a new typeof(type) type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000483 ///
484 /// By default, builds a new TypeOfType with the given underlying type.
485 QualType RebuildTypeOfType(QualType Underlying);
486
Mike Stump11289f42009-09-09 15:08:12 +0000487 /// \brief Build a new C++0x decltype type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000488 ///
489 /// By default, performs semantic analysis when building the decltype type.
490 /// Subclasses may override this routine to provide different behavior.
Douglas Gregora16548e2009-08-11 05:31:07 +0000491 QualType RebuildDecltypeType(ExprArg Underlying);
Mike Stump11289f42009-09-09 15:08:12 +0000492
Douglas Gregord6ff3322009-08-04 16:50:30 +0000493 /// \brief Build a new template specialization type.
494 ///
495 /// By default, performs semantic analysis when building the template
496 /// specialization type. Subclasses may override this routine to provide
497 /// different behavior.
498 QualType RebuildTemplateSpecializationType(TemplateName Template,
John McCall0ad16662009-10-29 08:12:44 +0000499 SourceLocation TemplateLoc,
500 SourceLocation LAngleLoc,
501 const TemplateArgumentLoc *Args,
502 unsigned NumArgs,
503 SourceLocation RAngleLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000504
Douglas Gregord6ff3322009-08-04 16:50:30 +0000505 /// \brief Build a new qualified name type.
506 ///
Mike Stump11289f42009-09-09 15:08:12 +0000507 /// By default, builds a new QualifiedNameType type from the
508 /// nested-name-specifier and the named type. Subclasses may override
Douglas Gregord6ff3322009-08-04 16:50:30 +0000509 /// this routine to provide different behavior.
510 QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
511 return SemaRef.Context.getQualifiedNameType(NNS, Named);
Mike Stump11289f42009-09-09 15:08:12 +0000512 }
Douglas Gregord6ff3322009-08-04 16:50:30 +0000513
514 /// \brief Build a new typename type that refers to a template-id.
515 ///
516 /// By default, builds a new TypenameType type from the nested-name-specifier
Mike Stump11289f42009-09-09 15:08:12 +0000517 /// and the given type. Subclasses may override this routine to provide
Douglas Gregord6ff3322009-08-04 16:50:30 +0000518 /// different behavior.
519 QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
520 if (NNS->isDependent())
Mike Stump11289f42009-09-09 15:08:12 +0000521 return SemaRef.Context.getTypenameType(NNS,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000522 cast<TemplateSpecializationType>(T));
Mike Stump11289f42009-09-09 15:08:12 +0000523
Douglas Gregord6ff3322009-08-04 16:50:30 +0000524 return SemaRef.Context.getQualifiedNameType(NNS, T);
Mike Stump11289f42009-09-09 15:08:12 +0000525 }
Douglas Gregord6ff3322009-08-04 16:50:30 +0000526
527 /// \brief Build a new typename type that refers to an identifier.
528 ///
529 /// By default, performs semantic analysis when building the typename type
Mike Stump11289f42009-09-09 15:08:12 +0000530 /// (or qualified name type). Subclasses may override this routine to provide
Douglas Gregord6ff3322009-08-04 16:50:30 +0000531 /// different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000532 QualType RebuildTypenameType(NestedNameSpecifier *NNS,
John McCall0ad16662009-10-29 08:12:44 +0000533 const IdentifierInfo *Id,
534 SourceRange SR) {
535 return SemaRef.CheckTypenameType(NNS, *Id, SR);
Douglas Gregor1135c352009-08-06 05:28:30 +0000536 }
Mike Stump11289f42009-09-09 15:08:12 +0000537
Douglas Gregor1135c352009-08-06 05:28:30 +0000538 /// \brief Build a new nested-name-specifier given the prefix and an
539 /// identifier that names the next step in the nested-name-specifier.
540 ///
541 /// By default, performs semantic analysis when building the new
542 /// nested-name-specifier. Subclasses may override this routine to provide
543 /// different behavior.
544 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
545 SourceRange Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +0000546 IdentifierInfo &II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +0000547 QualType ObjectType,
548 NamedDecl *FirstQualifierInScope);
Douglas Gregor1135c352009-08-06 05:28:30 +0000549
550 /// \brief Build a new nested-name-specifier given the prefix and the
551 /// namespace named in the next step in the nested-name-specifier.
552 ///
553 /// By default, performs semantic analysis when building the new
554 /// nested-name-specifier. Subclasses may override this routine to provide
555 /// different behavior.
556 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
557 SourceRange Range,
558 NamespaceDecl *NS);
559
560 /// \brief Build a new nested-name-specifier given the prefix and the
561 /// type named in the next step in the nested-name-specifier.
562 ///
563 /// By default, performs semantic analysis when building the new
564 /// nested-name-specifier. Subclasses may override this routine to provide
565 /// different behavior.
566 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
567 SourceRange Range,
568 bool TemplateKW,
569 QualType T);
Douglas Gregor71dc5092009-08-06 06:41:21 +0000570
571 /// \brief Build a new template name given a nested name specifier, a flag
572 /// indicating whether the "template" keyword was provided, and the template
573 /// that the template name refers to.
574 ///
575 /// By default, builds the new template name directly. Subclasses may override
576 /// this routine to provide different behavior.
577 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
578 bool TemplateKW,
579 TemplateDecl *Template);
580
581 /// \brief Build a new template name given a nested name specifier, a flag
582 /// indicating whether the "template" keyword was provided, and a set of
583 /// overloaded function templates.
584 ///
585 /// By default, builds the new template name directly. Subclasses may override
586 /// this routine to provide different behavior.
587 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
588 bool TemplateKW,
589 OverloadedFunctionDecl *Ovl);
Mike Stump11289f42009-09-09 15:08:12 +0000590
Douglas Gregor71dc5092009-08-06 06:41:21 +0000591 /// \brief Build a new template name given a nested name specifier and the
592 /// name that is referred to as a template.
593 ///
594 /// By default, performs semantic analysis to determine whether the name can
595 /// be resolved to a specific template, then builds the appropriate kind of
596 /// template name. Subclasses may override this routine to provide different
597 /// behavior.
598 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor308047d2009-09-09 00:23:06 +0000599 const IdentifierInfo &II,
600 QualType ObjectType);
Mike Stump11289f42009-09-09 15:08:12 +0000601
602
Douglas Gregorebe10102009-08-20 07:17:43 +0000603 /// \brief Build a new compound statement.
604 ///
605 /// By default, performs semantic analysis to build the new statement.
606 /// Subclasses may override this routine to provide different behavior.
607 OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
608 MultiStmtArg Statements,
609 SourceLocation RBraceLoc,
610 bool IsStmtExpr) {
611 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
612 IsStmtExpr);
613 }
614
615 /// \brief Build a new case statement.
616 ///
617 /// By default, performs semantic analysis to build the new statement.
618 /// Subclasses may override this routine to provide different behavior.
619 OwningStmtResult RebuildCaseStmt(SourceLocation CaseLoc,
620 ExprArg LHS,
621 SourceLocation EllipsisLoc,
622 ExprArg RHS,
623 SourceLocation ColonLoc) {
Mike Stump11289f42009-09-09 15:08:12 +0000624 return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
Douglas Gregorebe10102009-08-20 07:17:43 +0000625 ColonLoc);
626 }
Mike Stump11289f42009-09-09 15:08:12 +0000627
Douglas Gregorebe10102009-08-20 07:17:43 +0000628 /// \brief Attach the body to a new case statement.
629 ///
630 /// By default, performs semantic analysis to build the new statement.
631 /// Subclasses may override this routine to provide different behavior.
632 OwningStmtResult RebuildCaseStmtBody(StmtArg S, StmtArg Body) {
633 getSema().ActOnCaseStmtBody(S.get(), move(Body));
634 return move(S);
635 }
Mike Stump11289f42009-09-09 15:08:12 +0000636
Douglas Gregorebe10102009-08-20 07:17:43 +0000637 /// \brief Build a new default statement.
638 ///
639 /// By default, performs semantic analysis to build the new statement.
640 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000641 OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000642 SourceLocation ColonLoc,
643 StmtArg SubStmt) {
Mike Stump11289f42009-09-09 15:08:12 +0000644 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
Douglas Gregorebe10102009-08-20 07:17:43 +0000645 /*CurScope=*/0);
646 }
Mike Stump11289f42009-09-09 15:08:12 +0000647
Douglas Gregorebe10102009-08-20 07:17:43 +0000648 /// \brief Build a new label statement.
649 ///
650 /// By default, performs semantic analysis to build the new statement.
651 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000652 OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000653 IdentifierInfo *Id,
654 SourceLocation ColonLoc,
655 StmtArg SubStmt) {
656 return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
657 }
Mike Stump11289f42009-09-09 15:08:12 +0000658
Douglas Gregorebe10102009-08-20 07:17:43 +0000659 /// \brief Build a new "if" statement.
660 ///
661 /// By default, performs semantic analysis to build the new statement.
662 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000663 OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
664 StmtArg Then, SourceLocation ElseLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000665 StmtArg Else) {
666 return getSema().ActOnIfStmt(IfLoc, Cond, move(Then), ElseLoc, move(Else));
667 }
Mike Stump11289f42009-09-09 15:08:12 +0000668
Douglas Gregorebe10102009-08-20 07:17:43 +0000669 /// \brief Start building a new switch statement.
670 ///
671 /// By default, performs semantic analysis to build the new statement.
672 /// Subclasses may override this routine to provide different behavior.
673 OwningStmtResult RebuildSwitchStmtStart(ExprArg Cond) {
674 return getSema().ActOnStartOfSwitchStmt(move(Cond));
675 }
Mike Stump11289f42009-09-09 15:08:12 +0000676
Douglas Gregorebe10102009-08-20 07:17:43 +0000677 /// \brief Attach the body to the switch statement.
678 ///
679 /// By default, performs semantic analysis to build the new statement.
680 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000681 OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000682 StmtArg Switch, StmtArg Body) {
683 return getSema().ActOnFinishSwitchStmt(SwitchLoc, move(Switch),
684 move(Body));
685 }
686
687 /// \brief Build a new while statement.
688 ///
689 /// By default, performs semantic analysis to build the new statement.
690 /// Subclasses may override this routine to provide different behavior.
691 OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc,
692 Sema::FullExprArg Cond,
693 StmtArg Body) {
694 return getSema().ActOnWhileStmt(WhileLoc, Cond, move(Body));
695 }
Mike Stump11289f42009-09-09 15:08:12 +0000696
Douglas Gregorebe10102009-08-20 07:17:43 +0000697 /// \brief Build a new do-while statement.
698 ///
699 /// By default, performs semantic analysis to build the new statement.
700 /// Subclasses may override this routine to provide different behavior.
701 OwningStmtResult RebuildDoStmt(SourceLocation DoLoc, StmtArg Body,
702 SourceLocation WhileLoc,
703 SourceLocation LParenLoc,
704 ExprArg Cond,
705 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +0000706 return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000707 move(Cond), RParenLoc);
708 }
709
710 /// \brief Build a new for statement.
711 ///
712 /// By default, performs semantic analysis to build the new statement.
713 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000714 OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000715 SourceLocation LParenLoc,
716 StmtArg Init, ExprArg Cond, ExprArg Inc,
717 SourceLocation RParenLoc, StmtArg Body) {
Mike Stump11289f42009-09-09 15:08:12 +0000718 return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), move(Cond),
Douglas Gregorebe10102009-08-20 07:17:43 +0000719 move(Inc), RParenLoc, move(Body));
720 }
Mike Stump11289f42009-09-09 15:08:12 +0000721
Douglas Gregorebe10102009-08-20 07:17:43 +0000722 /// \brief Build a new goto statement.
723 ///
724 /// By default, performs semantic analysis to build the new statement.
725 /// Subclasses may override this routine to provide different behavior.
726 OwningStmtResult RebuildGotoStmt(SourceLocation GotoLoc,
727 SourceLocation LabelLoc,
728 LabelStmt *Label) {
729 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
730 }
731
732 /// \brief Build a new indirect goto statement.
733 ///
734 /// By default, performs semantic analysis to build the new statement.
735 /// Subclasses may override this routine to provide different behavior.
736 OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
737 SourceLocation StarLoc,
738 ExprArg Target) {
739 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
740 }
Mike Stump11289f42009-09-09 15:08:12 +0000741
Douglas Gregorebe10102009-08-20 07:17:43 +0000742 /// \brief Build a new return statement.
743 ///
744 /// By default, performs semantic analysis to build the new statement.
745 /// Subclasses may override this routine to provide different behavior.
746 OwningStmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
747 ExprArg Result) {
Mike Stump11289f42009-09-09 15:08:12 +0000748
Douglas Gregorebe10102009-08-20 07:17:43 +0000749 return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
750 }
Mike Stump11289f42009-09-09 15:08:12 +0000751
Douglas Gregorebe10102009-08-20 07:17:43 +0000752 /// \brief Build a new declaration statement.
753 ///
754 /// By default, performs semantic analysis to build the new statement.
755 /// Subclasses may override this routine to provide different behavior.
756 OwningStmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
Mike Stump11289f42009-09-09 15:08:12 +0000757 SourceLocation StartLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000758 SourceLocation EndLoc) {
759 return getSema().Owned(
760 new (getSema().Context) DeclStmt(
761 DeclGroupRef::Create(getSema().Context,
762 Decls, NumDecls),
763 StartLoc, EndLoc));
764 }
Mike Stump11289f42009-09-09 15:08:12 +0000765
Douglas Gregorebe10102009-08-20 07:17:43 +0000766 /// \brief Build a new C++ exception declaration.
767 ///
768 /// By default, performs semantic analysis to build the new decaration.
769 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000770 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
Douglas Gregorebe10102009-08-20 07:17:43 +0000771 DeclaratorInfo *Declarator,
772 IdentifierInfo *Name,
773 SourceLocation Loc,
774 SourceRange TypeRange) {
Mike Stump11289f42009-09-09 15:08:12 +0000775 return getSema().BuildExceptionDeclaration(0, T, Declarator, Name, Loc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000776 TypeRange);
777 }
778
779 /// \brief Build a new C++ catch statement.
780 ///
781 /// By default, performs semantic analysis to build the new statement.
782 /// Subclasses may override this routine to provide different behavior.
783 OwningStmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
784 VarDecl *ExceptionDecl,
785 StmtArg Handler) {
786 return getSema().Owned(
Mike Stump11289f42009-09-09 15:08:12 +0000787 new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
Douglas Gregorebe10102009-08-20 07:17:43 +0000788 Handler.takeAs<Stmt>()));
789 }
Mike Stump11289f42009-09-09 15:08:12 +0000790
Douglas Gregorebe10102009-08-20 07:17:43 +0000791 /// \brief Build a new C++ try statement.
792 ///
793 /// By default, performs semantic analysis to build the new statement.
794 /// Subclasses may override this routine to provide different behavior.
795 OwningStmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
796 StmtArg TryBlock,
797 MultiStmtArg Handlers) {
798 return getSema().ActOnCXXTryBlock(TryLoc, move(TryBlock), move(Handlers));
799 }
Mike Stump11289f42009-09-09 15:08:12 +0000800
Douglas Gregora16548e2009-08-11 05:31:07 +0000801 /// \brief Build a new expression that references a declaration.
802 ///
803 /// By default, performs semantic analysis to build the new expression.
804 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor4bd90e52009-10-23 18:54:35 +0000805 OwningExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
806 SourceRange QualifierRange,
807 NamedDecl *ND, SourceLocation Loc) {
808 CXXScopeSpec SS;
809 SS.setScopeRep(Qualifier);
810 SS.setRange(QualifierRange);
Douglas Gregora16548e2009-08-11 05:31:07 +0000811 return getSema().BuildDeclarationNameExpr(Loc, ND,
812 /*FIXME:*/false,
Douglas Gregor4bd90e52009-10-23 18:54:35 +0000813 &SS,
Douglas Gregora16548e2009-08-11 05:31:07 +0000814 /*FIXME:*/false);
815 }
Mike Stump11289f42009-09-09 15:08:12 +0000816
Douglas Gregora16548e2009-08-11 05:31:07 +0000817 /// \brief Build a new expression in parentheses.
Mike Stump11289f42009-09-09 15:08:12 +0000818 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000819 /// By default, performs semantic analysis to build the new expression.
820 /// Subclasses may override this routine to provide different behavior.
821 OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
822 SourceLocation RParen) {
823 return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
824 }
825
Douglas Gregorad8a3362009-09-04 17:36:40 +0000826 /// \brief Build a new pseudo-destructor expression.
Mike Stump11289f42009-09-09 15:08:12 +0000827 ///
Douglas Gregorad8a3362009-09-04 17:36:40 +0000828 /// By default, performs semantic analysis to build the new expression.
829 /// Subclasses may override this routine to provide different behavior.
830 OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
831 SourceLocation OperatorLoc,
832 bool isArrow,
833 SourceLocation DestroyedTypeLoc,
834 QualType DestroyedType,
835 NestedNameSpecifier *Qualifier,
836 SourceRange QualifierRange) {
837 CXXScopeSpec SS;
838 if (Qualifier) {
839 SS.setRange(QualifierRange);
840 SS.setScopeRep(Qualifier);
841 }
842
Mike Stump11289f42009-09-09 15:08:12 +0000843 DeclarationName Name
Douglas Gregorad8a3362009-09-04 17:36:40 +0000844 = SemaRef.Context.DeclarationNames.getCXXDestructorName(
845 SemaRef.Context.getCanonicalType(DestroyedType));
Mike Stump11289f42009-09-09 15:08:12 +0000846
847 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregorad8a3362009-09-04 17:36:40 +0000848 OperatorLoc,
849 isArrow? tok::arrow : tok::period,
850 DestroyedTypeLoc,
851 Name,
852 Sema::DeclPtrTy::make((Decl *)0),
853 &SS);
Mike Stump11289f42009-09-09 15:08:12 +0000854 }
855
Douglas Gregora16548e2009-08-11 05:31:07 +0000856 /// \brief Build a new unary operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000857 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000858 /// By default, performs semantic analysis to build the new expression.
859 /// Subclasses may override this routine to provide different behavior.
860 OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
861 UnaryOperator::Opcode Opc,
862 ExprArg SubExpr) {
863 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(SubExpr));
864 }
Mike Stump11289f42009-09-09 15:08:12 +0000865
Douglas Gregora16548e2009-08-11 05:31:07 +0000866 /// \brief Build a new sizeof or alignof expression with a type argument.
Mike Stump11289f42009-09-09 15:08:12 +0000867 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000868 /// By default, performs semantic analysis to build the new expression.
869 /// Subclasses may override this routine to provide different behavior.
870 OwningExprResult RebuildSizeOfAlignOf(QualType T, SourceLocation OpLoc,
871 bool isSizeOf, SourceRange R) {
872 return getSema().CreateSizeOfAlignOfExpr(T, OpLoc, isSizeOf, R);
873 }
874
Mike Stump11289f42009-09-09 15:08:12 +0000875 /// \brief Build a new sizeof or alignof expression with an expression
Douglas Gregora16548e2009-08-11 05:31:07 +0000876 /// argument.
Mike Stump11289f42009-09-09 15:08:12 +0000877 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000878 /// By default, performs semantic analysis to build the new expression.
879 /// Subclasses may override this routine to provide different behavior.
880 OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
881 bool isSizeOf, SourceRange R) {
Mike Stump11289f42009-09-09 15:08:12 +0000882 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +0000883 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
884 OpLoc, isSizeOf, R);
885 if (Result.isInvalid())
886 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +0000887
Douglas Gregora16548e2009-08-11 05:31:07 +0000888 SubExpr.release();
889 return move(Result);
890 }
Mike Stump11289f42009-09-09 15:08:12 +0000891
Douglas Gregora16548e2009-08-11 05:31:07 +0000892 /// \brief Build a new array subscript expression.
Mike Stump11289f42009-09-09 15:08:12 +0000893 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000894 /// By default, performs semantic analysis to build the new expression.
895 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000896 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
Douglas Gregora16548e2009-08-11 05:31:07 +0000897 SourceLocation LBracketLoc,
898 ExprArg RHS,
899 SourceLocation RBracketLoc) {
900 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
Mike Stump11289f42009-09-09 15:08:12 +0000901 LBracketLoc, move(RHS),
Douglas Gregora16548e2009-08-11 05:31:07 +0000902 RBracketLoc);
903 }
904
905 /// \brief Build a new call expression.
Mike Stump11289f42009-09-09 15:08:12 +0000906 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000907 /// By default, performs semantic analysis to build the new expression.
908 /// Subclasses may override this routine to provide different behavior.
909 OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
910 MultiExprArg Args,
911 SourceLocation *CommaLocs,
912 SourceLocation RParenLoc) {
913 return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
914 move(Args), CommaLocs, RParenLoc);
915 }
916
917 /// \brief Build a new member access expression.
Mike Stump11289f42009-09-09 15:08:12 +0000918 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000919 /// By default, performs semantic analysis to build the new expression.
920 /// Subclasses may override this routine to provide different behavior.
921 OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
Mike Stump11289f42009-09-09 15:08:12 +0000922 bool isArrow,
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000923 NestedNameSpecifier *Qualifier,
924 SourceRange QualifierRange,
925 SourceLocation MemberLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000926 NamedDecl *Member) {
Anders Carlsson5da84842009-09-01 04:26:58 +0000927 if (!Member->getDeclName()) {
928 // We have a reference to an unnamed field.
929 assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
Mike Stump11289f42009-09-09 15:08:12 +0000930
931 MemberExpr *ME =
Anders Carlsson5da84842009-09-01 04:26:58 +0000932 new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
933 Member, MemberLoc,
934 cast<FieldDecl>(Member)->getType());
935 return getSema().Owned(ME);
936 }
Mike Stump11289f42009-09-09 15:08:12 +0000937
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000938 CXXScopeSpec SS;
939 if (Qualifier) {
940 SS.setRange(QualifierRange);
941 SS.setScopeRep(Qualifier);
942 }
943
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000944 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000945 isArrow? tok::arrow : tok::period,
946 MemberLoc,
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000947 Member->getDeclName(),
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000948 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
949 &SS);
Douglas Gregora16548e2009-08-11 05:31:07 +0000950 }
Mike Stump11289f42009-09-09 15:08:12 +0000951
Douglas Gregora16548e2009-08-11 05:31:07 +0000952 /// \brief Build a new binary operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000953 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000954 /// By default, performs semantic analysis to build the new expression.
955 /// Subclasses may override this routine to provide different behavior.
956 OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
957 BinaryOperator::Opcode Opc,
958 ExprArg LHS, ExprArg RHS) {
959 OwningExprResult Result
Mike Stump11289f42009-09-09 15:08:12 +0000960 = getSema().CreateBuiltinBinOp(OpLoc, Opc, (Expr *)LHS.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +0000961 (Expr *)RHS.get());
962 if (Result.isInvalid())
963 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +0000964
Douglas Gregora16548e2009-08-11 05:31:07 +0000965 LHS.release();
966 RHS.release();
967 return move(Result);
968 }
969
970 /// \brief Build a new conditional operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000971 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000972 /// By default, performs semantic analysis to build the new expression.
973 /// Subclasses may override this routine to provide different behavior.
974 OwningExprResult RebuildConditionalOperator(ExprArg Cond,
975 SourceLocation QuestionLoc,
976 ExprArg LHS,
977 SourceLocation ColonLoc,
978 ExprArg RHS) {
Mike Stump11289f42009-09-09 15:08:12 +0000979 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
Douglas Gregora16548e2009-08-11 05:31:07 +0000980 move(LHS), move(RHS));
981 }
982
983 /// \brief Build a new implicit cast expression.
Mike Stump11289f42009-09-09 15:08:12 +0000984 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000985 /// By default, builds a new implicit cast without any semantic analysis.
986 /// Subclasses may override this routine to provide different behavior.
987 OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
988 ExprArg SubExpr, bool isLvalue) {
989 ImplicitCastExpr *ICE
Mike Stump11289f42009-09-09 15:08:12 +0000990 = new (getSema().Context) ImplicitCastExpr(T, Kind,
Douglas Gregora16548e2009-08-11 05:31:07 +0000991 (Expr *)SubExpr.release(),
992 isLvalue);
993 return getSema().Owned(ICE);
994 }
995
996 /// \brief Build a new C-style cast expression.
Mike Stump11289f42009-09-09 15:08:12 +0000997 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000998 /// By default, performs semantic analysis to build the new expression.
999 /// Subclasses may override this routine to provide different behavior.
1000 OwningExprResult RebuildCStyleCaseExpr(SourceLocation LParenLoc,
1001 QualType ExplicitTy,
1002 SourceLocation RParenLoc,
1003 ExprArg SubExpr) {
1004 return getSema().ActOnCastExpr(/*Scope=*/0,
1005 LParenLoc,
1006 ExplicitTy.getAsOpaquePtr(),
1007 RParenLoc,
1008 move(SubExpr));
1009 }
Mike Stump11289f42009-09-09 15:08:12 +00001010
Douglas Gregora16548e2009-08-11 05:31:07 +00001011 /// \brief Build a new compound literal expression.
Mike Stump11289f42009-09-09 15:08:12 +00001012 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001013 /// By default, performs semantic analysis to build the new expression.
1014 /// Subclasses may override this routine to provide different behavior.
1015 OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
1016 QualType T,
1017 SourceLocation RParenLoc,
1018 ExprArg Init) {
1019 return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
1020 RParenLoc, move(Init));
1021 }
Mike Stump11289f42009-09-09 15:08:12 +00001022
Douglas Gregora16548e2009-08-11 05:31:07 +00001023 /// \brief Build a new extended vector element access expression.
Mike Stump11289f42009-09-09 15:08:12 +00001024 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001025 /// By default, performs semantic analysis to build the new expression.
1026 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001027 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
Douglas Gregora16548e2009-08-11 05:31:07 +00001028 SourceLocation OpLoc,
1029 SourceLocation AccessorLoc,
1030 IdentifierInfo &Accessor) {
1031 return getSema().ActOnMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
1032 tok::period, AccessorLoc,
1033 Accessor,
1034 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
1035 }
Mike Stump11289f42009-09-09 15:08:12 +00001036
Douglas Gregora16548e2009-08-11 05:31:07 +00001037 /// \brief Build a new initializer list expression.
Mike Stump11289f42009-09-09 15:08:12 +00001038 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001039 /// By default, performs semantic analysis to build the new expression.
1040 /// Subclasses may override this routine to provide different behavior.
1041 OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
1042 MultiExprArg Inits,
1043 SourceLocation RBraceLoc) {
1044 return SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
1045 }
Mike Stump11289f42009-09-09 15:08:12 +00001046
Douglas Gregora16548e2009-08-11 05:31:07 +00001047 /// \brief Build a new designated initializer expression.
Mike Stump11289f42009-09-09 15:08:12 +00001048 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001049 /// By default, performs semantic analysis to build the new expression.
1050 /// Subclasses may override this routine to provide different behavior.
1051 OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
1052 MultiExprArg ArrayExprs,
1053 SourceLocation EqualOrColonLoc,
1054 bool GNUSyntax,
1055 ExprArg Init) {
1056 OwningExprResult Result
1057 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1058 move(Init));
1059 if (Result.isInvalid())
1060 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001061
Douglas Gregora16548e2009-08-11 05:31:07 +00001062 ArrayExprs.release();
1063 return move(Result);
1064 }
Mike Stump11289f42009-09-09 15:08:12 +00001065
Douglas Gregora16548e2009-08-11 05:31:07 +00001066 /// \brief Build a new value-initialized expression.
Mike Stump11289f42009-09-09 15:08:12 +00001067 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001068 /// By default, builds the implicit value initialization without performing
1069 /// any semantic analysis. Subclasses may override this routine to provide
1070 /// different behavior.
1071 OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
1072 return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1073 }
Mike Stump11289f42009-09-09 15:08:12 +00001074
Douglas Gregora16548e2009-08-11 05:31:07 +00001075 /// \brief Build a new \c va_arg expression.
Mike Stump11289f42009-09-09 15:08:12 +00001076 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001077 /// By default, performs semantic analysis to build the new expression.
1078 /// Subclasses may override this routine to provide different behavior.
1079 OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
1080 QualType T, SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001081 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
Douglas Gregora16548e2009-08-11 05:31:07 +00001082 RParenLoc);
1083 }
1084
1085 /// \brief Build a new expression list in parentheses.
Mike Stump11289f42009-09-09 15:08:12 +00001086 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001087 /// By default, performs semantic analysis to build the new expression.
1088 /// Subclasses may override this routine to provide different behavior.
1089 OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1090 MultiExprArg SubExprs,
1091 SourceLocation RParenLoc) {
1092 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
1093 }
Mike Stump11289f42009-09-09 15:08:12 +00001094
Douglas Gregora16548e2009-08-11 05:31:07 +00001095 /// \brief Build a new address-of-label expression.
Mike Stump11289f42009-09-09 15:08:12 +00001096 ///
1097 /// By default, performs semantic analysis, using the name of the label
Douglas Gregora16548e2009-08-11 05:31:07 +00001098 /// rather than attempting to map the label statement itself.
1099 /// Subclasses may override this routine to provide different behavior.
1100 OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1101 SourceLocation LabelLoc,
1102 LabelStmt *Label) {
1103 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
1104 }
Mike Stump11289f42009-09-09 15:08:12 +00001105
Douglas Gregora16548e2009-08-11 05:31:07 +00001106 /// \brief Build a new GNU statement expression.
Mike Stump11289f42009-09-09 15:08:12 +00001107 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001108 /// By default, performs semantic analysis to build the new expression.
1109 /// Subclasses may override this routine to provide different behavior.
1110 OwningExprResult RebuildStmtExpr(SourceLocation LParenLoc,
1111 StmtArg SubStmt,
1112 SourceLocation RParenLoc) {
1113 return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
1114 }
Mike Stump11289f42009-09-09 15:08:12 +00001115
Douglas Gregora16548e2009-08-11 05:31:07 +00001116 /// \brief Build a new __builtin_types_compatible_p expression.
1117 ///
1118 /// By default, performs semantic analysis to build the new expression.
1119 /// Subclasses may override this routine to provide different behavior.
1120 OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
1121 QualType T1, QualType T2,
1122 SourceLocation RParenLoc) {
1123 return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
1124 T1.getAsOpaquePtr(),
1125 T2.getAsOpaquePtr(),
1126 RParenLoc);
1127 }
Mike Stump11289f42009-09-09 15:08:12 +00001128
Douglas Gregora16548e2009-08-11 05:31:07 +00001129 /// \brief Build a new __builtin_choose_expr expression.
1130 ///
1131 /// By default, performs semantic analysis to build the new expression.
1132 /// Subclasses may override this routine to provide different behavior.
1133 OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1134 ExprArg Cond, ExprArg LHS, ExprArg RHS,
1135 SourceLocation RParenLoc) {
1136 return SemaRef.ActOnChooseExpr(BuiltinLoc,
1137 move(Cond), move(LHS), move(RHS),
1138 RParenLoc);
1139 }
Mike Stump11289f42009-09-09 15:08:12 +00001140
Douglas Gregora16548e2009-08-11 05:31:07 +00001141 /// \brief Build a new overloaded operator call expression.
1142 ///
1143 /// By default, performs semantic analysis to build the new expression.
1144 /// The semantic analysis provides the behavior of template instantiation,
1145 /// copying with transformations that turn what looks like an overloaded
Mike Stump11289f42009-09-09 15:08:12 +00001146 /// operator call into a use of a builtin operator, performing
Douglas Gregora16548e2009-08-11 05:31:07 +00001147 /// argument-dependent lookup, etc. Subclasses may override this routine to
1148 /// provide different behavior.
1149 OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1150 SourceLocation OpLoc,
1151 ExprArg Callee,
1152 ExprArg First,
1153 ExprArg Second);
Mike Stump11289f42009-09-09 15:08:12 +00001154
1155 /// \brief Build a new C++ "named" cast expression, such as static_cast or
Douglas Gregora16548e2009-08-11 05:31:07 +00001156 /// reinterpret_cast.
1157 ///
1158 /// By default, this routine dispatches to one of the more-specific routines
Mike Stump11289f42009-09-09 15:08:12 +00001159 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
Douglas Gregora16548e2009-08-11 05:31:07 +00001160 /// Subclasses may override this routine to provide different behavior.
1161 OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1162 Stmt::StmtClass Class,
1163 SourceLocation LAngleLoc,
1164 QualType T,
1165 SourceLocation RAngleLoc,
1166 SourceLocation LParenLoc,
1167 ExprArg SubExpr,
1168 SourceLocation RParenLoc) {
1169 switch (Class) {
1170 case Stmt::CXXStaticCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001171 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1172 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001173 move(SubExpr), RParenLoc);
1174
1175 case Stmt::CXXDynamicCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001176 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
1177 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001178 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001179
Douglas Gregora16548e2009-08-11 05:31:07 +00001180 case Stmt::CXXReinterpretCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001181 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1182 RAngleLoc, LParenLoc,
1183 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00001184 RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001185
Douglas Gregora16548e2009-08-11 05:31:07 +00001186 case Stmt::CXXConstCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001187 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1188 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001189 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001190
Douglas Gregora16548e2009-08-11 05:31:07 +00001191 default:
1192 assert(false && "Invalid C++ named cast");
1193 break;
1194 }
Mike Stump11289f42009-09-09 15:08:12 +00001195
Douglas Gregora16548e2009-08-11 05:31:07 +00001196 return getSema().ExprError();
1197 }
Mike Stump11289f42009-09-09 15:08:12 +00001198
Douglas Gregora16548e2009-08-11 05:31:07 +00001199 /// \brief Build a new C++ static_cast expression.
1200 ///
1201 /// By default, performs semantic analysis to build the new expression.
1202 /// Subclasses may override this routine to provide different behavior.
1203 OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1204 SourceLocation LAngleLoc,
1205 QualType T,
1206 SourceLocation RAngleLoc,
1207 SourceLocation LParenLoc,
1208 ExprArg SubExpr,
1209 SourceLocation RParenLoc) {
1210 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001211 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001212 LParenLoc, move(SubExpr), RParenLoc);
1213 }
1214
1215 /// \brief Build a new C++ dynamic_cast expression.
1216 ///
1217 /// By default, performs semantic analysis to build the new expression.
1218 /// Subclasses may override this routine to provide different behavior.
1219 OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1220 SourceLocation LAngleLoc,
1221 QualType T,
1222 SourceLocation RAngleLoc,
1223 SourceLocation LParenLoc,
1224 ExprArg SubExpr,
1225 SourceLocation RParenLoc) {
1226 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001227 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001228 LParenLoc, move(SubExpr), RParenLoc);
1229 }
1230
1231 /// \brief Build a new C++ reinterpret_cast expression.
1232 ///
1233 /// By default, performs semantic analysis to build the new expression.
1234 /// Subclasses may override this routine to provide different behavior.
1235 OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1236 SourceLocation LAngleLoc,
1237 QualType T,
1238 SourceLocation RAngleLoc,
1239 SourceLocation LParenLoc,
1240 ExprArg SubExpr,
1241 SourceLocation RParenLoc) {
1242 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1243 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1244 LParenLoc, move(SubExpr), RParenLoc);
1245 }
1246
1247 /// \brief Build a new C++ const_cast expression.
1248 ///
1249 /// By default, performs semantic analysis to build the new expression.
1250 /// Subclasses may override this routine to provide different behavior.
1251 OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1252 SourceLocation LAngleLoc,
1253 QualType T,
1254 SourceLocation RAngleLoc,
1255 SourceLocation LParenLoc,
1256 ExprArg SubExpr,
1257 SourceLocation RParenLoc) {
1258 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001259 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001260 LParenLoc, move(SubExpr), RParenLoc);
1261 }
Mike Stump11289f42009-09-09 15:08:12 +00001262
Douglas Gregora16548e2009-08-11 05:31:07 +00001263 /// \brief Build a new C++ functional-style cast expression.
1264 ///
1265 /// By default, performs semantic analysis to build the new expression.
1266 /// Subclasses may override this routine to provide different behavior.
1267 OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
1268 QualType T,
1269 SourceLocation LParenLoc,
1270 ExprArg SubExpr,
1271 SourceLocation RParenLoc) {
Chris Lattnerdca19592009-08-24 05:19:01 +00001272 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregora16548e2009-08-11 05:31:07 +00001273 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1274 T.getAsOpaquePtr(),
1275 LParenLoc,
Chris Lattnerdca19592009-08-24 05:19:01 +00001276 Sema::MultiExprArg(getSema(), &Sub, 1),
Mike Stump11289f42009-09-09 15:08:12 +00001277 /*CommaLocs=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001278 RParenLoc);
1279 }
Mike Stump11289f42009-09-09 15:08:12 +00001280
Douglas Gregora16548e2009-08-11 05:31:07 +00001281 /// \brief Build a new C++ typeid(type) expression.
1282 ///
1283 /// By default, performs semantic analysis to build the new expression.
1284 /// Subclasses may override this routine to provide different behavior.
1285 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1286 SourceLocation LParenLoc,
1287 QualType T,
1288 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001289 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
Douglas Gregora16548e2009-08-11 05:31:07 +00001290 T.getAsOpaquePtr(), RParenLoc);
1291 }
Mike Stump11289f42009-09-09 15:08:12 +00001292
Douglas Gregora16548e2009-08-11 05:31:07 +00001293 /// \brief Build a new C++ typeid(expr) expression.
1294 ///
1295 /// By default, performs semantic analysis to build the new expression.
1296 /// Subclasses may override this routine to provide different behavior.
1297 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1298 SourceLocation LParenLoc,
1299 ExprArg Operand,
1300 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001301 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00001302 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1303 RParenLoc);
1304 if (Result.isInvalid())
1305 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001306
Douglas Gregora16548e2009-08-11 05:31:07 +00001307 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1308 return move(Result);
Mike Stump11289f42009-09-09 15:08:12 +00001309 }
1310
Douglas Gregora16548e2009-08-11 05:31:07 +00001311 /// \brief Build a new C++ "this" expression.
1312 ///
1313 /// By default, builds a new "this" expression without performing any
Mike Stump11289f42009-09-09 15:08:12 +00001314 /// semantic analysis. Subclasses may override this routine to provide
Douglas Gregora16548e2009-08-11 05:31:07 +00001315 /// different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001316 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001317 QualType ThisType) {
1318 return getSema().Owned(
1319 new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
1320 }
1321
1322 /// \brief Build a new C++ throw expression.
1323 ///
1324 /// By default, performs semantic analysis to build the new expression.
1325 /// Subclasses may override this routine to provide different behavior.
1326 OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
1327 return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
1328 }
1329
1330 /// \brief Build a new C++ default-argument expression.
1331 ///
1332 /// By default, builds a new default-argument expression, which does not
1333 /// require any semantic analysis. Subclasses may override this routine to
1334 /// provide different behavior.
1335 OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
Anders Carlssone8271232009-08-14 18:30:22 +00001336 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregora16548e2009-08-11 05:31:07 +00001337 }
1338
1339 /// \brief Build a new C++ zero-initialization expression.
1340 ///
1341 /// By default, performs semantic analysis to build the new expression.
1342 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001343 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001344 SourceLocation LParenLoc,
1345 QualType T,
1346 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001347 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1348 T.getAsOpaquePtr(), LParenLoc,
1349 MultiExprArg(getSema(), 0, 0),
Douglas Gregora16548e2009-08-11 05:31:07 +00001350 0, RParenLoc);
1351 }
Mike Stump11289f42009-09-09 15:08:12 +00001352
Douglas Gregora16548e2009-08-11 05:31:07 +00001353 /// \brief Build a new C++ conditional declaration expression.
1354 ///
1355 /// By default, performs semantic analysis to build the new expression.
1356 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001357 OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001358 SourceLocation EqLoc,
1359 VarDecl *Var) {
1360 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(StartLoc,
1361 EqLoc,
1362 Var));
1363 }
Mike Stump11289f42009-09-09 15:08:12 +00001364
Douglas Gregora16548e2009-08-11 05:31:07 +00001365 /// \brief Build a new C++ "new" expression.
1366 ///
1367 /// By default, performs semantic analysis to build the new expression.
1368 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001369 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001370 bool UseGlobal,
1371 SourceLocation PlacementLParen,
1372 MultiExprArg PlacementArgs,
1373 SourceLocation PlacementRParen,
Mike Stump11289f42009-09-09 15:08:12 +00001374 bool ParenTypeId,
Douglas Gregora16548e2009-08-11 05:31:07 +00001375 QualType AllocType,
1376 SourceLocation TypeLoc,
1377 SourceRange TypeRange,
1378 ExprArg ArraySize,
1379 SourceLocation ConstructorLParen,
1380 MultiExprArg ConstructorArgs,
1381 SourceLocation ConstructorRParen) {
Mike Stump11289f42009-09-09 15:08:12 +00001382 return getSema().BuildCXXNew(StartLoc, UseGlobal,
Douglas Gregora16548e2009-08-11 05:31:07 +00001383 PlacementLParen,
1384 move(PlacementArgs),
1385 PlacementRParen,
1386 ParenTypeId,
1387 AllocType,
1388 TypeLoc,
1389 TypeRange,
1390 move(ArraySize),
1391 ConstructorLParen,
1392 move(ConstructorArgs),
1393 ConstructorRParen);
1394 }
Mike Stump11289f42009-09-09 15:08:12 +00001395
Douglas Gregora16548e2009-08-11 05:31:07 +00001396 /// \brief Build a new C++ "delete" expression.
1397 ///
1398 /// By default, performs semantic analysis to build the new expression.
1399 /// Subclasses may override this routine to provide different behavior.
1400 OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
1401 bool IsGlobalDelete,
1402 bool IsArrayForm,
1403 ExprArg Operand) {
1404 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
1405 move(Operand));
1406 }
Mike Stump11289f42009-09-09 15:08:12 +00001407
Douglas Gregora16548e2009-08-11 05:31:07 +00001408 /// \brief Build a new unary type trait expression.
1409 ///
1410 /// By default, performs semantic analysis to build the new expression.
1411 /// Subclasses may override this routine to provide different behavior.
1412 OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
1413 SourceLocation StartLoc,
1414 SourceLocation LParenLoc,
1415 QualType T,
1416 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001417 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001418 T.getAsOpaquePtr(), RParenLoc);
1419 }
1420
Mike Stump11289f42009-09-09 15:08:12 +00001421 /// \brief Build a new (previously unresolved) declaration reference
Douglas Gregora16548e2009-08-11 05:31:07 +00001422 /// expression.
1423 ///
1424 /// By default, performs semantic analysis to build the new expression.
1425 /// Subclasses may override this routine to provide different behavior.
1426 OwningExprResult RebuildUnresolvedDeclRefExpr(NestedNameSpecifier *NNS,
1427 SourceRange QualifierRange,
1428 DeclarationName Name,
1429 SourceLocation Location,
1430 bool IsAddressOfOperand) {
1431 CXXScopeSpec SS;
1432 SS.setRange(QualifierRange);
1433 SS.setScopeRep(NNS);
Mike Stump11289f42009-09-09 15:08:12 +00001434 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001435 Location,
1436 Name,
1437 /*Trailing lparen=*/false,
1438 &SS,
1439 IsAddressOfOperand);
1440 }
1441
1442 /// \brief Build a new template-id expression.
1443 ///
1444 /// By default, performs semantic analysis to build the new expression.
1445 /// Subclasses may override this routine to provide different behavior.
Douglas Gregord019ff62009-10-22 17:20:55 +00001446 OwningExprResult RebuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
1447 SourceRange QualifierRange,
1448 TemplateName Template,
Douglas Gregora16548e2009-08-11 05:31:07 +00001449 SourceLocation TemplateLoc,
1450 SourceLocation LAngleLoc,
John McCall0ad16662009-10-29 08:12:44 +00001451 TemplateArgumentLoc *TemplateArgs,
Douglas Gregora16548e2009-08-11 05:31:07 +00001452 unsigned NumTemplateArgs,
1453 SourceLocation RAngleLoc) {
Douglas Gregord019ff62009-10-22 17:20:55 +00001454 return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
1455 Template, TemplateLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001456 LAngleLoc,
1457 TemplateArgs, NumTemplateArgs,
1458 RAngleLoc);
1459 }
1460
1461 /// \brief Build a new object-construction expression.
1462 ///
1463 /// By default, performs semantic analysis to build the new expression.
1464 /// Subclasses may override this routine to provide different behavior.
1465 OwningExprResult RebuildCXXConstructExpr(QualType T,
1466 CXXConstructorDecl *Constructor,
1467 bool IsElidable,
1468 MultiExprArg Args) {
Anders Carlsson1b4ebfa2009-09-05 07:40:38 +00001469 return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/
1470 SourceLocation(),
1471 T, Constructor, IsElidable,
Anders Carlsson5995a3e2009-09-07 22:23:31 +00001472 move(Args));
Douglas Gregora16548e2009-08-11 05:31:07 +00001473 }
1474
1475 /// \brief Build a new object-construction expression.
1476 ///
1477 /// By default, performs semantic analysis to build the new expression.
1478 /// Subclasses may override this routine to provide different behavior.
1479 OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
1480 QualType T,
1481 SourceLocation LParenLoc,
1482 MultiExprArg Args,
1483 SourceLocation *Commas,
1484 SourceLocation RParenLoc) {
1485 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
1486 T.getAsOpaquePtr(),
1487 LParenLoc,
1488 move(Args),
1489 Commas,
1490 RParenLoc);
1491 }
1492
1493 /// \brief Build a new object-construction expression.
1494 ///
1495 /// By default, performs semantic analysis to build the new expression.
1496 /// Subclasses may override this routine to provide different behavior.
1497 OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
1498 QualType T,
1499 SourceLocation LParenLoc,
1500 MultiExprArg Args,
1501 SourceLocation *Commas,
1502 SourceLocation RParenLoc) {
1503 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
1504 /*FIXME*/LParenLoc),
1505 T.getAsOpaquePtr(),
1506 LParenLoc,
1507 move(Args),
1508 Commas,
1509 RParenLoc);
1510 }
Mike Stump11289f42009-09-09 15:08:12 +00001511
Douglas Gregora16548e2009-08-11 05:31:07 +00001512 /// \brief Build a new member reference expression.
1513 ///
1514 /// By default, performs semantic analysis to build the new expression.
1515 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001516 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
Douglas Gregora16548e2009-08-11 05:31:07 +00001517 bool IsArrow,
1518 SourceLocation OperatorLoc,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001519 NestedNameSpecifier *Qualifier,
1520 SourceRange QualifierRange,
Douglas Gregora16548e2009-08-11 05:31:07 +00001521 DeclarationName Name,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001522 SourceLocation MemberLoc,
1523 NamedDecl *FirstQualifierInScope) {
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001524 OwningExprResult Base = move(BaseE);
Douglas Gregora16548e2009-08-11 05:31:07 +00001525 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001526
Douglas Gregora16548e2009-08-11 05:31:07 +00001527 CXXScopeSpec SS;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001528 SS.setRange(QualifierRange);
1529 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001530
Douglas Gregor308047d2009-09-09 00:23:06 +00001531 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001532 move(Base), OperatorLoc, OpKind,
Douglas Gregorf14b46f2009-08-31 20:00:26 +00001533 MemberLoc,
1534 Name,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001535 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001536 &SS,
1537 FirstQualifierInScope);
Douglas Gregora16548e2009-08-11 05:31:07 +00001538 }
1539
Douglas Gregor308047d2009-09-09 00:23:06 +00001540 /// \brief Build a new member reference expression with explicit template
1541 /// arguments.
1542 ///
1543 /// By default, performs semantic analysis to build the new expression.
1544 /// Subclasses may override this routine to provide different behavior.
1545 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
1546 bool IsArrow,
1547 SourceLocation OperatorLoc,
1548 NestedNameSpecifier *Qualifier,
1549 SourceRange QualifierRange,
1550 TemplateName Template,
1551 SourceLocation TemplateNameLoc,
1552 NamedDecl *FirstQualifierInScope,
1553 SourceLocation LAngleLoc,
John McCall0ad16662009-10-29 08:12:44 +00001554 const TemplateArgumentLoc *TemplateArgs,
Douglas Gregor308047d2009-09-09 00:23:06 +00001555 unsigned NumTemplateArgs,
1556 SourceLocation RAngleLoc) {
1557 OwningExprResult Base = move(BaseE);
1558 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Mike Stump11289f42009-09-09 15:08:12 +00001559
Douglas Gregor308047d2009-09-09 00:23:06 +00001560 CXXScopeSpec SS;
1561 SS.setRange(QualifierRange);
1562 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001563
Douglas Gregor308047d2009-09-09 00:23:06 +00001564 // FIXME: We're going to end up looking up the template based on its name,
1565 // twice! Also, duplicates part of Sema::ActOnMemberTemplateIdReferenceExpr.
1566 DeclarationName Name;
1567 if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
1568 Name = ActualTemplate->getDeclName();
Mike Stump11289f42009-09-09 15:08:12 +00001569 else if (OverloadedFunctionDecl *Ovl
Douglas Gregor308047d2009-09-09 00:23:06 +00001570 = Template.getAsOverloadedFunctionDecl())
1571 Name = Ovl->getDeclName();
1572 else
1573 Name = Template.getAsDependentTemplateName()->getName();
Mike Stump11289f42009-09-09 15:08:12 +00001574
1575 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregor308047d2009-09-09 00:23:06 +00001576 OperatorLoc, OpKind,
1577 TemplateNameLoc, Name, true,
1578 LAngleLoc, TemplateArgs,
1579 NumTemplateArgs, RAngleLoc,
1580 Sema::DeclPtrTy(), &SS);
1581 }
Mike Stump11289f42009-09-09 15:08:12 +00001582
Douglas Gregora16548e2009-08-11 05:31:07 +00001583 /// \brief Build a new Objective-C @encode expression.
1584 ///
1585 /// By default, performs semantic analysis to build the new expression.
1586 /// Subclasses may override this routine to provide different behavior.
1587 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1588 QualType T,
1589 SourceLocation RParenLoc) {
1590 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1591 RParenLoc));
Mike Stump11289f42009-09-09 15:08:12 +00001592 }
Douglas Gregora16548e2009-08-11 05:31:07 +00001593
1594 /// \brief Build a new Objective-C protocol expression.
1595 ///
1596 /// By default, performs semantic analysis to build the new expression.
1597 /// Subclasses may override this routine to provide different behavior.
1598 OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1599 SourceLocation AtLoc,
1600 SourceLocation ProtoLoc,
1601 SourceLocation LParenLoc,
1602 SourceLocation RParenLoc) {
1603 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1604 Protocol->getIdentifier(),
1605 AtLoc,
1606 ProtoLoc,
1607 LParenLoc,
Mike Stump11289f42009-09-09 15:08:12 +00001608 RParenLoc));
Douglas Gregora16548e2009-08-11 05:31:07 +00001609 }
Mike Stump11289f42009-09-09 15:08:12 +00001610
Douglas Gregora16548e2009-08-11 05:31:07 +00001611 /// \brief Build a new shuffle vector expression.
1612 ///
1613 /// By default, performs semantic analysis to build the new expression.
1614 /// Subclasses may override this routine to provide different behavior.
1615 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1616 MultiExprArg SubExprs,
1617 SourceLocation RParenLoc) {
1618 // Find the declaration for __builtin_shufflevector
Mike Stump11289f42009-09-09 15:08:12 +00001619 const IdentifierInfo &Name
Douglas Gregora16548e2009-08-11 05:31:07 +00001620 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1621 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1622 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1623 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
Mike Stump11289f42009-09-09 15:08:12 +00001624
Douglas Gregora16548e2009-08-11 05:31:07 +00001625 // Build a reference to the __builtin_shufflevector builtin
1626 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Mike Stump11289f42009-09-09 15:08:12 +00001627 Expr *Callee
Douglas Gregora16548e2009-08-11 05:31:07 +00001628 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1629 BuiltinLoc, false, false);
1630 SemaRef.UsualUnaryConversions(Callee);
Mike Stump11289f42009-09-09 15:08:12 +00001631
1632 // Build the CallExpr
Douglas Gregora16548e2009-08-11 05:31:07 +00001633 unsigned NumSubExprs = SubExprs.size();
1634 Expr **Subs = (Expr **)SubExprs.release();
1635 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1636 Subs, NumSubExprs,
1637 Builtin->getResultType(),
1638 RParenLoc);
1639 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
Mike Stump11289f42009-09-09 15:08:12 +00001640
Douglas Gregora16548e2009-08-11 05:31:07 +00001641 // Type-check the __builtin_shufflevector expression.
1642 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1643 if (Result.isInvalid())
1644 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001645
Douglas Gregora16548e2009-08-11 05:31:07 +00001646 OwnedCall.release();
Mike Stump11289f42009-09-09 15:08:12 +00001647 return move(Result);
Douglas Gregora16548e2009-08-11 05:31:07 +00001648 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00001649};
Douglas Gregora16548e2009-08-11 05:31:07 +00001650
Douglas Gregorebe10102009-08-20 07:17:43 +00001651template<typename Derived>
1652Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1653 if (!S)
1654 return SemaRef.Owned(S);
Mike Stump11289f42009-09-09 15:08:12 +00001655
Douglas Gregorebe10102009-08-20 07:17:43 +00001656 switch (S->getStmtClass()) {
1657 case Stmt::NoStmtClass: break;
Mike Stump11289f42009-09-09 15:08:12 +00001658
Douglas Gregorebe10102009-08-20 07:17:43 +00001659 // Transform individual statement nodes
1660#define STMT(Node, Parent) \
1661 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1662#define EXPR(Node, Parent)
1663#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001664
Douglas Gregorebe10102009-08-20 07:17:43 +00001665 // Transform expressions by calling TransformExpr.
1666#define STMT(Node, Parent)
1667#define EXPR(Node, Parent) case Stmt::Node##Class:
1668#include "clang/AST/StmtNodes.def"
1669 {
1670 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1671 if (E.isInvalid())
1672 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00001673
Douglas Gregorebe10102009-08-20 07:17:43 +00001674 return getSema().Owned(E.takeAs<Stmt>());
1675 }
Mike Stump11289f42009-09-09 15:08:12 +00001676 }
1677
Douglas Gregorebe10102009-08-20 07:17:43 +00001678 return SemaRef.Owned(S->Retain());
1679}
Mike Stump11289f42009-09-09 15:08:12 +00001680
1681
Douglas Gregore922c772009-08-04 22:27:00 +00001682template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00001683Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1684 bool isAddressOfOperand) {
1685 if (!E)
1686 return SemaRef.Owned(E);
1687
1688 switch (E->getStmtClass()) {
1689 case Stmt::NoStmtClass: break;
1690#define STMT(Node, Parent) case Stmt::Node##Class: break;
1691#define EXPR(Node, Parent) \
1692 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
1693#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001694 }
1695
Douglas Gregora16548e2009-08-11 05:31:07 +00001696 return SemaRef.Owned(E->Retain());
Douglas Gregor766b0bb2009-08-06 22:17:10 +00001697}
1698
1699template<typename Derived>
Douglas Gregor1135c352009-08-06 05:28:30 +00001700NestedNameSpecifier *
1701TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001702 SourceRange Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001703 QualType ObjectType,
1704 NamedDecl *FirstQualifierInScope) {
Douglas Gregor96ee7892009-08-31 21:41:48 +00001705 if (!NNS)
1706 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001707
Douglas Gregorebe10102009-08-20 07:17:43 +00001708 // Transform the prefix of this nested name specifier.
Douglas Gregor1135c352009-08-06 05:28:30 +00001709 NestedNameSpecifier *Prefix = NNS->getPrefix();
1710 if (Prefix) {
Mike Stump11289f42009-09-09 15:08:12 +00001711 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001712 ObjectType,
1713 FirstQualifierInScope);
Douglas Gregor1135c352009-08-06 05:28:30 +00001714 if (!Prefix)
1715 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001716
1717 // Clear out the object type and the first qualifier in scope; they only
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001718 // apply to the first element in the nested-name-specifier.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001719 ObjectType = QualType();
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001720 FirstQualifierInScope = 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001721 }
Mike Stump11289f42009-09-09 15:08:12 +00001722
Douglas Gregor1135c352009-08-06 05:28:30 +00001723 switch (NNS->getKind()) {
1724 case NestedNameSpecifier::Identifier:
Mike Stump11289f42009-09-09 15:08:12 +00001725 assert((Prefix || !ObjectType.isNull()) &&
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001726 "Identifier nested-name-specifier with no prefix or object type");
1727 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
1728 ObjectType.isNull())
Douglas Gregor1135c352009-08-06 05:28:30 +00001729 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001730
1731 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001732 *NNS->getAsIdentifier(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001733 ObjectType,
1734 FirstQualifierInScope);
Mike Stump11289f42009-09-09 15:08:12 +00001735
Douglas Gregor1135c352009-08-06 05:28:30 +00001736 case NestedNameSpecifier::Namespace: {
Mike Stump11289f42009-09-09 15:08:12 +00001737 NamespaceDecl *NS
Douglas Gregor1135c352009-08-06 05:28:30 +00001738 = cast_or_null<NamespaceDecl>(
1739 getDerived().TransformDecl(NNS->getAsNamespace()));
Mike Stump11289f42009-09-09 15:08:12 +00001740 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor1135c352009-08-06 05:28:30 +00001741 Prefix == NNS->getPrefix() &&
1742 NS == NNS->getAsNamespace())
1743 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001744
Douglas Gregor1135c352009-08-06 05:28:30 +00001745 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1746 }
Mike Stump11289f42009-09-09 15:08:12 +00001747
Douglas Gregor1135c352009-08-06 05:28:30 +00001748 case NestedNameSpecifier::Global:
1749 // There is no meaningful transformation that one could perform on the
1750 // global scope.
1751 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001752
Douglas Gregor1135c352009-08-06 05:28:30 +00001753 case NestedNameSpecifier::TypeSpecWithTemplate:
1754 case NestedNameSpecifier::TypeSpec: {
Douglas Gregor07cc4ac2009-10-29 22:21:39 +00001755 TemporaryBase Rebase(*this, Range.getBegin(), DeclarationName());
Douglas Gregor1135c352009-08-06 05:28:30 +00001756 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregor71dc5092009-08-06 06:41:21 +00001757 if (T.isNull())
1758 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001759
Douglas Gregor1135c352009-08-06 05:28:30 +00001760 if (!getDerived().AlwaysRebuild() &&
1761 Prefix == NNS->getPrefix() &&
1762 T == QualType(NNS->getAsType(), 0))
1763 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001764
1765 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1766 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
Douglas Gregor1135c352009-08-06 05:28:30 +00001767 T);
1768 }
1769 }
Mike Stump11289f42009-09-09 15:08:12 +00001770
Douglas Gregor1135c352009-08-06 05:28:30 +00001771 // Required to silence a GCC warning
Mike Stump11289f42009-09-09 15:08:12 +00001772 return 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001773}
1774
1775template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001776DeclarationName
Douglas Gregorf816bd72009-09-03 22:13:48 +00001777TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
Douglas Gregorc59e5612009-10-19 22:04:39 +00001778 SourceLocation Loc,
1779 QualType ObjectType) {
Douglas Gregorf816bd72009-09-03 22:13:48 +00001780 if (!Name)
1781 return Name;
1782
1783 switch (Name.getNameKind()) {
1784 case DeclarationName::Identifier:
1785 case DeclarationName::ObjCZeroArgSelector:
1786 case DeclarationName::ObjCOneArgSelector:
1787 case DeclarationName::ObjCMultiArgSelector:
1788 case DeclarationName::CXXOperatorName:
1789 case DeclarationName::CXXUsingDirective:
1790 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001791
Douglas Gregorf816bd72009-09-03 22:13:48 +00001792 case DeclarationName::CXXConstructorName:
1793 case DeclarationName::CXXDestructorName:
1794 case DeclarationName::CXXConversionFunctionName: {
1795 TemporaryBase Rebase(*this, Loc, Name);
Douglas Gregorc59e5612009-10-19 22:04:39 +00001796 QualType T;
1797 if (!ObjectType.isNull() &&
1798 isa<TemplateSpecializationType>(Name.getCXXNameType())) {
1799 TemplateSpecializationType *SpecType
1800 = cast<TemplateSpecializationType>(Name.getCXXNameType());
1801 T = TransformTemplateSpecializationType(SpecType, ObjectType);
1802 } else
1803 T = getDerived().TransformType(Name.getCXXNameType());
Douglas Gregorf816bd72009-09-03 22:13:48 +00001804 if (T.isNull())
1805 return DeclarationName();
Mike Stump11289f42009-09-09 15:08:12 +00001806
Douglas Gregorf816bd72009-09-03 22:13:48 +00001807 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
Mike Stump11289f42009-09-09 15:08:12 +00001808 Name.getNameKind(),
Douglas Gregorf816bd72009-09-03 22:13:48 +00001809 SemaRef.Context.getCanonicalType(T));
Douglas Gregorf816bd72009-09-03 22:13:48 +00001810 }
Mike Stump11289f42009-09-09 15:08:12 +00001811 }
1812
Douglas Gregorf816bd72009-09-03 22:13:48 +00001813 return DeclarationName();
1814}
1815
1816template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001817TemplateName
Douglas Gregor308047d2009-09-09 00:23:06 +00001818TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
1819 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00001820 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001821 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001822 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1823 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1824 if (!NNS)
1825 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001826
Douglas Gregor71dc5092009-08-06 06:41:21 +00001827 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001828 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001829 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1830 if (!TransTemplate)
1831 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001832
Douglas Gregor71dc5092009-08-06 06:41:21 +00001833 if (!getDerived().AlwaysRebuild() &&
1834 NNS == QTN->getQualifier() &&
1835 TransTemplate == Template)
1836 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001837
Douglas Gregor71dc5092009-08-06 06:41:21 +00001838 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1839 TransTemplate);
1840 }
Mike Stump11289f42009-09-09 15:08:12 +00001841
Douglas Gregor71dc5092009-08-06 06:41:21 +00001842 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1843 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001844 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001845 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1846 if (!TransOvl)
1847 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001848
Douglas Gregor71dc5092009-08-06 06:41:21 +00001849 if (!getDerived().AlwaysRebuild() &&
1850 NNS == QTN->getQualifier() &&
1851 TransOvl == Ovl)
1852 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001853
Douglas Gregor71dc5092009-08-06 06:41:21 +00001854 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1855 TransOvl);
1856 }
Mike Stump11289f42009-09-09 15:08:12 +00001857
Douglas Gregor71dc5092009-08-06 06:41:21 +00001858 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001859 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001860 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1861 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
Douglas Gregor308047d2009-09-09 00:23:06 +00001862 if (!NNS && DTN->getQualifier())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001863 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001864
Douglas Gregor71dc5092009-08-06 06:41:21 +00001865 if (!getDerived().AlwaysRebuild() &&
Douglas Gregorc59e5612009-10-19 22:04:39 +00001866 NNS == DTN->getQualifier() &&
1867 ObjectType.isNull())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001868 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001869
Douglas Gregor308047d2009-09-09 00:23:06 +00001870 return getDerived().RebuildTemplateName(NNS, *DTN->getName(), ObjectType);
Douglas Gregor71dc5092009-08-06 06:41:21 +00001871 }
Mike Stump11289f42009-09-09 15:08:12 +00001872
Douglas Gregor71dc5092009-08-06 06:41:21 +00001873 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001874 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001875 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1876 if (!TransTemplate)
1877 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001878
Douglas Gregor71dc5092009-08-06 06:41:21 +00001879 if (!getDerived().AlwaysRebuild() &&
1880 TransTemplate == Template)
1881 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001882
Douglas Gregor71dc5092009-08-06 06:41:21 +00001883 return TemplateName(TransTemplate);
1884 }
Mike Stump11289f42009-09-09 15:08:12 +00001885
Douglas Gregor71dc5092009-08-06 06:41:21 +00001886 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1887 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001888 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001889 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1890 if (!TransOvl)
1891 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001892
Douglas Gregor71dc5092009-08-06 06:41:21 +00001893 if (!getDerived().AlwaysRebuild() &&
1894 TransOvl == Ovl)
1895 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001896
Douglas Gregor71dc5092009-08-06 06:41:21 +00001897 return TemplateName(TransOvl);
1898}
1899
1900template<typename Derived>
John McCall0ad16662009-10-29 08:12:44 +00001901void TreeTransform<Derived>::InventTemplateArgumentLoc(
1902 const TemplateArgument &Arg,
1903 TemplateArgumentLoc &Output) {
1904 SourceLocation Loc = getDerived().getBaseLocation();
1905 switch (Arg.getKind()) {
1906 case TemplateArgument::Null:
1907 llvm::llvm_unreachable("null template argument in TreeTransform");
1908 break;
1909
1910 case TemplateArgument::Type:
1911 Output = TemplateArgumentLoc(Arg,
1912 SemaRef.Context.getTrivialDeclaratorInfo(Arg.getAsType(), Loc));
1913
1914 break;
1915
1916 case TemplateArgument::Expression:
1917 Output = TemplateArgumentLoc(Arg, Arg.getAsExpr());
1918 break;
1919
1920 case TemplateArgument::Declaration:
1921 case TemplateArgument::Integral:
1922 case TemplateArgument::Pack:
John McCall0d07eb32009-10-29 18:45:58 +00001923 Output = TemplateArgumentLoc(Arg, TemplateArgumentLocInfo());
John McCall0ad16662009-10-29 08:12:44 +00001924 break;
1925 }
1926}
1927
1928template<typename Derived>
1929bool TreeTransform<Derived>::TransformTemplateArgument(
1930 const TemplateArgumentLoc &Input,
1931 TemplateArgumentLoc &Output) {
1932 const TemplateArgument &Arg = Input.getArgument();
Douglas Gregore922c772009-08-04 22:27:00 +00001933 switch (Arg.getKind()) {
1934 case TemplateArgument::Null:
1935 case TemplateArgument::Integral:
John McCall0ad16662009-10-29 08:12:44 +00001936 Output = Input;
1937 return false;
Mike Stump11289f42009-09-09 15:08:12 +00001938
Douglas Gregore922c772009-08-04 22:27:00 +00001939 case TemplateArgument::Type: {
John McCall0ad16662009-10-29 08:12:44 +00001940 DeclaratorInfo *DI = Input.getSourceDeclaratorInfo();
1941 if (DI == NULL)
1942 DI = InventDeclaratorInfo(Input.getArgument().getAsType());
1943
1944 DI = getDerived().TransformType(DI);
1945 if (!DI) return true;
1946
1947 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
1948 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00001949 }
Mike Stump11289f42009-09-09 15:08:12 +00001950
Douglas Gregore922c772009-08-04 22:27:00 +00001951 case TemplateArgument::Declaration: {
John McCall0ad16662009-10-29 08:12:44 +00001952 // FIXME: we should never have to transform one of these.
Douglas Gregoref6ab412009-10-27 06:26:26 +00001953 DeclarationName Name;
1954 if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
1955 Name = ND->getDeclName();
John McCall0ad16662009-10-29 08:12:44 +00001956 TemporaryBase Rebase(*this, SourceLocation(), Name);
Douglas Gregore922c772009-08-04 22:27:00 +00001957 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
John McCall0ad16662009-10-29 08:12:44 +00001958 if (!D) return true;
1959
John McCall0d07eb32009-10-29 18:45:58 +00001960 Expr *SourceExpr = Input.getSourceDeclExpression();
1961 if (SourceExpr) {
1962 EnterExpressionEvaluationContext Unevaluated(getSema(),
1963 Action::Unevaluated);
1964 Sema::OwningExprResult E = getDerived().TransformExpr(SourceExpr);
1965 if (E.isInvalid())
1966 SourceExpr = NULL;
1967 else {
1968 SourceExpr = E.takeAs<Expr>();
1969 SourceExpr->Retain();
1970 }
1971 }
1972
1973 Output = TemplateArgumentLoc(TemplateArgument(D), SourceExpr);
John McCall0ad16662009-10-29 08:12:44 +00001974 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00001975 }
Mike Stump11289f42009-09-09 15:08:12 +00001976
Douglas Gregore922c772009-08-04 22:27:00 +00001977 case TemplateArgument::Expression: {
1978 // Template argument expressions are not potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00001979 EnterExpressionEvaluationContext Unevaluated(getSema(),
Douglas Gregore922c772009-08-04 22:27:00 +00001980 Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00001981
John McCall0ad16662009-10-29 08:12:44 +00001982 Expr *InputExpr = Input.getSourceExpression();
1983 if (!InputExpr) InputExpr = Input.getArgument().getAsExpr();
1984
1985 Sema::OwningExprResult E
1986 = getDerived().TransformExpr(InputExpr);
1987 if (E.isInvalid()) return true;
1988
1989 Expr *ETaken = E.takeAs<Expr>();
John McCall0d07eb32009-10-29 18:45:58 +00001990 ETaken->Retain();
John McCall0ad16662009-10-29 08:12:44 +00001991 Output = TemplateArgumentLoc(TemplateArgument(ETaken), ETaken);
1992 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00001993 }
Mike Stump11289f42009-09-09 15:08:12 +00001994
Douglas Gregore922c772009-08-04 22:27:00 +00001995 case TemplateArgument::Pack: {
1996 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
1997 TransformedArgs.reserve(Arg.pack_size());
Mike Stump11289f42009-09-09 15:08:12 +00001998 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
Douglas Gregore922c772009-08-04 22:27:00 +00001999 AEnd = Arg.pack_end();
2000 A != AEnd; ++A) {
Mike Stump11289f42009-09-09 15:08:12 +00002001
John McCall0ad16662009-10-29 08:12:44 +00002002 // FIXME: preserve source information here when we start
2003 // caring about parameter packs.
2004
John McCall0d07eb32009-10-29 18:45:58 +00002005 TemplateArgumentLoc InputArg;
2006 TemplateArgumentLoc OutputArg;
2007 getDerived().InventTemplateArgumentLoc(*A, InputArg);
2008 if (getDerived().TransformTemplateArgument(InputArg, OutputArg))
John McCall0ad16662009-10-29 08:12:44 +00002009 return true;
2010
John McCall0d07eb32009-10-29 18:45:58 +00002011 TransformedArgs.push_back(OutputArg.getArgument());
Douglas Gregore922c772009-08-04 22:27:00 +00002012 }
2013 TemplateArgument Result;
Mike Stump11289f42009-09-09 15:08:12 +00002014 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
Douglas Gregore922c772009-08-04 22:27:00 +00002015 true);
John McCall0d07eb32009-10-29 18:45:58 +00002016 Output = TemplateArgumentLoc(Result, Input.getLocInfo());
John McCall0ad16662009-10-29 08:12:44 +00002017 return false;
Douglas Gregore922c772009-08-04 22:27:00 +00002018 }
2019 }
Mike Stump11289f42009-09-09 15:08:12 +00002020
Douglas Gregore922c772009-08-04 22:27:00 +00002021 // Work around bogus GCC warning
John McCall0ad16662009-10-29 08:12:44 +00002022 return true;
Douglas Gregore922c772009-08-04 22:27:00 +00002023}
2024
Douglas Gregord6ff3322009-08-04 16:50:30 +00002025//===----------------------------------------------------------------------===//
2026// Type transformation
2027//===----------------------------------------------------------------------===//
2028
2029template<typename Derived>
2030QualType TreeTransform<Derived>::TransformType(QualType T) {
2031 if (getDerived().AlreadyTransformed(T))
2032 return T;
Mike Stump11289f42009-09-09 15:08:12 +00002033
John McCall550e0c22009-10-21 00:40:46 +00002034 // Temporary workaround. All of these transformations should
2035 // eventually turn into transformations on TypeLocs.
2036 DeclaratorInfo *DI = getSema().Context.CreateDeclaratorInfo(T);
John McCallde889892009-10-21 00:44:26 +00002037 DI->getTypeLoc().initialize(getDerived().getBaseLocation());
John McCall550e0c22009-10-21 00:40:46 +00002038
2039 DeclaratorInfo *NewDI = getDerived().TransformType(DI);
John McCall8ccfcb52009-09-24 19:53:00 +00002040
John McCall550e0c22009-10-21 00:40:46 +00002041 if (!NewDI)
2042 return QualType();
2043
2044 return NewDI->getType();
2045}
2046
2047template<typename Derived>
2048DeclaratorInfo *TreeTransform<Derived>::TransformType(DeclaratorInfo *DI) {
2049 if (getDerived().AlreadyTransformed(DI->getType()))
2050 return DI;
2051
2052 TypeLocBuilder TLB;
2053
2054 TypeLoc TL = DI->getTypeLoc();
2055 TLB.reserve(TL.getFullDataSize());
2056
2057 QualType Result = getDerived().TransformType(TLB, TL);
2058 if (Result.isNull())
2059 return 0;
2060
2061 return TLB.getDeclaratorInfo(SemaRef.Context, Result);
2062}
2063
2064template<typename Derived>
2065QualType
2066TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
2067 switch (T.getTypeLocClass()) {
2068#define ABSTRACT_TYPELOC(CLASS, PARENT)
2069#define TYPELOC(CLASS, PARENT) \
2070 case TypeLoc::CLASS: \
2071 return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T));
2072#include "clang/AST/TypeLocNodes.def"
Douglas Gregord6ff3322009-08-04 16:50:30 +00002073 }
Mike Stump11289f42009-09-09 15:08:12 +00002074
John McCall550e0c22009-10-21 00:40:46 +00002075 llvm::llvm_unreachable("unhandled type loc!");
2076 return QualType();
2077}
2078
2079/// FIXME: By default, this routine adds type qualifiers only to types
2080/// that can have qualifiers, and silently suppresses those qualifiers
2081/// that are not permitted (e.g., qualifiers on reference or function
2082/// types). This is the right thing for template instantiation, but
2083/// probably not for other clients.
2084template<typename Derived>
2085QualType
2086TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
2087 QualifiedTypeLoc T) {
2088 Qualifiers Quals = T.getType().getQualifiers();
2089
2090 QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
2091 if (Result.isNull())
2092 return QualType();
2093
2094 // Silently suppress qualifiers if the result type can't be qualified.
2095 // FIXME: this is the right thing for template instantiation, but
2096 // probably not for other clients.
2097 if (Result->isFunctionType() || Result->isReferenceType())
Douglas Gregord6ff3322009-08-04 16:50:30 +00002098 return Result;
Mike Stump11289f42009-09-09 15:08:12 +00002099
John McCall550e0c22009-10-21 00:40:46 +00002100 Result = SemaRef.Context.getQualifiedType(Result, Quals);
2101
2102 TLB.push<QualifiedTypeLoc>(Result);
2103
2104 // No location information to preserve.
2105
2106 return Result;
2107}
2108
2109template <class TyLoc> static inline
2110QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
2111 TyLoc NewT = TLB.push<TyLoc>(T.getType());
2112 NewT.setNameLoc(T.getNameLoc());
2113 return T.getType();
2114}
2115
2116// Ugly metaprogramming macros because I couldn't be bothered to make
2117// the equivalent template version work.
2118#define TransformPointerLikeType(TypeClass) do { \
2119 QualType PointeeType \
2120 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2121 if (PointeeType.isNull()) \
2122 return QualType(); \
2123 \
2124 QualType Result = TL.getType(); \
2125 if (getDerived().AlwaysRebuild() || \
2126 PointeeType != TL.getPointeeLoc().getType()) { \
2127 Result = getDerived().Rebuild##TypeClass(PointeeType); \
2128 if (Result.isNull()) \
2129 return QualType(); \
2130 } \
2131 \
2132 TypeClass##Loc NewT = TLB.push<TypeClass##Loc>(Result); \
2133 NewT.setSigilLoc(TL.getSigilLoc()); \
2134 \
2135 return Result; \
2136} while(0)
2137
2138// Reference collapsing forces us to transform reference types
2139// differently from the other pointer-like types.
2140#define TransformReferenceType(TypeClass) do { \
2141 QualType PointeeType \
2142 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2143 if (PointeeType.isNull()) \
2144 return QualType(); \
2145 \
2146 QualType Result = TL.getType(); \
2147 if (getDerived().AlwaysRebuild() || \
2148 PointeeType != TL.getPointeeLoc().getType()) { \
2149 Result = getDerived().Rebuild##TypeClass(PointeeType); \
2150 if (Result.isNull()) \
2151 return QualType(); \
2152 } \
2153 \
2154 /* Workaround: rebuild doesn't always change the type */ \
2155 /* FIXME: avoid losing this location information. */ \
2156 if (Result == PointeeType) \
2157 return Result; \
2158 ReferenceTypeLoc NewTL; \
2159 if (isa<LValueReferenceType>(Result)) \
2160 NewTL = TLB.push<LValueReferenceTypeLoc>(Result); \
2161 else \
2162 NewTL = TLB.push<RValueReferenceTypeLoc>(Result); \
2163 NewTL.setSigilLoc(TL.getSigilLoc()); \
2164 return Result; \
2165} while (0)
2166
2167template<typename Derived>
2168QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
2169 BuiltinTypeLoc T) {
2170 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002171}
Mike Stump11289f42009-09-09 15:08:12 +00002172
Douglas Gregord6ff3322009-08-04 16:50:30 +00002173template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002174QualType
John McCall550e0c22009-10-21 00:40:46 +00002175TreeTransform<Derived>::TransformFixedWidthIntType(TypeLocBuilder &TLB,
2176 FixedWidthIntTypeLoc T) {
2177 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002178}
Argyrios Kyrtzidise9189262009-08-19 01:28:17 +00002179
Douglas Gregord6ff3322009-08-04 16:50:30 +00002180template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002181QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
2182 ComplexTypeLoc T) {
2183 // FIXME: recurse?
2184 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002185}
Mike Stump11289f42009-09-09 15:08:12 +00002186
Douglas Gregord6ff3322009-08-04 16:50:30 +00002187template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002188QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
2189 PointerTypeLoc TL) {
2190 TransformPointerLikeType(PointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002191}
Mike Stump11289f42009-09-09 15:08:12 +00002192
2193template<typename Derived>
2194QualType
John McCall550e0c22009-10-21 00:40:46 +00002195TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
2196 BlockPointerTypeLoc TL) {
2197 TransformPointerLikeType(BlockPointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002198}
2199
Mike Stump11289f42009-09-09 15:08:12 +00002200template<typename Derived>
2201QualType
John McCall550e0c22009-10-21 00:40:46 +00002202TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
2203 LValueReferenceTypeLoc TL) {
2204 TransformReferenceType(LValueReferenceType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002205}
2206
Mike Stump11289f42009-09-09 15:08:12 +00002207template<typename Derived>
2208QualType
John McCall550e0c22009-10-21 00:40:46 +00002209TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
2210 RValueReferenceTypeLoc TL) {
2211 TransformReferenceType(RValueReferenceType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002212}
Mike Stump11289f42009-09-09 15:08:12 +00002213
Douglas Gregord6ff3322009-08-04 16:50:30 +00002214template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002215QualType
John McCall550e0c22009-10-21 00:40:46 +00002216TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
2217 MemberPointerTypeLoc TL) {
2218 MemberPointerType *T = TL.getTypePtr();
2219
2220 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002221 if (PointeeType.isNull())
2222 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002223
John McCall550e0c22009-10-21 00:40:46 +00002224 // TODO: preserve source information for this.
2225 QualType ClassType
2226 = getDerived().TransformType(QualType(T->getClass(), 0));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002227 if (ClassType.isNull())
2228 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002229
John McCall550e0c22009-10-21 00:40:46 +00002230 QualType Result = TL.getType();
2231 if (getDerived().AlwaysRebuild() ||
2232 PointeeType != T->getPointeeType() ||
2233 ClassType != QualType(T->getClass(), 0)) {
2234 Result = getDerived().RebuildMemberPointerType(PointeeType, ClassType);
2235 if (Result.isNull())
2236 return QualType();
2237 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002238
John McCall550e0c22009-10-21 00:40:46 +00002239 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
2240 NewTL.setSigilLoc(TL.getSigilLoc());
2241
2242 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002243}
2244
Mike Stump11289f42009-09-09 15:08:12 +00002245template<typename Derived>
2246QualType
John McCall550e0c22009-10-21 00:40:46 +00002247TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
2248 ConstantArrayTypeLoc TL) {
2249 ConstantArrayType *T = TL.getTypePtr();
2250 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002251 if (ElementType.isNull())
2252 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002253
John McCall550e0c22009-10-21 00:40:46 +00002254 QualType Result = TL.getType();
2255 if (getDerived().AlwaysRebuild() ||
2256 ElementType != T->getElementType()) {
2257 Result = getDerived().RebuildConstantArrayType(ElementType,
2258 T->getSizeModifier(),
2259 T->getSize(),
2260 T->getIndexTypeCVRQualifiers());
2261 if (Result.isNull())
2262 return QualType();
2263 }
2264
2265 ConstantArrayTypeLoc NewTL = TLB.push<ConstantArrayTypeLoc>(Result);
2266 NewTL.setLBracketLoc(TL.getLBracketLoc());
2267 NewTL.setRBracketLoc(TL.getRBracketLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002268
John McCall550e0c22009-10-21 00:40:46 +00002269 Expr *Size = TL.getSizeExpr();
2270 if (Size) {
2271 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2272 Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
2273 }
2274 NewTL.setSizeExpr(Size);
2275
2276 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002277}
Mike Stump11289f42009-09-09 15:08:12 +00002278
Douglas Gregord6ff3322009-08-04 16:50:30 +00002279template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002280QualType TreeTransform<Derived>::TransformIncompleteArrayType(
John McCall550e0c22009-10-21 00:40:46 +00002281 TypeLocBuilder &TLB,
2282 IncompleteArrayTypeLoc TL) {
2283 IncompleteArrayType *T = TL.getTypePtr();
2284 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002285 if (ElementType.isNull())
2286 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002287
John McCall550e0c22009-10-21 00:40:46 +00002288 QualType Result = TL.getType();
2289 if (getDerived().AlwaysRebuild() ||
2290 ElementType != T->getElementType()) {
2291 Result = getDerived().RebuildIncompleteArrayType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002292 T->getSizeModifier(),
John McCall550e0c22009-10-21 00:40:46 +00002293 T->getIndexTypeCVRQualifiers());
2294 if (Result.isNull())
2295 return QualType();
2296 }
2297
2298 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
2299 NewTL.setLBracketLoc(TL.getLBracketLoc());
2300 NewTL.setRBracketLoc(TL.getRBracketLoc());
2301 NewTL.setSizeExpr(0);
2302
2303 return Result;
2304}
2305
2306template<typename Derived>
2307QualType
2308TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
2309 VariableArrayTypeLoc TL) {
2310 VariableArrayType *T = TL.getTypePtr();
2311 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2312 if (ElementType.isNull())
2313 return QualType();
2314
2315 // Array bounds are not potentially evaluated contexts
2316 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2317
2318 Sema::OwningExprResult SizeResult
2319 = getDerived().TransformExpr(T->getSizeExpr());
2320 if (SizeResult.isInvalid())
2321 return QualType();
2322
2323 Expr *Size = static_cast<Expr*>(SizeResult.get());
2324
2325 QualType Result = TL.getType();
2326 if (getDerived().AlwaysRebuild() ||
2327 ElementType != T->getElementType() ||
2328 Size != T->getSizeExpr()) {
2329 Result = getDerived().RebuildVariableArrayType(ElementType,
2330 T->getSizeModifier(),
2331 move(SizeResult),
2332 T->getIndexTypeCVRQualifiers(),
2333 T->getBracketsRange());
2334 if (Result.isNull())
2335 return QualType();
2336 }
2337 else SizeResult.take();
2338
2339 VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
2340 NewTL.setLBracketLoc(TL.getLBracketLoc());
2341 NewTL.setRBracketLoc(TL.getRBracketLoc());
2342 NewTL.setSizeExpr(Size);
2343
2344 return Result;
2345}
2346
2347template<typename Derived>
2348QualType
2349TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
2350 DependentSizedArrayTypeLoc TL) {
2351 DependentSizedArrayType *T = TL.getTypePtr();
2352 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2353 if (ElementType.isNull())
2354 return QualType();
2355
2356 // Array bounds are not potentially evaluated contexts
2357 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2358
2359 Sema::OwningExprResult SizeResult
2360 = getDerived().TransformExpr(T->getSizeExpr());
2361 if (SizeResult.isInvalid())
2362 return QualType();
2363
2364 Expr *Size = static_cast<Expr*>(SizeResult.get());
2365
2366 QualType Result = TL.getType();
2367 if (getDerived().AlwaysRebuild() ||
2368 ElementType != T->getElementType() ||
2369 Size != T->getSizeExpr()) {
2370 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
2371 T->getSizeModifier(),
2372 move(SizeResult),
2373 T->getIndexTypeCVRQualifiers(),
2374 T->getBracketsRange());
2375 if (Result.isNull())
2376 return QualType();
2377 }
2378 else SizeResult.take();
2379
2380 // We might have any sort of array type now, but fortunately they
2381 // all have the same location layout.
2382 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
2383 NewTL.setLBracketLoc(TL.getLBracketLoc());
2384 NewTL.setRBracketLoc(TL.getRBracketLoc());
2385 NewTL.setSizeExpr(Size);
2386
2387 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002388}
Mike Stump11289f42009-09-09 15:08:12 +00002389
2390template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002391QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
John McCall550e0c22009-10-21 00:40:46 +00002392 TypeLocBuilder &TLB,
2393 DependentSizedExtVectorTypeLoc TL) {
2394 DependentSizedExtVectorType *T = TL.getTypePtr();
2395
2396 // FIXME: ext vector locs should be nested
Douglas Gregord6ff3322009-08-04 16:50:30 +00002397 QualType ElementType = getDerived().TransformType(T->getElementType());
2398 if (ElementType.isNull())
2399 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002400
Douglas Gregore922c772009-08-04 22:27:00 +00002401 // Vector sizes are not potentially evaluated contexts
2402 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2403
Douglas Gregord6ff3322009-08-04 16:50:30 +00002404 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2405 if (Size.isInvalid())
2406 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002407
John McCall550e0c22009-10-21 00:40:46 +00002408 QualType Result = TL.getType();
2409 if (getDerived().AlwaysRebuild() ||
John McCall24e7cb62009-10-23 17:55:45 +00002410 ElementType != T->getElementType() ||
2411 Size.get() != T->getSizeExpr()) {
John McCall550e0c22009-10-21 00:40:46 +00002412 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002413 move(Size),
2414 T->getAttributeLoc());
John McCall550e0c22009-10-21 00:40:46 +00002415 if (Result.isNull())
2416 return QualType();
2417 }
2418 else Size.take();
2419
2420 // Result might be dependent or not.
2421 if (isa<DependentSizedExtVectorType>(Result)) {
2422 DependentSizedExtVectorTypeLoc NewTL
2423 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
2424 NewTL.setNameLoc(TL.getNameLoc());
2425 } else {
2426 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2427 NewTL.setNameLoc(TL.getNameLoc());
2428 }
2429
2430 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002431}
Mike Stump11289f42009-09-09 15:08:12 +00002432
2433template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002434QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
2435 VectorTypeLoc TL) {
2436 VectorType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002437 QualType ElementType = getDerived().TransformType(T->getElementType());
2438 if (ElementType.isNull())
2439 return QualType();
2440
John McCall550e0c22009-10-21 00:40:46 +00002441 QualType Result = TL.getType();
2442 if (getDerived().AlwaysRebuild() ||
2443 ElementType != T->getElementType()) {
2444 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements());
2445 if (Result.isNull())
2446 return QualType();
2447 }
2448
2449 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
2450 NewTL.setNameLoc(TL.getNameLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002451
John McCall550e0c22009-10-21 00:40:46 +00002452 return Result;
2453}
2454
2455template<typename Derived>
2456QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
2457 ExtVectorTypeLoc TL) {
2458 VectorType *T = TL.getTypePtr();
2459 QualType ElementType = getDerived().TransformType(T->getElementType());
2460 if (ElementType.isNull())
2461 return QualType();
2462
2463 QualType Result = TL.getType();
2464 if (getDerived().AlwaysRebuild() ||
2465 ElementType != T->getElementType()) {
2466 Result = getDerived().RebuildExtVectorType(ElementType,
2467 T->getNumElements(),
2468 /*FIXME*/ SourceLocation());
2469 if (Result.isNull())
2470 return QualType();
2471 }
2472
2473 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2474 NewTL.setNameLoc(TL.getNameLoc());
2475
2476 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002477}
Mike Stump11289f42009-09-09 15:08:12 +00002478
2479template<typename Derived>
2480QualType
John McCall550e0c22009-10-21 00:40:46 +00002481TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
2482 FunctionProtoTypeLoc TL) {
2483 FunctionProtoType *T = TL.getTypePtr();
2484 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002485 if (ResultType.isNull())
2486 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002487
John McCall550e0c22009-10-21 00:40:46 +00002488 // Transform the parameters.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002489 llvm::SmallVector<QualType, 4> ParamTypes;
John McCall550e0c22009-10-21 00:40:46 +00002490 llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
2491 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2492 ParmVarDecl *OldParm = TL.getArg(i);
Mike Stump11289f42009-09-09 15:08:12 +00002493
John McCall550e0c22009-10-21 00:40:46 +00002494 QualType NewType;
2495 ParmVarDecl *NewParm;
2496
2497 if (OldParm) {
2498 DeclaratorInfo *OldDI = OldParm->getDeclaratorInfo();
2499 assert(OldDI->getType() == T->getArgType(i));
2500
2501 DeclaratorInfo *NewDI = getDerived().TransformType(OldDI);
2502 if (!NewDI)
2503 return QualType();
2504
2505 if (NewDI == OldDI)
2506 NewParm = OldParm;
2507 else
2508 NewParm = ParmVarDecl::Create(SemaRef.Context,
2509 OldParm->getDeclContext(),
2510 OldParm->getLocation(),
2511 OldParm->getIdentifier(),
2512 NewDI->getType(),
2513 NewDI,
2514 OldParm->getStorageClass(),
2515 /* DefArg */ NULL);
2516 NewType = NewParm->getType();
2517
2518 // Deal with the possibility that we don't have a parameter
2519 // declaration for this parameter.
2520 } else {
2521 NewParm = 0;
2522
2523 QualType OldType = T->getArgType(i);
2524 NewType = getDerived().TransformType(OldType);
2525 if (NewType.isNull())
2526 return QualType();
2527 }
2528
2529 ParamTypes.push_back(NewType);
2530 ParamDecls.push_back(NewParm);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002531 }
Mike Stump11289f42009-09-09 15:08:12 +00002532
John McCall550e0c22009-10-21 00:40:46 +00002533 QualType Result = TL.getType();
2534 if (getDerived().AlwaysRebuild() ||
2535 ResultType != T->getResultType() ||
2536 !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
2537 Result = getDerived().RebuildFunctionProtoType(ResultType,
2538 ParamTypes.data(),
2539 ParamTypes.size(),
2540 T->isVariadic(),
2541 T->getTypeQuals());
2542 if (Result.isNull())
2543 return QualType();
2544 }
Mike Stump11289f42009-09-09 15:08:12 +00002545
John McCall550e0c22009-10-21 00:40:46 +00002546 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
2547 NewTL.setLParenLoc(TL.getLParenLoc());
2548 NewTL.setRParenLoc(TL.getRParenLoc());
2549 for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
2550 NewTL.setArg(i, ParamDecls[i]);
2551
2552 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002553}
Mike Stump11289f42009-09-09 15:08:12 +00002554
Douglas Gregord6ff3322009-08-04 16:50:30 +00002555template<typename Derived>
2556QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
John McCall550e0c22009-10-21 00:40:46 +00002557 TypeLocBuilder &TLB,
2558 FunctionNoProtoTypeLoc TL) {
2559 FunctionNoProtoType *T = TL.getTypePtr();
2560 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
2561 if (ResultType.isNull())
2562 return QualType();
2563
2564 QualType Result = TL.getType();
2565 if (getDerived().AlwaysRebuild() ||
2566 ResultType != T->getResultType())
2567 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
2568
2569 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
2570 NewTL.setLParenLoc(TL.getLParenLoc());
2571 NewTL.setRParenLoc(TL.getRParenLoc());
2572
2573 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002574}
Mike Stump11289f42009-09-09 15:08:12 +00002575
Douglas Gregord6ff3322009-08-04 16:50:30 +00002576template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002577QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
2578 TypedefTypeLoc TL) {
2579 TypedefType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002580 TypedefDecl *Typedef
2581 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2582 if (!Typedef)
2583 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002584
John McCall550e0c22009-10-21 00:40:46 +00002585 QualType Result = TL.getType();
2586 if (getDerived().AlwaysRebuild() ||
2587 Typedef != T->getDecl()) {
2588 Result = getDerived().RebuildTypedefType(Typedef);
2589 if (Result.isNull())
2590 return QualType();
2591 }
Mike Stump11289f42009-09-09 15:08:12 +00002592
John McCall550e0c22009-10-21 00:40:46 +00002593 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
2594 NewTL.setNameLoc(TL.getNameLoc());
2595
2596 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002597}
Mike Stump11289f42009-09-09 15:08:12 +00002598
Douglas Gregord6ff3322009-08-04 16:50:30 +00002599template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002600QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
2601 TypeOfExprTypeLoc TL) {
2602 TypeOfExprType *T = TL.getTypePtr();
2603
Douglas Gregore922c772009-08-04 22:27:00 +00002604 // typeof expressions are not potentially evaluated contexts
2605 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002606
Douglas Gregord6ff3322009-08-04 16:50:30 +00002607 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2608 if (E.isInvalid())
2609 return QualType();
2610
John McCall550e0c22009-10-21 00:40:46 +00002611 QualType Result = TL.getType();
2612 if (getDerived().AlwaysRebuild() ||
2613 E.get() != T->getUnderlyingExpr()) {
2614 Result = getDerived().RebuildTypeOfExprType(move(E));
2615 if (Result.isNull())
2616 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002617 }
John McCall550e0c22009-10-21 00:40:46 +00002618 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002619
John McCall550e0c22009-10-21 00:40:46 +00002620 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
2621 NewTL.setNameLoc(TL.getNameLoc());
2622
2623 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002624}
Mike Stump11289f42009-09-09 15:08:12 +00002625
2626template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002627QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
2628 TypeOfTypeLoc TL) {
2629 TypeOfType *T = TL.getTypePtr();
2630
2631 // FIXME: should be an inner type, or at least have a DeclaratorInfo.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002632 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2633 if (Underlying.isNull())
2634 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002635
John McCall550e0c22009-10-21 00:40:46 +00002636 QualType Result = TL.getType();
2637 if (getDerived().AlwaysRebuild() ||
2638 Underlying != T->getUnderlyingType()) {
2639 Result = getDerived().RebuildTypeOfType(Underlying);
2640 if (Result.isNull())
2641 return QualType();
2642 }
Mike Stump11289f42009-09-09 15:08:12 +00002643
John McCall550e0c22009-10-21 00:40:46 +00002644 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
2645 NewTL.setNameLoc(TL.getNameLoc());
2646
2647 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002648}
Mike Stump11289f42009-09-09 15:08:12 +00002649
2650template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002651QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
2652 DecltypeTypeLoc TL) {
2653 DecltypeType *T = TL.getTypePtr();
2654
Douglas Gregore922c772009-08-04 22:27:00 +00002655 // decltype expressions are not potentially evaluated contexts
2656 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002657
Douglas Gregord6ff3322009-08-04 16:50:30 +00002658 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2659 if (E.isInvalid())
2660 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002661
John McCall550e0c22009-10-21 00:40:46 +00002662 QualType Result = TL.getType();
2663 if (getDerived().AlwaysRebuild() ||
2664 E.get() != T->getUnderlyingExpr()) {
2665 Result = getDerived().RebuildDecltypeType(move(E));
2666 if (Result.isNull())
2667 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002668 }
John McCall550e0c22009-10-21 00:40:46 +00002669 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002670
John McCall550e0c22009-10-21 00:40:46 +00002671 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
2672 NewTL.setNameLoc(TL.getNameLoc());
2673
2674 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002675}
2676
2677template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002678QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
2679 RecordTypeLoc TL) {
2680 RecordType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002681 RecordDecl *Record
John McCall550e0c22009-10-21 00:40:46 +00002682 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002683 if (!Record)
2684 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002685
John McCall550e0c22009-10-21 00:40:46 +00002686 QualType Result = TL.getType();
2687 if (getDerived().AlwaysRebuild() ||
2688 Record != T->getDecl()) {
2689 Result = getDerived().RebuildRecordType(Record);
2690 if (Result.isNull())
2691 return QualType();
2692 }
Mike Stump11289f42009-09-09 15:08:12 +00002693
John McCall550e0c22009-10-21 00:40:46 +00002694 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
2695 NewTL.setNameLoc(TL.getNameLoc());
2696
2697 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002698}
Mike Stump11289f42009-09-09 15:08:12 +00002699
2700template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002701QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
2702 EnumTypeLoc TL) {
2703 EnumType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002704 EnumDecl *Enum
John McCall550e0c22009-10-21 00:40:46 +00002705 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002706 if (!Enum)
2707 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002708
John McCall550e0c22009-10-21 00:40:46 +00002709 QualType Result = TL.getType();
2710 if (getDerived().AlwaysRebuild() ||
2711 Enum != T->getDecl()) {
2712 Result = getDerived().RebuildEnumType(Enum);
2713 if (Result.isNull())
2714 return QualType();
2715 }
Mike Stump11289f42009-09-09 15:08:12 +00002716
John McCall550e0c22009-10-21 00:40:46 +00002717 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
2718 NewTL.setNameLoc(TL.getNameLoc());
2719
2720 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002721}
John McCallfcc33b02009-09-05 00:15:47 +00002722
2723template <typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002724QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
2725 ElaboratedTypeLoc TL) {
2726 ElaboratedType *T = TL.getTypePtr();
2727
2728 // FIXME: this should be a nested type.
John McCallfcc33b02009-09-05 00:15:47 +00002729 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2730 if (Underlying.isNull())
2731 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002732
John McCall550e0c22009-10-21 00:40:46 +00002733 QualType Result = TL.getType();
2734 if (getDerived().AlwaysRebuild() ||
2735 Underlying != T->getUnderlyingType()) {
2736 Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
2737 if (Result.isNull())
2738 return QualType();
2739 }
Mike Stump11289f42009-09-09 15:08:12 +00002740
John McCall550e0c22009-10-21 00:40:46 +00002741 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
2742 NewTL.setNameLoc(TL.getNameLoc());
2743
2744 return Result;
John McCallfcc33b02009-09-05 00:15:47 +00002745}
Mike Stump11289f42009-09-09 15:08:12 +00002746
2747
Douglas Gregord6ff3322009-08-04 16:50:30 +00002748template<typename Derived>
2749QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002750 TypeLocBuilder &TLB,
2751 TemplateTypeParmTypeLoc TL) {
2752 return TransformTypeSpecType(TLB, TL);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002753}
2754
Mike Stump11289f42009-09-09 15:08:12 +00002755template<typename Derived>
John McCallcebee162009-10-18 09:09:24 +00002756QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002757 TypeLocBuilder &TLB,
2758 SubstTemplateTypeParmTypeLoc TL) {
2759 return TransformTypeSpecType(TLB, TL);
John McCallcebee162009-10-18 09:09:24 +00002760}
2761
2762template<typename Derived>
Douglas Gregorc59e5612009-10-19 22:04:39 +00002763inline QualType
2764TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall550e0c22009-10-21 00:40:46 +00002765 TypeLocBuilder &TLB,
2766 TemplateSpecializationTypeLoc TL) {
John McCall0ad16662009-10-29 08:12:44 +00002767 return TransformTemplateSpecializationType(TLB, TL, QualType());
2768}
John McCall550e0c22009-10-21 00:40:46 +00002769
John McCall0ad16662009-10-29 08:12:44 +00002770template<typename Derived>
2771QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
2772 const TemplateSpecializationType *TST,
2773 QualType ObjectType) {
2774 // FIXME: this entire method is a temporary workaround; callers
2775 // should be rewritten to provide real type locs.
John McCall550e0c22009-10-21 00:40:46 +00002776
John McCall0ad16662009-10-29 08:12:44 +00002777 // Fake up a TemplateSpecializationTypeLoc.
2778 TypeLocBuilder TLB;
2779 TemplateSpecializationTypeLoc TL
2780 = TLB.push<TemplateSpecializationTypeLoc>(QualType(TST, 0));
2781
John McCall0d07eb32009-10-29 18:45:58 +00002782 SourceLocation BaseLoc = getDerived().getBaseLocation();
2783
2784 TL.setTemplateNameLoc(BaseLoc);
2785 TL.setLAngleLoc(BaseLoc);
2786 TL.setRAngleLoc(BaseLoc);
John McCall0ad16662009-10-29 08:12:44 +00002787 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2788 const TemplateArgument &TA = TST->getArg(i);
2789 TemplateArgumentLoc TAL;
2790 getDerived().InventTemplateArgumentLoc(TA, TAL);
2791 TL.setArgLocInfo(i, TAL.getLocInfo());
2792 }
2793
2794 TypeLocBuilder IgnoredTLB;
2795 return TransformTemplateSpecializationType(IgnoredTLB, TL, ObjectType);
Douglas Gregorc59e5612009-10-19 22:04:39 +00002796}
2797
2798template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002799QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall0ad16662009-10-29 08:12:44 +00002800 TypeLocBuilder &TLB,
2801 TemplateSpecializationTypeLoc TL,
2802 QualType ObjectType) {
2803 const TemplateSpecializationType *T = TL.getTypePtr();
2804
Mike Stump11289f42009-09-09 15:08:12 +00002805 TemplateName Template
Douglas Gregorc59e5612009-10-19 22:04:39 +00002806 = getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002807 if (Template.isNull())
2808 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002809
John McCall0ad16662009-10-29 08:12:44 +00002810 llvm::SmallVector<TemplateArgumentLoc, 4> NewTemplateArgs(T->getNumArgs());
2811 for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i)
2812 if (getDerived().TransformTemplateArgument(TL.getArgLoc(i),
2813 NewTemplateArgs[i]))
Douglas Gregord6ff3322009-08-04 16:50:30 +00002814 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002815
John McCall0ad16662009-10-29 08:12:44 +00002816 // FIXME: maybe don't rebuild if all the template arguments are the same.
2817
2818 QualType Result =
2819 getDerived().RebuildTemplateSpecializationType(Template,
2820 TL.getTemplateNameLoc(),
2821 TL.getLAngleLoc(),
2822 NewTemplateArgs.data(),
2823 NewTemplateArgs.size(),
2824 TL.getRAngleLoc());
2825
2826 if (!Result.isNull()) {
2827 TemplateSpecializationTypeLoc NewTL
2828 = TLB.push<TemplateSpecializationTypeLoc>(Result);
2829 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
2830 NewTL.setLAngleLoc(TL.getLAngleLoc());
2831 NewTL.setRAngleLoc(TL.getRAngleLoc());
2832 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
2833 NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002834 }
Mike Stump11289f42009-09-09 15:08:12 +00002835
John McCall0ad16662009-10-29 08:12:44 +00002836 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002837}
Mike Stump11289f42009-09-09 15:08:12 +00002838
2839template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002840QualType
2841TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
2842 QualifiedNameTypeLoc TL) {
2843 QualifiedNameType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002844 NestedNameSpecifier *NNS
2845 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2846 SourceRange());
2847 if (!NNS)
2848 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002849
Douglas Gregord6ff3322009-08-04 16:50:30 +00002850 QualType Named = getDerived().TransformType(T->getNamedType());
2851 if (Named.isNull())
2852 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002853
John McCall550e0c22009-10-21 00:40:46 +00002854 QualType Result = TL.getType();
2855 if (getDerived().AlwaysRebuild() ||
2856 NNS != T->getQualifier() ||
2857 Named != T->getNamedType()) {
2858 Result = getDerived().RebuildQualifiedNameType(NNS, Named);
2859 if (Result.isNull())
2860 return QualType();
2861 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002862
John McCall550e0c22009-10-21 00:40:46 +00002863 QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
2864 NewTL.setNameLoc(TL.getNameLoc());
2865
2866 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002867}
Mike Stump11289f42009-09-09 15:08:12 +00002868
2869template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002870QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
2871 TypenameTypeLoc TL) {
2872 TypenameType *T = TL.getTypePtr();
John McCall0ad16662009-10-29 08:12:44 +00002873
2874 /* FIXME: preserve source information better than this */
2875 SourceRange SR(TL.getNameLoc());
2876
Douglas Gregord6ff3322009-08-04 16:50:30 +00002877 NestedNameSpecifier *NNS
John McCall0ad16662009-10-29 08:12:44 +00002878 = getDerived().TransformNestedNameSpecifier(T->getQualifier(), SR);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002879 if (!NNS)
2880 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002881
John McCall550e0c22009-10-21 00:40:46 +00002882 QualType Result;
2883
Douglas Gregord6ff3322009-08-04 16:50:30 +00002884 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
Mike Stump11289f42009-09-09 15:08:12 +00002885 QualType NewTemplateId
Douglas Gregord6ff3322009-08-04 16:50:30 +00002886 = getDerived().TransformType(QualType(TemplateId, 0));
2887 if (NewTemplateId.isNull())
2888 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002889
Douglas Gregord6ff3322009-08-04 16:50:30 +00002890 if (!getDerived().AlwaysRebuild() &&
2891 NNS == T->getQualifier() &&
2892 NewTemplateId == QualType(TemplateId, 0))
2893 return QualType(T, 0);
Mike Stump11289f42009-09-09 15:08:12 +00002894
John McCall550e0c22009-10-21 00:40:46 +00002895 Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
2896 } else {
John McCall0ad16662009-10-29 08:12:44 +00002897 Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier(), SR);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002898 }
John McCall550e0c22009-10-21 00:40:46 +00002899 if (Result.isNull())
2900 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002901
John McCall550e0c22009-10-21 00:40:46 +00002902 TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
2903 NewTL.setNameLoc(TL.getNameLoc());
2904
2905 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002906}
Mike Stump11289f42009-09-09 15:08:12 +00002907
Douglas Gregord6ff3322009-08-04 16:50:30 +00002908template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002909QualType
2910TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
2911 ObjCInterfaceTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002912 assert(false && "TransformObjCInterfaceType unimplemented");
2913 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002914}
Mike Stump11289f42009-09-09 15:08:12 +00002915
2916template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002917QualType
2918TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
2919 ObjCObjectPointerTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002920 assert(false && "TransformObjCObjectPointerType unimplemented");
2921 return QualType();
Argyrios Kyrtzidisa7a36df2009-09-29 19:42:55 +00002922}
2923
Douglas Gregord6ff3322009-08-04 16:50:30 +00002924//===----------------------------------------------------------------------===//
Douglas Gregorebe10102009-08-20 07:17:43 +00002925// Statement transformation
2926//===----------------------------------------------------------------------===//
2927template<typename Derived>
2928Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002929TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2930 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00002931}
2932
2933template<typename Derived>
2934Sema::OwningStmtResult
2935TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2936 return getDerived().TransformCompoundStmt(S, false);
2937}
2938
2939template<typename Derived>
2940Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002941TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
Douglas Gregorebe10102009-08-20 07:17:43 +00002942 bool IsStmtExpr) {
2943 bool SubStmtChanged = false;
2944 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2945 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2946 B != BEnd; ++B) {
2947 OwningStmtResult Result = getDerived().TransformStmt(*B);
2948 if (Result.isInvalid())
2949 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002950
Douglas Gregorebe10102009-08-20 07:17:43 +00002951 SubStmtChanged = SubStmtChanged || Result.get() != *B;
2952 Statements.push_back(Result.takeAs<Stmt>());
2953 }
Mike Stump11289f42009-09-09 15:08:12 +00002954
Douglas Gregorebe10102009-08-20 07:17:43 +00002955 if (!getDerived().AlwaysRebuild() &&
2956 !SubStmtChanged)
Mike Stump11289f42009-09-09 15:08:12 +00002957 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00002958
2959 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
2960 move_arg(Statements),
2961 S->getRBracLoc(),
2962 IsStmtExpr);
2963}
Mike Stump11289f42009-09-09 15:08:12 +00002964
Douglas Gregorebe10102009-08-20 07:17:43 +00002965template<typename Derived>
2966Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002967TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002968 // The case value expressions are not potentially evaluated.
2969 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002970
Douglas Gregorebe10102009-08-20 07:17:43 +00002971 // Transform the left-hand case value.
2972 OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
2973 if (LHS.isInvalid())
2974 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002975
Douglas Gregorebe10102009-08-20 07:17:43 +00002976 // Transform the right-hand case value (for the GNU case-range extension).
2977 OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
2978 if (RHS.isInvalid())
2979 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002980
Douglas Gregorebe10102009-08-20 07:17:43 +00002981 // Build the case statement.
2982 // Case statements are always rebuilt so that they will attached to their
2983 // transformed switch statement.
2984 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
2985 move(LHS),
2986 S->getEllipsisLoc(),
2987 move(RHS),
2988 S->getColonLoc());
2989 if (Case.isInvalid())
2990 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002991
Douglas Gregorebe10102009-08-20 07:17:43 +00002992 // Transform the statement following the case
2993 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2994 if (SubStmt.isInvalid())
2995 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002996
Douglas Gregorebe10102009-08-20 07:17:43 +00002997 // Attach the body to the case statement
2998 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
2999}
3000
3001template<typename Derived>
3002Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003003TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003004 // Transform the statement following the default case
3005 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3006 if (SubStmt.isInvalid())
3007 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003008
Douglas Gregorebe10102009-08-20 07:17:43 +00003009 // Default statements are always rebuilt
3010 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
3011 move(SubStmt));
3012}
Mike Stump11289f42009-09-09 15:08:12 +00003013
Douglas Gregorebe10102009-08-20 07:17:43 +00003014template<typename Derived>
3015Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003016TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003017 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
3018 if (SubStmt.isInvalid())
3019 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003020
Douglas Gregorebe10102009-08-20 07:17:43 +00003021 // FIXME: Pass the real colon location in.
3022 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
3023 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
3024 move(SubStmt));
3025}
Mike Stump11289f42009-09-09 15:08:12 +00003026
Douglas Gregorebe10102009-08-20 07:17:43 +00003027template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003028Sema::OwningStmtResult
3029TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003030 // Transform the condition
3031 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3032 if (Cond.isInvalid())
3033 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003034
Douglas Gregorebe10102009-08-20 07:17:43 +00003035 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00003036
Douglas Gregorebe10102009-08-20 07:17:43 +00003037 // Transform the "then" branch.
3038 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
3039 if (Then.isInvalid())
3040 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003041
Douglas Gregorebe10102009-08-20 07:17:43 +00003042 // Transform the "else" branch.
3043 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
3044 if (Else.isInvalid())
3045 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003046
Douglas Gregorebe10102009-08-20 07:17:43 +00003047 if (!getDerived().AlwaysRebuild() &&
3048 FullCond->get() == S->getCond() &&
3049 Then.get() == S->getThen() &&
3050 Else.get() == S->getElse())
Mike Stump11289f42009-09-09 15:08:12 +00003051 return SemaRef.Owned(S->Retain());
3052
Douglas Gregorebe10102009-08-20 07:17:43 +00003053 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
Mike Stump11289f42009-09-09 15:08:12 +00003054 S->getElseLoc(), move(Else));
Douglas Gregorebe10102009-08-20 07:17:43 +00003055}
3056
3057template<typename Derived>
3058Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003059TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003060 // Transform the condition.
3061 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3062 if (Cond.isInvalid())
3063 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003064
Douglas Gregorebe10102009-08-20 07:17:43 +00003065 // Rebuild the switch statement.
3066 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
3067 if (Switch.isInvalid())
3068 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003069
Douglas Gregorebe10102009-08-20 07:17:43 +00003070 // Transform the body of the switch statement.
3071 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3072 if (Body.isInvalid())
3073 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003074
Douglas Gregorebe10102009-08-20 07:17:43 +00003075 // Complete the switch statement.
3076 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
3077 move(Body));
3078}
Mike Stump11289f42009-09-09 15:08:12 +00003079
Douglas Gregorebe10102009-08-20 07:17:43 +00003080template<typename Derived>
3081Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003082TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003083 // Transform the condition
3084 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3085 if (Cond.isInvalid())
3086 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003087
Douglas Gregorebe10102009-08-20 07:17:43 +00003088 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00003089
Douglas Gregorebe10102009-08-20 07:17:43 +00003090 // Transform the body
3091 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3092 if (Body.isInvalid())
3093 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003094
Douglas Gregorebe10102009-08-20 07:17:43 +00003095 if (!getDerived().AlwaysRebuild() &&
3096 FullCond->get() == S->getCond() &&
3097 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003098 return SemaRef.Owned(S->Retain());
3099
Douglas Gregorebe10102009-08-20 07:17:43 +00003100 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
3101}
Mike Stump11289f42009-09-09 15:08:12 +00003102
Douglas Gregorebe10102009-08-20 07:17:43 +00003103template<typename Derived>
3104Sema::OwningStmtResult
3105TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
3106 // Transform the condition
3107 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3108 if (Cond.isInvalid())
3109 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003110
Douglas Gregorebe10102009-08-20 07:17:43 +00003111 // Transform the body
3112 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3113 if (Body.isInvalid())
3114 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003115
Douglas Gregorebe10102009-08-20 07:17:43 +00003116 if (!getDerived().AlwaysRebuild() &&
3117 Cond.get() == S->getCond() &&
3118 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003119 return SemaRef.Owned(S->Retain());
3120
Douglas Gregorebe10102009-08-20 07:17:43 +00003121 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
3122 /*FIXME:*/S->getWhileLoc(), move(Cond),
3123 S->getRParenLoc());
3124}
Mike Stump11289f42009-09-09 15:08:12 +00003125
Douglas Gregorebe10102009-08-20 07:17:43 +00003126template<typename Derived>
3127Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003128TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003129 // Transform the initialization statement
3130 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
3131 if (Init.isInvalid())
3132 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003133
Douglas Gregorebe10102009-08-20 07:17:43 +00003134 // Transform the condition
3135 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3136 if (Cond.isInvalid())
3137 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003138
Douglas Gregorebe10102009-08-20 07:17:43 +00003139 // Transform the increment
3140 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
3141 if (Inc.isInvalid())
3142 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003143
Douglas Gregorebe10102009-08-20 07:17:43 +00003144 // Transform the body
3145 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3146 if (Body.isInvalid())
3147 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003148
Douglas Gregorebe10102009-08-20 07:17:43 +00003149 if (!getDerived().AlwaysRebuild() &&
3150 Init.get() == S->getInit() &&
3151 Cond.get() == S->getCond() &&
3152 Inc.get() == S->getInc() &&
3153 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003154 return SemaRef.Owned(S->Retain());
3155
Douglas Gregorebe10102009-08-20 07:17:43 +00003156 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
3157 move(Init), move(Cond), move(Inc),
3158 S->getRParenLoc(), move(Body));
3159}
3160
3161template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003162Sema::OwningStmtResult
3163TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003164 // Goto statements must always be rebuilt, to resolve the label.
Mike Stump11289f42009-09-09 15:08:12 +00003165 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003166 S->getLabel());
3167}
3168
3169template<typename Derived>
3170Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003171TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003172 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
3173 if (Target.isInvalid())
3174 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003175
Douglas Gregorebe10102009-08-20 07:17:43 +00003176 if (!getDerived().AlwaysRebuild() &&
3177 Target.get() == S->getTarget())
Mike Stump11289f42009-09-09 15:08:12 +00003178 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003179
3180 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
3181 move(Target));
3182}
3183
3184template<typename Derived>
3185Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003186TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
3187 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003188}
Mike Stump11289f42009-09-09 15:08:12 +00003189
Douglas Gregorebe10102009-08-20 07:17:43 +00003190template<typename Derived>
3191Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003192TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
3193 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003194}
Mike Stump11289f42009-09-09 15:08:12 +00003195
Douglas Gregorebe10102009-08-20 07:17:43 +00003196template<typename Derived>
3197Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003198TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003199 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
3200 if (Result.isInvalid())
3201 return SemaRef.StmtError();
3202
Mike Stump11289f42009-09-09 15:08:12 +00003203 // FIXME: We always rebuild the return statement because there is no way
Douglas Gregorebe10102009-08-20 07:17:43 +00003204 // to tell whether the return type of the function has changed.
3205 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
3206}
Mike Stump11289f42009-09-09 15:08:12 +00003207
Douglas Gregorebe10102009-08-20 07:17:43 +00003208template<typename Derived>
3209Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003210TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003211 bool DeclChanged = false;
3212 llvm::SmallVector<Decl *, 4> Decls;
3213 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
3214 D != DEnd; ++D) {
3215 Decl *Transformed = getDerived().TransformDefinition(*D);
3216 if (!Transformed)
3217 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003218
Douglas Gregorebe10102009-08-20 07:17:43 +00003219 if (Transformed != *D)
3220 DeclChanged = true;
Mike Stump11289f42009-09-09 15:08:12 +00003221
Douglas Gregorebe10102009-08-20 07:17:43 +00003222 Decls.push_back(Transformed);
3223 }
Mike Stump11289f42009-09-09 15:08:12 +00003224
Douglas Gregorebe10102009-08-20 07:17:43 +00003225 if (!getDerived().AlwaysRebuild() && !DeclChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003226 return SemaRef.Owned(S->Retain());
3227
3228 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003229 S->getStartLoc(), S->getEndLoc());
3230}
Mike Stump11289f42009-09-09 15:08:12 +00003231
Douglas Gregorebe10102009-08-20 07:17:43 +00003232template<typename Derived>
3233Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003234TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003235 assert(false && "SwitchCase is abstract and cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003236 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003237}
3238
3239template<typename Derived>
3240Sema::OwningStmtResult
3241TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
3242 // FIXME: Implement!
3243 assert(false && "Inline assembly cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003244 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003245}
3246
3247
3248template<typename Derived>
3249Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003250TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003251 // FIXME: Implement this
3252 assert(false && "Cannot transform an Objective-C @try statement");
Mike Stump11289f42009-09-09 15:08:12 +00003253 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003254}
Mike Stump11289f42009-09-09 15:08:12 +00003255
Douglas Gregorebe10102009-08-20 07:17:43 +00003256template<typename Derived>
3257Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003258TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003259 // FIXME: Implement this
3260 assert(false && "Cannot transform an Objective-C @catch statement");
3261 return SemaRef.Owned(S->Retain());
3262}
Mike Stump11289f42009-09-09 15:08:12 +00003263
Douglas Gregorebe10102009-08-20 07:17:43 +00003264template<typename Derived>
3265Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003266TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003267 // FIXME: Implement this
3268 assert(false && "Cannot transform an Objective-C @finally statement");
Mike Stump11289f42009-09-09 15:08:12 +00003269 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003270}
Mike Stump11289f42009-09-09 15:08:12 +00003271
Douglas Gregorebe10102009-08-20 07:17:43 +00003272template<typename Derived>
3273Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003274TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003275 // FIXME: Implement this
3276 assert(false && "Cannot transform an Objective-C @throw statement");
Mike Stump11289f42009-09-09 15:08:12 +00003277 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003278}
Mike Stump11289f42009-09-09 15:08:12 +00003279
Douglas Gregorebe10102009-08-20 07:17:43 +00003280template<typename Derived>
3281Sema::OwningStmtResult
3282TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003283 ObjCAtSynchronizedStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003284 // FIXME: Implement this
3285 assert(false && "Cannot transform an Objective-C @synchronized statement");
Mike Stump11289f42009-09-09 15:08:12 +00003286 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003287}
3288
3289template<typename Derived>
3290Sema::OwningStmtResult
3291TreeTransform<Derived>::TransformObjCForCollectionStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003292 ObjCForCollectionStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003293 // FIXME: Implement this
3294 assert(false && "Cannot transform an Objective-C for-each statement");
Mike Stump11289f42009-09-09 15:08:12 +00003295 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003296}
3297
3298
3299template<typename Derived>
3300Sema::OwningStmtResult
3301TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
3302 // Transform the exception declaration, if any.
3303 VarDecl *Var = 0;
3304 if (S->getExceptionDecl()) {
3305 VarDecl *ExceptionDecl = S->getExceptionDecl();
3306 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
3307 ExceptionDecl->getDeclName());
3308
3309 QualType T = getDerived().TransformType(ExceptionDecl->getType());
3310 if (T.isNull())
3311 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003312
Douglas Gregorebe10102009-08-20 07:17:43 +00003313 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
3314 T,
3315 ExceptionDecl->getDeclaratorInfo(),
3316 ExceptionDecl->getIdentifier(),
3317 ExceptionDecl->getLocation(),
3318 /*FIXME: Inaccurate*/
3319 SourceRange(ExceptionDecl->getLocation()));
3320 if (!Var || Var->isInvalidDecl()) {
3321 if (Var)
3322 Var->Destroy(SemaRef.Context);
3323 return SemaRef.StmtError();
3324 }
3325 }
Mike Stump11289f42009-09-09 15:08:12 +00003326
Douglas Gregorebe10102009-08-20 07:17:43 +00003327 // Transform the actual exception handler.
3328 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
3329 if (Handler.isInvalid()) {
3330 if (Var)
3331 Var->Destroy(SemaRef.Context);
3332 return SemaRef.StmtError();
3333 }
Mike Stump11289f42009-09-09 15:08:12 +00003334
Douglas Gregorebe10102009-08-20 07:17:43 +00003335 if (!getDerived().AlwaysRebuild() &&
3336 !Var &&
3337 Handler.get() == S->getHandlerBlock())
Mike Stump11289f42009-09-09 15:08:12 +00003338 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003339
3340 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
3341 Var,
3342 move(Handler));
3343}
Mike Stump11289f42009-09-09 15:08:12 +00003344
Douglas Gregorebe10102009-08-20 07:17:43 +00003345template<typename Derived>
3346Sema::OwningStmtResult
3347TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
3348 // Transform the try block itself.
Mike Stump11289f42009-09-09 15:08:12 +00003349 OwningStmtResult TryBlock
Douglas Gregorebe10102009-08-20 07:17:43 +00003350 = getDerived().TransformCompoundStmt(S->getTryBlock());
3351 if (TryBlock.isInvalid())
3352 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003353
Douglas Gregorebe10102009-08-20 07:17:43 +00003354 // Transform the handlers.
3355 bool HandlerChanged = false;
3356 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
3357 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +00003358 OwningStmtResult Handler
Douglas Gregorebe10102009-08-20 07:17:43 +00003359 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
3360 if (Handler.isInvalid())
3361 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003362
Douglas Gregorebe10102009-08-20 07:17:43 +00003363 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
3364 Handlers.push_back(Handler.takeAs<Stmt>());
3365 }
Mike Stump11289f42009-09-09 15:08:12 +00003366
Douglas Gregorebe10102009-08-20 07:17:43 +00003367 if (!getDerived().AlwaysRebuild() &&
3368 TryBlock.get() == S->getTryBlock() &&
3369 !HandlerChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003370 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003371
3372 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
Mike Stump11289f42009-09-09 15:08:12 +00003373 move_arg(Handlers));
Douglas Gregorebe10102009-08-20 07:17:43 +00003374}
Mike Stump11289f42009-09-09 15:08:12 +00003375
Douglas Gregorebe10102009-08-20 07:17:43 +00003376//===----------------------------------------------------------------------===//
Douglas Gregora16548e2009-08-11 05:31:07 +00003377// Expression transformation
3378//===----------------------------------------------------------------------===//
Mike Stump11289f42009-09-09 15:08:12 +00003379template<typename Derived>
3380Sema::OwningExprResult
3381TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
3382 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003383}
Mike Stump11289f42009-09-09 15:08:12 +00003384
3385template<typename Derived>
3386Sema::OwningExprResult
3387TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003388 NestedNameSpecifier *Qualifier = 0;
3389 if (E->getQualifier()) {
3390 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3391 E->getQualifierRange());
3392 if (!Qualifier)
3393 return SemaRef.ExprError();
3394 }
3395
Mike Stump11289f42009-09-09 15:08:12 +00003396 NamedDecl *ND
Douglas Gregora16548e2009-08-11 05:31:07 +00003397 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3398 if (!ND)
3399 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003400
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003401 if (!getDerived().AlwaysRebuild() &&
3402 Qualifier == E->getQualifier() &&
3403 ND == E->getDecl() &&
3404 !E->hasExplicitTemplateArgumentList())
Mike Stump11289f42009-09-09 15:08:12 +00003405 return SemaRef.Owned(E->Retain());
3406
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003407 // FIXME: We're losing the explicit template arguments in this transformation.
3408
John McCall0ad16662009-10-29 08:12:44 +00003409 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003410 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00003411 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
3412 TransArgs[I]))
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003413 return SemaRef.ExprError();
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003414 }
3415
3416 // FIXME: Pass the qualifier/qualifier range along.
3417 return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
3418 ND, E->getLocation());
Douglas Gregora16548e2009-08-11 05:31:07 +00003419}
Mike Stump11289f42009-09-09 15:08:12 +00003420
Douglas Gregora16548e2009-08-11 05:31:07 +00003421template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003422Sema::OwningExprResult
3423TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
3424 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003425}
Mike Stump11289f42009-09-09 15:08:12 +00003426
Douglas Gregora16548e2009-08-11 05:31:07 +00003427template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003428Sema::OwningExprResult
3429TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
3430 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003431}
Mike Stump11289f42009-09-09 15:08:12 +00003432
Douglas Gregora16548e2009-08-11 05:31:07 +00003433template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003434Sema::OwningExprResult
3435TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
3436 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003437}
Mike Stump11289f42009-09-09 15:08:12 +00003438
Douglas Gregora16548e2009-08-11 05:31:07 +00003439template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003440Sema::OwningExprResult
3441TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
3442 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003443}
Mike Stump11289f42009-09-09 15:08:12 +00003444
Douglas Gregora16548e2009-08-11 05:31:07 +00003445template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003446Sema::OwningExprResult
3447TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
3448 return SemaRef.Owned(E->Retain());
3449}
3450
3451template<typename Derived>
3452Sema::OwningExprResult
3453TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003454 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3455 if (SubExpr.isInvalid())
3456 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003457
Douglas Gregora16548e2009-08-11 05:31:07 +00003458 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003459 return SemaRef.Owned(E->Retain());
3460
3461 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003462 E->getRParen());
3463}
3464
Mike Stump11289f42009-09-09 15:08:12 +00003465template<typename Derived>
3466Sema::OwningExprResult
3467TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003468 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3469 if (SubExpr.isInvalid())
3470 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003471
Douglas Gregora16548e2009-08-11 05:31:07 +00003472 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003473 return SemaRef.Owned(E->Retain());
3474
Douglas Gregora16548e2009-08-11 05:31:07 +00003475 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
3476 E->getOpcode(),
3477 move(SubExpr));
3478}
Mike Stump11289f42009-09-09 15:08:12 +00003479
Douglas Gregora16548e2009-08-11 05:31:07 +00003480template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003481Sema::OwningExprResult
3482TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003483 if (E->isArgumentType()) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003484 TemporaryBase Rebase(*this, E->getOperatorLoc(), DeclarationName());
3485
Douglas Gregora16548e2009-08-11 05:31:07 +00003486 QualType T = getDerived().TransformType(E->getArgumentType());
3487 if (T.isNull())
3488 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003489
Douglas Gregora16548e2009-08-11 05:31:07 +00003490 if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
3491 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003492
3493 return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
3494 E->isSizeOf(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003495 E->getSourceRange());
3496 }
Mike Stump11289f42009-09-09 15:08:12 +00003497
Douglas Gregora16548e2009-08-11 05:31:07 +00003498 Sema::OwningExprResult SubExpr(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00003499 {
Douglas Gregora16548e2009-08-11 05:31:07 +00003500 // C++0x [expr.sizeof]p1:
3501 // The operand is either an expression, which is an unevaluated operand
3502 // [...]
3503 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00003504
Douglas Gregora16548e2009-08-11 05:31:07 +00003505 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
3506 if (SubExpr.isInvalid())
3507 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003508
Douglas Gregora16548e2009-08-11 05:31:07 +00003509 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
3510 return SemaRef.Owned(E->Retain());
3511 }
Mike Stump11289f42009-09-09 15:08:12 +00003512
Douglas Gregora16548e2009-08-11 05:31:07 +00003513 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
3514 E->isSizeOf(),
3515 E->getSourceRange());
3516}
Mike Stump11289f42009-09-09 15:08:12 +00003517
Douglas Gregora16548e2009-08-11 05:31:07 +00003518template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003519Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003520TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
3521 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3522 if (LHS.isInvalid())
3523 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003524
Douglas Gregora16548e2009-08-11 05:31:07 +00003525 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3526 if (RHS.isInvalid())
3527 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003528
3529
Douglas Gregora16548e2009-08-11 05:31:07 +00003530 if (!getDerived().AlwaysRebuild() &&
3531 LHS.get() == E->getLHS() &&
3532 RHS.get() == E->getRHS())
3533 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003534
Douglas Gregora16548e2009-08-11 05:31:07 +00003535 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3536 /*FIXME:*/E->getLHS()->getLocStart(),
3537 move(RHS),
3538 E->getRBracketLoc());
3539}
Mike Stump11289f42009-09-09 15:08:12 +00003540
3541template<typename Derived>
3542Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003543TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
3544 // Transform the callee.
3545 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3546 if (Callee.isInvalid())
3547 return SemaRef.ExprError();
3548
3549 // Transform arguments.
3550 bool ArgChanged = false;
3551 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3552 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3553 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3554 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3555 if (Arg.isInvalid())
3556 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003557
Douglas Gregora16548e2009-08-11 05:31:07 +00003558 // FIXME: Wrong source location information for the ','.
3559 FakeCommaLocs.push_back(
3560 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
Mike Stump11289f42009-09-09 15:08:12 +00003561
3562 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
Douglas Gregora16548e2009-08-11 05:31:07 +00003563 Args.push_back(Arg.takeAs<Expr>());
3564 }
Mike Stump11289f42009-09-09 15:08:12 +00003565
Douglas Gregora16548e2009-08-11 05:31:07 +00003566 if (!getDerived().AlwaysRebuild() &&
3567 Callee.get() == E->getCallee() &&
3568 !ArgChanged)
3569 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003570
Douglas Gregora16548e2009-08-11 05:31:07 +00003571 // FIXME: Wrong source location information for the '('.
Mike Stump11289f42009-09-09 15:08:12 +00003572 SourceLocation FakeLParenLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003573 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3574 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3575 move_arg(Args),
3576 FakeCommaLocs.data(),
3577 E->getRParenLoc());
3578}
Mike Stump11289f42009-09-09 15:08:12 +00003579
3580template<typename Derived>
3581Sema::OwningExprResult
3582TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003583 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3584 if (Base.isInvalid())
3585 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003586
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003587 NestedNameSpecifier *Qualifier = 0;
3588 if (E->hasQualifier()) {
Mike Stump11289f42009-09-09 15:08:12 +00003589 Qualifier
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003590 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3591 E->getQualifierRange());
Douglas Gregor84f14dd2009-09-01 00:37:14 +00003592 if (Qualifier == 0)
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003593 return SemaRef.ExprError();
3594 }
Mike Stump11289f42009-09-09 15:08:12 +00003595
3596 NamedDecl *Member
Douglas Gregora16548e2009-08-11 05:31:07 +00003597 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3598 if (!Member)
3599 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003600
Douglas Gregora16548e2009-08-11 05:31:07 +00003601 if (!getDerived().AlwaysRebuild() &&
3602 Base.get() == E->getBase() &&
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003603 Qualifier == E->getQualifier() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00003604 Member == E->getMemberDecl())
Mike Stump11289f42009-09-09 15:08:12 +00003605 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003606
3607 // FIXME: Bogus source location for the operator
3608 SourceLocation FakeOperatorLoc
3609 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3610
3611 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3612 E->isArrow(),
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003613 Qualifier,
3614 E->getQualifierRange(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003615 E->getMemberLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003616 Member);
Douglas Gregora16548e2009-08-11 05:31:07 +00003617}
Mike Stump11289f42009-09-09 15:08:12 +00003618
Douglas Gregora16548e2009-08-11 05:31:07 +00003619template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003620Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003621TreeTransform<Derived>::TransformCastExpr(CastExpr *E) {
3622 assert(false && "Cannot transform abstract class");
3623 return SemaRef.Owned(E->Retain());
3624}
3625
3626template<typename Derived>
3627Sema::OwningExprResult
3628TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003629 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3630 if (LHS.isInvalid())
3631 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003632
Douglas Gregora16548e2009-08-11 05:31:07 +00003633 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3634 if (RHS.isInvalid())
3635 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003636
Douglas Gregora16548e2009-08-11 05:31:07 +00003637 if (!getDerived().AlwaysRebuild() &&
3638 LHS.get() == E->getLHS() &&
3639 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00003640 return SemaRef.Owned(E->Retain());
3641
Douglas Gregora16548e2009-08-11 05:31:07 +00003642 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3643 move(LHS), move(RHS));
3644}
3645
Mike Stump11289f42009-09-09 15:08:12 +00003646template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003647Sema::OwningExprResult
3648TreeTransform<Derived>::TransformCompoundAssignOperator(
3649 CompoundAssignOperator *E) {
3650 return getDerived().TransformBinaryOperator(E);
3651}
Mike Stump11289f42009-09-09 15:08:12 +00003652
Douglas Gregora16548e2009-08-11 05:31:07 +00003653template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003654Sema::OwningExprResult
3655TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003656 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3657 if (Cond.isInvalid())
3658 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003659
Douglas Gregora16548e2009-08-11 05:31:07 +00003660 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3661 if (LHS.isInvalid())
3662 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003663
Douglas Gregora16548e2009-08-11 05:31:07 +00003664 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3665 if (RHS.isInvalid())
3666 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003667
Douglas Gregora16548e2009-08-11 05:31:07 +00003668 if (!getDerived().AlwaysRebuild() &&
3669 Cond.get() == E->getCond() &&
3670 LHS.get() == E->getLHS() &&
3671 RHS.get() == E->getRHS())
3672 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003673
3674 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003675 E->getQuestionLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003676 move(LHS),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003677 E->getColonLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003678 move(RHS));
3679}
Mike Stump11289f42009-09-09 15:08:12 +00003680
3681template<typename Derived>
3682Sema::OwningExprResult
3683TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003684 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3685
3686 // FIXME: Will we ever have type information here? It seems like we won't,
3687 // so do we even need to transform the type?
Douglas Gregora16548e2009-08-11 05:31:07 +00003688 QualType T = getDerived().TransformType(E->getType());
3689 if (T.isNull())
3690 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003691
Douglas Gregora16548e2009-08-11 05:31:07 +00003692 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3693 if (SubExpr.isInvalid())
3694 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003695
Douglas Gregora16548e2009-08-11 05:31:07 +00003696 if (!getDerived().AlwaysRebuild() &&
3697 T == E->getType() &&
3698 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003699 return SemaRef.Owned(E->Retain());
3700
Douglas Gregora16548e2009-08-11 05:31:07 +00003701 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
Mike Stump11289f42009-09-09 15:08:12 +00003702 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00003703 E->isLvalueCast());
3704}
Mike Stump11289f42009-09-09 15:08:12 +00003705
Douglas Gregora16548e2009-08-11 05:31:07 +00003706template<typename Derived>
3707Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003708TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E) {
3709 assert(false && "Cannot transform abstract class");
3710 return SemaRef.Owned(E->Retain());
3711}
3712
3713template<typename Derived>
3714Sema::OwningExprResult
3715TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003716 QualType T;
3717 {
3718 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003719 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003720 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3721 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003722
Douglas Gregora16548e2009-08-11 05:31:07 +00003723 T = getDerived().TransformType(E->getTypeAsWritten());
3724 if (T.isNull())
3725 return SemaRef.ExprError();
3726 }
Mike Stump11289f42009-09-09 15:08:12 +00003727
Douglas Gregora16548e2009-08-11 05:31:07 +00003728 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3729 if (SubExpr.isInvalid())
3730 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003731
Douglas Gregora16548e2009-08-11 05:31:07 +00003732 if (!getDerived().AlwaysRebuild() &&
3733 T == E->getTypeAsWritten() &&
3734 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003735 return SemaRef.Owned(E->Retain());
3736
Douglas Gregora16548e2009-08-11 05:31:07 +00003737 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3738 E->getRParenLoc(),
3739 move(SubExpr));
3740}
Mike Stump11289f42009-09-09 15:08:12 +00003741
Douglas Gregora16548e2009-08-11 05:31:07 +00003742template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003743Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003744TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
3745 QualType T;
3746 {
3747 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003748 SourceLocation FakeTypeLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003749 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3750 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003751
Douglas Gregora16548e2009-08-11 05:31:07 +00003752 T = getDerived().TransformType(E->getType());
3753 if (T.isNull())
3754 return SemaRef.ExprError();
3755 }
Mike Stump11289f42009-09-09 15:08:12 +00003756
Douglas Gregora16548e2009-08-11 05:31:07 +00003757 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3758 if (Init.isInvalid())
3759 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003760
Douglas Gregora16548e2009-08-11 05:31:07 +00003761 if (!getDerived().AlwaysRebuild() &&
3762 T == E->getType() &&
3763 Init.get() == E->getInitializer())
Mike Stump11289f42009-09-09 15:08:12 +00003764 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003765
3766 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3767 /*FIXME:*/E->getInitializer()->getLocEnd(),
3768 move(Init));
3769}
Mike Stump11289f42009-09-09 15:08:12 +00003770
Douglas Gregora16548e2009-08-11 05:31:07 +00003771template<typename Derived>
3772Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003773TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003774 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3775 if (Base.isInvalid())
3776 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003777
Douglas Gregora16548e2009-08-11 05:31:07 +00003778 if (!getDerived().AlwaysRebuild() &&
3779 Base.get() == E->getBase())
Mike Stump11289f42009-09-09 15:08:12 +00003780 return SemaRef.Owned(E->Retain());
3781
Douglas Gregora16548e2009-08-11 05:31:07 +00003782 // FIXME: Bad source location
Mike Stump11289f42009-09-09 15:08:12 +00003783 SourceLocation FakeOperatorLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003784 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3785 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3786 E->getAccessorLoc(),
3787 E->getAccessor());
3788}
Mike Stump11289f42009-09-09 15:08:12 +00003789
Douglas Gregora16548e2009-08-11 05:31:07 +00003790template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003791Sema::OwningExprResult
3792TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003793 bool InitChanged = false;
Mike Stump11289f42009-09-09 15:08:12 +00003794
Douglas Gregora16548e2009-08-11 05:31:07 +00003795 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3796 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3797 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3798 if (Init.isInvalid())
3799 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003800
Douglas Gregora16548e2009-08-11 05:31:07 +00003801 InitChanged = InitChanged || Init.get() != E->getInit(I);
3802 Inits.push_back(Init.takeAs<Expr>());
3803 }
Mike Stump11289f42009-09-09 15:08:12 +00003804
Douglas Gregora16548e2009-08-11 05:31:07 +00003805 if (!getDerived().AlwaysRebuild() && !InitChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003806 return SemaRef.Owned(E->Retain());
3807
Douglas Gregora16548e2009-08-11 05:31:07 +00003808 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
3809 E->getRBraceLoc());
3810}
Mike Stump11289f42009-09-09 15:08:12 +00003811
Douglas Gregora16548e2009-08-11 05:31:07 +00003812template<typename Derived>
3813Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003814TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003815 Designation Desig;
Mike Stump11289f42009-09-09 15:08:12 +00003816
Douglas Gregorebe10102009-08-20 07:17:43 +00003817 // transform the initializer value
Douglas Gregora16548e2009-08-11 05:31:07 +00003818 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3819 if (Init.isInvalid())
3820 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003821
Douglas Gregorebe10102009-08-20 07:17:43 +00003822 // transform the designators.
Douglas Gregora16548e2009-08-11 05:31:07 +00003823 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3824 bool ExprChanged = false;
3825 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3826 DEnd = E->designators_end();
3827 D != DEnd; ++D) {
3828 if (D->isFieldDesignator()) {
3829 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3830 D->getDotLoc(),
3831 D->getFieldLoc()));
3832 continue;
3833 }
Mike Stump11289f42009-09-09 15:08:12 +00003834
Douglas Gregora16548e2009-08-11 05:31:07 +00003835 if (D->isArrayDesignator()) {
3836 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3837 if (Index.isInvalid())
3838 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003839
3840 Desig.AddDesignator(Designator::getArray(Index.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003841 D->getLBracketLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003842
Douglas Gregora16548e2009-08-11 05:31:07 +00003843 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3844 ArrayExprs.push_back(Index.release());
3845 continue;
3846 }
Mike Stump11289f42009-09-09 15:08:12 +00003847
Douglas Gregora16548e2009-08-11 05:31:07 +00003848 assert(D->isArrayRangeDesignator() && "New kind of designator?");
Mike Stump11289f42009-09-09 15:08:12 +00003849 OwningExprResult Start
Douglas Gregora16548e2009-08-11 05:31:07 +00003850 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3851 if (Start.isInvalid())
3852 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003853
Douglas Gregora16548e2009-08-11 05:31:07 +00003854 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3855 if (End.isInvalid())
3856 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003857
3858 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003859 End.get(),
3860 D->getLBracketLoc(),
3861 D->getEllipsisLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003862
Douglas Gregora16548e2009-08-11 05:31:07 +00003863 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3864 End.get() != E->getArrayRangeEnd(*D);
Mike Stump11289f42009-09-09 15:08:12 +00003865
Douglas Gregora16548e2009-08-11 05:31:07 +00003866 ArrayExprs.push_back(Start.release());
3867 ArrayExprs.push_back(End.release());
3868 }
Mike Stump11289f42009-09-09 15:08:12 +00003869
Douglas Gregora16548e2009-08-11 05:31:07 +00003870 if (!getDerived().AlwaysRebuild() &&
3871 Init.get() == E->getInit() &&
3872 !ExprChanged)
3873 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003874
Douglas Gregora16548e2009-08-11 05:31:07 +00003875 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3876 E->getEqualOrColonLoc(),
3877 E->usesGNUSyntax(), move(Init));
3878}
Mike Stump11289f42009-09-09 15:08:12 +00003879
Douglas Gregora16548e2009-08-11 05:31:07 +00003880template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003881Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003882TreeTransform<Derived>::TransformImplicitValueInitExpr(
Mike Stump11289f42009-09-09 15:08:12 +00003883 ImplicitValueInitExpr *E) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003884 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3885
3886 // FIXME: Will we ever have proper type location here? Will we actually
3887 // need to transform the type?
Douglas Gregora16548e2009-08-11 05:31:07 +00003888 QualType T = getDerived().TransformType(E->getType());
3889 if (T.isNull())
3890 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003891
Douglas Gregora16548e2009-08-11 05:31:07 +00003892 if (!getDerived().AlwaysRebuild() &&
3893 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00003894 return SemaRef.Owned(E->Retain());
3895
Douglas Gregora16548e2009-08-11 05:31:07 +00003896 return getDerived().RebuildImplicitValueInitExpr(T);
3897}
Mike Stump11289f42009-09-09 15:08:12 +00003898
Douglas Gregora16548e2009-08-11 05:31:07 +00003899template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003900Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003901TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
3902 // FIXME: Do we want the type as written?
3903 QualType T;
Mike Stump11289f42009-09-09 15:08:12 +00003904
Douglas Gregora16548e2009-08-11 05:31:07 +00003905 {
3906 // FIXME: Source location isn't quite accurate.
3907 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3908 T = getDerived().TransformType(E->getType());
3909 if (T.isNull())
3910 return SemaRef.ExprError();
3911 }
Mike Stump11289f42009-09-09 15:08:12 +00003912
Douglas Gregora16548e2009-08-11 05:31:07 +00003913 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3914 if (SubExpr.isInvalid())
3915 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003916
Douglas Gregora16548e2009-08-11 05:31:07 +00003917 if (!getDerived().AlwaysRebuild() &&
3918 T == E->getType() &&
3919 SubExpr.get() == E->getSubExpr())
3920 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003921
Douglas Gregora16548e2009-08-11 05:31:07 +00003922 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
3923 T, E->getRParenLoc());
3924}
3925
3926template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003927Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003928TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
3929 bool ArgumentChanged = false;
3930 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3931 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
3932 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
3933 if (Init.isInvalid())
3934 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003935
Douglas Gregora16548e2009-08-11 05:31:07 +00003936 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
3937 Inits.push_back(Init.takeAs<Expr>());
3938 }
Mike Stump11289f42009-09-09 15:08:12 +00003939
Douglas Gregora16548e2009-08-11 05:31:07 +00003940 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
3941 move_arg(Inits),
3942 E->getRParenLoc());
3943}
Mike Stump11289f42009-09-09 15:08:12 +00003944
Douglas Gregora16548e2009-08-11 05:31:07 +00003945/// \brief Transform an address-of-label expression.
3946///
3947/// By default, the transformation of an address-of-label expression always
3948/// rebuilds the expression, so that the label identifier can be resolved to
3949/// the corresponding label statement by semantic analysis.
3950template<typename Derived>
3951Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003952TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003953 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
3954 E->getLabel());
3955}
Mike Stump11289f42009-09-09 15:08:12 +00003956
3957template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003958Sema::OwningExprResult TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
Mike Stump11289f42009-09-09 15:08:12 +00003959 OwningStmtResult SubStmt
Douglas Gregora16548e2009-08-11 05:31:07 +00003960 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
3961 if (SubStmt.isInvalid())
3962 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003963
Douglas Gregora16548e2009-08-11 05:31:07 +00003964 if (!getDerived().AlwaysRebuild() &&
3965 SubStmt.get() == E->getSubStmt())
3966 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003967
3968 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003969 move(SubStmt),
3970 E->getRParenLoc());
3971}
Mike Stump11289f42009-09-09 15:08:12 +00003972
Douglas Gregora16548e2009-08-11 05:31:07 +00003973template<typename Derived>
3974Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003975TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003976 QualType T1, T2;
3977 {
3978 // FIXME: Source location isn't quite accurate.
3979 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003980
Douglas Gregora16548e2009-08-11 05:31:07 +00003981 T1 = getDerived().TransformType(E->getArgType1());
3982 if (T1.isNull())
3983 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003984
Douglas Gregora16548e2009-08-11 05:31:07 +00003985 T2 = getDerived().TransformType(E->getArgType2());
3986 if (T2.isNull())
3987 return SemaRef.ExprError();
3988 }
3989
3990 if (!getDerived().AlwaysRebuild() &&
3991 T1 == E->getArgType1() &&
3992 T2 == E->getArgType2())
Mike Stump11289f42009-09-09 15:08:12 +00003993 return SemaRef.Owned(E->Retain());
3994
Douglas Gregora16548e2009-08-11 05:31:07 +00003995 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
3996 T1, T2, E->getRParenLoc());
3997}
Mike Stump11289f42009-09-09 15:08:12 +00003998
Douglas Gregora16548e2009-08-11 05:31:07 +00003999template<typename Derived>
4000Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004001TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004002 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
4003 if (Cond.isInvalid())
4004 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004005
Douglas Gregora16548e2009-08-11 05:31:07 +00004006 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
4007 if (LHS.isInvalid())
4008 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004009
Douglas Gregora16548e2009-08-11 05:31:07 +00004010 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
4011 if (RHS.isInvalid())
4012 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004013
Douglas Gregora16548e2009-08-11 05:31:07 +00004014 if (!getDerived().AlwaysRebuild() &&
4015 Cond.get() == E->getCond() &&
4016 LHS.get() == E->getLHS() &&
4017 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00004018 return SemaRef.Owned(E->Retain());
4019
Douglas Gregora16548e2009-08-11 05:31:07 +00004020 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
4021 move(Cond), move(LHS), move(RHS),
4022 E->getRParenLoc());
4023}
Mike Stump11289f42009-09-09 15:08:12 +00004024
Douglas Gregora16548e2009-08-11 05:31:07 +00004025template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004026Sema::OwningExprResult
4027TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
4028 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004029}
4030
4031template<typename Derived>
4032Sema::OwningExprResult
4033TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
4034 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
4035 if (Callee.isInvalid())
4036 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004037
Douglas Gregora16548e2009-08-11 05:31:07 +00004038 OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
4039 if (First.isInvalid())
4040 return SemaRef.ExprError();
4041
4042 OwningExprResult Second(SemaRef);
4043 if (E->getNumArgs() == 2) {
4044 Second = getDerived().TransformExpr(E->getArg(1));
4045 if (Second.isInvalid())
4046 return SemaRef.ExprError();
4047 }
Mike Stump11289f42009-09-09 15:08:12 +00004048
Douglas Gregora16548e2009-08-11 05:31:07 +00004049 if (!getDerived().AlwaysRebuild() &&
4050 Callee.get() == E->getCallee() &&
4051 First.get() == E->getArg(0) &&
Mike Stump11289f42009-09-09 15:08:12 +00004052 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
4053 return SemaRef.Owned(E->Retain());
4054
Douglas Gregora16548e2009-08-11 05:31:07 +00004055 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
4056 E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00004057 move(Callee),
Douglas Gregora16548e2009-08-11 05:31:07 +00004058 move(First),
4059 move(Second));
4060}
Mike Stump11289f42009-09-09 15:08:12 +00004061
Douglas Gregora16548e2009-08-11 05:31:07 +00004062template<typename Derived>
4063Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004064TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004065 return getDerived().TransformCallExpr(E);
4066}
Mike Stump11289f42009-09-09 15:08:12 +00004067
Douglas Gregora16548e2009-08-11 05:31:07 +00004068template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004069Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004070TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
4071 QualType ExplicitTy;
4072 {
4073 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00004074 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004075 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4076 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004077
Douglas Gregora16548e2009-08-11 05:31:07 +00004078 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4079 if (ExplicitTy.isNull())
4080 return SemaRef.ExprError();
4081 }
Mike Stump11289f42009-09-09 15:08:12 +00004082
Douglas Gregora16548e2009-08-11 05:31:07 +00004083 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4084 if (SubExpr.isInvalid())
4085 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004086
Douglas Gregora16548e2009-08-11 05:31:07 +00004087 if (!getDerived().AlwaysRebuild() &&
4088 ExplicitTy == E->getTypeAsWritten() &&
4089 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004090 return SemaRef.Owned(E->Retain());
4091
Douglas Gregora16548e2009-08-11 05:31:07 +00004092 // FIXME: Poor source location information here.
Mike Stump11289f42009-09-09 15:08:12 +00004093 SourceLocation FakeLAngleLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004094 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
4095 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
4096 SourceLocation FakeRParenLoc
4097 = SemaRef.PP.getLocForEndOfToken(
4098 E->getSubExpr()->getSourceRange().getEnd());
4099 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00004100 E->getStmtClass(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004101 FakeLAngleLoc,
4102 ExplicitTy,
4103 FakeRAngleLoc,
4104 FakeRAngleLoc,
4105 move(SubExpr),
4106 FakeRParenLoc);
4107}
Mike Stump11289f42009-09-09 15:08:12 +00004108
Douglas Gregora16548e2009-08-11 05:31:07 +00004109template<typename Derived>
4110Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004111TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004112 return getDerived().TransformCXXNamedCastExpr(E);
4113}
Mike Stump11289f42009-09-09 15:08:12 +00004114
4115template<typename Derived>
4116Sema::OwningExprResult
4117TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
4118 return getDerived().TransformCXXNamedCastExpr(E);
4119}
4120
Douglas Gregora16548e2009-08-11 05:31:07 +00004121template<typename Derived>
4122Sema::OwningExprResult
4123TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004124 CXXReinterpretCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004125 return getDerived().TransformCXXNamedCastExpr(E);
4126}
Mike Stump11289f42009-09-09 15:08:12 +00004127
Douglas Gregora16548e2009-08-11 05:31:07 +00004128template<typename Derived>
4129Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004130TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004131 return getDerived().TransformCXXNamedCastExpr(E);
4132}
Mike Stump11289f42009-09-09 15:08:12 +00004133
Douglas Gregora16548e2009-08-11 05:31:07 +00004134template<typename Derived>
4135Sema::OwningExprResult
4136TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004137 CXXFunctionalCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004138 QualType ExplicitTy;
4139 {
4140 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004141
Douglas Gregora16548e2009-08-11 05:31:07 +00004142 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4143 if (ExplicitTy.isNull())
4144 return SemaRef.ExprError();
4145 }
Mike Stump11289f42009-09-09 15:08:12 +00004146
Douglas Gregora16548e2009-08-11 05:31:07 +00004147 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4148 if (SubExpr.isInvalid())
4149 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004150
Douglas Gregora16548e2009-08-11 05:31:07 +00004151 if (!getDerived().AlwaysRebuild() &&
4152 ExplicitTy == E->getTypeAsWritten() &&
4153 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004154 return SemaRef.Owned(E->Retain());
4155
Douglas Gregora16548e2009-08-11 05:31:07 +00004156 // FIXME: The end of the type's source range is wrong
4157 return getDerived().RebuildCXXFunctionalCastExpr(
4158 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
4159 ExplicitTy,
4160 /*FIXME:*/E->getSubExpr()->getLocStart(),
4161 move(SubExpr),
4162 E->getRParenLoc());
4163}
Mike Stump11289f42009-09-09 15:08:12 +00004164
Douglas Gregora16548e2009-08-11 05:31:07 +00004165template<typename Derived>
4166Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004167TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004168 if (E->isTypeOperand()) {
4169 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004170
Douglas Gregora16548e2009-08-11 05:31:07 +00004171 QualType T = getDerived().TransformType(E->getTypeOperand());
4172 if (T.isNull())
4173 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004174
Douglas Gregora16548e2009-08-11 05:31:07 +00004175 if (!getDerived().AlwaysRebuild() &&
4176 T == E->getTypeOperand())
4177 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004178
Douglas Gregora16548e2009-08-11 05:31:07 +00004179 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4180 /*FIXME:*/E->getLocStart(),
4181 T,
4182 E->getLocEnd());
4183 }
Mike Stump11289f42009-09-09 15:08:12 +00004184
Douglas Gregora16548e2009-08-11 05:31:07 +00004185 // We don't know whether the expression is potentially evaluated until
4186 // after we perform semantic analysis, so the expression is potentially
4187 // potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00004188 EnterExpressionEvaluationContext Unevaluated(SemaRef,
Douglas Gregora16548e2009-08-11 05:31:07 +00004189 Action::PotentiallyPotentiallyEvaluated);
Mike Stump11289f42009-09-09 15:08:12 +00004190
Douglas Gregora16548e2009-08-11 05:31:07 +00004191 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
4192 if (SubExpr.isInvalid())
4193 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004194
Douglas Gregora16548e2009-08-11 05:31:07 +00004195 if (!getDerived().AlwaysRebuild() &&
4196 SubExpr.get() == E->getExprOperand())
Mike Stump11289f42009-09-09 15:08:12 +00004197 return SemaRef.Owned(E->Retain());
4198
Douglas Gregora16548e2009-08-11 05:31:07 +00004199 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4200 /*FIXME:*/E->getLocStart(),
4201 move(SubExpr),
4202 E->getLocEnd());
4203}
4204
4205template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004206Sema::OwningExprResult
4207TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
4208 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004209}
Mike Stump11289f42009-09-09 15:08:12 +00004210
Douglas Gregora16548e2009-08-11 05:31:07 +00004211template<typename Derived>
4212Sema::OwningExprResult
4213TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004214 CXXNullPtrLiteralExpr *E) {
4215 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004216}
Mike Stump11289f42009-09-09 15:08:12 +00004217
Douglas Gregora16548e2009-08-11 05:31:07 +00004218template<typename Derived>
4219Sema::OwningExprResult
4220TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
4221 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004222
Douglas Gregora16548e2009-08-11 05:31:07 +00004223 QualType T = getDerived().TransformType(E->getType());
4224 if (T.isNull())
4225 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004226
Douglas Gregora16548e2009-08-11 05:31:07 +00004227 if (!getDerived().AlwaysRebuild() &&
4228 T == E->getType())
4229 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004230
Douglas Gregora16548e2009-08-11 05:31:07 +00004231 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
4232}
Mike Stump11289f42009-09-09 15:08:12 +00004233
Douglas Gregora16548e2009-08-11 05:31:07 +00004234template<typename Derived>
4235Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004236TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004237 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4238 if (SubExpr.isInvalid())
4239 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004240
Douglas Gregora16548e2009-08-11 05:31:07 +00004241 if (!getDerived().AlwaysRebuild() &&
4242 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004243 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004244
4245 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
4246}
Mike Stump11289f42009-09-09 15:08:12 +00004247
Douglas Gregora16548e2009-08-11 05:31:07 +00004248template<typename Derived>
4249Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004250TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
4251 ParmVarDecl *Param
Douglas Gregora16548e2009-08-11 05:31:07 +00004252 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
4253 if (!Param)
4254 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004255
Douglas Gregora16548e2009-08-11 05:31:07 +00004256 if (getDerived().AlwaysRebuild() &&
4257 Param == E->getParam())
4258 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004259
Douglas Gregora16548e2009-08-11 05:31:07 +00004260 return getDerived().RebuildCXXDefaultArgExpr(Param);
4261}
Mike Stump11289f42009-09-09 15:08:12 +00004262
Douglas Gregora16548e2009-08-11 05:31:07 +00004263template<typename Derived>
4264Sema::OwningExprResult
4265TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
4266 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4267
4268 QualType T = getDerived().TransformType(E->getType());
4269 if (T.isNull())
4270 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004271
Douglas Gregora16548e2009-08-11 05:31:07 +00004272 if (!getDerived().AlwaysRebuild() &&
4273 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00004274 return SemaRef.Owned(E->Retain());
4275
4276 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004277 /*FIXME:*/E->getTypeBeginLoc(),
4278 T,
4279 E->getRParenLoc());
4280}
Mike Stump11289f42009-09-09 15:08:12 +00004281
Douglas Gregora16548e2009-08-11 05:31:07 +00004282template<typename Derived>
4283Sema::OwningExprResult
4284TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
Mike Stump11289f42009-09-09 15:08:12 +00004285 VarDecl *Var
Douglas Gregorebe10102009-08-20 07:17:43 +00004286 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregora16548e2009-08-11 05:31:07 +00004287 if (!Var)
4288 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004289
Douglas Gregora16548e2009-08-11 05:31:07 +00004290 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004291 Var == E->getVarDecl())
Douglas Gregora16548e2009-08-11 05:31:07 +00004292 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004293
4294 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004295 /*FIXME:*/E->getStartLoc(),
4296 Var);
4297}
Mike Stump11289f42009-09-09 15:08:12 +00004298
Douglas Gregora16548e2009-08-11 05:31:07 +00004299template<typename Derived>
4300Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004301TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004302 // Transform the type that we're allocating
4303 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
4304 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
4305 if (AllocType.isNull())
4306 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004307
Douglas Gregora16548e2009-08-11 05:31:07 +00004308 // Transform the size of the array we're allocating (if any).
4309 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
4310 if (ArraySize.isInvalid())
4311 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004312
Douglas Gregora16548e2009-08-11 05:31:07 +00004313 // Transform the placement arguments (if any).
4314 bool ArgumentChanged = false;
4315 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
4316 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
4317 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
4318 if (Arg.isInvalid())
4319 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004320
Douglas Gregora16548e2009-08-11 05:31:07 +00004321 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
4322 PlacementArgs.push_back(Arg.take());
4323 }
Mike Stump11289f42009-09-09 15:08:12 +00004324
Douglas Gregorebe10102009-08-20 07:17:43 +00004325 // transform the constructor arguments (if any).
Douglas Gregora16548e2009-08-11 05:31:07 +00004326 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
4327 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
4328 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
4329 if (Arg.isInvalid())
4330 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004331
Douglas Gregora16548e2009-08-11 05:31:07 +00004332 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
4333 ConstructorArgs.push_back(Arg.take());
4334 }
Mike Stump11289f42009-09-09 15:08:12 +00004335
Douglas Gregora16548e2009-08-11 05:31:07 +00004336 if (!getDerived().AlwaysRebuild() &&
4337 AllocType == E->getAllocatedType() &&
4338 ArraySize.get() == E->getArraySize() &&
4339 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004340 return SemaRef.Owned(E->Retain());
4341
Douglas Gregora16548e2009-08-11 05:31:07 +00004342 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
4343 E->isGlobalNew(),
4344 /*FIXME:*/E->getLocStart(),
4345 move_arg(PlacementArgs),
4346 /*FIXME:*/E->getLocStart(),
4347 E->isParenTypeId(),
4348 AllocType,
4349 /*FIXME:*/E->getLocStart(),
4350 /*FIXME:*/SourceRange(),
4351 move(ArraySize),
4352 /*FIXME:*/E->getLocStart(),
4353 move_arg(ConstructorArgs),
Mike Stump11289f42009-09-09 15:08:12 +00004354 E->getLocEnd());
Douglas Gregora16548e2009-08-11 05:31:07 +00004355}
Mike Stump11289f42009-09-09 15:08:12 +00004356
Douglas Gregora16548e2009-08-11 05:31:07 +00004357template<typename Derived>
4358Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004359TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004360 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
4361 if (Operand.isInvalid())
4362 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004363
Douglas Gregora16548e2009-08-11 05:31:07 +00004364 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004365 Operand.get() == E->getArgument())
4366 return SemaRef.Owned(E->Retain());
4367
Douglas Gregora16548e2009-08-11 05:31:07 +00004368 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
4369 E->isGlobalDelete(),
4370 E->isArrayForm(),
4371 move(Operand));
4372}
Mike Stump11289f42009-09-09 15:08:12 +00004373
Douglas Gregora16548e2009-08-11 05:31:07 +00004374template<typename Derived>
4375Sema::OwningExprResult
Douglas Gregorad8a3362009-09-04 17:36:40 +00004376TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
4377 CXXPseudoDestructorExpr *E) {
4378 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4379 if (Base.isInvalid())
4380 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004381
Douglas Gregorad8a3362009-09-04 17:36:40 +00004382 NestedNameSpecifier *Qualifier
4383 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4384 E->getQualifierRange());
4385 if (E->getQualifier() && !Qualifier)
4386 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004387
Douglas Gregorad8a3362009-09-04 17:36:40 +00004388 QualType DestroyedType;
4389 {
4390 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
4391 DestroyedType = getDerived().TransformType(E->getDestroyedType());
4392 if (DestroyedType.isNull())
4393 return SemaRef.ExprError();
4394 }
Mike Stump11289f42009-09-09 15:08:12 +00004395
Douglas Gregorad8a3362009-09-04 17:36:40 +00004396 if (!getDerived().AlwaysRebuild() &&
4397 Base.get() == E->getBase() &&
4398 Qualifier == E->getQualifier() &&
4399 DestroyedType == E->getDestroyedType())
4400 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004401
Douglas Gregorad8a3362009-09-04 17:36:40 +00004402 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
4403 E->getOperatorLoc(),
4404 E->isArrow(),
4405 E->getDestroyedTypeLoc(),
4406 DestroyedType,
4407 Qualifier,
4408 E->getQualifierRange());
4409}
Mike Stump11289f42009-09-09 15:08:12 +00004410
Douglas Gregorad8a3362009-09-04 17:36:40 +00004411template<typename Derived>
4412Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004413TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004414 UnresolvedFunctionNameExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004415 // There is no transformation we can apply to an unresolved function name.
Mike Stump11289f42009-09-09 15:08:12 +00004416 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004417}
Mike Stump11289f42009-09-09 15:08:12 +00004418
Douglas Gregora16548e2009-08-11 05:31:07 +00004419template<typename Derived>
4420Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004421TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004422 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004423
Douglas Gregora16548e2009-08-11 05:31:07 +00004424 QualType T = getDerived().TransformType(E->getQueriedType());
4425 if (T.isNull())
4426 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004427
Douglas Gregora16548e2009-08-11 05:31:07 +00004428 if (!getDerived().AlwaysRebuild() &&
4429 T == E->getQueriedType())
4430 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004431
Douglas Gregora16548e2009-08-11 05:31:07 +00004432 // FIXME: Bad location information
4433 SourceLocation FakeLParenLoc
4434 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
Mike Stump11289f42009-09-09 15:08:12 +00004435
4436 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004437 E->getLocStart(),
4438 /*FIXME:*/FakeLParenLoc,
4439 T,
4440 E->getLocEnd());
4441}
Mike Stump11289f42009-09-09 15:08:12 +00004442
Douglas Gregora16548e2009-08-11 05:31:07 +00004443template<typename Derived>
4444Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004445TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004446 UnresolvedDeclRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004447 NestedNameSpecifier *NNS
Douglas Gregord019ff62009-10-22 17:20:55 +00004448 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4449 E->getQualifierRange());
Douglas Gregora16548e2009-08-11 05:31:07 +00004450 if (!NNS)
4451 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004452
4453 DeclarationName Name
Douglas Gregorf816bd72009-09-03 22:13:48 +00004454 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
4455 if (!Name)
4456 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004457
4458 if (!getDerived().AlwaysRebuild() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00004459 NNS == E->getQualifier() &&
4460 Name == E->getDeclName())
Mike Stump11289f42009-09-09 15:08:12 +00004461 return SemaRef.Owned(E->Retain());
4462
4463 return getDerived().RebuildUnresolvedDeclRefExpr(NNS,
Douglas Gregora16548e2009-08-11 05:31:07 +00004464 E->getQualifierRange(),
4465 Name,
4466 E->getLocation(),
4467 /*FIXME:*/false);
4468}
4469
4470template<typename Derived>
4471Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004472TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
Douglas Gregorba91b892009-10-29 17:56:10 +00004473 TemporaryBase Rebase(*this, E->getTemplateNameLoc(), DeclarationName());
4474
Mike Stump11289f42009-09-09 15:08:12 +00004475 TemplateName Template
Douglas Gregora16548e2009-08-11 05:31:07 +00004476 = getDerived().TransformTemplateName(E->getTemplateName());
4477 if (Template.isNull())
4478 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004479
Douglas Gregord019ff62009-10-22 17:20:55 +00004480 NestedNameSpecifier *Qualifier = 0;
4481 if (E->getQualifier()) {
4482 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4483 E->getQualifierRange());
4484 if (!Qualifier)
4485 return SemaRef.ExprError();
4486 }
4487
John McCall0ad16662009-10-29 08:12:44 +00004488 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregora16548e2009-08-11 05:31:07 +00004489 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00004490 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
4491 TransArgs[I]))
Douglas Gregora16548e2009-08-11 05:31:07 +00004492 return SemaRef.ExprError();
Douglas Gregora16548e2009-08-11 05:31:07 +00004493 }
4494
4495 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
4496 // compare template arguments (yet).
Mike Stump11289f42009-09-09 15:08:12 +00004497
4498 // FIXME: It's possible that we'll find out now that the template name
Douglas Gregora16548e2009-08-11 05:31:07 +00004499 // actually refers to a type, in which case the caller is actually dealing
4500 // with a functional cast. Give a reasonable error message!
Douglas Gregord019ff62009-10-22 17:20:55 +00004501 return getDerived().RebuildTemplateIdExpr(Qualifier, E->getQualifierRange(),
4502 Template, E->getTemplateNameLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004503 E->getLAngleLoc(),
4504 TransArgs.data(),
4505 TransArgs.size(),
4506 E->getRAngleLoc());
4507}
4508
4509template<typename Derived>
4510Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004511TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004512 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4513
4514 QualType T = getDerived().TransformType(E->getType());
4515 if (T.isNull())
4516 return SemaRef.ExprError();
4517
4518 CXXConstructorDecl *Constructor
4519 = cast_or_null<CXXConstructorDecl>(
4520 getDerived().TransformDecl(E->getConstructor()));
4521 if (!Constructor)
4522 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004523
Douglas Gregora16548e2009-08-11 05:31:07 +00004524 bool ArgumentChanged = false;
4525 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00004526 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004527 ArgEnd = E->arg_end();
4528 Arg != ArgEnd; ++Arg) {
4529 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4530 if (TransArg.isInvalid())
4531 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004532
Douglas Gregora16548e2009-08-11 05:31:07 +00004533 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4534 Args.push_back(TransArg.takeAs<Expr>());
4535 }
4536
4537 if (!getDerived().AlwaysRebuild() &&
4538 T == E->getType() &&
4539 Constructor == E->getConstructor() &&
4540 !ArgumentChanged)
4541 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004542
Douglas Gregora16548e2009-08-11 05:31:07 +00004543 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4544 move_arg(Args));
4545}
Mike Stump11289f42009-09-09 15:08:12 +00004546
Douglas Gregora16548e2009-08-11 05:31:07 +00004547/// \brief Transform a C++ temporary-binding expression.
4548///
Mike Stump11289f42009-09-09 15:08:12 +00004549/// The transformation of a temporary-binding expression always attempts to
4550/// bind a new temporary variable to its subexpression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004551/// subexpression itself did not change, because the temporary variable itself
4552/// must be unique.
4553template<typename Derived>
4554Sema::OwningExprResult
4555TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
4556 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4557 if (SubExpr.isInvalid())
4558 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004559
Douglas Gregora16548e2009-08-11 05:31:07 +00004560 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4561}
Mike Stump11289f42009-09-09 15:08:12 +00004562
4563/// \brief Transform a C++ expression that contains temporaries that should
Douglas Gregora16548e2009-08-11 05:31:07 +00004564/// be destroyed after the expression is evaluated.
4565///
Mike Stump11289f42009-09-09 15:08:12 +00004566/// The transformation of a full expression always attempts to build a new
4567/// CXXExprWithTemporaries expression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004568/// subexpression itself did not change, because it will need to capture the
4569/// the new temporary variables introduced in the subexpression.
4570template<typename Derived>
4571Sema::OwningExprResult
4572TreeTransform<Derived>::TransformCXXExprWithTemporaries(
Mike Stump11289f42009-09-09 15:08:12 +00004573 CXXExprWithTemporaries *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004574 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4575 if (SubExpr.isInvalid())
4576 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004577
Douglas Gregora16548e2009-08-11 05:31:07 +00004578 return SemaRef.Owned(
4579 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4580 E->shouldDestroyTemporaries()));
4581}
Mike Stump11289f42009-09-09 15:08:12 +00004582
Douglas Gregora16548e2009-08-11 05:31:07 +00004583template<typename Derived>
4584Sema::OwningExprResult
4585TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004586 CXXTemporaryObjectExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004587 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4588 QualType T = getDerived().TransformType(E->getType());
4589 if (T.isNull())
4590 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004591
Douglas Gregora16548e2009-08-11 05:31:07 +00004592 CXXConstructorDecl *Constructor
4593 = cast_or_null<CXXConstructorDecl>(
4594 getDerived().TransformDecl(E->getConstructor()));
4595 if (!Constructor)
4596 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004597
Douglas Gregora16548e2009-08-11 05:31:07 +00004598 bool ArgumentChanged = false;
4599 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4600 Args.reserve(E->getNumArgs());
Mike Stump11289f42009-09-09 15:08:12 +00004601 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004602 ArgEnd = E->arg_end();
4603 Arg != ArgEnd; ++Arg) {
4604 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4605 if (TransArg.isInvalid())
4606 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004607
Douglas Gregora16548e2009-08-11 05:31:07 +00004608 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4609 Args.push_back((Expr *)TransArg.release());
4610 }
Mike Stump11289f42009-09-09 15:08:12 +00004611
Douglas Gregora16548e2009-08-11 05:31:07 +00004612 if (!getDerived().AlwaysRebuild() &&
4613 T == E->getType() &&
4614 Constructor == E->getConstructor() &&
4615 !ArgumentChanged)
4616 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004617
Douglas Gregora16548e2009-08-11 05:31:07 +00004618 // FIXME: Bogus location information
4619 SourceLocation CommaLoc;
4620 if (Args.size() > 1) {
4621 Expr *First = (Expr *)Args[0];
Mike Stump11289f42009-09-09 15:08:12 +00004622 CommaLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004623 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4624 }
4625 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4626 T,
4627 /*FIXME:*/E->getTypeBeginLoc(),
4628 move_arg(Args),
4629 &CommaLoc,
4630 E->getLocEnd());
4631}
Mike Stump11289f42009-09-09 15:08:12 +00004632
Douglas Gregora16548e2009-08-11 05:31:07 +00004633template<typename Derived>
4634Sema::OwningExprResult
4635TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004636 CXXUnresolvedConstructExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004637 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4638 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4639 if (T.isNull())
4640 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004641
Douglas Gregora16548e2009-08-11 05:31:07 +00004642 bool ArgumentChanged = false;
4643 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4644 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4645 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4646 ArgEnd = E->arg_end();
4647 Arg != ArgEnd; ++Arg) {
4648 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4649 if (TransArg.isInvalid())
4650 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004651
Douglas Gregora16548e2009-08-11 05:31:07 +00004652 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4653 FakeCommaLocs.push_back(
4654 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4655 Args.push_back(TransArg.takeAs<Expr>());
4656 }
Mike Stump11289f42009-09-09 15:08:12 +00004657
Douglas Gregora16548e2009-08-11 05:31:07 +00004658 if (!getDerived().AlwaysRebuild() &&
4659 T == E->getTypeAsWritten() &&
4660 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004661 return SemaRef.Owned(E->Retain());
4662
Douglas Gregora16548e2009-08-11 05:31:07 +00004663 // FIXME: we're faking the locations of the commas
4664 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4665 T,
4666 E->getLParenLoc(),
4667 move_arg(Args),
4668 FakeCommaLocs.data(),
4669 E->getRParenLoc());
4670}
Mike Stump11289f42009-09-09 15:08:12 +00004671
Douglas Gregora16548e2009-08-11 05:31:07 +00004672template<typename Derived>
4673Sema::OwningExprResult
4674TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004675 CXXUnresolvedMemberExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004676 // Transform the base of the expression.
4677 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4678 if (Base.isInvalid())
4679 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004680
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004681 // Start the member reference and compute the object's type.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004682 Sema::TypeTy *ObjectType = 0;
Mike Stump11289f42009-09-09 15:08:12 +00004683 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004684 E->getOperatorLoc(),
4685 E->isArrow()? tok::arrow : tok::period,
4686 ObjectType);
4687 if (Base.isInvalid())
4688 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004689
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004690 // Transform the first part of the nested-name-specifier that qualifies
4691 // the member name.
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004692 NamedDecl *FirstQualifierInScope
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004693 = getDerived().TransformFirstQualifierInScope(
4694 E->getFirstQualifierFoundInScope(),
4695 E->getQualifierRange().getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00004696
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004697 NestedNameSpecifier *Qualifier = 0;
4698 if (E->getQualifier()) {
4699 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4700 E->getQualifierRange(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004701 QualType::getFromOpaquePtr(ObjectType),
4702 FirstQualifierInScope);
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004703 if (!Qualifier)
4704 return SemaRef.ExprError();
4705 }
Mike Stump11289f42009-09-09 15:08:12 +00004706
4707 DeclarationName Name
Douglas Gregorc59e5612009-10-19 22:04:39 +00004708 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
4709 QualType::getFromOpaquePtr(ObjectType));
Douglas Gregorf816bd72009-09-03 22:13:48 +00004710 if (!Name)
4711 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004712
Douglas Gregor308047d2009-09-09 00:23:06 +00004713 if (!E->hasExplicitTemplateArgumentList()) {
4714 // This is a reference to a member without an explicitly-specified
4715 // template argument list. Optimize for this common case.
4716 if (!getDerived().AlwaysRebuild() &&
4717 Base.get() == E->getBase() &&
4718 Qualifier == E->getQualifier() &&
4719 Name == E->getMember() &&
4720 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
Mike Stump11289f42009-09-09 15:08:12 +00004721 return SemaRef.Owned(E->Retain());
4722
Douglas Gregor308047d2009-09-09 00:23:06 +00004723 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4724 E->isArrow(),
4725 E->getOperatorLoc(),
4726 Qualifier,
4727 E->getQualifierRange(),
4728 Name,
4729 E->getMemberLoc(),
4730 FirstQualifierInScope);
4731 }
4732
4733 // FIXME: This is an ugly hack, which forces the same template name to
4734 // be looked up multiple times. Yuck!
4735 // FIXME: This also won't work for, e.g., x->template operator+<int>
4736 TemplateName OrigTemplateName
4737 = SemaRef.Context.getDependentTemplateName(0, Name.getAsIdentifierInfo());
Mike Stump11289f42009-09-09 15:08:12 +00004738
4739 TemplateName Template
4740 = getDerived().TransformTemplateName(OrigTemplateName,
Douglas Gregor308047d2009-09-09 00:23:06 +00004741 QualType::getFromOpaquePtr(ObjectType));
4742 if (Template.isNull())
4743 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004744
John McCall0ad16662009-10-29 08:12:44 +00004745 llvm::SmallVector<TemplateArgumentLoc, 4> TransArgs(E->getNumTemplateArgs());
Douglas Gregor308047d2009-09-09 00:23:06 +00004746 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
John McCall0ad16662009-10-29 08:12:44 +00004747 if (getDerived().TransformTemplateArgument(E->getTemplateArgs()[I],
4748 TransArgs[I]))
Douglas Gregor308047d2009-09-09 00:23:06 +00004749 return SemaRef.ExprError();
Douglas Gregor308047d2009-09-09 00:23:06 +00004750 }
Mike Stump11289f42009-09-09 15:08:12 +00004751
Douglas Gregora16548e2009-08-11 05:31:07 +00004752 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4753 E->isArrow(),
4754 E->getOperatorLoc(),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004755 Qualifier,
4756 E->getQualifierRange(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004757 Template,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004758 E->getMemberLoc(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004759 FirstQualifierInScope,
4760 E->getLAngleLoc(),
4761 TransArgs.data(),
4762 TransArgs.size(),
4763 E->getRAngleLoc());
Douglas Gregora16548e2009-08-11 05:31:07 +00004764}
4765
4766template<typename Derived>
4767Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004768TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
4769 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004770}
4771
Mike Stump11289f42009-09-09 15:08:12 +00004772template<typename Derived>
4773Sema::OwningExprResult
4774TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004775 // FIXME: poor source location
4776 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4777 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4778 if (EncodedType.isNull())
4779 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004780
Douglas Gregora16548e2009-08-11 05:31:07 +00004781 if (!getDerived().AlwaysRebuild() &&
4782 EncodedType == E->getEncodedType())
Mike Stump11289f42009-09-09 15:08:12 +00004783 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004784
4785 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4786 EncodedType,
4787 E->getRParenLoc());
4788}
Mike Stump11289f42009-09-09 15:08:12 +00004789
Douglas Gregora16548e2009-08-11 05:31:07 +00004790template<typename Derived>
4791Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004792TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004793 // FIXME: Implement this!
4794 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004795 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004796}
4797
Mike Stump11289f42009-09-09 15:08:12 +00004798template<typename Derived>
4799Sema::OwningExprResult
4800TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
4801 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004802}
4803
Mike Stump11289f42009-09-09 15:08:12 +00004804template<typename Derived>
4805Sema::OwningExprResult
4806TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
4807 ObjCProtocolDecl *Protocol
Douglas Gregora16548e2009-08-11 05:31:07 +00004808 = cast_or_null<ObjCProtocolDecl>(
4809 getDerived().TransformDecl(E->getProtocol()));
4810 if (!Protocol)
4811 return SemaRef.ExprError();
4812
4813 if (!getDerived().AlwaysRebuild() &&
4814 Protocol == E->getProtocol())
Mike Stump11289f42009-09-09 15:08:12 +00004815 return SemaRef.Owned(E->Retain());
4816
Douglas Gregora16548e2009-08-11 05:31:07 +00004817 return getDerived().RebuildObjCProtocolExpr(Protocol,
4818 E->getAtLoc(),
4819 /*FIXME:*/E->getAtLoc(),
4820 /*FIXME:*/E->getAtLoc(),
4821 E->getRParenLoc());
Mike Stump11289f42009-09-09 15:08:12 +00004822
Douglas Gregora16548e2009-08-11 05:31:07 +00004823}
4824
Mike Stump11289f42009-09-09 15:08:12 +00004825template<typename Derived>
4826Sema::OwningExprResult
4827TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004828 // FIXME: Implement this!
4829 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004830 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004831}
4832
Mike Stump11289f42009-09-09 15:08:12 +00004833template<typename Derived>
4834Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004835TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
4836 // FIXME: Implement this!
4837 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004838 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004839}
4840
Mike Stump11289f42009-09-09 15:08:12 +00004841template<typename Derived>
4842Sema::OwningExprResult
Fariborz Jahanian9a846652009-08-20 17:02:02 +00004843TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004844 ObjCImplicitSetterGetterRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004845 // FIXME: Implement this!
4846 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004847 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004848}
4849
Mike Stump11289f42009-09-09 15:08:12 +00004850template<typename Derived>
4851Sema::OwningExprResult
4852TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004853 // FIXME: Implement this!
4854 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004855 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004856}
4857
Mike Stump11289f42009-09-09 15:08:12 +00004858template<typename Derived>
4859Sema::OwningExprResult
4860TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004861 // FIXME: Implement this!
4862 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004863 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004864}
4865
Mike Stump11289f42009-09-09 15:08:12 +00004866template<typename Derived>
4867Sema::OwningExprResult
4868TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004869 bool ArgumentChanged = false;
4870 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
4871 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
4872 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
4873 if (SubExpr.isInvalid())
4874 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004875
Douglas Gregora16548e2009-08-11 05:31:07 +00004876 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
4877 SubExprs.push_back(SubExpr.takeAs<Expr>());
4878 }
Mike Stump11289f42009-09-09 15:08:12 +00004879
Douglas Gregora16548e2009-08-11 05:31:07 +00004880 if (!getDerived().AlwaysRebuild() &&
4881 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004882 return SemaRef.Owned(E->Retain());
4883
Douglas Gregora16548e2009-08-11 05:31:07 +00004884 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
4885 move_arg(SubExprs),
4886 E->getRParenLoc());
4887}
4888
Mike Stump11289f42009-09-09 15:08:12 +00004889template<typename Derived>
4890Sema::OwningExprResult
4891TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004892 // FIXME: Implement this!
4893 assert(false && "Cannot transform block expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004894 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004895}
4896
Mike Stump11289f42009-09-09 15:08:12 +00004897template<typename Derived>
4898Sema::OwningExprResult
4899TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004900 // FIXME: Implement this!
4901 assert(false && "Cannot transform block-related expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004902 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004903}
Mike Stump11289f42009-09-09 15:08:12 +00004904
Douglas Gregora16548e2009-08-11 05:31:07 +00004905//===----------------------------------------------------------------------===//
Douglas Gregord6ff3322009-08-04 16:50:30 +00004906// Type reconstruction
4907//===----------------------------------------------------------------------===//
4908
Mike Stump11289f42009-09-09 15:08:12 +00004909template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00004910QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004911 return SemaRef.BuildPointerType(PointeeType, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004912 getDerived().getBaseLocation(),
4913 getDerived().getBaseEntity());
4914}
4915
Mike Stump11289f42009-09-09 15:08:12 +00004916template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00004917QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004918 return SemaRef.BuildBlockPointerType(PointeeType, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004919 getDerived().getBaseLocation(),
4920 getDerived().getBaseEntity());
4921}
4922
Mike Stump11289f42009-09-09 15:08:12 +00004923template<typename Derived>
4924QualType
Douglas Gregord6ff3322009-08-04 16:50:30 +00004925TreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004926 return SemaRef.BuildReferenceType(ReferentType, true, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004927 getDerived().getBaseLocation(),
4928 getDerived().getBaseEntity());
4929}
4930
4931template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004932QualType
4933TreeTransform<Derived>::RebuildRValueReferenceType(QualType ReferentType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004934 return SemaRef.BuildReferenceType(ReferentType, false, Qualifiers(),
Mike Stump11289f42009-09-09 15:08:12 +00004935 getDerived().getBaseLocation(),
4936 getDerived().getBaseEntity());
4937}
4938
4939template<typename Derived>
4940QualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004941 QualType ClassType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004942 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004943 getDerived().getBaseLocation(),
4944 getDerived().getBaseEntity());
4945}
4946
4947template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004948QualType
John McCall550e0c22009-10-21 00:40:46 +00004949TreeTransform<Derived>::RebuildObjCObjectPointerType(QualType PointeeType) {
4950 return SemaRef.BuildPointerType(PointeeType, Qualifiers(),
4951 getDerived().getBaseLocation(),
4952 getDerived().getBaseEntity());
4953}
4954
4955template<typename Derived>
4956QualType
Douglas Gregord6ff3322009-08-04 16:50:30 +00004957TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
4958 ArrayType::ArraySizeModifier SizeMod,
4959 const llvm::APInt *Size,
4960 Expr *SizeExpr,
4961 unsigned IndexTypeQuals,
4962 SourceRange BracketsRange) {
4963 if (SizeExpr || !Size)
4964 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
4965 IndexTypeQuals, BracketsRange,
4966 getDerived().getBaseEntity());
Mike Stump11289f42009-09-09 15:08:12 +00004967
4968 QualType Types[] = {
4969 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
4970 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
4971 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
Douglas Gregord6ff3322009-08-04 16:50:30 +00004972 };
4973 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
4974 QualType SizeType;
4975 for (unsigned I = 0; I != NumTypes; ++I)
4976 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
4977 SizeType = Types[I];
4978 break;
4979 }
Mike Stump11289f42009-09-09 15:08:12 +00004980
Douglas Gregord6ff3322009-08-04 16:50:30 +00004981 if (SizeType.isNull())
4982 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
Mike Stump11289f42009-09-09 15:08:12 +00004983
Douglas Gregord6ff3322009-08-04 16:50:30 +00004984 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00004985 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004986 IndexTypeQuals, BracketsRange,
Mike Stump11289f42009-09-09 15:08:12 +00004987 getDerived().getBaseEntity());
Douglas Gregord6ff3322009-08-04 16:50:30 +00004988}
Mike Stump11289f42009-09-09 15:08:12 +00004989
Douglas Gregord6ff3322009-08-04 16:50:30 +00004990template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004991QualType
4992TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004993 ArrayType::ArraySizeModifier SizeMod,
4994 const llvm::APInt &Size,
4995 unsigned IndexTypeQuals) {
Mike Stump11289f42009-09-09 15:08:12 +00004996 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004997 IndexTypeQuals, SourceRange());
4998}
4999
5000template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005001QualType
Mike Stump11289f42009-09-09 15:08:12 +00005002TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005003 ArrayType::ArraySizeModifier SizeMod,
5004 unsigned IndexTypeQuals) {
Mike Stump11289f42009-09-09 15:08:12 +00005005 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005006 IndexTypeQuals, SourceRange());
5007}
Mike Stump11289f42009-09-09 15:08:12 +00005008
Douglas Gregord6ff3322009-08-04 16:50:30 +00005009template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005010QualType
5011TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005012 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00005013 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005014 unsigned IndexTypeQuals,
5015 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005016 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005017 SizeExpr.takeAs<Expr>(),
5018 IndexTypeQuals, BracketsRange);
5019}
5020
5021template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005022QualType
5023TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005024 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00005025 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005026 unsigned IndexTypeQuals,
5027 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00005028 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005029 SizeExpr.takeAs<Expr>(),
5030 IndexTypeQuals, BracketsRange);
5031}
5032
5033template<typename Derived>
5034QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
5035 unsigned NumElements) {
5036 // FIXME: semantic checking!
5037 return SemaRef.Context.getVectorType(ElementType, NumElements);
5038}
Mike Stump11289f42009-09-09 15:08:12 +00005039
Douglas Gregord6ff3322009-08-04 16:50:30 +00005040template<typename Derived>
5041QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
5042 unsigned NumElements,
5043 SourceLocation AttributeLoc) {
5044 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
5045 NumElements, true);
5046 IntegerLiteral *VectorSize
Mike Stump11289f42009-09-09 15:08:12 +00005047 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005048 AttributeLoc);
5049 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
5050 AttributeLoc);
5051}
Mike Stump11289f42009-09-09 15:08:12 +00005052
Douglas Gregord6ff3322009-08-04 16:50:30 +00005053template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005054QualType
5055TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregora16548e2009-08-11 05:31:07 +00005056 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005057 SourceLocation AttributeLoc) {
5058 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
5059}
Mike Stump11289f42009-09-09 15:08:12 +00005060
Douglas Gregord6ff3322009-08-04 16:50:30 +00005061template<typename Derived>
5062QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
Mike Stump11289f42009-09-09 15:08:12 +00005063 QualType *ParamTypes,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005064 unsigned NumParamTypes,
Mike Stump11289f42009-09-09 15:08:12 +00005065 bool Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005066 unsigned Quals) {
Mike Stump11289f42009-09-09 15:08:12 +00005067 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00005068 Quals,
5069 getDerived().getBaseLocation(),
5070 getDerived().getBaseEntity());
5071}
Mike Stump11289f42009-09-09 15:08:12 +00005072
Douglas Gregord6ff3322009-08-04 16:50:30 +00005073template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00005074QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
5075 return SemaRef.Context.getFunctionNoProtoType(T);
5076}
5077
5078template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00005079QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00005080 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
5081}
5082
5083template<typename Derived>
5084QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
5085 return SemaRef.Context.getTypeOfType(Underlying);
5086}
5087
5088template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00005089QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00005090 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
5091}
5092
5093template<typename Derived>
5094QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
John McCall0ad16662009-10-29 08:12:44 +00005095 TemplateName Template,
5096 SourceLocation TemplateNameLoc,
5097 SourceLocation LAngleLoc,
5098 const TemplateArgumentLoc *Args,
5099 unsigned NumArgs,
5100 SourceLocation RAngleLoc) {
5101 return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, LAngleLoc,
5102 Args, NumArgs, RAngleLoc);
Douglas Gregord6ff3322009-08-04 16:50:30 +00005103}
Mike Stump11289f42009-09-09 15:08:12 +00005104
Douglas Gregor1135c352009-08-06 05:28:30 +00005105template<typename Derived>
5106NestedNameSpecifier *
5107TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5108 SourceRange Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00005109 IdentifierInfo &II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00005110 QualType ObjectType,
5111 NamedDecl *FirstQualifierInScope) {
Douglas Gregor1135c352009-08-06 05:28:30 +00005112 CXXScopeSpec SS;
5113 // FIXME: The source location information is all wrong.
5114 SS.setRange(Range);
5115 SS.setScopeRep(Prefix);
5116 return static_cast<NestedNameSpecifier *>(
Mike Stump11289f42009-09-09 15:08:12 +00005117 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregore861bac2009-08-25 22:51:20 +00005118 Range.getEnd(), II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00005119 ObjectType,
5120 FirstQualifierInScope,
Douglas Gregore861bac2009-08-25 22:51:20 +00005121 false));
Douglas Gregor1135c352009-08-06 05:28:30 +00005122}
5123
5124template<typename Derived>
5125NestedNameSpecifier *
5126TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5127 SourceRange Range,
5128 NamespaceDecl *NS) {
5129 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
5130}
5131
5132template<typename Derived>
5133NestedNameSpecifier *
5134TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5135 SourceRange Range,
5136 bool TemplateKW,
5137 QualType T) {
5138 if (T->isDependentType() || T->isRecordType() ||
5139 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
John McCall8ccfcb52009-09-24 19:53:00 +00005140 assert(!T.hasQualifiers() && "Can't get cv-qualifiers here");
Douglas Gregor1135c352009-08-06 05:28:30 +00005141 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
5142 T.getTypePtr());
5143 }
Mike Stump11289f42009-09-09 15:08:12 +00005144
Douglas Gregor1135c352009-08-06 05:28:30 +00005145 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
5146 return 0;
5147}
Mike Stump11289f42009-09-09 15:08:12 +00005148
Douglas Gregor71dc5092009-08-06 06:41:21 +00005149template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005150TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005151TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5152 bool TemplateKW,
5153 TemplateDecl *Template) {
Mike Stump11289f42009-09-09 15:08:12 +00005154 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
Douglas Gregor71dc5092009-08-06 06:41:21 +00005155 Template);
5156}
5157
5158template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005159TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005160TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5161 bool TemplateKW,
5162 OverloadedFunctionDecl *Ovl) {
5163 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
5164}
5165
5166template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005167TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005168TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor308047d2009-09-09 00:23:06 +00005169 const IdentifierInfo &II,
5170 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00005171 CXXScopeSpec SS;
5172 SS.setRange(SourceRange(getDerived().getBaseLocation()));
Mike Stump11289f42009-09-09 15:08:12 +00005173 SS.setScopeRep(Qualifier);
Douglas Gregor308047d2009-09-09 00:23:06 +00005174 return getSema().ActOnDependentTemplateName(
5175 /*FIXME:*/getDerived().getBaseLocation(),
5176 II,
5177 /*FIXME:*/getDerived().getBaseLocation(),
5178 SS,
5179 ObjectType.getAsOpaquePtr())
5180 .template getAsVal<TemplateName>();
Douglas Gregor71dc5092009-08-06 06:41:21 +00005181}
Mike Stump11289f42009-09-09 15:08:12 +00005182
Douglas Gregora16548e2009-08-11 05:31:07 +00005183template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005184Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00005185TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
5186 SourceLocation OpLoc,
5187 ExprArg Callee,
5188 ExprArg First,
5189 ExprArg Second) {
5190 Expr *FirstExpr = (Expr *)First.get();
5191 Expr *SecondExpr = (Expr *)Second.get();
Sebastian Redladba46e2009-10-29 20:17:01 +00005192 DeclRefExpr *DRE
5193 = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
Douglas Gregora16548e2009-08-11 05:31:07 +00005194 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
Mike Stump11289f42009-09-09 15:08:12 +00005195
Douglas Gregora16548e2009-08-11 05:31:07 +00005196 // Determine whether this should be a builtin operation.
Sebastian Redladba46e2009-10-29 20:17:01 +00005197 if (Op == OO_Subscript) {
5198 if (!FirstExpr->getType()->isOverloadableType() &&
5199 !SecondExpr->getType()->isOverloadableType())
5200 return getSema().CreateBuiltinArraySubscriptExpr(move(First),
5201 DRE->getLocStart(),
5202 move(Second), OpLoc);
5203 } else if (SecondExpr == 0 || isPostIncDec) {
Douglas Gregora16548e2009-08-11 05:31:07 +00005204 if (!FirstExpr->getType()->isOverloadableType()) {
5205 // The argument is not of overloadable type, so try to create a
5206 // built-in unary operation.
Mike Stump11289f42009-09-09 15:08:12 +00005207 UnaryOperator::Opcode Opc
Douglas Gregora16548e2009-08-11 05:31:07 +00005208 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
Mike Stump11289f42009-09-09 15:08:12 +00005209
Douglas Gregora16548e2009-08-11 05:31:07 +00005210 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
5211 }
5212 } else {
Mike Stump11289f42009-09-09 15:08:12 +00005213 if (!FirstExpr->getType()->isOverloadableType() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00005214 !SecondExpr->getType()->isOverloadableType()) {
5215 // Neither of the arguments is an overloadable type, so try to
5216 // create a built-in binary operation.
5217 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
Mike Stump11289f42009-09-09 15:08:12 +00005218 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00005219 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
5220 if (Result.isInvalid())
5221 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005222
Douglas Gregora16548e2009-08-11 05:31:07 +00005223 First.release();
5224 Second.release();
5225 return move(Result);
5226 }
5227 }
Mike Stump11289f42009-09-09 15:08:12 +00005228
5229 // Compute the transformed set of functions (and function templates) to be
Douglas Gregora16548e2009-08-11 05:31:07 +00005230 // used during overload resolution.
5231 Sema::FunctionSet Functions;
Mike Stump11289f42009-09-09 15:08:12 +00005232
Douglas Gregora16548e2009-08-11 05:31:07 +00005233 // FIXME: Do we have to check
5234 // IsAcceptableNonMemberOperatorCandidate for each of these?
Douglas Gregor32e2c842009-09-01 16:58:52 +00005235 for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
Douglas Gregora16548e2009-08-11 05:31:07 +00005236 Functions.insert(*F);
Mike Stump11289f42009-09-09 15:08:12 +00005237
Douglas Gregora16548e2009-08-11 05:31:07 +00005238 // Add any functions found via argument-dependent lookup.
5239 Expr *Args[2] = { FirstExpr, SecondExpr };
5240 unsigned NumArgs = 1 + (SecondExpr != 0);
Mike Stump11289f42009-09-09 15:08:12 +00005241 DeclarationName OpName
Douglas Gregora16548e2009-08-11 05:31:07 +00005242 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
Sebastian Redlc057f422009-10-23 19:23:15 +00005243 SemaRef.ArgumentDependentLookup(OpName, /*Operator*/true, Args, NumArgs,
5244 Functions);
Mike Stump11289f42009-09-09 15:08:12 +00005245
Douglas Gregora16548e2009-08-11 05:31:07 +00005246 // Create the overloaded operator invocation for unary operators.
5247 if (NumArgs == 1 || isPostIncDec) {
Mike Stump11289f42009-09-09 15:08:12 +00005248 UnaryOperator::Opcode Opc
Douglas Gregora16548e2009-08-11 05:31:07 +00005249 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
5250 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
5251 }
Mike Stump11289f42009-09-09 15:08:12 +00005252
Sebastian Redladba46e2009-10-29 20:17:01 +00005253 if (Op == OO_Subscript)
5254 return SemaRef.CreateOverloadedArraySubscriptExpr(DRE->getLocStart(), OpLoc,
5255 move(First),move(Second));
5256
Douglas Gregora16548e2009-08-11 05:31:07 +00005257 // Create the overloaded operator invocation for binary operators.
Mike Stump11289f42009-09-09 15:08:12 +00005258 BinaryOperator::Opcode Opc =
Douglas Gregora16548e2009-08-11 05:31:07 +00005259 BinaryOperator::getOverloadedOpcode(Op);
Mike Stump11289f42009-09-09 15:08:12 +00005260 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00005261 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
5262 if (Result.isInvalid())
5263 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005264
Douglas Gregora16548e2009-08-11 05:31:07 +00005265 First.release();
5266 Second.release();
Mike Stump11289f42009-09-09 15:08:12 +00005267 return move(Result);
Douglas Gregora16548e2009-08-11 05:31:07 +00005268}
Mike Stump11289f42009-09-09 15:08:12 +00005269
Douglas Gregord6ff3322009-08-04 16:50:30 +00005270} // end namespace clang
5271
5272#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H