blob: b4ec2fa71e78062ce1e3d4f722899e54008722e6 [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.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000293 TemplateArgument TransformTemplateArgument(const TemplateArgument &Arg);
Mike Stump11289f42009-09-09 15:08:12 +0000294
John McCall550e0c22009-10-21 00:40:46 +0000295#define ABSTRACT_TYPELOC(CLASS, PARENT)
296#define TYPELOC(CLASS, PARENT) \
297 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
298#include "clang/AST/TypeLocNodes.def"
Douglas Gregord6ff3322009-08-04 16:50:30 +0000299
Douglas Gregorc59e5612009-10-19 22:04:39 +0000300 QualType
301 TransformTemplateSpecializationType(const TemplateSpecializationType *T,
302 QualType ObjectType);
303
Douglas Gregorebe10102009-08-20 07:17:43 +0000304 OwningStmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
Mike Stump11289f42009-09-09 15:08:12 +0000305
Douglas Gregorebe10102009-08-20 07:17:43 +0000306#define STMT(Node, Parent) \
307 OwningStmtResult Transform##Node(Node *S);
Douglas Gregora16548e2009-08-11 05:31:07 +0000308#define EXPR(Node, Parent) \
309 OwningExprResult Transform##Node(Node *E);
310#define ABSTRACT_EXPR(Node, Parent)
311#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +0000312
Douglas Gregord6ff3322009-08-04 16:50:30 +0000313 /// \brief Build a new pointer type given its pointee type.
314 ///
315 /// By default, performs semantic analysis when building the pointer type.
316 /// Subclasses may override this routine to provide different behavior.
317 QualType RebuildPointerType(QualType PointeeType);
318
319 /// \brief Build a new block pointer type given its pointee type.
320 ///
Mike Stump11289f42009-09-09 15:08:12 +0000321 /// By default, performs semantic analysis when building the block pointer
Douglas Gregord6ff3322009-08-04 16:50:30 +0000322 /// type. Subclasses may override this routine to provide different behavior.
323 QualType RebuildBlockPointerType(QualType PointeeType);
324
325 /// \brief Build a new lvalue reference type given the type it references.
326 ///
327 /// By default, performs semantic analysis when building the lvalue reference
328 /// type. Subclasses may override this routine to provide different behavior.
329 QualType RebuildLValueReferenceType(QualType ReferentType);
330
331 /// \brief Build a new rvalue reference type given the type it references.
332 ///
333 /// By default, performs semantic analysis when building the rvalue reference
334 /// type. Subclasses may override this routine to provide different behavior.
335 QualType RebuildRValueReferenceType(QualType ReferentType);
Mike Stump11289f42009-09-09 15:08:12 +0000336
Douglas Gregord6ff3322009-08-04 16:50:30 +0000337 /// \brief Build a new member pointer type given the pointee type and the
338 /// class type it refers into.
339 ///
340 /// By default, performs semantic analysis when building the member pointer
341 /// type. Subclasses may override this routine to provide different behavior.
342 QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType);
Mike Stump11289f42009-09-09 15:08:12 +0000343
John McCall550e0c22009-10-21 00:40:46 +0000344 /// \brief Build a new Objective C object pointer type.
345 QualType RebuildObjCObjectPointerType(QualType PointeeType);
346
Douglas Gregord6ff3322009-08-04 16:50:30 +0000347 /// \brief Build a new array type given the element type, size
348 /// modifier, size of the array (if known), size expression, and index type
349 /// qualifiers.
350 ///
351 /// By default, performs semantic analysis when building the array type.
352 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000353 /// Also by default, all of the other Rebuild*Array
Douglas Gregord6ff3322009-08-04 16:50:30 +0000354 QualType RebuildArrayType(QualType ElementType,
355 ArrayType::ArraySizeModifier SizeMod,
356 const llvm::APInt *Size,
357 Expr *SizeExpr,
358 unsigned IndexTypeQuals,
359 SourceRange BracketsRange);
Mike Stump11289f42009-09-09 15:08:12 +0000360
Douglas Gregord6ff3322009-08-04 16:50:30 +0000361 /// \brief Build a new constant array type given the element type, size
362 /// modifier, (known) size of the array, and index type qualifiers.
363 ///
364 /// By default, performs semantic analysis when building the array type.
365 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000366 QualType RebuildConstantArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000367 ArrayType::ArraySizeModifier SizeMod,
368 const llvm::APInt &Size,
369 unsigned IndexTypeQuals);
370
Douglas Gregord6ff3322009-08-04 16:50:30 +0000371 /// \brief Build a new incomplete array type given the element type, size
372 /// modifier, and index type qualifiers.
373 ///
374 /// By default, performs semantic analysis when building the array type.
375 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000376 QualType RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000377 ArrayType::ArraySizeModifier SizeMod,
378 unsigned IndexTypeQuals);
379
Mike Stump11289f42009-09-09 15:08:12 +0000380 /// \brief Build a new variable-length array type given the element type,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000381 /// size modifier, size expression, and index type qualifiers.
382 ///
383 /// By default, performs semantic analysis when building the array type.
384 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000385 QualType RebuildVariableArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000386 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +0000387 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000388 unsigned IndexTypeQuals,
389 SourceRange BracketsRange);
390
Mike Stump11289f42009-09-09 15:08:12 +0000391 /// \brief Build a new dependent-sized array type given the element type,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000392 /// size modifier, size expression, and index type qualifiers.
393 ///
394 /// By default, performs semantic analysis when building the array type.
395 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000396 QualType RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000397 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +0000398 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000399 unsigned IndexTypeQuals,
400 SourceRange BracketsRange);
401
402 /// \brief Build a new vector type given the element type and
403 /// number of elements.
404 ///
405 /// By default, performs semantic analysis when building the vector type.
406 /// Subclasses may override this routine to provide different behavior.
407 QualType RebuildVectorType(QualType ElementType, unsigned NumElements);
Mike Stump11289f42009-09-09 15:08:12 +0000408
Douglas Gregord6ff3322009-08-04 16:50:30 +0000409 /// \brief Build a new extended vector type given the element type and
410 /// number of elements.
411 ///
412 /// By default, performs semantic analysis when building the vector type.
413 /// Subclasses may override this routine to provide different behavior.
414 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
415 SourceLocation AttributeLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000416
417 /// \brief Build a new potentially dependently-sized extended vector type
Douglas Gregord6ff3322009-08-04 16:50:30 +0000418 /// given the element type and number of elements.
419 ///
420 /// By default, performs semantic analysis when building the vector type.
421 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000422 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregora16548e2009-08-11 05:31:07 +0000423 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000424 SourceLocation AttributeLoc);
Mike Stump11289f42009-09-09 15:08:12 +0000425
Douglas Gregord6ff3322009-08-04 16:50:30 +0000426 /// \brief Build a new function type.
427 ///
428 /// By default, performs semantic analysis when building the function type.
429 /// Subclasses may override this routine to provide different behavior.
430 QualType RebuildFunctionProtoType(QualType T,
Mike Stump11289f42009-09-09 15:08:12 +0000431 QualType *ParamTypes,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000432 unsigned NumParamTypes,
433 bool Variadic, unsigned Quals);
Mike Stump11289f42009-09-09 15:08:12 +0000434
John McCall550e0c22009-10-21 00:40:46 +0000435 /// \brief Build a new unprototyped function type.
436 QualType RebuildFunctionNoProtoType(QualType ResultType);
437
Douglas Gregord6ff3322009-08-04 16:50:30 +0000438 /// \brief Build a new typedef type.
439 QualType RebuildTypedefType(TypedefDecl *Typedef) {
440 return SemaRef.Context.getTypeDeclType(Typedef);
441 }
442
443 /// \brief Build a new class/struct/union type.
444 QualType RebuildRecordType(RecordDecl *Record) {
445 return SemaRef.Context.getTypeDeclType(Record);
446 }
447
448 /// \brief Build a new Enum type.
449 QualType RebuildEnumType(EnumDecl *Enum) {
450 return SemaRef.Context.getTypeDeclType(Enum);
451 }
John McCallfcc33b02009-09-05 00:15:47 +0000452
453 /// \brief Build a new elaborated type.
454 QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag) {
455 return SemaRef.Context.getElaboratedType(T, Tag);
456 }
Mike Stump11289f42009-09-09 15:08:12 +0000457
458 /// \brief Build a new typeof(expr) type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000459 ///
460 /// By default, performs semantic analysis when building the typeof type.
461 /// Subclasses may override this routine to provide different behavior.
Douglas Gregora16548e2009-08-11 05:31:07 +0000462 QualType RebuildTypeOfExprType(ExprArg Underlying);
Douglas Gregord6ff3322009-08-04 16:50:30 +0000463
Mike Stump11289f42009-09-09 15:08:12 +0000464 /// \brief Build a new typeof(type) type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000465 ///
466 /// By default, builds a new TypeOfType with the given underlying type.
467 QualType RebuildTypeOfType(QualType Underlying);
468
Mike Stump11289f42009-09-09 15:08:12 +0000469 /// \brief Build a new C++0x decltype type.
Douglas Gregord6ff3322009-08-04 16:50:30 +0000470 ///
471 /// By default, performs semantic analysis when building the decltype type.
472 /// Subclasses may override this routine to provide different behavior.
Douglas Gregora16548e2009-08-11 05:31:07 +0000473 QualType RebuildDecltypeType(ExprArg Underlying);
Mike Stump11289f42009-09-09 15:08:12 +0000474
Douglas Gregord6ff3322009-08-04 16:50:30 +0000475 /// \brief Build a new template specialization type.
476 ///
477 /// By default, performs semantic analysis when building the template
478 /// specialization type. Subclasses may override this routine to provide
479 /// different behavior.
480 QualType RebuildTemplateSpecializationType(TemplateName Template,
481 const TemplateArgument *Args,
482 unsigned NumArgs);
Mike Stump11289f42009-09-09 15:08:12 +0000483
Douglas Gregord6ff3322009-08-04 16:50:30 +0000484 /// \brief Build a new qualified name type.
485 ///
Mike Stump11289f42009-09-09 15:08:12 +0000486 /// By default, builds a new QualifiedNameType type from the
487 /// nested-name-specifier and the named type. Subclasses may override
Douglas Gregord6ff3322009-08-04 16:50:30 +0000488 /// this routine to provide different behavior.
489 QualType RebuildQualifiedNameType(NestedNameSpecifier *NNS, QualType Named) {
490 return SemaRef.Context.getQualifiedNameType(NNS, Named);
Mike Stump11289f42009-09-09 15:08:12 +0000491 }
Douglas Gregord6ff3322009-08-04 16:50:30 +0000492
493 /// \brief Build a new typename type that refers to a template-id.
494 ///
495 /// By default, builds a new TypenameType type from the nested-name-specifier
Mike Stump11289f42009-09-09 15:08:12 +0000496 /// and the given type. Subclasses may override this routine to provide
Douglas Gregord6ff3322009-08-04 16:50:30 +0000497 /// different behavior.
498 QualType RebuildTypenameType(NestedNameSpecifier *NNS, QualType T) {
499 if (NNS->isDependent())
Mike Stump11289f42009-09-09 15:08:12 +0000500 return SemaRef.Context.getTypenameType(NNS,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000501 cast<TemplateSpecializationType>(T));
Mike Stump11289f42009-09-09 15:08:12 +0000502
Douglas Gregord6ff3322009-08-04 16:50:30 +0000503 return SemaRef.Context.getQualifiedNameType(NNS, T);
Mike Stump11289f42009-09-09 15:08:12 +0000504 }
Douglas Gregord6ff3322009-08-04 16:50:30 +0000505
506 /// \brief Build a new typename type that refers to an identifier.
507 ///
508 /// By default, performs semantic analysis when building the typename type
Mike Stump11289f42009-09-09 15:08:12 +0000509 /// (or qualified name type). Subclasses may override this routine to provide
Douglas Gregord6ff3322009-08-04 16:50:30 +0000510 /// different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000511 QualType RebuildTypenameType(NestedNameSpecifier *NNS,
Douglas Gregord6ff3322009-08-04 16:50:30 +0000512 const IdentifierInfo *Id) {
513 return SemaRef.CheckTypenameType(NNS, *Id,
514 SourceRange(getDerived().getBaseLocation()));
Douglas Gregor1135c352009-08-06 05:28:30 +0000515 }
Mike Stump11289f42009-09-09 15:08:12 +0000516
Douglas Gregor1135c352009-08-06 05:28:30 +0000517 /// \brief Build a new nested-name-specifier given the prefix and an
518 /// identifier that names the next step in the nested-name-specifier.
519 ///
520 /// By default, performs semantic analysis when building the new
521 /// nested-name-specifier. Subclasses may override this routine to provide
522 /// different behavior.
523 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
524 SourceRange Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +0000525 IdentifierInfo &II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +0000526 QualType ObjectType,
527 NamedDecl *FirstQualifierInScope);
Douglas Gregor1135c352009-08-06 05:28:30 +0000528
529 /// \brief Build a new nested-name-specifier given the prefix and the
530 /// namespace named in the next step in the nested-name-specifier.
531 ///
532 /// By default, performs semantic analysis when building the new
533 /// nested-name-specifier. Subclasses may override this routine to provide
534 /// different behavior.
535 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
536 SourceRange Range,
537 NamespaceDecl *NS);
538
539 /// \brief Build a new nested-name-specifier given the prefix and the
540 /// type named in the next step in the nested-name-specifier.
541 ///
542 /// By default, performs semantic analysis when building the new
543 /// nested-name-specifier. Subclasses may override this routine to provide
544 /// different behavior.
545 NestedNameSpecifier *RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
546 SourceRange Range,
547 bool TemplateKW,
548 QualType T);
Douglas Gregor71dc5092009-08-06 06:41:21 +0000549
550 /// \brief Build a new template name given a nested name specifier, a flag
551 /// indicating whether the "template" keyword was provided, and the template
552 /// that the template name refers to.
553 ///
554 /// By default, builds the new template name directly. Subclasses may override
555 /// this routine to provide different behavior.
556 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
557 bool TemplateKW,
558 TemplateDecl *Template);
559
560 /// \brief Build a new template name given a nested name specifier, a flag
561 /// indicating whether the "template" keyword was provided, and a set of
562 /// overloaded function templates.
563 ///
564 /// By default, builds the new template name directly. Subclasses may override
565 /// this routine to provide different behavior.
566 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
567 bool TemplateKW,
568 OverloadedFunctionDecl *Ovl);
Mike Stump11289f42009-09-09 15:08:12 +0000569
Douglas Gregor71dc5092009-08-06 06:41:21 +0000570 /// \brief Build a new template name given a nested name specifier and the
571 /// name that is referred to as a template.
572 ///
573 /// By default, performs semantic analysis to determine whether the name can
574 /// be resolved to a specific template, then builds the appropriate kind of
575 /// template name. Subclasses may override this routine to provide different
576 /// behavior.
577 TemplateName RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor308047d2009-09-09 00:23:06 +0000578 const IdentifierInfo &II,
579 QualType ObjectType);
Mike Stump11289f42009-09-09 15:08:12 +0000580
581
Douglas Gregorebe10102009-08-20 07:17:43 +0000582 /// \brief Build a new compound statement.
583 ///
584 /// By default, performs semantic analysis to build the new statement.
585 /// Subclasses may override this routine to provide different behavior.
586 OwningStmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
587 MultiStmtArg Statements,
588 SourceLocation RBraceLoc,
589 bool IsStmtExpr) {
590 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, move(Statements),
591 IsStmtExpr);
592 }
593
594 /// \brief Build a new case statement.
595 ///
596 /// By default, performs semantic analysis to build the new statement.
597 /// Subclasses may override this routine to provide different behavior.
598 OwningStmtResult RebuildCaseStmt(SourceLocation CaseLoc,
599 ExprArg LHS,
600 SourceLocation EllipsisLoc,
601 ExprArg RHS,
602 SourceLocation ColonLoc) {
Mike Stump11289f42009-09-09 15:08:12 +0000603 return getSema().ActOnCaseStmt(CaseLoc, move(LHS), EllipsisLoc, move(RHS),
Douglas Gregorebe10102009-08-20 07:17:43 +0000604 ColonLoc);
605 }
Mike Stump11289f42009-09-09 15:08:12 +0000606
Douglas Gregorebe10102009-08-20 07:17:43 +0000607 /// \brief Attach the body to a new case statement.
608 ///
609 /// By default, performs semantic analysis to build the new statement.
610 /// Subclasses may override this routine to provide different behavior.
611 OwningStmtResult RebuildCaseStmtBody(StmtArg S, StmtArg Body) {
612 getSema().ActOnCaseStmtBody(S.get(), move(Body));
613 return move(S);
614 }
Mike Stump11289f42009-09-09 15:08:12 +0000615
Douglas Gregorebe10102009-08-20 07:17:43 +0000616 /// \brief Build a new default statement.
617 ///
618 /// By default, performs semantic analysis to build the new statement.
619 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000620 OwningStmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000621 SourceLocation ColonLoc,
622 StmtArg SubStmt) {
Mike Stump11289f42009-09-09 15:08:12 +0000623 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, move(SubStmt),
Douglas Gregorebe10102009-08-20 07:17:43 +0000624 /*CurScope=*/0);
625 }
Mike Stump11289f42009-09-09 15:08:12 +0000626
Douglas Gregorebe10102009-08-20 07:17:43 +0000627 /// \brief Build a new label statement.
628 ///
629 /// By default, performs semantic analysis to build the new statement.
630 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000631 OwningStmtResult RebuildLabelStmt(SourceLocation IdentLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000632 IdentifierInfo *Id,
633 SourceLocation ColonLoc,
634 StmtArg SubStmt) {
635 return SemaRef.ActOnLabelStmt(IdentLoc, Id, ColonLoc, move(SubStmt));
636 }
Mike Stump11289f42009-09-09 15:08:12 +0000637
Douglas Gregorebe10102009-08-20 07:17:43 +0000638 /// \brief Build a new "if" statement.
639 ///
640 /// By default, performs semantic analysis to build the new statement.
641 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000642 OwningStmtResult RebuildIfStmt(SourceLocation IfLoc, Sema::FullExprArg Cond,
643 StmtArg Then, SourceLocation ElseLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000644 StmtArg Else) {
645 return getSema().ActOnIfStmt(IfLoc, Cond, move(Then), ElseLoc, move(Else));
646 }
Mike Stump11289f42009-09-09 15:08:12 +0000647
Douglas Gregorebe10102009-08-20 07:17:43 +0000648 /// \brief Start building a new switch statement.
649 ///
650 /// By default, performs semantic analysis to build the new statement.
651 /// Subclasses may override this routine to provide different behavior.
652 OwningStmtResult RebuildSwitchStmtStart(ExprArg Cond) {
653 return getSema().ActOnStartOfSwitchStmt(move(Cond));
654 }
Mike Stump11289f42009-09-09 15:08:12 +0000655
Douglas Gregorebe10102009-08-20 07:17:43 +0000656 /// \brief Attach the body to the switch statement.
657 ///
658 /// By default, performs semantic analysis to build the new statement.
659 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000660 OwningStmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000661 StmtArg Switch, StmtArg Body) {
662 return getSema().ActOnFinishSwitchStmt(SwitchLoc, move(Switch),
663 move(Body));
664 }
665
666 /// \brief Build a new while statement.
667 ///
668 /// By default, performs semantic analysis to build the new statement.
669 /// Subclasses may override this routine to provide different behavior.
670 OwningStmtResult RebuildWhileStmt(SourceLocation WhileLoc,
671 Sema::FullExprArg Cond,
672 StmtArg Body) {
673 return getSema().ActOnWhileStmt(WhileLoc, Cond, move(Body));
674 }
Mike Stump11289f42009-09-09 15:08:12 +0000675
Douglas Gregorebe10102009-08-20 07:17:43 +0000676 /// \brief Build a new do-while statement.
677 ///
678 /// By default, performs semantic analysis to build the new statement.
679 /// Subclasses may override this routine to provide different behavior.
680 OwningStmtResult RebuildDoStmt(SourceLocation DoLoc, StmtArg Body,
681 SourceLocation WhileLoc,
682 SourceLocation LParenLoc,
683 ExprArg Cond,
684 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +0000685 return getSema().ActOnDoStmt(DoLoc, move(Body), WhileLoc, LParenLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000686 move(Cond), RParenLoc);
687 }
688
689 /// \brief Build a new for statement.
690 ///
691 /// By default, performs semantic analysis to build the new statement.
692 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000693 OwningStmtResult RebuildForStmt(SourceLocation ForLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000694 SourceLocation LParenLoc,
695 StmtArg Init, ExprArg Cond, ExprArg Inc,
696 SourceLocation RParenLoc, StmtArg Body) {
Mike Stump11289f42009-09-09 15:08:12 +0000697 return getSema().ActOnForStmt(ForLoc, LParenLoc, move(Init), move(Cond),
Douglas Gregorebe10102009-08-20 07:17:43 +0000698 move(Inc), RParenLoc, move(Body));
699 }
Mike Stump11289f42009-09-09 15:08:12 +0000700
Douglas Gregorebe10102009-08-20 07:17:43 +0000701 /// \brief Build a new goto statement.
702 ///
703 /// By default, performs semantic analysis to build the new statement.
704 /// Subclasses may override this routine to provide different behavior.
705 OwningStmtResult RebuildGotoStmt(SourceLocation GotoLoc,
706 SourceLocation LabelLoc,
707 LabelStmt *Label) {
708 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label->getID());
709 }
710
711 /// \brief Build a new indirect goto statement.
712 ///
713 /// By default, performs semantic analysis to build the new statement.
714 /// Subclasses may override this routine to provide different behavior.
715 OwningStmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
716 SourceLocation StarLoc,
717 ExprArg Target) {
718 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, move(Target));
719 }
Mike Stump11289f42009-09-09 15:08:12 +0000720
Douglas Gregorebe10102009-08-20 07:17:43 +0000721 /// \brief Build a new return statement.
722 ///
723 /// By default, performs semantic analysis to build the new statement.
724 /// Subclasses may override this routine to provide different behavior.
725 OwningStmtResult RebuildReturnStmt(SourceLocation ReturnLoc,
726 ExprArg Result) {
Mike Stump11289f42009-09-09 15:08:12 +0000727
Douglas Gregorebe10102009-08-20 07:17:43 +0000728 return getSema().ActOnReturnStmt(ReturnLoc, move(Result));
729 }
Mike Stump11289f42009-09-09 15:08:12 +0000730
Douglas Gregorebe10102009-08-20 07:17:43 +0000731 /// \brief Build a new declaration statement.
732 ///
733 /// By default, performs semantic analysis to build the new statement.
734 /// Subclasses may override this routine to provide different behavior.
735 OwningStmtResult RebuildDeclStmt(Decl **Decls, unsigned NumDecls,
Mike Stump11289f42009-09-09 15:08:12 +0000736 SourceLocation StartLoc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000737 SourceLocation EndLoc) {
738 return getSema().Owned(
739 new (getSema().Context) DeclStmt(
740 DeclGroupRef::Create(getSema().Context,
741 Decls, NumDecls),
742 StartLoc, EndLoc));
743 }
Mike Stump11289f42009-09-09 15:08:12 +0000744
Douglas Gregorebe10102009-08-20 07:17:43 +0000745 /// \brief Build a new C++ exception declaration.
746 ///
747 /// By default, performs semantic analysis to build the new decaration.
748 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000749 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl, QualType T,
Douglas Gregorebe10102009-08-20 07:17:43 +0000750 DeclaratorInfo *Declarator,
751 IdentifierInfo *Name,
752 SourceLocation Loc,
753 SourceRange TypeRange) {
Mike Stump11289f42009-09-09 15:08:12 +0000754 return getSema().BuildExceptionDeclaration(0, T, Declarator, Name, Loc,
Douglas Gregorebe10102009-08-20 07:17:43 +0000755 TypeRange);
756 }
757
758 /// \brief Build a new C++ catch statement.
759 ///
760 /// By default, performs semantic analysis to build the new statement.
761 /// Subclasses may override this routine to provide different behavior.
762 OwningStmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
763 VarDecl *ExceptionDecl,
764 StmtArg Handler) {
765 return getSema().Owned(
Mike Stump11289f42009-09-09 15:08:12 +0000766 new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
Douglas Gregorebe10102009-08-20 07:17:43 +0000767 Handler.takeAs<Stmt>()));
768 }
Mike Stump11289f42009-09-09 15:08:12 +0000769
Douglas Gregorebe10102009-08-20 07:17:43 +0000770 /// \brief Build a new C++ try statement.
771 ///
772 /// By default, performs semantic analysis to build the new statement.
773 /// Subclasses may override this routine to provide different behavior.
774 OwningStmtResult RebuildCXXTryStmt(SourceLocation TryLoc,
775 StmtArg TryBlock,
776 MultiStmtArg Handlers) {
777 return getSema().ActOnCXXTryBlock(TryLoc, move(TryBlock), move(Handlers));
778 }
Mike Stump11289f42009-09-09 15:08:12 +0000779
Douglas Gregora16548e2009-08-11 05:31:07 +0000780 /// \brief Build a new expression that references a declaration.
781 ///
782 /// By default, performs semantic analysis to build the new expression.
783 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor4bd90e52009-10-23 18:54:35 +0000784 OwningExprResult RebuildDeclRefExpr(NestedNameSpecifier *Qualifier,
785 SourceRange QualifierRange,
786 NamedDecl *ND, SourceLocation Loc) {
787 CXXScopeSpec SS;
788 SS.setScopeRep(Qualifier);
789 SS.setRange(QualifierRange);
Douglas Gregora16548e2009-08-11 05:31:07 +0000790 return getSema().BuildDeclarationNameExpr(Loc, ND,
791 /*FIXME:*/false,
Douglas Gregor4bd90e52009-10-23 18:54:35 +0000792 &SS,
Douglas Gregora16548e2009-08-11 05:31:07 +0000793 /*FIXME:*/false);
794 }
Mike Stump11289f42009-09-09 15:08:12 +0000795
Douglas Gregora16548e2009-08-11 05:31:07 +0000796 /// \brief Build a new expression in parentheses.
Mike Stump11289f42009-09-09 15:08:12 +0000797 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000798 /// By default, performs semantic analysis to build the new expression.
799 /// Subclasses may override this routine to provide different behavior.
800 OwningExprResult RebuildParenExpr(ExprArg SubExpr, SourceLocation LParen,
801 SourceLocation RParen) {
802 return getSema().ActOnParenExpr(LParen, RParen, move(SubExpr));
803 }
804
Douglas Gregorad8a3362009-09-04 17:36:40 +0000805 /// \brief Build a new pseudo-destructor expression.
Mike Stump11289f42009-09-09 15:08:12 +0000806 ///
Douglas Gregorad8a3362009-09-04 17:36:40 +0000807 /// By default, performs semantic analysis to build the new expression.
808 /// Subclasses may override this routine to provide different behavior.
809 OwningExprResult RebuildCXXPseudoDestructorExpr(ExprArg Base,
810 SourceLocation OperatorLoc,
811 bool isArrow,
812 SourceLocation DestroyedTypeLoc,
813 QualType DestroyedType,
814 NestedNameSpecifier *Qualifier,
815 SourceRange QualifierRange) {
816 CXXScopeSpec SS;
817 if (Qualifier) {
818 SS.setRange(QualifierRange);
819 SS.setScopeRep(Qualifier);
820 }
821
Mike Stump11289f42009-09-09 15:08:12 +0000822 DeclarationName Name
Douglas Gregorad8a3362009-09-04 17:36:40 +0000823 = SemaRef.Context.DeclarationNames.getCXXDestructorName(
824 SemaRef.Context.getCanonicalType(DestroyedType));
Mike Stump11289f42009-09-09 15:08:12 +0000825
826 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregorad8a3362009-09-04 17:36:40 +0000827 OperatorLoc,
828 isArrow? tok::arrow : tok::period,
829 DestroyedTypeLoc,
830 Name,
831 Sema::DeclPtrTy::make((Decl *)0),
832 &SS);
Mike Stump11289f42009-09-09 15:08:12 +0000833 }
834
Douglas Gregora16548e2009-08-11 05:31:07 +0000835 /// \brief Build a new unary operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000836 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000837 /// By default, performs semantic analysis to build the new expression.
838 /// Subclasses may override this routine to provide different behavior.
839 OwningExprResult RebuildUnaryOperator(SourceLocation OpLoc,
840 UnaryOperator::Opcode Opc,
841 ExprArg SubExpr) {
842 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(SubExpr));
843 }
Mike Stump11289f42009-09-09 15:08:12 +0000844
Douglas Gregora16548e2009-08-11 05:31:07 +0000845 /// \brief Build a new sizeof or alignof expression with a type argument.
Mike Stump11289f42009-09-09 15:08:12 +0000846 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000847 /// By default, performs semantic analysis to build the new expression.
848 /// Subclasses may override this routine to provide different behavior.
849 OwningExprResult RebuildSizeOfAlignOf(QualType T, SourceLocation OpLoc,
850 bool isSizeOf, SourceRange R) {
851 return getSema().CreateSizeOfAlignOfExpr(T, OpLoc, isSizeOf, R);
852 }
853
Mike Stump11289f42009-09-09 15:08:12 +0000854 /// \brief Build a new sizeof or alignof expression with an expression
Douglas Gregora16548e2009-08-11 05:31:07 +0000855 /// argument.
Mike Stump11289f42009-09-09 15:08:12 +0000856 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000857 /// By default, performs semantic analysis to build the new expression.
858 /// Subclasses may override this routine to provide different behavior.
859 OwningExprResult RebuildSizeOfAlignOf(ExprArg SubExpr, SourceLocation OpLoc,
860 bool isSizeOf, SourceRange R) {
Mike Stump11289f42009-09-09 15:08:12 +0000861 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +0000862 = getSema().CreateSizeOfAlignOfExpr((Expr *)SubExpr.get(),
863 OpLoc, isSizeOf, R);
864 if (Result.isInvalid())
865 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +0000866
Douglas Gregora16548e2009-08-11 05:31:07 +0000867 SubExpr.release();
868 return move(Result);
869 }
Mike Stump11289f42009-09-09 15:08:12 +0000870
Douglas Gregora16548e2009-08-11 05:31:07 +0000871 /// \brief Build a new array subscript expression.
Mike Stump11289f42009-09-09 15:08:12 +0000872 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000873 /// By default, performs semantic analysis to build the new expression.
874 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +0000875 OwningExprResult RebuildArraySubscriptExpr(ExprArg LHS,
Douglas Gregora16548e2009-08-11 05:31:07 +0000876 SourceLocation LBracketLoc,
877 ExprArg RHS,
878 SourceLocation RBracketLoc) {
879 return getSema().ActOnArraySubscriptExpr(/*Scope=*/0, move(LHS),
Mike Stump11289f42009-09-09 15:08:12 +0000880 LBracketLoc, move(RHS),
Douglas Gregora16548e2009-08-11 05:31:07 +0000881 RBracketLoc);
882 }
883
884 /// \brief Build a new call expression.
Mike Stump11289f42009-09-09 15:08:12 +0000885 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000886 /// By default, performs semantic analysis to build the new expression.
887 /// Subclasses may override this routine to provide different behavior.
888 OwningExprResult RebuildCallExpr(ExprArg Callee, SourceLocation LParenLoc,
889 MultiExprArg Args,
890 SourceLocation *CommaLocs,
891 SourceLocation RParenLoc) {
892 return getSema().ActOnCallExpr(/*Scope=*/0, move(Callee), LParenLoc,
893 move(Args), CommaLocs, RParenLoc);
894 }
895
896 /// \brief Build a new member access expression.
Mike Stump11289f42009-09-09 15:08:12 +0000897 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000898 /// By default, performs semantic analysis to build the new expression.
899 /// Subclasses may override this routine to provide different behavior.
900 OwningExprResult RebuildMemberExpr(ExprArg Base, SourceLocation OpLoc,
Mike Stump11289f42009-09-09 15:08:12 +0000901 bool isArrow,
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000902 NestedNameSpecifier *Qualifier,
903 SourceRange QualifierRange,
904 SourceLocation MemberLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000905 NamedDecl *Member) {
Anders Carlsson5da84842009-09-01 04:26:58 +0000906 if (!Member->getDeclName()) {
907 // We have a reference to an unnamed field.
908 assert(!Qualifier && "Can't have an unnamed field with a qualifier!");
Mike Stump11289f42009-09-09 15:08:12 +0000909
910 MemberExpr *ME =
Anders Carlsson5da84842009-09-01 04:26:58 +0000911 new (getSema().Context) MemberExpr(Base.takeAs<Expr>(), isArrow,
912 Member, MemberLoc,
913 cast<FieldDecl>(Member)->getType());
914 return getSema().Owned(ME);
915 }
Mike Stump11289f42009-09-09 15:08:12 +0000916
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000917 CXXScopeSpec SS;
918 if (Qualifier) {
919 SS.setRange(QualifierRange);
920 SS.setScopeRep(Qualifier);
921 }
922
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000923 return getSema().BuildMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +0000924 isArrow? tok::arrow : tok::period,
925 MemberLoc,
Douglas Gregorf14b46f2009-08-31 20:00:26 +0000926 Member->getDeclName(),
Douglas Gregorf405d7e2009-08-31 23:41:50 +0000927 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
928 &SS);
Douglas Gregora16548e2009-08-11 05:31:07 +0000929 }
Mike Stump11289f42009-09-09 15:08:12 +0000930
Douglas Gregora16548e2009-08-11 05:31:07 +0000931 /// \brief Build a new binary operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000932 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000933 /// By default, performs semantic analysis to build the new expression.
934 /// Subclasses may override this routine to provide different behavior.
935 OwningExprResult RebuildBinaryOperator(SourceLocation OpLoc,
936 BinaryOperator::Opcode Opc,
937 ExprArg LHS, ExprArg RHS) {
938 OwningExprResult Result
Mike Stump11289f42009-09-09 15:08:12 +0000939 = getSema().CreateBuiltinBinOp(OpLoc, Opc, (Expr *)LHS.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +0000940 (Expr *)RHS.get());
941 if (Result.isInvalid())
942 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +0000943
Douglas Gregora16548e2009-08-11 05:31:07 +0000944 LHS.release();
945 RHS.release();
946 return move(Result);
947 }
948
949 /// \brief Build a new conditional operator expression.
Mike Stump11289f42009-09-09 15:08:12 +0000950 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000951 /// By default, performs semantic analysis to build the new expression.
952 /// Subclasses may override this routine to provide different behavior.
953 OwningExprResult RebuildConditionalOperator(ExprArg Cond,
954 SourceLocation QuestionLoc,
955 ExprArg LHS,
956 SourceLocation ColonLoc,
957 ExprArg RHS) {
Mike Stump11289f42009-09-09 15:08:12 +0000958 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, move(Cond),
Douglas Gregora16548e2009-08-11 05:31:07 +0000959 move(LHS), move(RHS));
960 }
961
962 /// \brief Build a new implicit cast expression.
Mike Stump11289f42009-09-09 15:08:12 +0000963 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000964 /// By default, builds a new implicit cast without any semantic analysis.
965 /// Subclasses may override this routine to provide different behavior.
966 OwningExprResult RebuildImplicitCastExpr(QualType T, CastExpr::CastKind Kind,
967 ExprArg SubExpr, bool isLvalue) {
968 ImplicitCastExpr *ICE
Mike Stump11289f42009-09-09 15:08:12 +0000969 = new (getSema().Context) ImplicitCastExpr(T, Kind,
Douglas Gregora16548e2009-08-11 05:31:07 +0000970 (Expr *)SubExpr.release(),
971 isLvalue);
972 return getSema().Owned(ICE);
973 }
974
975 /// \brief Build a new C-style cast expression.
Mike Stump11289f42009-09-09 15:08:12 +0000976 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000977 /// By default, performs semantic analysis to build the new expression.
978 /// Subclasses may override this routine to provide different behavior.
979 OwningExprResult RebuildCStyleCaseExpr(SourceLocation LParenLoc,
980 QualType ExplicitTy,
981 SourceLocation RParenLoc,
982 ExprArg SubExpr) {
983 return getSema().ActOnCastExpr(/*Scope=*/0,
984 LParenLoc,
985 ExplicitTy.getAsOpaquePtr(),
986 RParenLoc,
987 move(SubExpr));
988 }
Mike Stump11289f42009-09-09 15:08:12 +0000989
Douglas Gregora16548e2009-08-11 05:31:07 +0000990 /// \brief Build a new compound literal expression.
Mike Stump11289f42009-09-09 15:08:12 +0000991 ///
Douglas Gregora16548e2009-08-11 05:31:07 +0000992 /// By default, performs semantic analysis to build the new expression.
993 /// Subclasses may override this routine to provide different behavior.
994 OwningExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
995 QualType T,
996 SourceLocation RParenLoc,
997 ExprArg Init) {
998 return getSema().ActOnCompoundLiteral(LParenLoc, T.getAsOpaquePtr(),
999 RParenLoc, move(Init));
1000 }
Mike Stump11289f42009-09-09 15:08:12 +00001001
Douglas Gregora16548e2009-08-11 05:31:07 +00001002 /// \brief Build a new extended vector element access expression.
Mike Stump11289f42009-09-09 15:08:12 +00001003 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001004 /// By default, performs semantic analysis to build the new expression.
1005 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001006 OwningExprResult RebuildExtVectorElementExpr(ExprArg Base,
Douglas Gregora16548e2009-08-11 05:31:07 +00001007 SourceLocation OpLoc,
1008 SourceLocation AccessorLoc,
1009 IdentifierInfo &Accessor) {
1010 return getSema().ActOnMemberReferenceExpr(/*Scope=*/0, move(Base), OpLoc,
1011 tok::period, AccessorLoc,
1012 Accessor,
1013 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0));
1014 }
Mike Stump11289f42009-09-09 15:08:12 +00001015
Douglas Gregora16548e2009-08-11 05:31:07 +00001016 /// \brief Build a new initializer list expression.
Mike Stump11289f42009-09-09 15:08:12 +00001017 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001018 /// By default, performs semantic analysis to build the new expression.
1019 /// Subclasses may override this routine to provide different behavior.
1020 OwningExprResult RebuildInitList(SourceLocation LBraceLoc,
1021 MultiExprArg Inits,
1022 SourceLocation RBraceLoc) {
1023 return SemaRef.ActOnInitList(LBraceLoc, move(Inits), RBraceLoc);
1024 }
Mike Stump11289f42009-09-09 15:08:12 +00001025
Douglas Gregora16548e2009-08-11 05:31:07 +00001026 /// \brief Build a new designated initializer expression.
Mike Stump11289f42009-09-09 15:08:12 +00001027 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001028 /// By default, performs semantic analysis to build the new expression.
1029 /// Subclasses may override this routine to provide different behavior.
1030 OwningExprResult RebuildDesignatedInitExpr(Designation &Desig,
1031 MultiExprArg ArrayExprs,
1032 SourceLocation EqualOrColonLoc,
1033 bool GNUSyntax,
1034 ExprArg Init) {
1035 OwningExprResult Result
1036 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
1037 move(Init));
1038 if (Result.isInvalid())
1039 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001040
Douglas Gregora16548e2009-08-11 05:31:07 +00001041 ArrayExprs.release();
1042 return move(Result);
1043 }
Mike Stump11289f42009-09-09 15:08:12 +00001044
Douglas Gregora16548e2009-08-11 05:31:07 +00001045 /// \brief Build a new value-initialized expression.
Mike Stump11289f42009-09-09 15:08:12 +00001046 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001047 /// By default, builds the implicit value initialization without performing
1048 /// any semantic analysis. Subclasses may override this routine to provide
1049 /// different behavior.
1050 OwningExprResult RebuildImplicitValueInitExpr(QualType T) {
1051 return SemaRef.Owned(new (SemaRef.Context) ImplicitValueInitExpr(T));
1052 }
Mike Stump11289f42009-09-09 15:08:12 +00001053
Douglas Gregora16548e2009-08-11 05:31:07 +00001054 /// \brief Build a new \c va_arg expression.
Mike Stump11289f42009-09-09 15:08:12 +00001055 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001056 /// By default, performs semantic analysis to build the new expression.
1057 /// Subclasses may override this routine to provide different behavior.
1058 OwningExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc, ExprArg SubExpr,
1059 QualType T, SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001060 return getSema().ActOnVAArg(BuiltinLoc, move(SubExpr), T.getAsOpaquePtr(),
Douglas Gregora16548e2009-08-11 05:31:07 +00001061 RParenLoc);
1062 }
1063
1064 /// \brief Build a new expression list in parentheses.
Mike Stump11289f42009-09-09 15:08:12 +00001065 ///
Douglas Gregora16548e2009-08-11 05:31:07 +00001066 /// By default, performs semantic analysis to build the new expression.
1067 /// Subclasses may override this routine to provide different behavior.
1068 OwningExprResult RebuildParenListExpr(SourceLocation LParenLoc,
1069 MultiExprArg SubExprs,
1070 SourceLocation RParenLoc) {
1071 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, move(SubExprs));
1072 }
Mike Stump11289f42009-09-09 15:08:12 +00001073
Douglas Gregora16548e2009-08-11 05:31:07 +00001074 /// \brief Build a new address-of-label expression.
Mike Stump11289f42009-09-09 15:08:12 +00001075 ///
1076 /// By default, performs semantic analysis, using the name of the label
Douglas Gregora16548e2009-08-11 05:31:07 +00001077 /// rather than attempting to map the label statement itself.
1078 /// Subclasses may override this routine to provide different behavior.
1079 OwningExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
1080 SourceLocation LabelLoc,
1081 LabelStmt *Label) {
1082 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label->getID());
1083 }
Mike Stump11289f42009-09-09 15:08:12 +00001084
Douglas Gregora16548e2009-08-11 05:31:07 +00001085 /// \brief Build a new GNU statement expression.
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 RebuildStmtExpr(SourceLocation LParenLoc,
1090 StmtArg SubStmt,
1091 SourceLocation RParenLoc) {
1092 return getSema().ActOnStmtExpr(LParenLoc, move(SubStmt), RParenLoc);
1093 }
Mike Stump11289f42009-09-09 15:08:12 +00001094
Douglas Gregora16548e2009-08-11 05:31:07 +00001095 /// \brief Build a new __builtin_types_compatible_p expression.
1096 ///
1097 /// By default, performs semantic analysis to build the new expression.
1098 /// Subclasses may override this routine to provide different behavior.
1099 OwningExprResult RebuildTypesCompatibleExpr(SourceLocation BuiltinLoc,
1100 QualType T1, QualType T2,
1101 SourceLocation RParenLoc) {
1102 return getSema().ActOnTypesCompatibleExpr(BuiltinLoc,
1103 T1.getAsOpaquePtr(),
1104 T2.getAsOpaquePtr(),
1105 RParenLoc);
1106 }
Mike Stump11289f42009-09-09 15:08:12 +00001107
Douglas Gregora16548e2009-08-11 05:31:07 +00001108 /// \brief Build a new __builtin_choose_expr expression.
1109 ///
1110 /// By default, performs semantic analysis to build the new expression.
1111 /// Subclasses may override this routine to provide different behavior.
1112 OwningExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
1113 ExprArg Cond, ExprArg LHS, ExprArg RHS,
1114 SourceLocation RParenLoc) {
1115 return SemaRef.ActOnChooseExpr(BuiltinLoc,
1116 move(Cond), move(LHS), move(RHS),
1117 RParenLoc);
1118 }
Mike Stump11289f42009-09-09 15:08:12 +00001119
Douglas Gregora16548e2009-08-11 05:31:07 +00001120 /// \brief Build a new overloaded operator call expression.
1121 ///
1122 /// By default, performs semantic analysis to build the new expression.
1123 /// The semantic analysis provides the behavior of template instantiation,
1124 /// copying with transformations that turn what looks like an overloaded
Mike Stump11289f42009-09-09 15:08:12 +00001125 /// operator call into a use of a builtin operator, performing
Douglas Gregora16548e2009-08-11 05:31:07 +00001126 /// argument-dependent lookup, etc. Subclasses may override this routine to
1127 /// provide different behavior.
1128 OwningExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
1129 SourceLocation OpLoc,
1130 ExprArg Callee,
1131 ExprArg First,
1132 ExprArg Second);
Mike Stump11289f42009-09-09 15:08:12 +00001133
1134 /// \brief Build a new C++ "named" cast expression, such as static_cast or
Douglas Gregora16548e2009-08-11 05:31:07 +00001135 /// reinterpret_cast.
1136 ///
1137 /// By default, this routine dispatches to one of the more-specific routines
Mike Stump11289f42009-09-09 15:08:12 +00001138 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
Douglas Gregora16548e2009-08-11 05:31:07 +00001139 /// Subclasses may override this routine to provide different behavior.
1140 OwningExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
1141 Stmt::StmtClass Class,
1142 SourceLocation LAngleLoc,
1143 QualType T,
1144 SourceLocation RAngleLoc,
1145 SourceLocation LParenLoc,
1146 ExprArg SubExpr,
1147 SourceLocation RParenLoc) {
1148 switch (Class) {
1149 case Stmt::CXXStaticCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001150 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, T,
1151 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001152 move(SubExpr), RParenLoc);
1153
1154 case Stmt::CXXDynamicCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001155 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, T,
1156 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001157 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001158
Douglas Gregora16548e2009-08-11 05:31:07 +00001159 case Stmt::CXXReinterpretCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001160 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, T,
1161 RAngleLoc, LParenLoc,
1162 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00001163 RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001164
Douglas Gregora16548e2009-08-11 05:31:07 +00001165 case Stmt::CXXConstCastExprClass:
Mike Stump11289f42009-09-09 15:08:12 +00001166 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, T,
1167 RAngleLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001168 move(SubExpr), RParenLoc);
Mike Stump11289f42009-09-09 15:08:12 +00001169
Douglas Gregora16548e2009-08-11 05:31:07 +00001170 default:
1171 assert(false && "Invalid C++ named cast");
1172 break;
1173 }
Mike Stump11289f42009-09-09 15:08:12 +00001174
Douglas Gregora16548e2009-08-11 05:31:07 +00001175 return getSema().ExprError();
1176 }
Mike Stump11289f42009-09-09 15:08:12 +00001177
Douglas Gregora16548e2009-08-11 05:31:07 +00001178 /// \brief Build a new C++ static_cast expression.
1179 ///
1180 /// By default, performs semantic analysis to build the new expression.
1181 /// Subclasses may override this routine to provide different behavior.
1182 OwningExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
1183 SourceLocation LAngleLoc,
1184 QualType T,
1185 SourceLocation RAngleLoc,
1186 SourceLocation LParenLoc,
1187 ExprArg SubExpr,
1188 SourceLocation RParenLoc) {
1189 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_static_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001190 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001191 LParenLoc, move(SubExpr), RParenLoc);
1192 }
1193
1194 /// \brief Build a new C++ dynamic_cast expression.
1195 ///
1196 /// By default, performs semantic analysis to build the new expression.
1197 /// Subclasses may override this routine to provide different behavior.
1198 OwningExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
1199 SourceLocation LAngleLoc,
1200 QualType T,
1201 SourceLocation RAngleLoc,
1202 SourceLocation LParenLoc,
1203 ExprArg SubExpr,
1204 SourceLocation RParenLoc) {
1205 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001206 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001207 LParenLoc, move(SubExpr), RParenLoc);
1208 }
1209
1210 /// \brief Build a new C++ reinterpret_cast expression.
1211 ///
1212 /// By default, performs semantic analysis to build the new expression.
1213 /// Subclasses may override this routine to provide different behavior.
1214 OwningExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
1215 SourceLocation LAngleLoc,
1216 QualType T,
1217 SourceLocation RAngleLoc,
1218 SourceLocation LParenLoc,
1219 ExprArg SubExpr,
1220 SourceLocation RParenLoc) {
1221 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
1222 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
1223 LParenLoc, move(SubExpr), RParenLoc);
1224 }
1225
1226 /// \brief Build a new C++ const_cast expression.
1227 ///
1228 /// By default, performs semantic analysis to build the new expression.
1229 /// Subclasses may override this routine to provide different behavior.
1230 OwningExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
1231 SourceLocation LAngleLoc,
1232 QualType T,
1233 SourceLocation RAngleLoc,
1234 SourceLocation LParenLoc,
1235 ExprArg SubExpr,
1236 SourceLocation RParenLoc) {
1237 return getSema().ActOnCXXNamedCast(OpLoc, tok::kw_const_cast,
Mike Stump11289f42009-09-09 15:08:12 +00001238 LAngleLoc, T.getAsOpaquePtr(), RAngleLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001239 LParenLoc, move(SubExpr), RParenLoc);
1240 }
Mike Stump11289f42009-09-09 15:08:12 +00001241
Douglas Gregora16548e2009-08-11 05:31:07 +00001242 /// \brief Build a new C++ functional-style cast expression.
1243 ///
1244 /// By default, performs semantic analysis to build the new expression.
1245 /// Subclasses may override this routine to provide different behavior.
1246 OwningExprResult RebuildCXXFunctionalCastExpr(SourceRange TypeRange,
1247 QualType T,
1248 SourceLocation LParenLoc,
1249 ExprArg SubExpr,
1250 SourceLocation RParenLoc) {
Chris Lattnerdca19592009-08-24 05:19:01 +00001251 void *Sub = SubExpr.takeAs<Expr>();
Douglas Gregora16548e2009-08-11 05:31:07 +00001252 return getSema().ActOnCXXTypeConstructExpr(TypeRange,
1253 T.getAsOpaquePtr(),
1254 LParenLoc,
Chris Lattnerdca19592009-08-24 05:19:01 +00001255 Sema::MultiExprArg(getSema(), &Sub, 1),
Mike Stump11289f42009-09-09 15:08:12 +00001256 /*CommaLocs=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001257 RParenLoc);
1258 }
Mike Stump11289f42009-09-09 15:08:12 +00001259
Douglas Gregora16548e2009-08-11 05:31:07 +00001260 /// \brief Build a new C++ typeid(type) expression.
1261 ///
1262 /// By default, performs semantic analysis to build the new expression.
1263 /// Subclasses may override this routine to provide different behavior.
1264 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1265 SourceLocation LParenLoc,
1266 QualType T,
1267 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001268 return getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, true,
Douglas Gregora16548e2009-08-11 05:31:07 +00001269 T.getAsOpaquePtr(), RParenLoc);
1270 }
Mike Stump11289f42009-09-09 15:08:12 +00001271
Douglas Gregora16548e2009-08-11 05:31:07 +00001272 /// \brief Build a new C++ typeid(expr) expression.
1273 ///
1274 /// By default, performs semantic analysis to build the new expression.
1275 /// Subclasses may override this routine to provide different behavior.
1276 OwningExprResult RebuildCXXTypeidExpr(SourceLocation TypeidLoc,
1277 SourceLocation LParenLoc,
1278 ExprArg Operand,
1279 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001280 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00001281 = getSema().ActOnCXXTypeid(TypeidLoc, LParenLoc, false, Operand.get(),
1282 RParenLoc);
1283 if (Result.isInvalid())
1284 return getSema().ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001285
Douglas Gregora16548e2009-08-11 05:31:07 +00001286 Operand.release(); // FIXME: since ActOnCXXTypeid silently took ownership
1287 return move(Result);
Mike Stump11289f42009-09-09 15:08:12 +00001288 }
1289
Douglas Gregora16548e2009-08-11 05:31:07 +00001290 /// \brief Build a new C++ "this" expression.
1291 ///
1292 /// By default, builds a new "this" expression without performing any
Mike Stump11289f42009-09-09 15:08:12 +00001293 /// semantic analysis. Subclasses may override this routine to provide
Douglas Gregora16548e2009-08-11 05:31:07 +00001294 /// different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001295 OwningExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001296 QualType ThisType) {
1297 return getSema().Owned(
1298 new (getSema().Context) CXXThisExpr(ThisLoc, ThisType));
1299 }
1300
1301 /// \brief Build a new C++ throw expression.
1302 ///
1303 /// By default, performs semantic analysis to build the new expression.
1304 /// Subclasses may override this routine to provide different behavior.
1305 OwningExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, ExprArg Sub) {
1306 return getSema().ActOnCXXThrow(ThrowLoc, move(Sub));
1307 }
1308
1309 /// \brief Build a new C++ default-argument expression.
1310 ///
1311 /// By default, builds a new default-argument expression, which does not
1312 /// require any semantic analysis. Subclasses may override this routine to
1313 /// provide different behavior.
1314 OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
Anders Carlssone8271232009-08-14 18:30:22 +00001315 return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
Douglas Gregora16548e2009-08-11 05:31:07 +00001316 }
1317
1318 /// \brief Build a new C++ zero-initialization expression.
1319 ///
1320 /// By default, performs semantic analysis to build the new expression.
1321 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001322 OwningExprResult RebuildCXXZeroInitValueExpr(SourceLocation TypeStartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001323 SourceLocation LParenLoc,
1324 QualType T,
1325 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001326 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeStartLoc),
1327 T.getAsOpaquePtr(), LParenLoc,
1328 MultiExprArg(getSema(), 0, 0),
Douglas Gregora16548e2009-08-11 05:31:07 +00001329 0, RParenLoc);
1330 }
Mike Stump11289f42009-09-09 15:08:12 +00001331
Douglas Gregora16548e2009-08-11 05:31:07 +00001332 /// \brief Build a new C++ conditional declaration expression.
1333 ///
1334 /// By default, performs semantic analysis to build the new expression.
1335 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001336 OwningExprResult RebuildCXXConditionDeclExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001337 SourceLocation EqLoc,
1338 VarDecl *Var) {
1339 return SemaRef.Owned(new (SemaRef.Context) CXXConditionDeclExpr(StartLoc,
1340 EqLoc,
1341 Var));
1342 }
Mike Stump11289f42009-09-09 15:08:12 +00001343
Douglas Gregora16548e2009-08-11 05:31:07 +00001344 /// \brief Build a new C++ "new" expression.
1345 ///
1346 /// By default, performs semantic analysis to build the new expression.
1347 /// Subclasses may override this routine to provide different behavior.
Mike Stump11289f42009-09-09 15:08:12 +00001348 OwningExprResult RebuildCXXNewExpr(SourceLocation StartLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001349 bool UseGlobal,
1350 SourceLocation PlacementLParen,
1351 MultiExprArg PlacementArgs,
1352 SourceLocation PlacementRParen,
Mike Stump11289f42009-09-09 15:08:12 +00001353 bool ParenTypeId,
Douglas Gregora16548e2009-08-11 05:31:07 +00001354 QualType AllocType,
1355 SourceLocation TypeLoc,
1356 SourceRange TypeRange,
1357 ExprArg ArraySize,
1358 SourceLocation ConstructorLParen,
1359 MultiExprArg ConstructorArgs,
1360 SourceLocation ConstructorRParen) {
Mike Stump11289f42009-09-09 15:08:12 +00001361 return getSema().BuildCXXNew(StartLoc, UseGlobal,
Douglas Gregora16548e2009-08-11 05:31:07 +00001362 PlacementLParen,
1363 move(PlacementArgs),
1364 PlacementRParen,
1365 ParenTypeId,
1366 AllocType,
1367 TypeLoc,
1368 TypeRange,
1369 move(ArraySize),
1370 ConstructorLParen,
1371 move(ConstructorArgs),
1372 ConstructorRParen);
1373 }
Mike Stump11289f42009-09-09 15:08:12 +00001374
Douglas Gregora16548e2009-08-11 05:31:07 +00001375 /// \brief Build a new C++ "delete" expression.
1376 ///
1377 /// By default, performs semantic analysis to build the new expression.
1378 /// Subclasses may override this routine to provide different behavior.
1379 OwningExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
1380 bool IsGlobalDelete,
1381 bool IsArrayForm,
1382 ExprArg Operand) {
1383 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
1384 move(Operand));
1385 }
Mike Stump11289f42009-09-09 15:08:12 +00001386
Douglas Gregora16548e2009-08-11 05:31:07 +00001387 /// \brief Build a new unary type trait expression.
1388 ///
1389 /// By default, performs semantic analysis to build the new expression.
1390 /// Subclasses may override this routine to provide different behavior.
1391 OwningExprResult RebuildUnaryTypeTrait(UnaryTypeTrait Trait,
1392 SourceLocation StartLoc,
1393 SourceLocation LParenLoc,
1394 QualType T,
1395 SourceLocation RParenLoc) {
Mike Stump11289f42009-09-09 15:08:12 +00001396 return getSema().ActOnUnaryTypeTrait(Trait, StartLoc, LParenLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001397 T.getAsOpaquePtr(), RParenLoc);
1398 }
1399
Mike Stump11289f42009-09-09 15:08:12 +00001400 /// \brief Build a new (previously unresolved) declaration reference
Douglas Gregora16548e2009-08-11 05:31:07 +00001401 /// expression.
1402 ///
1403 /// By default, performs semantic analysis to build the new expression.
1404 /// Subclasses may override this routine to provide different behavior.
1405 OwningExprResult RebuildUnresolvedDeclRefExpr(NestedNameSpecifier *NNS,
1406 SourceRange QualifierRange,
1407 DeclarationName Name,
1408 SourceLocation Location,
1409 bool IsAddressOfOperand) {
1410 CXXScopeSpec SS;
1411 SS.setRange(QualifierRange);
1412 SS.setScopeRep(NNS);
Mike Stump11289f42009-09-09 15:08:12 +00001413 return getSema().ActOnDeclarationNameExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001414 Location,
1415 Name,
1416 /*Trailing lparen=*/false,
1417 &SS,
1418 IsAddressOfOperand);
1419 }
1420
1421 /// \brief Build a new template-id expression.
1422 ///
1423 /// By default, performs semantic analysis to build the new expression.
1424 /// Subclasses may override this routine to provide different behavior.
Douglas Gregord019ff62009-10-22 17:20:55 +00001425 OwningExprResult RebuildTemplateIdExpr(NestedNameSpecifier *Qualifier,
1426 SourceRange QualifierRange,
1427 TemplateName Template,
Douglas Gregora16548e2009-08-11 05:31:07 +00001428 SourceLocation TemplateLoc,
1429 SourceLocation LAngleLoc,
1430 TemplateArgument *TemplateArgs,
1431 unsigned NumTemplateArgs,
1432 SourceLocation RAngleLoc) {
Douglas Gregord019ff62009-10-22 17:20:55 +00001433 return getSema().BuildTemplateIdExpr(Qualifier, QualifierRange,
1434 Template, TemplateLoc,
Douglas Gregora16548e2009-08-11 05:31:07 +00001435 LAngleLoc,
1436 TemplateArgs, NumTemplateArgs,
1437 RAngleLoc);
1438 }
1439
1440 /// \brief Build a new object-construction expression.
1441 ///
1442 /// By default, performs semantic analysis to build the new expression.
1443 /// Subclasses may override this routine to provide different behavior.
1444 OwningExprResult RebuildCXXConstructExpr(QualType T,
1445 CXXConstructorDecl *Constructor,
1446 bool IsElidable,
1447 MultiExprArg Args) {
Anders Carlsson1b4ebfa2009-09-05 07:40:38 +00001448 return getSema().BuildCXXConstructExpr(/*FIXME:ConstructLoc*/
1449 SourceLocation(),
1450 T, Constructor, IsElidable,
Anders Carlsson5995a3e2009-09-07 22:23:31 +00001451 move(Args));
Douglas Gregora16548e2009-08-11 05:31:07 +00001452 }
1453
1454 /// \brief Build a new object-construction expression.
1455 ///
1456 /// By default, performs semantic analysis to build the new expression.
1457 /// Subclasses may override this routine to provide different behavior.
1458 OwningExprResult RebuildCXXTemporaryObjectExpr(SourceLocation TypeBeginLoc,
1459 QualType T,
1460 SourceLocation LParenLoc,
1461 MultiExprArg Args,
1462 SourceLocation *Commas,
1463 SourceLocation RParenLoc) {
1464 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc),
1465 T.getAsOpaquePtr(),
1466 LParenLoc,
1467 move(Args),
1468 Commas,
1469 RParenLoc);
1470 }
1471
1472 /// \brief Build a new object-construction expression.
1473 ///
1474 /// By default, performs semantic analysis to build the new expression.
1475 /// Subclasses may override this routine to provide different behavior.
1476 OwningExprResult RebuildCXXUnresolvedConstructExpr(SourceLocation TypeBeginLoc,
1477 QualType T,
1478 SourceLocation LParenLoc,
1479 MultiExprArg Args,
1480 SourceLocation *Commas,
1481 SourceLocation RParenLoc) {
1482 return getSema().ActOnCXXTypeConstructExpr(SourceRange(TypeBeginLoc,
1483 /*FIXME*/LParenLoc),
1484 T.getAsOpaquePtr(),
1485 LParenLoc,
1486 move(Args),
1487 Commas,
1488 RParenLoc);
1489 }
Mike Stump11289f42009-09-09 15:08:12 +00001490
Douglas Gregora16548e2009-08-11 05:31:07 +00001491 /// \brief Build a new member reference expression.
1492 ///
1493 /// By default, performs semantic analysis to build the new expression.
1494 /// Subclasses may override this routine to provide different behavior.
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001495 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
Douglas Gregora16548e2009-08-11 05:31:07 +00001496 bool IsArrow,
1497 SourceLocation OperatorLoc,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001498 NestedNameSpecifier *Qualifier,
1499 SourceRange QualifierRange,
Douglas Gregora16548e2009-08-11 05:31:07 +00001500 DeclarationName Name,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001501 SourceLocation MemberLoc,
1502 NamedDecl *FirstQualifierInScope) {
Douglas Gregor2168a9f2009-08-11 15:56:57 +00001503 OwningExprResult Base = move(BaseE);
Douglas Gregora16548e2009-08-11 05:31:07 +00001504 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001505
Douglas Gregora16548e2009-08-11 05:31:07 +00001506 CXXScopeSpec SS;
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001507 SS.setRange(QualifierRange);
1508 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001509
Douglas Gregor308047d2009-09-09 00:23:06 +00001510 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0,
Douglas Gregora16548e2009-08-11 05:31:07 +00001511 move(Base), OperatorLoc, OpKind,
Douglas Gregorf14b46f2009-08-31 20:00:26 +00001512 MemberLoc,
1513 Name,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001514 /*FIXME?*/Sema::DeclPtrTy::make((Decl*)0),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001515 &SS,
1516 FirstQualifierInScope);
Douglas Gregora16548e2009-08-11 05:31:07 +00001517 }
1518
Douglas Gregor308047d2009-09-09 00:23:06 +00001519 /// \brief Build a new member reference expression with explicit template
1520 /// arguments.
1521 ///
1522 /// By default, performs semantic analysis to build the new expression.
1523 /// Subclasses may override this routine to provide different behavior.
1524 OwningExprResult RebuildCXXUnresolvedMemberExpr(ExprArg BaseE,
1525 bool IsArrow,
1526 SourceLocation OperatorLoc,
1527 NestedNameSpecifier *Qualifier,
1528 SourceRange QualifierRange,
1529 TemplateName Template,
1530 SourceLocation TemplateNameLoc,
1531 NamedDecl *FirstQualifierInScope,
1532 SourceLocation LAngleLoc,
1533 const TemplateArgument *TemplateArgs,
1534 unsigned NumTemplateArgs,
1535 SourceLocation RAngleLoc) {
1536 OwningExprResult Base = move(BaseE);
1537 tok::TokenKind OpKind = IsArrow? tok::arrow : tok::period;
Mike Stump11289f42009-09-09 15:08:12 +00001538
Douglas Gregor308047d2009-09-09 00:23:06 +00001539 CXXScopeSpec SS;
1540 SS.setRange(QualifierRange);
1541 SS.setScopeRep(Qualifier);
Mike Stump11289f42009-09-09 15:08:12 +00001542
Douglas Gregor308047d2009-09-09 00:23:06 +00001543 // FIXME: We're going to end up looking up the template based on its name,
1544 // twice! Also, duplicates part of Sema::ActOnMemberTemplateIdReferenceExpr.
1545 DeclarationName Name;
1546 if (TemplateDecl *ActualTemplate = Template.getAsTemplateDecl())
1547 Name = ActualTemplate->getDeclName();
Mike Stump11289f42009-09-09 15:08:12 +00001548 else if (OverloadedFunctionDecl *Ovl
Douglas Gregor308047d2009-09-09 00:23:06 +00001549 = Template.getAsOverloadedFunctionDecl())
1550 Name = Ovl->getDeclName();
1551 else
1552 Name = Template.getAsDependentTemplateName()->getName();
Mike Stump11289f42009-09-09 15:08:12 +00001553
1554 return SemaRef.BuildMemberReferenceExpr(/*Scope=*/0, move(Base),
Douglas Gregor308047d2009-09-09 00:23:06 +00001555 OperatorLoc, OpKind,
1556 TemplateNameLoc, Name, true,
1557 LAngleLoc, TemplateArgs,
1558 NumTemplateArgs, RAngleLoc,
1559 Sema::DeclPtrTy(), &SS);
1560 }
Mike Stump11289f42009-09-09 15:08:12 +00001561
Douglas Gregora16548e2009-08-11 05:31:07 +00001562 /// \brief Build a new Objective-C @encode expression.
1563 ///
1564 /// By default, performs semantic analysis to build the new expression.
1565 /// Subclasses may override this routine to provide different behavior.
1566 OwningExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
1567 QualType T,
1568 SourceLocation RParenLoc) {
1569 return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(AtLoc, T,
1570 RParenLoc));
Mike Stump11289f42009-09-09 15:08:12 +00001571 }
Douglas Gregora16548e2009-08-11 05:31:07 +00001572
1573 /// \brief Build a new Objective-C protocol expression.
1574 ///
1575 /// By default, performs semantic analysis to build the new expression.
1576 /// Subclasses may override this routine to provide different behavior.
1577 OwningExprResult RebuildObjCProtocolExpr(ObjCProtocolDecl *Protocol,
1578 SourceLocation AtLoc,
1579 SourceLocation ProtoLoc,
1580 SourceLocation LParenLoc,
1581 SourceLocation RParenLoc) {
1582 return SemaRef.Owned(SemaRef.ParseObjCProtocolExpression(
1583 Protocol->getIdentifier(),
1584 AtLoc,
1585 ProtoLoc,
1586 LParenLoc,
Mike Stump11289f42009-09-09 15:08:12 +00001587 RParenLoc));
Douglas Gregora16548e2009-08-11 05:31:07 +00001588 }
Mike Stump11289f42009-09-09 15:08:12 +00001589
Douglas Gregora16548e2009-08-11 05:31:07 +00001590 /// \brief Build a new shuffle vector expression.
1591 ///
1592 /// By default, performs semantic analysis to build the new expression.
1593 /// Subclasses may override this routine to provide different behavior.
1594 OwningExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
1595 MultiExprArg SubExprs,
1596 SourceLocation RParenLoc) {
1597 // Find the declaration for __builtin_shufflevector
Mike Stump11289f42009-09-09 15:08:12 +00001598 const IdentifierInfo &Name
Douglas Gregora16548e2009-08-11 05:31:07 +00001599 = SemaRef.Context.Idents.get("__builtin_shufflevector");
1600 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
1601 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
1602 assert(Lookup.first != Lookup.second && "No __builtin_shufflevector?");
Mike Stump11289f42009-09-09 15:08:12 +00001603
Douglas Gregora16548e2009-08-11 05:31:07 +00001604 // Build a reference to the __builtin_shufflevector builtin
1605 FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first);
Mike Stump11289f42009-09-09 15:08:12 +00001606 Expr *Callee
Douglas Gregora16548e2009-08-11 05:31:07 +00001607 = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(),
1608 BuiltinLoc, false, false);
1609 SemaRef.UsualUnaryConversions(Callee);
Mike Stump11289f42009-09-09 15:08:12 +00001610
1611 // Build the CallExpr
Douglas Gregora16548e2009-08-11 05:31:07 +00001612 unsigned NumSubExprs = SubExprs.size();
1613 Expr **Subs = (Expr **)SubExprs.release();
1614 CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee,
1615 Subs, NumSubExprs,
1616 Builtin->getResultType(),
1617 RParenLoc);
1618 OwningExprResult OwnedCall(SemaRef.Owned(TheCall));
Mike Stump11289f42009-09-09 15:08:12 +00001619
Douglas Gregora16548e2009-08-11 05:31:07 +00001620 // Type-check the __builtin_shufflevector expression.
1621 OwningExprResult Result = SemaRef.SemaBuiltinShuffleVector(TheCall);
1622 if (Result.isInvalid())
1623 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00001624
Douglas Gregora16548e2009-08-11 05:31:07 +00001625 OwnedCall.release();
Mike Stump11289f42009-09-09 15:08:12 +00001626 return move(Result);
Douglas Gregora16548e2009-08-11 05:31:07 +00001627 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00001628};
Douglas Gregora16548e2009-08-11 05:31:07 +00001629
Douglas Gregorebe10102009-08-20 07:17:43 +00001630template<typename Derived>
1631Sema::OwningStmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) {
1632 if (!S)
1633 return SemaRef.Owned(S);
Mike Stump11289f42009-09-09 15:08:12 +00001634
Douglas Gregorebe10102009-08-20 07:17:43 +00001635 switch (S->getStmtClass()) {
1636 case Stmt::NoStmtClass: break;
Mike Stump11289f42009-09-09 15:08:12 +00001637
Douglas Gregorebe10102009-08-20 07:17:43 +00001638 // Transform individual statement nodes
1639#define STMT(Node, Parent) \
1640 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
1641#define EXPR(Node, Parent)
1642#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001643
Douglas Gregorebe10102009-08-20 07:17:43 +00001644 // Transform expressions by calling TransformExpr.
1645#define STMT(Node, Parent)
1646#define EXPR(Node, Parent) case Stmt::Node##Class:
1647#include "clang/AST/StmtNodes.def"
1648 {
1649 Sema::OwningExprResult E = getDerived().TransformExpr(cast<Expr>(S));
1650 if (E.isInvalid())
1651 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00001652
Douglas Gregorebe10102009-08-20 07:17:43 +00001653 return getSema().Owned(E.takeAs<Stmt>());
1654 }
Mike Stump11289f42009-09-09 15:08:12 +00001655 }
1656
Douglas Gregorebe10102009-08-20 07:17:43 +00001657 return SemaRef.Owned(S->Retain());
1658}
Mike Stump11289f42009-09-09 15:08:12 +00001659
1660
Douglas Gregore922c772009-08-04 22:27:00 +00001661template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00001662Sema::OwningExprResult TreeTransform<Derived>::TransformExpr(Expr *E,
1663 bool isAddressOfOperand) {
1664 if (!E)
1665 return SemaRef.Owned(E);
1666
1667 switch (E->getStmtClass()) {
1668 case Stmt::NoStmtClass: break;
1669#define STMT(Node, Parent) case Stmt::Node##Class: break;
1670#define EXPR(Node, Parent) \
1671 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
1672#include "clang/AST/StmtNodes.def"
Mike Stump11289f42009-09-09 15:08:12 +00001673 }
1674
Douglas Gregora16548e2009-08-11 05:31:07 +00001675 return SemaRef.Owned(E->Retain());
Douglas Gregor766b0bb2009-08-06 22:17:10 +00001676}
1677
1678template<typename Derived>
Douglas Gregor1135c352009-08-06 05:28:30 +00001679NestedNameSpecifier *
1680TreeTransform<Derived>::TransformNestedNameSpecifier(NestedNameSpecifier *NNS,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001681 SourceRange Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001682 QualType ObjectType,
1683 NamedDecl *FirstQualifierInScope) {
Douglas Gregor96ee7892009-08-31 21:41:48 +00001684 if (!NNS)
1685 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001686
Douglas Gregorebe10102009-08-20 07:17:43 +00001687 // Transform the prefix of this nested name specifier.
Douglas Gregor1135c352009-08-06 05:28:30 +00001688 NestedNameSpecifier *Prefix = NNS->getPrefix();
1689 if (Prefix) {
Mike Stump11289f42009-09-09 15:08:12 +00001690 Prefix = getDerived().TransformNestedNameSpecifier(Prefix, Range,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001691 ObjectType,
1692 FirstQualifierInScope);
Douglas Gregor1135c352009-08-06 05:28:30 +00001693 if (!Prefix)
1694 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001695
1696 // Clear out the object type and the first qualifier in scope; they only
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001697 // apply to the first element in the nested-name-specifier.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001698 ObjectType = QualType();
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001699 FirstQualifierInScope = 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001700 }
Mike Stump11289f42009-09-09 15:08:12 +00001701
Douglas Gregor1135c352009-08-06 05:28:30 +00001702 switch (NNS->getKind()) {
1703 case NestedNameSpecifier::Identifier:
Mike Stump11289f42009-09-09 15:08:12 +00001704 assert((Prefix || !ObjectType.isNull()) &&
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001705 "Identifier nested-name-specifier with no prefix or object type");
1706 if (!getDerived().AlwaysRebuild() && Prefix == NNS->getPrefix() &&
1707 ObjectType.isNull())
Douglas Gregor1135c352009-08-06 05:28:30 +00001708 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001709
1710 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00001711 *NNS->getAsIdentifier(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00001712 ObjectType,
1713 FirstQualifierInScope);
Mike Stump11289f42009-09-09 15:08:12 +00001714
Douglas Gregor1135c352009-08-06 05:28:30 +00001715 case NestedNameSpecifier::Namespace: {
Mike Stump11289f42009-09-09 15:08:12 +00001716 NamespaceDecl *NS
Douglas Gregor1135c352009-08-06 05:28:30 +00001717 = cast_or_null<NamespaceDecl>(
1718 getDerived().TransformDecl(NNS->getAsNamespace()));
Mike Stump11289f42009-09-09 15:08:12 +00001719 if (!getDerived().AlwaysRebuild() &&
Douglas Gregor1135c352009-08-06 05:28:30 +00001720 Prefix == NNS->getPrefix() &&
1721 NS == NNS->getAsNamespace())
1722 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001723
Douglas Gregor1135c352009-08-06 05:28:30 +00001724 return getDerived().RebuildNestedNameSpecifier(Prefix, Range, NS);
1725 }
Mike Stump11289f42009-09-09 15:08:12 +00001726
Douglas Gregor1135c352009-08-06 05:28:30 +00001727 case NestedNameSpecifier::Global:
1728 // There is no meaningful transformation that one could perform on the
1729 // global scope.
1730 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001731
Douglas Gregor1135c352009-08-06 05:28:30 +00001732 case NestedNameSpecifier::TypeSpecWithTemplate:
1733 case NestedNameSpecifier::TypeSpec: {
1734 QualType T = getDerived().TransformType(QualType(NNS->getAsType(), 0));
Douglas Gregor71dc5092009-08-06 06:41:21 +00001735 if (T.isNull())
1736 return 0;
Mike Stump11289f42009-09-09 15:08:12 +00001737
Douglas Gregor1135c352009-08-06 05:28:30 +00001738 if (!getDerived().AlwaysRebuild() &&
1739 Prefix == NNS->getPrefix() &&
1740 T == QualType(NNS->getAsType(), 0))
1741 return NNS;
Mike Stump11289f42009-09-09 15:08:12 +00001742
1743 return getDerived().RebuildNestedNameSpecifier(Prefix, Range,
1744 NNS->getKind() == NestedNameSpecifier::TypeSpecWithTemplate,
Douglas Gregor1135c352009-08-06 05:28:30 +00001745 T);
1746 }
1747 }
Mike Stump11289f42009-09-09 15:08:12 +00001748
Douglas Gregor1135c352009-08-06 05:28:30 +00001749 // Required to silence a GCC warning
Mike Stump11289f42009-09-09 15:08:12 +00001750 return 0;
Douglas Gregor1135c352009-08-06 05:28:30 +00001751}
1752
1753template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001754DeclarationName
Douglas Gregorf816bd72009-09-03 22:13:48 +00001755TreeTransform<Derived>::TransformDeclarationName(DeclarationName Name,
Douglas Gregorc59e5612009-10-19 22:04:39 +00001756 SourceLocation Loc,
1757 QualType ObjectType) {
Douglas Gregorf816bd72009-09-03 22:13:48 +00001758 if (!Name)
1759 return Name;
1760
1761 switch (Name.getNameKind()) {
1762 case DeclarationName::Identifier:
1763 case DeclarationName::ObjCZeroArgSelector:
1764 case DeclarationName::ObjCOneArgSelector:
1765 case DeclarationName::ObjCMultiArgSelector:
1766 case DeclarationName::CXXOperatorName:
1767 case DeclarationName::CXXUsingDirective:
1768 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001769
Douglas Gregorf816bd72009-09-03 22:13:48 +00001770 case DeclarationName::CXXConstructorName:
1771 case DeclarationName::CXXDestructorName:
1772 case DeclarationName::CXXConversionFunctionName: {
1773 TemporaryBase Rebase(*this, Loc, Name);
Douglas Gregorc59e5612009-10-19 22:04:39 +00001774 QualType T;
1775 if (!ObjectType.isNull() &&
1776 isa<TemplateSpecializationType>(Name.getCXXNameType())) {
1777 TemplateSpecializationType *SpecType
1778 = cast<TemplateSpecializationType>(Name.getCXXNameType());
1779 T = TransformTemplateSpecializationType(SpecType, ObjectType);
1780 } else
1781 T = getDerived().TransformType(Name.getCXXNameType());
Douglas Gregorf816bd72009-09-03 22:13:48 +00001782 if (T.isNull())
1783 return DeclarationName();
Mike Stump11289f42009-09-09 15:08:12 +00001784
Douglas Gregorf816bd72009-09-03 22:13:48 +00001785 return SemaRef.Context.DeclarationNames.getCXXSpecialName(
Mike Stump11289f42009-09-09 15:08:12 +00001786 Name.getNameKind(),
Douglas Gregorf816bd72009-09-03 22:13:48 +00001787 SemaRef.Context.getCanonicalType(T));
Douglas Gregorf816bd72009-09-03 22:13:48 +00001788 }
Mike Stump11289f42009-09-09 15:08:12 +00001789 }
1790
Douglas Gregorf816bd72009-09-03 22:13:48 +00001791 return DeclarationName();
1792}
1793
1794template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001795TemplateName
Douglas Gregor308047d2009-09-09 00:23:06 +00001796TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
1797 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00001798 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001799 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001800 = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
1801 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
1802 if (!NNS)
1803 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001804
Douglas Gregor71dc5092009-08-06 06:41:21 +00001805 if (TemplateDecl *Template = QTN->getTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001806 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001807 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1808 if (!TransTemplate)
1809 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001810
Douglas Gregor71dc5092009-08-06 06:41:21 +00001811 if (!getDerived().AlwaysRebuild() &&
1812 NNS == QTN->getQualifier() &&
1813 TransTemplate == Template)
1814 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001815
Douglas Gregor71dc5092009-08-06 06:41:21 +00001816 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1817 TransTemplate);
1818 }
Mike Stump11289f42009-09-09 15:08:12 +00001819
Douglas Gregor71dc5092009-08-06 06:41:21 +00001820 OverloadedFunctionDecl *Ovl = QTN->getOverloadedFunctionDecl();
1821 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001822 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001823 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1824 if (!TransOvl)
1825 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001826
Douglas Gregor71dc5092009-08-06 06:41:21 +00001827 if (!getDerived().AlwaysRebuild() &&
1828 NNS == QTN->getQualifier() &&
1829 TransOvl == Ovl)
1830 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001831
Douglas Gregor71dc5092009-08-06 06:41:21 +00001832 return getDerived().RebuildTemplateName(NNS, QTN->hasTemplateKeyword(),
1833 TransOvl);
1834 }
Mike Stump11289f42009-09-09 15:08:12 +00001835
Douglas Gregor71dc5092009-08-06 06:41:21 +00001836 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
Mike Stump11289f42009-09-09 15:08:12 +00001837 NestedNameSpecifier *NNS
Douglas Gregor71dc5092009-08-06 06:41:21 +00001838 = getDerived().TransformNestedNameSpecifier(DTN->getQualifier(),
1839 /*FIXME:*/SourceRange(getDerived().getBaseLocation()));
Douglas Gregor308047d2009-09-09 00:23:06 +00001840 if (!NNS && DTN->getQualifier())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001841 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001842
Douglas Gregor71dc5092009-08-06 06:41:21 +00001843 if (!getDerived().AlwaysRebuild() &&
Douglas Gregorc59e5612009-10-19 22:04:39 +00001844 NNS == DTN->getQualifier() &&
1845 ObjectType.isNull())
Douglas Gregor71dc5092009-08-06 06:41:21 +00001846 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001847
Douglas Gregor308047d2009-09-09 00:23:06 +00001848 return getDerived().RebuildTemplateName(NNS, *DTN->getName(), ObjectType);
Douglas Gregor71dc5092009-08-06 06:41:21 +00001849 }
Mike Stump11289f42009-09-09 15:08:12 +00001850
Douglas Gregor71dc5092009-08-06 06:41:21 +00001851 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
Mike Stump11289f42009-09-09 15:08:12 +00001852 TemplateDecl *TransTemplate
Douglas Gregor71dc5092009-08-06 06:41:21 +00001853 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
1854 if (!TransTemplate)
1855 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001856
Douglas Gregor71dc5092009-08-06 06:41:21 +00001857 if (!getDerived().AlwaysRebuild() &&
1858 TransTemplate == Template)
1859 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001860
Douglas Gregor71dc5092009-08-06 06:41:21 +00001861 return TemplateName(TransTemplate);
1862 }
Mike Stump11289f42009-09-09 15:08:12 +00001863
Douglas Gregor71dc5092009-08-06 06:41:21 +00001864 OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl();
1865 assert(Ovl && "Not a template name or an overload set?");
Mike Stump11289f42009-09-09 15:08:12 +00001866 OverloadedFunctionDecl *TransOvl
Douglas Gregor71dc5092009-08-06 06:41:21 +00001867 = cast_or_null<OverloadedFunctionDecl>(getDerived().TransformDecl(Ovl));
1868 if (!TransOvl)
1869 return TemplateName();
Mike Stump11289f42009-09-09 15:08:12 +00001870
Douglas Gregor71dc5092009-08-06 06:41:21 +00001871 if (!getDerived().AlwaysRebuild() &&
1872 TransOvl == Ovl)
1873 return Name;
Mike Stump11289f42009-09-09 15:08:12 +00001874
Douglas Gregor71dc5092009-08-06 06:41:21 +00001875 return TemplateName(TransOvl);
1876}
1877
1878template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00001879TemplateArgument
Douglas Gregore922c772009-08-04 22:27:00 +00001880TreeTransform<Derived>::TransformTemplateArgument(const TemplateArgument &Arg) {
1881 switch (Arg.getKind()) {
1882 case TemplateArgument::Null:
1883 case TemplateArgument::Integral:
1884 return Arg;
Mike Stump11289f42009-09-09 15:08:12 +00001885
Douglas Gregore922c772009-08-04 22:27:00 +00001886 case TemplateArgument::Type: {
Douglas Gregoref6ab412009-10-27 06:26:26 +00001887 TemporaryBase Rebase(*this, Arg.getLocation(), DeclarationName());
Douglas Gregore922c772009-08-04 22:27:00 +00001888 QualType T = getDerived().TransformType(Arg.getAsType());
1889 if (T.isNull())
1890 return TemplateArgument();
1891 return TemplateArgument(Arg.getLocation(), T);
1892 }
Mike Stump11289f42009-09-09 15:08:12 +00001893
Douglas Gregore922c772009-08-04 22:27:00 +00001894 case TemplateArgument::Declaration: {
Douglas Gregoref6ab412009-10-27 06:26:26 +00001895 DeclarationName Name;
1896 if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
1897 Name = ND->getDeclName();
1898 TemporaryBase Rebase(*this, Arg.getLocation(), Name);
Douglas Gregore922c772009-08-04 22:27:00 +00001899 Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
1900 if (!D)
1901 return TemplateArgument();
1902 return TemplateArgument(Arg.getLocation(), D);
1903 }
Mike Stump11289f42009-09-09 15:08:12 +00001904
Douglas Gregore922c772009-08-04 22:27:00 +00001905 case TemplateArgument::Expression: {
1906 // Template argument expressions are not potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00001907 EnterExpressionEvaluationContext Unevaluated(getSema(),
Douglas Gregore922c772009-08-04 22:27:00 +00001908 Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00001909
Douglas Gregore922c772009-08-04 22:27:00 +00001910 Sema::OwningExprResult E = getDerived().TransformExpr(Arg.getAsExpr());
1911 if (E.isInvalid())
1912 return TemplateArgument();
1913 return TemplateArgument(E.takeAs<Expr>());
1914 }
Mike Stump11289f42009-09-09 15:08:12 +00001915
Douglas Gregore922c772009-08-04 22:27:00 +00001916 case TemplateArgument::Pack: {
1917 llvm::SmallVector<TemplateArgument, 4> TransformedArgs;
1918 TransformedArgs.reserve(Arg.pack_size());
Mike Stump11289f42009-09-09 15:08:12 +00001919 for (TemplateArgument::pack_iterator A = Arg.pack_begin(),
Douglas Gregore922c772009-08-04 22:27:00 +00001920 AEnd = Arg.pack_end();
1921 A != AEnd; ++A) {
1922 TemplateArgument TA = getDerived().TransformTemplateArgument(*A);
1923 if (TA.isNull())
1924 return TA;
Mike Stump11289f42009-09-09 15:08:12 +00001925
Douglas Gregore922c772009-08-04 22:27:00 +00001926 TransformedArgs.push_back(TA);
1927 }
1928 TemplateArgument Result;
Mike Stump11289f42009-09-09 15:08:12 +00001929 Result.setArgumentPack(TransformedArgs.data(), TransformedArgs.size(),
Douglas Gregore922c772009-08-04 22:27:00 +00001930 true);
1931 return Result;
1932 }
1933 }
Mike Stump11289f42009-09-09 15:08:12 +00001934
Douglas Gregore922c772009-08-04 22:27:00 +00001935 // Work around bogus GCC warning
1936 return TemplateArgument();
1937}
1938
Douglas Gregord6ff3322009-08-04 16:50:30 +00001939//===----------------------------------------------------------------------===//
1940// Type transformation
1941//===----------------------------------------------------------------------===//
1942
1943template<typename Derived>
1944QualType TreeTransform<Derived>::TransformType(QualType T) {
1945 if (getDerived().AlreadyTransformed(T))
1946 return T;
Mike Stump11289f42009-09-09 15:08:12 +00001947
John McCall550e0c22009-10-21 00:40:46 +00001948 // Temporary workaround. All of these transformations should
1949 // eventually turn into transformations on TypeLocs.
1950 DeclaratorInfo *DI = getSema().Context.CreateDeclaratorInfo(T);
John McCallde889892009-10-21 00:44:26 +00001951 DI->getTypeLoc().initialize(getDerived().getBaseLocation());
John McCall550e0c22009-10-21 00:40:46 +00001952
1953 DeclaratorInfo *NewDI = getDerived().TransformType(DI);
John McCall8ccfcb52009-09-24 19:53:00 +00001954
John McCall550e0c22009-10-21 00:40:46 +00001955 if (!NewDI)
1956 return QualType();
1957
1958 return NewDI->getType();
1959}
1960
1961template<typename Derived>
1962DeclaratorInfo *TreeTransform<Derived>::TransformType(DeclaratorInfo *DI) {
1963 if (getDerived().AlreadyTransformed(DI->getType()))
1964 return DI;
1965
1966 TypeLocBuilder TLB;
1967
1968 TypeLoc TL = DI->getTypeLoc();
1969 TLB.reserve(TL.getFullDataSize());
1970
1971 QualType Result = getDerived().TransformType(TLB, TL);
1972 if (Result.isNull())
1973 return 0;
1974
1975 return TLB.getDeclaratorInfo(SemaRef.Context, Result);
1976}
1977
1978template<typename Derived>
1979QualType
1980TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
1981 switch (T.getTypeLocClass()) {
1982#define ABSTRACT_TYPELOC(CLASS, PARENT)
1983#define TYPELOC(CLASS, PARENT) \
1984 case TypeLoc::CLASS: \
1985 return getDerived().Transform##CLASS##Type(TLB, cast<CLASS##TypeLoc>(T));
1986#include "clang/AST/TypeLocNodes.def"
Douglas Gregord6ff3322009-08-04 16:50:30 +00001987 }
Mike Stump11289f42009-09-09 15:08:12 +00001988
John McCall550e0c22009-10-21 00:40:46 +00001989 llvm::llvm_unreachable("unhandled type loc!");
1990 return QualType();
1991}
1992
1993/// FIXME: By default, this routine adds type qualifiers only to types
1994/// that can have qualifiers, and silently suppresses those qualifiers
1995/// that are not permitted (e.g., qualifiers on reference or function
1996/// types). This is the right thing for template instantiation, but
1997/// probably not for other clients.
1998template<typename Derived>
1999QualType
2000TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
2001 QualifiedTypeLoc T) {
2002 Qualifiers Quals = T.getType().getQualifiers();
2003
2004 QualType Result = getDerived().TransformType(TLB, T.getUnqualifiedLoc());
2005 if (Result.isNull())
2006 return QualType();
2007
2008 // Silently suppress qualifiers if the result type can't be qualified.
2009 // FIXME: this is the right thing for template instantiation, but
2010 // probably not for other clients.
2011 if (Result->isFunctionType() || Result->isReferenceType())
Douglas Gregord6ff3322009-08-04 16:50:30 +00002012 return Result;
Mike Stump11289f42009-09-09 15:08:12 +00002013
John McCall550e0c22009-10-21 00:40:46 +00002014 Result = SemaRef.Context.getQualifiedType(Result, Quals);
2015
2016 TLB.push<QualifiedTypeLoc>(Result);
2017
2018 // No location information to preserve.
2019
2020 return Result;
2021}
2022
2023template <class TyLoc> static inline
2024QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
2025 TyLoc NewT = TLB.push<TyLoc>(T.getType());
2026 NewT.setNameLoc(T.getNameLoc());
2027 return T.getType();
2028}
2029
2030// Ugly metaprogramming macros because I couldn't be bothered to make
2031// the equivalent template version work.
2032#define TransformPointerLikeType(TypeClass) do { \
2033 QualType PointeeType \
2034 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2035 if (PointeeType.isNull()) \
2036 return QualType(); \
2037 \
2038 QualType Result = TL.getType(); \
2039 if (getDerived().AlwaysRebuild() || \
2040 PointeeType != TL.getPointeeLoc().getType()) { \
2041 Result = getDerived().Rebuild##TypeClass(PointeeType); \
2042 if (Result.isNull()) \
2043 return QualType(); \
2044 } \
2045 \
2046 TypeClass##Loc NewT = TLB.push<TypeClass##Loc>(Result); \
2047 NewT.setSigilLoc(TL.getSigilLoc()); \
2048 \
2049 return Result; \
2050} while(0)
2051
2052// Reference collapsing forces us to transform reference types
2053// differently from the other pointer-like types.
2054#define TransformReferenceType(TypeClass) do { \
2055 QualType PointeeType \
2056 = getDerived().TransformType(TLB, TL.getPointeeLoc()); \
2057 if (PointeeType.isNull()) \
2058 return QualType(); \
2059 \
2060 QualType Result = TL.getType(); \
2061 if (getDerived().AlwaysRebuild() || \
2062 PointeeType != TL.getPointeeLoc().getType()) { \
2063 Result = getDerived().Rebuild##TypeClass(PointeeType); \
2064 if (Result.isNull()) \
2065 return QualType(); \
2066 } \
2067 \
2068 /* Workaround: rebuild doesn't always change the type */ \
2069 /* FIXME: avoid losing this location information. */ \
2070 if (Result == PointeeType) \
2071 return Result; \
2072 ReferenceTypeLoc NewTL; \
2073 if (isa<LValueReferenceType>(Result)) \
2074 NewTL = TLB.push<LValueReferenceTypeLoc>(Result); \
2075 else \
2076 NewTL = TLB.push<RValueReferenceTypeLoc>(Result); \
2077 NewTL.setSigilLoc(TL.getSigilLoc()); \
2078 return Result; \
2079} while (0)
2080
2081template<typename Derived>
2082QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
2083 BuiltinTypeLoc T) {
2084 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002085}
Mike Stump11289f42009-09-09 15:08:12 +00002086
Douglas Gregord6ff3322009-08-04 16:50:30 +00002087template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002088QualType
John McCall550e0c22009-10-21 00:40:46 +00002089TreeTransform<Derived>::TransformFixedWidthIntType(TypeLocBuilder &TLB,
2090 FixedWidthIntTypeLoc T) {
2091 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002092}
Argyrios Kyrtzidise9189262009-08-19 01:28:17 +00002093
Douglas Gregord6ff3322009-08-04 16:50:30 +00002094template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002095QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
2096 ComplexTypeLoc T) {
2097 // FIXME: recurse?
2098 return TransformTypeSpecType(TLB, T);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002099}
Mike Stump11289f42009-09-09 15:08:12 +00002100
Douglas Gregord6ff3322009-08-04 16:50:30 +00002101template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002102QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
2103 PointerTypeLoc TL) {
2104 TransformPointerLikeType(PointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002105}
Mike Stump11289f42009-09-09 15:08:12 +00002106
2107template<typename Derived>
2108QualType
John McCall550e0c22009-10-21 00:40:46 +00002109TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
2110 BlockPointerTypeLoc TL) {
2111 TransformPointerLikeType(BlockPointerType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002112}
2113
Mike Stump11289f42009-09-09 15:08:12 +00002114template<typename Derived>
2115QualType
John McCall550e0c22009-10-21 00:40:46 +00002116TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
2117 LValueReferenceTypeLoc TL) {
2118 TransformReferenceType(LValueReferenceType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002119}
2120
Mike Stump11289f42009-09-09 15:08:12 +00002121template<typename Derived>
2122QualType
John McCall550e0c22009-10-21 00:40:46 +00002123TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
2124 RValueReferenceTypeLoc TL) {
2125 TransformReferenceType(RValueReferenceType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002126}
Mike Stump11289f42009-09-09 15:08:12 +00002127
Douglas Gregord6ff3322009-08-04 16:50:30 +00002128template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002129QualType
John McCall550e0c22009-10-21 00:40:46 +00002130TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
2131 MemberPointerTypeLoc TL) {
2132 MemberPointerType *T = TL.getTypePtr();
2133
2134 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002135 if (PointeeType.isNull())
2136 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002137
John McCall550e0c22009-10-21 00:40:46 +00002138 // TODO: preserve source information for this.
2139 QualType ClassType
2140 = getDerived().TransformType(QualType(T->getClass(), 0));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002141 if (ClassType.isNull())
2142 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002143
John McCall550e0c22009-10-21 00:40:46 +00002144 QualType Result = TL.getType();
2145 if (getDerived().AlwaysRebuild() ||
2146 PointeeType != T->getPointeeType() ||
2147 ClassType != QualType(T->getClass(), 0)) {
2148 Result = getDerived().RebuildMemberPointerType(PointeeType, ClassType);
2149 if (Result.isNull())
2150 return QualType();
2151 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002152
John McCall550e0c22009-10-21 00:40:46 +00002153 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
2154 NewTL.setSigilLoc(TL.getSigilLoc());
2155
2156 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002157}
2158
Mike Stump11289f42009-09-09 15:08:12 +00002159template<typename Derived>
2160QualType
John McCall550e0c22009-10-21 00:40:46 +00002161TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
2162 ConstantArrayTypeLoc TL) {
2163 ConstantArrayType *T = TL.getTypePtr();
2164 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002165 if (ElementType.isNull())
2166 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002167
John McCall550e0c22009-10-21 00:40:46 +00002168 QualType Result = TL.getType();
2169 if (getDerived().AlwaysRebuild() ||
2170 ElementType != T->getElementType()) {
2171 Result = getDerived().RebuildConstantArrayType(ElementType,
2172 T->getSizeModifier(),
2173 T->getSize(),
2174 T->getIndexTypeCVRQualifiers());
2175 if (Result.isNull())
2176 return QualType();
2177 }
2178
2179 ConstantArrayTypeLoc NewTL = TLB.push<ConstantArrayTypeLoc>(Result);
2180 NewTL.setLBracketLoc(TL.getLBracketLoc());
2181 NewTL.setRBracketLoc(TL.getRBracketLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002182
John McCall550e0c22009-10-21 00:40:46 +00002183 Expr *Size = TL.getSizeExpr();
2184 if (Size) {
2185 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2186 Size = getDerived().TransformExpr(Size).template takeAs<Expr>();
2187 }
2188 NewTL.setSizeExpr(Size);
2189
2190 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002191}
Mike Stump11289f42009-09-09 15:08:12 +00002192
Douglas Gregord6ff3322009-08-04 16:50:30 +00002193template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002194QualType TreeTransform<Derived>::TransformIncompleteArrayType(
John McCall550e0c22009-10-21 00:40:46 +00002195 TypeLocBuilder &TLB,
2196 IncompleteArrayTypeLoc TL) {
2197 IncompleteArrayType *T = TL.getTypePtr();
2198 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002199 if (ElementType.isNull())
2200 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002201
John McCall550e0c22009-10-21 00:40:46 +00002202 QualType Result = TL.getType();
2203 if (getDerived().AlwaysRebuild() ||
2204 ElementType != T->getElementType()) {
2205 Result = getDerived().RebuildIncompleteArrayType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002206 T->getSizeModifier(),
John McCall550e0c22009-10-21 00:40:46 +00002207 T->getIndexTypeCVRQualifiers());
2208 if (Result.isNull())
2209 return QualType();
2210 }
2211
2212 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
2213 NewTL.setLBracketLoc(TL.getLBracketLoc());
2214 NewTL.setRBracketLoc(TL.getRBracketLoc());
2215 NewTL.setSizeExpr(0);
2216
2217 return Result;
2218}
2219
2220template<typename Derived>
2221QualType
2222TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
2223 VariableArrayTypeLoc TL) {
2224 VariableArrayType *T = TL.getTypePtr();
2225 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2226 if (ElementType.isNull())
2227 return QualType();
2228
2229 // Array bounds are not potentially evaluated contexts
2230 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2231
2232 Sema::OwningExprResult SizeResult
2233 = getDerived().TransformExpr(T->getSizeExpr());
2234 if (SizeResult.isInvalid())
2235 return QualType();
2236
2237 Expr *Size = static_cast<Expr*>(SizeResult.get());
2238
2239 QualType Result = TL.getType();
2240 if (getDerived().AlwaysRebuild() ||
2241 ElementType != T->getElementType() ||
2242 Size != T->getSizeExpr()) {
2243 Result = getDerived().RebuildVariableArrayType(ElementType,
2244 T->getSizeModifier(),
2245 move(SizeResult),
2246 T->getIndexTypeCVRQualifiers(),
2247 T->getBracketsRange());
2248 if (Result.isNull())
2249 return QualType();
2250 }
2251 else SizeResult.take();
2252
2253 VariableArrayTypeLoc NewTL = TLB.push<VariableArrayTypeLoc>(Result);
2254 NewTL.setLBracketLoc(TL.getLBracketLoc());
2255 NewTL.setRBracketLoc(TL.getRBracketLoc());
2256 NewTL.setSizeExpr(Size);
2257
2258 return Result;
2259}
2260
2261template<typename Derived>
2262QualType
2263TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
2264 DependentSizedArrayTypeLoc TL) {
2265 DependentSizedArrayType *T = TL.getTypePtr();
2266 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
2267 if (ElementType.isNull())
2268 return QualType();
2269
2270 // Array bounds are not potentially evaluated contexts
2271 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2272
2273 Sema::OwningExprResult SizeResult
2274 = getDerived().TransformExpr(T->getSizeExpr());
2275 if (SizeResult.isInvalid())
2276 return QualType();
2277
2278 Expr *Size = static_cast<Expr*>(SizeResult.get());
2279
2280 QualType Result = TL.getType();
2281 if (getDerived().AlwaysRebuild() ||
2282 ElementType != T->getElementType() ||
2283 Size != T->getSizeExpr()) {
2284 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
2285 T->getSizeModifier(),
2286 move(SizeResult),
2287 T->getIndexTypeCVRQualifiers(),
2288 T->getBracketsRange());
2289 if (Result.isNull())
2290 return QualType();
2291 }
2292 else SizeResult.take();
2293
2294 // We might have any sort of array type now, but fortunately they
2295 // all have the same location layout.
2296 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
2297 NewTL.setLBracketLoc(TL.getLBracketLoc());
2298 NewTL.setRBracketLoc(TL.getRBracketLoc());
2299 NewTL.setSizeExpr(Size);
2300
2301 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002302}
Mike Stump11289f42009-09-09 15:08:12 +00002303
2304template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002305QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
John McCall550e0c22009-10-21 00:40:46 +00002306 TypeLocBuilder &TLB,
2307 DependentSizedExtVectorTypeLoc TL) {
2308 DependentSizedExtVectorType *T = TL.getTypePtr();
2309
2310 // FIXME: ext vector locs should be nested
Douglas Gregord6ff3322009-08-04 16:50:30 +00002311 QualType ElementType = getDerived().TransformType(T->getElementType());
2312 if (ElementType.isNull())
2313 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002314
Douglas Gregore922c772009-08-04 22:27:00 +00002315 // Vector sizes are not potentially evaluated contexts
2316 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
2317
Douglas Gregord6ff3322009-08-04 16:50:30 +00002318 Sema::OwningExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
2319 if (Size.isInvalid())
2320 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002321
John McCall550e0c22009-10-21 00:40:46 +00002322 QualType Result = TL.getType();
2323 if (getDerived().AlwaysRebuild() ||
John McCall24e7cb62009-10-23 17:55:45 +00002324 ElementType != T->getElementType() ||
2325 Size.get() != T->getSizeExpr()) {
John McCall550e0c22009-10-21 00:40:46 +00002326 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00002327 move(Size),
2328 T->getAttributeLoc());
John McCall550e0c22009-10-21 00:40:46 +00002329 if (Result.isNull())
2330 return QualType();
2331 }
2332 else Size.take();
2333
2334 // Result might be dependent or not.
2335 if (isa<DependentSizedExtVectorType>(Result)) {
2336 DependentSizedExtVectorTypeLoc NewTL
2337 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
2338 NewTL.setNameLoc(TL.getNameLoc());
2339 } else {
2340 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2341 NewTL.setNameLoc(TL.getNameLoc());
2342 }
2343
2344 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002345}
Mike Stump11289f42009-09-09 15:08:12 +00002346
2347template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002348QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
2349 VectorTypeLoc TL) {
2350 VectorType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002351 QualType ElementType = getDerived().TransformType(T->getElementType());
2352 if (ElementType.isNull())
2353 return QualType();
2354
John McCall550e0c22009-10-21 00:40:46 +00002355 QualType Result = TL.getType();
2356 if (getDerived().AlwaysRebuild() ||
2357 ElementType != T->getElementType()) {
2358 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements());
2359 if (Result.isNull())
2360 return QualType();
2361 }
2362
2363 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
2364 NewTL.setNameLoc(TL.getNameLoc());
Mike Stump11289f42009-09-09 15:08:12 +00002365
John McCall550e0c22009-10-21 00:40:46 +00002366 return Result;
2367}
2368
2369template<typename Derived>
2370QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
2371 ExtVectorTypeLoc TL) {
2372 VectorType *T = TL.getTypePtr();
2373 QualType ElementType = getDerived().TransformType(T->getElementType());
2374 if (ElementType.isNull())
2375 return QualType();
2376
2377 QualType Result = TL.getType();
2378 if (getDerived().AlwaysRebuild() ||
2379 ElementType != T->getElementType()) {
2380 Result = getDerived().RebuildExtVectorType(ElementType,
2381 T->getNumElements(),
2382 /*FIXME*/ SourceLocation());
2383 if (Result.isNull())
2384 return QualType();
2385 }
2386
2387 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
2388 NewTL.setNameLoc(TL.getNameLoc());
2389
2390 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002391}
Mike Stump11289f42009-09-09 15:08:12 +00002392
2393template<typename Derived>
2394QualType
John McCall550e0c22009-10-21 00:40:46 +00002395TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
2396 FunctionProtoTypeLoc TL) {
2397 FunctionProtoType *T = TL.getTypePtr();
2398 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002399 if (ResultType.isNull())
2400 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002401
John McCall550e0c22009-10-21 00:40:46 +00002402 // Transform the parameters.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002403 llvm::SmallVector<QualType, 4> ParamTypes;
John McCall550e0c22009-10-21 00:40:46 +00002404 llvm::SmallVector<ParmVarDecl*, 4> ParamDecls;
2405 for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) {
2406 ParmVarDecl *OldParm = TL.getArg(i);
Mike Stump11289f42009-09-09 15:08:12 +00002407
John McCall550e0c22009-10-21 00:40:46 +00002408 QualType NewType;
2409 ParmVarDecl *NewParm;
2410
2411 if (OldParm) {
2412 DeclaratorInfo *OldDI = OldParm->getDeclaratorInfo();
2413 assert(OldDI->getType() == T->getArgType(i));
2414
2415 DeclaratorInfo *NewDI = getDerived().TransformType(OldDI);
2416 if (!NewDI)
2417 return QualType();
2418
2419 if (NewDI == OldDI)
2420 NewParm = OldParm;
2421 else
2422 NewParm = ParmVarDecl::Create(SemaRef.Context,
2423 OldParm->getDeclContext(),
2424 OldParm->getLocation(),
2425 OldParm->getIdentifier(),
2426 NewDI->getType(),
2427 NewDI,
2428 OldParm->getStorageClass(),
2429 /* DefArg */ NULL);
2430 NewType = NewParm->getType();
2431
2432 // Deal with the possibility that we don't have a parameter
2433 // declaration for this parameter.
2434 } else {
2435 NewParm = 0;
2436
2437 QualType OldType = T->getArgType(i);
2438 NewType = getDerived().TransformType(OldType);
2439 if (NewType.isNull())
2440 return QualType();
2441 }
2442
2443 ParamTypes.push_back(NewType);
2444 ParamDecls.push_back(NewParm);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002445 }
Mike Stump11289f42009-09-09 15:08:12 +00002446
John McCall550e0c22009-10-21 00:40:46 +00002447 QualType Result = TL.getType();
2448 if (getDerived().AlwaysRebuild() ||
2449 ResultType != T->getResultType() ||
2450 !std::equal(T->arg_type_begin(), T->arg_type_end(), ParamTypes.begin())) {
2451 Result = getDerived().RebuildFunctionProtoType(ResultType,
2452 ParamTypes.data(),
2453 ParamTypes.size(),
2454 T->isVariadic(),
2455 T->getTypeQuals());
2456 if (Result.isNull())
2457 return QualType();
2458 }
Mike Stump11289f42009-09-09 15:08:12 +00002459
John McCall550e0c22009-10-21 00:40:46 +00002460 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
2461 NewTL.setLParenLoc(TL.getLParenLoc());
2462 NewTL.setRParenLoc(TL.getRParenLoc());
2463 for (unsigned i = 0, e = NewTL.getNumArgs(); i != e; ++i)
2464 NewTL.setArg(i, ParamDecls[i]);
2465
2466 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002467}
Mike Stump11289f42009-09-09 15:08:12 +00002468
Douglas Gregord6ff3322009-08-04 16:50:30 +00002469template<typename Derived>
2470QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
John McCall550e0c22009-10-21 00:40:46 +00002471 TypeLocBuilder &TLB,
2472 FunctionNoProtoTypeLoc TL) {
2473 FunctionNoProtoType *T = TL.getTypePtr();
2474 QualType ResultType = getDerived().TransformType(TLB, TL.getResultLoc());
2475 if (ResultType.isNull())
2476 return QualType();
2477
2478 QualType Result = TL.getType();
2479 if (getDerived().AlwaysRebuild() ||
2480 ResultType != T->getResultType())
2481 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
2482
2483 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
2484 NewTL.setLParenLoc(TL.getLParenLoc());
2485 NewTL.setRParenLoc(TL.getRParenLoc());
2486
2487 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002488}
Mike Stump11289f42009-09-09 15:08:12 +00002489
Douglas Gregord6ff3322009-08-04 16:50:30 +00002490template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002491QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
2492 TypedefTypeLoc TL) {
2493 TypedefType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002494 TypedefDecl *Typedef
2495 = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
2496 if (!Typedef)
2497 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002498
John McCall550e0c22009-10-21 00:40:46 +00002499 QualType Result = TL.getType();
2500 if (getDerived().AlwaysRebuild() ||
2501 Typedef != T->getDecl()) {
2502 Result = getDerived().RebuildTypedefType(Typedef);
2503 if (Result.isNull())
2504 return QualType();
2505 }
Mike Stump11289f42009-09-09 15:08:12 +00002506
John McCall550e0c22009-10-21 00:40:46 +00002507 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
2508 NewTL.setNameLoc(TL.getNameLoc());
2509
2510 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002511}
Mike Stump11289f42009-09-09 15:08:12 +00002512
Douglas Gregord6ff3322009-08-04 16:50:30 +00002513template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002514QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
2515 TypeOfExprTypeLoc TL) {
2516 TypeOfExprType *T = TL.getTypePtr();
2517
Douglas Gregore922c772009-08-04 22:27:00 +00002518 // typeof expressions are not potentially evaluated contexts
2519 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002520
Douglas Gregord6ff3322009-08-04 16:50:30 +00002521 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2522 if (E.isInvalid())
2523 return QualType();
2524
John McCall550e0c22009-10-21 00:40:46 +00002525 QualType Result = TL.getType();
2526 if (getDerived().AlwaysRebuild() ||
2527 E.get() != T->getUnderlyingExpr()) {
2528 Result = getDerived().RebuildTypeOfExprType(move(E));
2529 if (Result.isNull())
2530 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002531 }
John McCall550e0c22009-10-21 00:40:46 +00002532 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002533
John McCall550e0c22009-10-21 00:40:46 +00002534 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
2535 NewTL.setNameLoc(TL.getNameLoc());
2536
2537 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002538}
Mike Stump11289f42009-09-09 15:08:12 +00002539
2540template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002541QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
2542 TypeOfTypeLoc TL) {
2543 TypeOfType *T = TL.getTypePtr();
2544
2545 // FIXME: should be an inner type, or at least have a DeclaratorInfo.
Douglas Gregord6ff3322009-08-04 16:50:30 +00002546 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2547 if (Underlying.isNull())
2548 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002549
John McCall550e0c22009-10-21 00:40:46 +00002550 QualType Result = TL.getType();
2551 if (getDerived().AlwaysRebuild() ||
2552 Underlying != T->getUnderlyingType()) {
2553 Result = getDerived().RebuildTypeOfType(Underlying);
2554 if (Result.isNull())
2555 return QualType();
2556 }
Mike Stump11289f42009-09-09 15:08:12 +00002557
John McCall550e0c22009-10-21 00:40:46 +00002558 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
2559 NewTL.setNameLoc(TL.getNameLoc());
2560
2561 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002562}
Mike Stump11289f42009-09-09 15:08:12 +00002563
2564template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002565QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
2566 DecltypeTypeLoc TL) {
2567 DecltypeType *T = TL.getTypePtr();
2568
Douglas Gregore922c772009-08-04 22:27:00 +00002569 // decltype expressions are not potentially evaluated contexts
2570 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002571
Douglas Gregord6ff3322009-08-04 16:50:30 +00002572 Sema::OwningExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
2573 if (E.isInvalid())
2574 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002575
John McCall550e0c22009-10-21 00:40:46 +00002576 QualType Result = TL.getType();
2577 if (getDerived().AlwaysRebuild() ||
2578 E.get() != T->getUnderlyingExpr()) {
2579 Result = getDerived().RebuildDecltypeType(move(E));
2580 if (Result.isNull())
2581 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002582 }
John McCall550e0c22009-10-21 00:40:46 +00002583 else E.take();
Mike Stump11289f42009-09-09 15:08:12 +00002584
John McCall550e0c22009-10-21 00:40:46 +00002585 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
2586 NewTL.setNameLoc(TL.getNameLoc());
2587
2588 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002589}
2590
2591template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002592QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
2593 RecordTypeLoc TL) {
2594 RecordType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002595 RecordDecl *Record
John McCall550e0c22009-10-21 00:40:46 +00002596 = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002597 if (!Record)
2598 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002599
John McCall550e0c22009-10-21 00:40:46 +00002600 QualType Result = TL.getType();
2601 if (getDerived().AlwaysRebuild() ||
2602 Record != T->getDecl()) {
2603 Result = getDerived().RebuildRecordType(Record);
2604 if (Result.isNull())
2605 return QualType();
2606 }
Mike Stump11289f42009-09-09 15:08:12 +00002607
John McCall550e0c22009-10-21 00:40:46 +00002608 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
2609 NewTL.setNameLoc(TL.getNameLoc());
2610
2611 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002612}
Mike Stump11289f42009-09-09 15:08:12 +00002613
2614template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002615QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
2616 EnumTypeLoc TL) {
2617 EnumType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002618 EnumDecl *Enum
John McCall550e0c22009-10-21 00:40:46 +00002619 = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002620 if (!Enum)
2621 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002622
John McCall550e0c22009-10-21 00:40:46 +00002623 QualType Result = TL.getType();
2624 if (getDerived().AlwaysRebuild() ||
2625 Enum != T->getDecl()) {
2626 Result = getDerived().RebuildEnumType(Enum);
2627 if (Result.isNull())
2628 return QualType();
2629 }
Mike Stump11289f42009-09-09 15:08:12 +00002630
John McCall550e0c22009-10-21 00:40:46 +00002631 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
2632 NewTL.setNameLoc(TL.getNameLoc());
2633
2634 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002635}
John McCallfcc33b02009-09-05 00:15:47 +00002636
2637template <typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002638QualType TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
2639 ElaboratedTypeLoc TL) {
2640 ElaboratedType *T = TL.getTypePtr();
2641
2642 // FIXME: this should be a nested type.
John McCallfcc33b02009-09-05 00:15:47 +00002643 QualType Underlying = getDerived().TransformType(T->getUnderlyingType());
2644 if (Underlying.isNull())
2645 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002646
John McCall550e0c22009-10-21 00:40:46 +00002647 QualType Result = TL.getType();
2648 if (getDerived().AlwaysRebuild() ||
2649 Underlying != T->getUnderlyingType()) {
2650 Result = getDerived().RebuildElaboratedType(Underlying, T->getTagKind());
2651 if (Result.isNull())
2652 return QualType();
2653 }
Mike Stump11289f42009-09-09 15:08:12 +00002654
John McCall550e0c22009-10-21 00:40:46 +00002655 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
2656 NewTL.setNameLoc(TL.getNameLoc());
2657
2658 return Result;
John McCallfcc33b02009-09-05 00:15:47 +00002659}
Mike Stump11289f42009-09-09 15:08:12 +00002660
2661
Douglas Gregord6ff3322009-08-04 16:50:30 +00002662template<typename Derived>
2663QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002664 TypeLocBuilder &TLB,
2665 TemplateTypeParmTypeLoc TL) {
2666 return TransformTypeSpecType(TLB, TL);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002667}
2668
Mike Stump11289f42009-09-09 15:08:12 +00002669template<typename Derived>
John McCallcebee162009-10-18 09:09:24 +00002670QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
John McCall550e0c22009-10-21 00:40:46 +00002671 TypeLocBuilder &TLB,
2672 SubstTemplateTypeParmTypeLoc TL) {
2673 return TransformTypeSpecType(TLB, TL);
John McCallcebee162009-10-18 09:09:24 +00002674}
2675
2676template<typename Derived>
Douglas Gregorc59e5612009-10-19 22:04:39 +00002677inline QualType
2678TreeTransform<Derived>::TransformTemplateSpecializationType(
John McCall550e0c22009-10-21 00:40:46 +00002679 TypeLocBuilder &TLB,
2680 TemplateSpecializationTypeLoc TL) {
2681 // TODO: figure out how make this work with an ObjectType.
2682 QualType Result
2683 = TransformTemplateSpecializationType(TL.getTypePtr(), QualType());
2684 if (Result.isNull())
2685 return QualType();
2686
2687 TemplateSpecializationTypeLoc NewTL
2688 = TLB.push<TemplateSpecializationTypeLoc>(Result);
2689 NewTL.setNameLoc(TL.getNameLoc());
2690
2691 return Result;
Douglas Gregorc59e5612009-10-19 22:04:39 +00002692}
2693
2694template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00002695QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
Douglas Gregorc59e5612009-10-19 22:04:39 +00002696 const TemplateSpecializationType *T,
2697 QualType ObjectType) {
Mike Stump11289f42009-09-09 15:08:12 +00002698 TemplateName Template
Douglas Gregorc59e5612009-10-19 22:04:39 +00002699 = getDerived().TransformTemplateName(T->getTemplateName(), ObjectType);
Douglas Gregord6ff3322009-08-04 16:50:30 +00002700 if (Template.isNull())
2701 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002702
Douglas Gregord6ff3322009-08-04 16:50:30 +00002703 llvm::SmallVector<TemplateArgument, 4> NewTemplateArgs;
2704 NewTemplateArgs.reserve(T->getNumArgs());
2705 for (TemplateSpecializationType::iterator Arg = T->begin(), ArgEnd = T->end();
2706 Arg != ArgEnd; ++Arg) {
2707 TemplateArgument NewArg = getDerived().TransformTemplateArgument(*Arg);
2708 if (NewArg.isNull())
2709 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002710
Douglas Gregord6ff3322009-08-04 16:50:30 +00002711 NewTemplateArgs.push_back(NewArg);
2712 }
Mike Stump11289f42009-09-09 15:08:12 +00002713
Douglas Gregord6ff3322009-08-04 16:50:30 +00002714 // FIXME: early abort if all of the template arguments and such are the
2715 // same.
Mike Stump11289f42009-09-09 15:08:12 +00002716
Douglas Gregord6ff3322009-08-04 16:50:30 +00002717 // FIXME: We're missing the locations of the template name, '<', and '>'.
2718 return getDerived().RebuildTemplateSpecializationType(Template,
2719 NewTemplateArgs.data(),
2720 NewTemplateArgs.size());
2721}
Mike Stump11289f42009-09-09 15:08:12 +00002722
2723template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002724QualType
2725TreeTransform<Derived>::TransformQualifiedNameType(TypeLocBuilder &TLB,
2726 QualifiedNameTypeLoc TL) {
2727 QualifiedNameType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002728 NestedNameSpecifier *NNS
2729 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
2730 SourceRange());
2731 if (!NNS)
2732 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002733
Douglas Gregord6ff3322009-08-04 16:50:30 +00002734 QualType Named = getDerived().TransformType(T->getNamedType());
2735 if (Named.isNull())
2736 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002737
John McCall550e0c22009-10-21 00:40:46 +00002738 QualType Result = TL.getType();
2739 if (getDerived().AlwaysRebuild() ||
2740 NNS != T->getQualifier() ||
2741 Named != T->getNamedType()) {
2742 Result = getDerived().RebuildQualifiedNameType(NNS, Named);
2743 if (Result.isNull())
2744 return QualType();
2745 }
Douglas Gregord6ff3322009-08-04 16:50:30 +00002746
John McCall550e0c22009-10-21 00:40:46 +00002747 QualifiedNameTypeLoc NewTL = TLB.push<QualifiedNameTypeLoc>(Result);
2748 NewTL.setNameLoc(TL.getNameLoc());
2749
2750 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002751}
Mike Stump11289f42009-09-09 15:08:12 +00002752
2753template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002754QualType TreeTransform<Derived>::TransformTypenameType(TypeLocBuilder &TLB,
2755 TypenameTypeLoc TL) {
2756 TypenameType *T = TL.getTypePtr();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002757 NestedNameSpecifier *NNS
2758 = getDerived().TransformNestedNameSpecifier(T->getQualifier(),
Douglas Gregor15acfb92009-08-06 16:20:37 +00002759 SourceRange(/*FIXME:*/getDerived().getBaseLocation()));
Douglas Gregord6ff3322009-08-04 16:50:30 +00002760 if (!NNS)
2761 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002762
John McCall550e0c22009-10-21 00:40:46 +00002763 QualType Result;
2764
Douglas Gregord6ff3322009-08-04 16:50:30 +00002765 if (const TemplateSpecializationType *TemplateId = T->getTemplateId()) {
Mike Stump11289f42009-09-09 15:08:12 +00002766 QualType NewTemplateId
Douglas Gregord6ff3322009-08-04 16:50:30 +00002767 = getDerived().TransformType(QualType(TemplateId, 0));
2768 if (NewTemplateId.isNull())
2769 return QualType();
Mike Stump11289f42009-09-09 15:08:12 +00002770
Douglas Gregord6ff3322009-08-04 16:50:30 +00002771 if (!getDerived().AlwaysRebuild() &&
2772 NNS == T->getQualifier() &&
2773 NewTemplateId == QualType(TemplateId, 0))
2774 return QualType(T, 0);
Mike Stump11289f42009-09-09 15:08:12 +00002775
John McCall550e0c22009-10-21 00:40:46 +00002776 Result = getDerived().RebuildTypenameType(NNS, NewTemplateId);
2777 } else {
2778 Result = getDerived().RebuildTypenameType(NNS, T->getIdentifier());
Douglas Gregord6ff3322009-08-04 16:50:30 +00002779 }
John McCall550e0c22009-10-21 00:40:46 +00002780 if (Result.isNull())
2781 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002782
John McCall550e0c22009-10-21 00:40:46 +00002783 TypenameTypeLoc NewTL = TLB.push<TypenameTypeLoc>(Result);
2784 NewTL.setNameLoc(TL.getNameLoc());
2785
2786 return Result;
Douglas Gregord6ff3322009-08-04 16:50:30 +00002787}
Mike Stump11289f42009-09-09 15:08:12 +00002788
Douglas Gregord6ff3322009-08-04 16:50:30 +00002789template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002790QualType
2791TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
2792 ObjCInterfaceTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002793 assert(false && "TransformObjCInterfaceType unimplemented");
2794 return QualType();
Douglas Gregord6ff3322009-08-04 16:50:30 +00002795}
Mike Stump11289f42009-09-09 15:08:12 +00002796
2797template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00002798QualType
2799TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
2800 ObjCObjectPointerTypeLoc TL) {
John McCallfc93cf92009-10-22 22:37:11 +00002801 assert(false && "TransformObjCObjectPointerType unimplemented");
2802 return QualType();
Argyrios Kyrtzidisa7a36df2009-09-29 19:42:55 +00002803}
2804
Douglas Gregord6ff3322009-08-04 16:50:30 +00002805//===----------------------------------------------------------------------===//
Douglas Gregorebe10102009-08-20 07:17:43 +00002806// Statement transformation
2807//===----------------------------------------------------------------------===//
2808template<typename Derived>
2809Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002810TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
2811 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00002812}
2813
2814template<typename Derived>
2815Sema::OwningStmtResult
2816TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
2817 return getDerived().TransformCompoundStmt(S, false);
2818}
2819
2820template<typename Derived>
2821Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002822TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
Douglas Gregorebe10102009-08-20 07:17:43 +00002823 bool IsStmtExpr) {
2824 bool SubStmtChanged = false;
2825 ASTOwningVector<&ActionBase::DeleteStmt> Statements(getSema());
2826 for (CompoundStmt::body_iterator B = S->body_begin(), BEnd = S->body_end();
2827 B != BEnd; ++B) {
2828 OwningStmtResult Result = getDerived().TransformStmt(*B);
2829 if (Result.isInvalid())
2830 return getSema().StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002831
Douglas Gregorebe10102009-08-20 07:17:43 +00002832 SubStmtChanged = SubStmtChanged || Result.get() != *B;
2833 Statements.push_back(Result.takeAs<Stmt>());
2834 }
Mike Stump11289f42009-09-09 15:08:12 +00002835
Douglas Gregorebe10102009-08-20 07:17:43 +00002836 if (!getDerived().AlwaysRebuild() &&
2837 !SubStmtChanged)
Mike Stump11289f42009-09-09 15:08:12 +00002838 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00002839
2840 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
2841 move_arg(Statements),
2842 S->getRBracLoc(),
2843 IsStmtExpr);
2844}
Mike Stump11289f42009-09-09 15:08:12 +00002845
Douglas Gregorebe10102009-08-20 07:17:43 +00002846template<typename Derived>
2847Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002848TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002849 // The case value expressions are not potentially evaluated.
2850 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00002851
Douglas Gregorebe10102009-08-20 07:17:43 +00002852 // Transform the left-hand case value.
2853 OwningExprResult LHS = getDerived().TransformExpr(S->getLHS());
2854 if (LHS.isInvalid())
2855 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002856
Douglas Gregorebe10102009-08-20 07:17:43 +00002857 // Transform the right-hand case value (for the GNU case-range extension).
2858 OwningExprResult RHS = getDerived().TransformExpr(S->getRHS());
2859 if (RHS.isInvalid())
2860 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002861
Douglas Gregorebe10102009-08-20 07:17:43 +00002862 // Build the case statement.
2863 // Case statements are always rebuilt so that they will attached to their
2864 // transformed switch statement.
2865 OwningStmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
2866 move(LHS),
2867 S->getEllipsisLoc(),
2868 move(RHS),
2869 S->getColonLoc());
2870 if (Case.isInvalid())
2871 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002872
Douglas Gregorebe10102009-08-20 07:17:43 +00002873 // Transform the statement following the case
2874 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2875 if (SubStmt.isInvalid())
2876 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002877
Douglas Gregorebe10102009-08-20 07:17:43 +00002878 // Attach the body to the case statement
2879 return getDerived().RebuildCaseStmtBody(move(Case), move(SubStmt));
2880}
2881
2882template<typename Derived>
2883Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002884TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002885 // Transform the statement following the default case
2886 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2887 if (SubStmt.isInvalid())
2888 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002889
Douglas Gregorebe10102009-08-20 07:17:43 +00002890 // Default statements are always rebuilt
2891 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
2892 move(SubStmt));
2893}
Mike Stump11289f42009-09-09 15:08:12 +00002894
Douglas Gregorebe10102009-08-20 07:17:43 +00002895template<typename Derived>
2896Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002897TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002898 OwningStmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt());
2899 if (SubStmt.isInvalid())
2900 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002901
Douglas Gregorebe10102009-08-20 07:17:43 +00002902 // FIXME: Pass the real colon location in.
2903 SourceLocation ColonLoc = SemaRef.PP.getLocForEndOfToken(S->getIdentLoc());
2904 return getDerived().RebuildLabelStmt(S->getIdentLoc(), S->getID(), ColonLoc,
2905 move(SubStmt));
2906}
Mike Stump11289f42009-09-09 15:08:12 +00002907
Douglas Gregorebe10102009-08-20 07:17:43 +00002908template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00002909Sema::OwningStmtResult
2910TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002911 // Transform the condition
2912 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2913 if (Cond.isInvalid())
2914 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002915
Douglas Gregorebe10102009-08-20 07:17:43 +00002916 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00002917
Douglas Gregorebe10102009-08-20 07:17:43 +00002918 // Transform the "then" branch.
2919 OwningStmtResult Then = getDerived().TransformStmt(S->getThen());
2920 if (Then.isInvalid())
2921 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002922
Douglas Gregorebe10102009-08-20 07:17:43 +00002923 // Transform the "else" branch.
2924 OwningStmtResult Else = getDerived().TransformStmt(S->getElse());
2925 if (Else.isInvalid())
2926 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002927
Douglas Gregorebe10102009-08-20 07:17:43 +00002928 if (!getDerived().AlwaysRebuild() &&
2929 FullCond->get() == S->getCond() &&
2930 Then.get() == S->getThen() &&
2931 Else.get() == S->getElse())
Mike Stump11289f42009-09-09 15:08:12 +00002932 return SemaRef.Owned(S->Retain());
2933
Douglas Gregorebe10102009-08-20 07:17:43 +00002934 return getDerived().RebuildIfStmt(S->getIfLoc(), FullCond, move(Then),
Mike Stump11289f42009-09-09 15:08:12 +00002935 S->getElseLoc(), move(Else));
Douglas Gregorebe10102009-08-20 07:17:43 +00002936}
2937
2938template<typename Derived>
2939Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002940TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002941 // Transform the condition.
2942 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2943 if (Cond.isInvalid())
2944 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002945
Douglas Gregorebe10102009-08-20 07:17:43 +00002946 // Rebuild the switch statement.
2947 OwningStmtResult Switch = getDerived().RebuildSwitchStmtStart(move(Cond));
2948 if (Switch.isInvalid())
2949 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002950
Douglas Gregorebe10102009-08-20 07:17:43 +00002951 // Transform the body of the switch statement.
2952 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2953 if (Body.isInvalid())
2954 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002955
Douglas Gregorebe10102009-08-20 07:17:43 +00002956 // Complete the switch statement.
2957 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), move(Switch),
2958 move(Body));
2959}
Mike Stump11289f42009-09-09 15:08:12 +00002960
Douglas Gregorebe10102009-08-20 07:17:43 +00002961template<typename Derived>
2962Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00002963TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00002964 // Transform the condition
2965 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2966 if (Cond.isInvalid())
2967 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002968
Douglas Gregorebe10102009-08-20 07:17:43 +00002969 Sema::FullExprArg FullCond(getSema().FullExpr(Cond));
Mike Stump11289f42009-09-09 15:08:12 +00002970
Douglas Gregorebe10102009-08-20 07:17:43 +00002971 // Transform the body
2972 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2973 if (Body.isInvalid())
2974 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002975
Douglas Gregorebe10102009-08-20 07:17:43 +00002976 if (!getDerived().AlwaysRebuild() &&
2977 FullCond->get() == S->getCond() &&
2978 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00002979 return SemaRef.Owned(S->Retain());
2980
Douglas Gregorebe10102009-08-20 07:17:43 +00002981 return getDerived().RebuildWhileStmt(S->getWhileLoc(), FullCond, move(Body));
2982}
Mike Stump11289f42009-09-09 15:08:12 +00002983
Douglas Gregorebe10102009-08-20 07:17:43 +00002984template<typename Derived>
2985Sema::OwningStmtResult
2986TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
2987 // Transform the condition
2988 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
2989 if (Cond.isInvalid())
2990 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002991
Douglas Gregorebe10102009-08-20 07:17:43 +00002992 // Transform the body
2993 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
2994 if (Body.isInvalid())
2995 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00002996
Douglas Gregorebe10102009-08-20 07:17:43 +00002997 if (!getDerived().AlwaysRebuild() &&
2998 Cond.get() == S->getCond() &&
2999 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003000 return SemaRef.Owned(S->Retain());
3001
Douglas Gregorebe10102009-08-20 07:17:43 +00003002 return getDerived().RebuildDoStmt(S->getDoLoc(), move(Body), S->getWhileLoc(),
3003 /*FIXME:*/S->getWhileLoc(), move(Cond),
3004 S->getRParenLoc());
3005}
Mike Stump11289f42009-09-09 15:08:12 +00003006
Douglas Gregorebe10102009-08-20 07:17:43 +00003007template<typename Derived>
3008Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003009TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003010 // Transform the initialization statement
3011 OwningStmtResult Init = getDerived().TransformStmt(S->getInit());
3012 if (Init.isInvalid())
3013 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003014
Douglas Gregorebe10102009-08-20 07:17:43 +00003015 // Transform the condition
3016 OwningExprResult Cond = getDerived().TransformExpr(S->getCond());
3017 if (Cond.isInvalid())
3018 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003019
Douglas Gregorebe10102009-08-20 07:17:43 +00003020 // Transform the increment
3021 OwningExprResult Inc = getDerived().TransformExpr(S->getInc());
3022 if (Inc.isInvalid())
3023 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003024
Douglas Gregorebe10102009-08-20 07:17:43 +00003025 // Transform the body
3026 OwningStmtResult Body = getDerived().TransformStmt(S->getBody());
3027 if (Body.isInvalid())
3028 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003029
Douglas Gregorebe10102009-08-20 07:17:43 +00003030 if (!getDerived().AlwaysRebuild() &&
3031 Init.get() == S->getInit() &&
3032 Cond.get() == S->getCond() &&
3033 Inc.get() == S->getInc() &&
3034 Body.get() == S->getBody())
Mike Stump11289f42009-09-09 15:08:12 +00003035 return SemaRef.Owned(S->Retain());
3036
Douglas Gregorebe10102009-08-20 07:17:43 +00003037 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
3038 move(Init), move(Cond), move(Inc),
3039 S->getRParenLoc(), move(Body));
3040}
3041
3042template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003043Sema::OwningStmtResult
3044TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003045 // Goto statements must always be rebuilt, to resolve the label.
Mike Stump11289f42009-09-09 15:08:12 +00003046 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003047 S->getLabel());
3048}
3049
3050template<typename Derived>
3051Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003052TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003053 OwningExprResult Target = getDerived().TransformExpr(S->getTarget());
3054 if (Target.isInvalid())
3055 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003056
Douglas Gregorebe10102009-08-20 07:17:43 +00003057 if (!getDerived().AlwaysRebuild() &&
3058 Target.get() == S->getTarget())
Mike Stump11289f42009-09-09 15:08:12 +00003059 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003060
3061 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
3062 move(Target));
3063}
3064
3065template<typename Derived>
3066Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003067TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
3068 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003069}
Mike Stump11289f42009-09-09 15:08:12 +00003070
Douglas Gregorebe10102009-08-20 07:17:43 +00003071template<typename Derived>
3072Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003073TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
3074 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003075}
Mike Stump11289f42009-09-09 15:08:12 +00003076
Douglas Gregorebe10102009-08-20 07:17:43 +00003077template<typename Derived>
3078Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003079TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003080 Sema::OwningExprResult Result = getDerived().TransformExpr(S->getRetValue());
3081 if (Result.isInvalid())
3082 return SemaRef.StmtError();
3083
Mike Stump11289f42009-09-09 15:08:12 +00003084 // FIXME: We always rebuild the return statement because there is no way
Douglas Gregorebe10102009-08-20 07:17:43 +00003085 // to tell whether the return type of the function has changed.
3086 return getDerived().RebuildReturnStmt(S->getReturnLoc(), move(Result));
3087}
Mike Stump11289f42009-09-09 15:08:12 +00003088
Douglas Gregorebe10102009-08-20 07:17:43 +00003089template<typename Derived>
3090Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003091TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003092 bool DeclChanged = false;
3093 llvm::SmallVector<Decl *, 4> Decls;
3094 for (DeclStmt::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
3095 D != DEnd; ++D) {
3096 Decl *Transformed = getDerived().TransformDefinition(*D);
3097 if (!Transformed)
3098 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003099
Douglas Gregorebe10102009-08-20 07:17:43 +00003100 if (Transformed != *D)
3101 DeclChanged = true;
Mike Stump11289f42009-09-09 15:08:12 +00003102
Douglas Gregorebe10102009-08-20 07:17:43 +00003103 Decls.push_back(Transformed);
3104 }
Mike Stump11289f42009-09-09 15:08:12 +00003105
Douglas Gregorebe10102009-08-20 07:17:43 +00003106 if (!getDerived().AlwaysRebuild() && !DeclChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003107 return SemaRef.Owned(S->Retain());
3108
3109 return getDerived().RebuildDeclStmt(Decls.data(), Decls.size(),
Douglas Gregorebe10102009-08-20 07:17:43 +00003110 S->getStartLoc(), S->getEndLoc());
3111}
Mike Stump11289f42009-09-09 15:08:12 +00003112
Douglas Gregorebe10102009-08-20 07:17:43 +00003113template<typename Derived>
3114Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003115TreeTransform<Derived>::TransformSwitchCase(SwitchCase *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003116 assert(false && "SwitchCase is abstract and cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003117 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003118}
3119
3120template<typename Derived>
3121Sema::OwningStmtResult
3122TreeTransform<Derived>::TransformAsmStmt(AsmStmt *S) {
3123 // FIXME: Implement!
3124 assert(false && "Inline assembly cannot be transformed");
Mike Stump11289f42009-09-09 15:08:12 +00003125 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003126}
3127
3128
3129template<typename Derived>
3130Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003131TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003132 // FIXME: Implement this
3133 assert(false && "Cannot transform an Objective-C @try statement");
Mike Stump11289f42009-09-09 15:08:12 +00003134 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003135}
Mike Stump11289f42009-09-09 15:08:12 +00003136
Douglas Gregorebe10102009-08-20 07:17:43 +00003137template<typename Derived>
3138Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003139TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003140 // FIXME: Implement this
3141 assert(false && "Cannot transform an Objective-C @catch statement");
3142 return SemaRef.Owned(S->Retain());
3143}
Mike Stump11289f42009-09-09 15:08:12 +00003144
Douglas Gregorebe10102009-08-20 07:17:43 +00003145template<typename Derived>
3146Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003147TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003148 // FIXME: Implement this
3149 assert(false && "Cannot transform an Objective-C @finally statement");
Mike Stump11289f42009-09-09 15:08:12 +00003150 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003151}
Mike Stump11289f42009-09-09 15:08:12 +00003152
Douglas Gregorebe10102009-08-20 07:17:43 +00003153template<typename Derived>
3154Sema::OwningStmtResult
Mike Stump11289f42009-09-09 15:08:12 +00003155TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003156 // FIXME: Implement this
3157 assert(false && "Cannot transform an Objective-C @throw statement");
Mike Stump11289f42009-09-09 15:08:12 +00003158 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003159}
Mike Stump11289f42009-09-09 15:08:12 +00003160
Douglas Gregorebe10102009-08-20 07:17:43 +00003161template<typename Derived>
3162Sema::OwningStmtResult
3163TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003164 ObjCAtSynchronizedStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003165 // FIXME: Implement this
3166 assert(false && "Cannot transform an Objective-C @synchronized statement");
Mike Stump11289f42009-09-09 15:08:12 +00003167 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003168}
3169
3170template<typename Derived>
3171Sema::OwningStmtResult
3172TreeTransform<Derived>::TransformObjCForCollectionStmt(
Mike Stump11289f42009-09-09 15:08:12 +00003173 ObjCForCollectionStmt *S) {
Douglas Gregorebe10102009-08-20 07:17:43 +00003174 // FIXME: Implement this
3175 assert(false && "Cannot transform an Objective-C for-each statement");
Mike Stump11289f42009-09-09 15:08:12 +00003176 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003177}
3178
3179
3180template<typename Derived>
3181Sema::OwningStmtResult
3182TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
3183 // Transform the exception declaration, if any.
3184 VarDecl *Var = 0;
3185 if (S->getExceptionDecl()) {
3186 VarDecl *ExceptionDecl = S->getExceptionDecl();
3187 TemporaryBase Rebase(*this, ExceptionDecl->getLocation(),
3188 ExceptionDecl->getDeclName());
3189
3190 QualType T = getDerived().TransformType(ExceptionDecl->getType());
3191 if (T.isNull())
3192 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003193
Douglas Gregorebe10102009-08-20 07:17:43 +00003194 Var = getDerived().RebuildExceptionDecl(ExceptionDecl,
3195 T,
3196 ExceptionDecl->getDeclaratorInfo(),
3197 ExceptionDecl->getIdentifier(),
3198 ExceptionDecl->getLocation(),
3199 /*FIXME: Inaccurate*/
3200 SourceRange(ExceptionDecl->getLocation()));
3201 if (!Var || Var->isInvalidDecl()) {
3202 if (Var)
3203 Var->Destroy(SemaRef.Context);
3204 return SemaRef.StmtError();
3205 }
3206 }
Mike Stump11289f42009-09-09 15:08:12 +00003207
Douglas Gregorebe10102009-08-20 07:17:43 +00003208 // Transform the actual exception handler.
3209 OwningStmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
3210 if (Handler.isInvalid()) {
3211 if (Var)
3212 Var->Destroy(SemaRef.Context);
3213 return SemaRef.StmtError();
3214 }
Mike Stump11289f42009-09-09 15:08:12 +00003215
Douglas Gregorebe10102009-08-20 07:17:43 +00003216 if (!getDerived().AlwaysRebuild() &&
3217 !Var &&
3218 Handler.get() == S->getHandlerBlock())
Mike Stump11289f42009-09-09 15:08:12 +00003219 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003220
3221 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(),
3222 Var,
3223 move(Handler));
3224}
Mike Stump11289f42009-09-09 15:08:12 +00003225
Douglas Gregorebe10102009-08-20 07:17:43 +00003226template<typename Derived>
3227Sema::OwningStmtResult
3228TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
3229 // Transform the try block itself.
Mike Stump11289f42009-09-09 15:08:12 +00003230 OwningStmtResult TryBlock
Douglas Gregorebe10102009-08-20 07:17:43 +00003231 = getDerived().TransformCompoundStmt(S->getTryBlock());
3232 if (TryBlock.isInvalid())
3233 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003234
Douglas Gregorebe10102009-08-20 07:17:43 +00003235 // Transform the handlers.
3236 bool HandlerChanged = false;
3237 ASTOwningVector<&ActionBase::DeleteStmt> Handlers(SemaRef);
3238 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +00003239 OwningStmtResult Handler
Douglas Gregorebe10102009-08-20 07:17:43 +00003240 = getDerived().TransformCXXCatchStmt(S->getHandler(I));
3241 if (Handler.isInvalid())
3242 return SemaRef.StmtError();
Mike Stump11289f42009-09-09 15:08:12 +00003243
Douglas Gregorebe10102009-08-20 07:17:43 +00003244 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(I);
3245 Handlers.push_back(Handler.takeAs<Stmt>());
3246 }
Mike Stump11289f42009-09-09 15:08:12 +00003247
Douglas Gregorebe10102009-08-20 07:17:43 +00003248 if (!getDerived().AlwaysRebuild() &&
3249 TryBlock.get() == S->getTryBlock() &&
3250 !HandlerChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003251 return SemaRef.Owned(S->Retain());
Douglas Gregorebe10102009-08-20 07:17:43 +00003252
3253 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), move(TryBlock),
Mike Stump11289f42009-09-09 15:08:12 +00003254 move_arg(Handlers));
Douglas Gregorebe10102009-08-20 07:17:43 +00003255}
Mike Stump11289f42009-09-09 15:08:12 +00003256
Douglas Gregorebe10102009-08-20 07:17:43 +00003257//===----------------------------------------------------------------------===//
Douglas Gregora16548e2009-08-11 05:31:07 +00003258// Expression transformation
3259//===----------------------------------------------------------------------===//
Mike Stump11289f42009-09-09 15:08:12 +00003260template<typename Derived>
3261Sema::OwningExprResult
3262TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
3263 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003264}
Mike Stump11289f42009-09-09 15:08:12 +00003265
3266template<typename Derived>
3267Sema::OwningExprResult
3268TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003269 NestedNameSpecifier *Qualifier = 0;
3270 if (E->getQualifier()) {
3271 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3272 E->getQualifierRange());
3273 if (!Qualifier)
3274 return SemaRef.ExprError();
3275 }
3276
Mike Stump11289f42009-09-09 15:08:12 +00003277 NamedDecl *ND
Douglas Gregora16548e2009-08-11 05:31:07 +00003278 = dyn_cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getDecl()));
3279 if (!ND)
3280 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003281
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003282 if (!getDerived().AlwaysRebuild() &&
3283 Qualifier == E->getQualifier() &&
3284 ND == E->getDecl() &&
3285 !E->hasExplicitTemplateArgumentList())
Mike Stump11289f42009-09-09 15:08:12 +00003286 return SemaRef.Owned(E->Retain());
3287
Douglas Gregor4bd90e52009-10-23 18:54:35 +00003288 // FIXME: We're losing the explicit template arguments in this transformation.
3289
3290 llvm::SmallVector<TemplateArgument, 4> TransArgs;
3291 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
3292 TemplateArgument TransArg
3293 = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
3294 if (TransArg.isNull())
3295 return SemaRef.ExprError();
3296
3297 TransArgs.push_back(TransArg);
3298 }
3299
3300 // FIXME: Pass the qualifier/qualifier range along.
3301 return getDerived().RebuildDeclRefExpr(Qualifier, E->getQualifierRange(),
3302 ND, E->getLocation());
Douglas Gregora16548e2009-08-11 05:31:07 +00003303}
Mike Stump11289f42009-09-09 15:08:12 +00003304
Douglas Gregora16548e2009-08-11 05:31:07 +00003305template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003306Sema::OwningExprResult
3307TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
3308 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003309}
Mike Stump11289f42009-09-09 15:08:12 +00003310
Douglas Gregora16548e2009-08-11 05:31:07 +00003311template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003312Sema::OwningExprResult
3313TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
3314 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003315}
Mike Stump11289f42009-09-09 15:08:12 +00003316
Douglas Gregora16548e2009-08-11 05:31:07 +00003317template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003318Sema::OwningExprResult
3319TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
3320 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003321}
Mike Stump11289f42009-09-09 15:08:12 +00003322
Douglas Gregora16548e2009-08-11 05:31:07 +00003323template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003324Sema::OwningExprResult
3325TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
3326 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003327}
Mike Stump11289f42009-09-09 15:08:12 +00003328
Douglas Gregora16548e2009-08-11 05:31:07 +00003329template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003330Sema::OwningExprResult
3331TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
3332 return SemaRef.Owned(E->Retain());
3333}
3334
3335template<typename Derived>
3336Sema::OwningExprResult
3337TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003338 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3339 if (SubExpr.isInvalid())
3340 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003341
Douglas Gregora16548e2009-08-11 05:31:07 +00003342 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003343 return SemaRef.Owned(E->Retain());
3344
3345 return getDerived().RebuildParenExpr(move(SubExpr), E->getLParen(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003346 E->getRParen());
3347}
3348
Mike Stump11289f42009-09-09 15:08:12 +00003349template<typename Derived>
3350Sema::OwningExprResult
3351TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003352 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3353 if (SubExpr.isInvalid())
3354 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003355
Douglas Gregora16548e2009-08-11 05:31:07 +00003356 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003357 return SemaRef.Owned(E->Retain());
3358
Douglas Gregora16548e2009-08-11 05:31:07 +00003359 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
3360 E->getOpcode(),
3361 move(SubExpr));
3362}
Mike Stump11289f42009-09-09 15:08:12 +00003363
Douglas Gregora16548e2009-08-11 05:31:07 +00003364template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003365Sema::OwningExprResult
3366TreeTransform<Derived>::TransformSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003367 if (E->isArgumentType()) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003368 TemporaryBase Rebase(*this, E->getOperatorLoc(), DeclarationName());
3369
Douglas Gregora16548e2009-08-11 05:31:07 +00003370 QualType T = getDerived().TransformType(E->getArgumentType());
3371 if (T.isNull())
3372 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003373
Douglas Gregora16548e2009-08-11 05:31:07 +00003374 if (!getDerived().AlwaysRebuild() && T == E->getArgumentType())
3375 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003376
3377 return getDerived().RebuildSizeOfAlignOf(T, E->getOperatorLoc(),
3378 E->isSizeOf(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003379 E->getSourceRange());
3380 }
Mike Stump11289f42009-09-09 15:08:12 +00003381
Douglas Gregora16548e2009-08-11 05:31:07 +00003382 Sema::OwningExprResult SubExpr(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00003383 {
Douglas Gregora16548e2009-08-11 05:31:07 +00003384 // C++0x [expr.sizeof]p1:
3385 // The operand is either an expression, which is an unevaluated operand
3386 // [...]
3387 EnterExpressionEvaluationContext Unevaluated(SemaRef, Action::Unevaluated);
Mike Stump11289f42009-09-09 15:08:12 +00003388
Douglas Gregora16548e2009-08-11 05:31:07 +00003389 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
3390 if (SubExpr.isInvalid())
3391 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003392
Douglas Gregora16548e2009-08-11 05:31:07 +00003393 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
3394 return SemaRef.Owned(E->Retain());
3395 }
Mike Stump11289f42009-09-09 15:08:12 +00003396
Douglas Gregora16548e2009-08-11 05:31:07 +00003397 return getDerived().RebuildSizeOfAlignOf(move(SubExpr), E->getOperatorLoc(),
3398 E->isSizeOf(),
3399 E->getSourceRange());
3400}
Mike Stump11289f42009-09-09 15:08:12 +00003401
Douglas Gregora16548e2009-08-11 05:31:07 +00003402template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003403Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003404TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
3405 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3406 if (LHS.isInvalid())
3407 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003408
Douglas Gregora16548e2009-08-11 05:31:07 +00003409 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3410 if (RHS.isInvalid())
3411 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003412
3413
Douglas Gregora16548e2009-08-11 05:31:07 +00003414 if (!getDerived().AlwaysRebuild() &&
3415 LHS.get() == E->getLHS() &&
3416 RHS.get() == E->getRHS())
3417 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003418
Douglas Gregora16548e2009-08-11 05:31:07 +00003419 return getDerived().RebuildArraySubscriptExpr(move(LHS),
3420 /*FIXME:*/E->getLHS()->getLocStart(),
3421 move(RHS),
3422 E->getRBracketLoc());
3423}
Mike Stump11289f42009-09-09 15:08:12 +00003424
3425template<typename Derived>
3426Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003427TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
3428 // Transform the callee.
3429 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3430 if (Callee.isInvalid())
3431 return SemaRef.ExprError();
3432
3433 // Transform arguments.
3434 bool ArgChanged = false;
3435 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
3436 llvm::SmallVector<SourceLocation, 4> FakeCommaLocs;
3437 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
3438 OwningExprResult Arg = getDerived().TransformExpr(E->getArg(I));
3439 if (Arg.isInvalid())
3440 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003441
Douglas Gregora16548e2009-08-11 05:31:07 +00003442 // FIXME: Wrong source location information for the ','.
3443 FakeCommaLocs.push_back(
3444 SemaRef.PP.getLocForEndOfToken(E->getArg(I)->getSourceRange().getEnd()));
Mike Stump11289f42009-09-09 15:08:12 +00003445
3446 ArgChanged = ArgChanged || Arg.get() != E->getArg(I);
Douglas Gregora16548e2009-08-11 05:31:07 +00003447 Args.push_back(Arg.takeAs<Expr>());
3448 }
Mike Stump11289f42009-09-09 15:08:12 +00003449
Douglas Gregora16548e2009-08-11 05:31:07 +00003450 if (!getDerived().AlwaysRebuild() &&
3451 Callee.get() == E->getCallee() &&
3452 !ArgChanged)
3453 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003454
Douglas Gregora16548e2009-08-11 05:31:07 +00003455 // FIXME: Wrong source location information for the '('.
Mike Stump11289f42009-09-09 15:08:12 +00003456 SourceLocation FakeLParenLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003457 = ((Expr *)Callee.get())->getSourceRange().getBegin();
3458 return getDerived().RebuildCallExpr(move(Callee), FakeLParenLoc,
3459 move_arg(Args),
3460 FakeCommaLocs.data(),
3461 E->getRParenLoc());
3462}
Mike Stump11289f42009-09-09 15:08:12 +00003463
3464template<typename Derived>
3465Sema::OwningExprResult
3466TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003467 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3468 if (Base.isInvalid())
3469 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003470
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003471 NestedNameSpecifier *Qualifier = 0;
3472 if (E->hasQualifier()) {
Mike Stump11289f42009-09-09 15:08:12 +00003473 Qualifier
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003474 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
3475 E->getQualifierRange());
Douglas Gregor84f14dd2009-09-01 00:37:14 +00003476 if (Qualifier == 0)
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003477 return SemaRef.ExprError();
3478 }
Mike Stump11289f42009-09-09 15:08:12 +00003479
3480 NamedDecl *Member
Douglas Gregora16548e2009-08-11 05:31:07 +00003481 = cast_or_null<NamedDecl>(getDerived().TransformDecl(E->getMemberDecl()));
3482 if (!Member)
3483 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003484
Douglas Gregora16548e2009-08-11 05:31:07 +00003485 if (!getDerived().AlwaysRebuild() &&
3486 Base.get() == E->getBase() &&
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003487 Qualifier == E->getQualifier() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00003488 Member == E->getMemberDecl())
Mike Stump11289f42009-09-09 15:08:12 +00003489 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003490
3491 // FIXME: Bogus source location for the operator
3492 SourceLocation FakeOperatorLoc
3493 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
3494
3495 return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
3496 E->isArrow(),
Douglas Gregorf405d7e2009-08-31 23:41:50 +00003497 Qualifier,
3498 E->getQualifierRange(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003499 E->getMemberLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003500 Member);
Douglas Gregora16548e2009-08-11 05:31:07 +00003501}
Mike Stump11289f42009-09-09 15:08:12 +00003502
Douglas Gregora16548e2009-08-11 05:31:07 +00003503template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003504Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003505TreeTransform<Derived>::TransformCastExpr(CastExpr *E) {
3506 assert(false && "Cannot transform abstract class");
3507 return SemaRef.Owned(E->Retain());
3508}
3509
3510template<typename Derived>
3511Sema::OwningExprResult
3512TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003513 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3514 if (LHS.isInvalid())
3515 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003516
Douglas Gregora16548e2009-08-11 05:31:07 +00003517 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3518 if (RHS.isInvalid())
3519 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003520
Douglas Gregora16548e2009-08-11 05:31:07 +00003521 if (!getDerived().AlwaysRebuild() &&
3522 LHS.get() == E->getLHS() &&
3523 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00003524 return SemaRef.Owned(E->Retain());
3525
Douglas Gregora16548e2009-08-11 05:31:07 +00003526 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
3527 move(LHS), move(RHS));
3528}
3529
Mike Stump11289f42009-09-09 15:08:12 +00003530template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003531Sema::OwningExprResult
3532TreeTransform<Derived>::TransformCompoundAssignOperator(
3533 CompoundAssignOperator *E) {
3534 return getDerived().TransformBinaryOperator(E);
3535}
Mike Stump11289f42009-09-09 15:08:12 +00003536
Douglas Gregora16548e2009-08-11 05:31:07 +00003537template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003538Sema::OwningExprResult
3539TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003540 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3541 if (Cond.isInvalid())
3542 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003543
Douglas Gregora16548e2009-08-11 05:31:07 +00003544 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3545 if (LHS.isInvalid())
3546 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003547
Douglas Gregora16548e2009-08-11 05:31:07 +00003548 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3549 if (RHS.isInvalid())
3550 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003551
Douglas Gregora16548e2009-08-11 05:31:07 +00003552 if (!getDerived().AlwaysRebuild() &&
3553 Cond.get() == E->getCond() &&
3554 LHS.get() == E->getLHS() &&
3555 RHS.get() == E->getRHS())
3556 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003557
3558 return getDerived().RebuildConditionalOperator(move(Cond),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003559 E->getQuestionLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003560 move(LHS),
Douglas Gregor7e112b02009-08-26 14:37:04 +00003561 E->getColonLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003562 move(RHS));
3563}
Mike Stump11289f42009-09-09 15:08:12 +00003564
3565template<typename Derived>
3566Sema::OwningExprResult
3567TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003568 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3569
3570 // FIXME: Will we ever have type information here? It seems like we won't,
3571 // so do we even need to transform the type?
Douglas Gregora16548e2009-08-11 05:31:07 +00003572 QualType T = getDerived().TransformType(E->getType());
3573 if (T.isNull())
3574 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003575
Douglas Gregora16548e2009-08-11 05:31:07 +00003576 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3577 if (SubExpr.isInvalid())
3578 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003579
Douglas Gregora16548e2009-08-11 05:31:07 +00003580 if (!getDerived().AlwaysRebuild() &&
3581 T == E->getType() &&
3582 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003583 return SemaRef.Owned(E->Retain());
3584
Douglas Gregora16548e2009-08-11 05:31:07 +00003585 return getDerived().RebuildImplicitCastExpr(T, E->getCastKind(),
Mike Stump11289f42009-09-09 15:08:12 +00003586 move(SubExpr),
Douglas Gregora16548e2009-08-11 05:31:07 +00003587 E->isLvalueCast());
3588}
Mike Stump11289f42009-09-09 15:08:12 +00003589
Douglas Gregora16548e2009-08-11 05:31:07 +00003590template<typename Derived>
3591Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003592TreeTransform<Derived>::TransformExplicitCastExpr(ExplicitCastExpr *E) {
3593 assert(false && "Cannot transform abstract class");
3594 return SemaRef.Owned(E->Retain());
3595}
3596
3597template<typename Derived>
3598Sema::OwningExprResult
3599TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003600 QualType T;
3601 {
3602 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003603 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003604 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3605 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003606
Douglas Gregora16548e2009-08-11 05:31:07 +00003607 T = getDerived().TransformType(E->getTypeAsWritten());
3608 if (T.isNull())
3609 return SemaRef.ExprError();
3610 }
Mike Stump11289f42009-09-09 15:08:12 +00003611
Douglas Gregora16548e2009-08-11 05:31:07 +00003612 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3613 if (SubExpr.isInvalid())
3614 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003615
Douglas Gregora16548e2009-08-11 05:31:07 +00003616 if (!getDerived().AlwaysRebuild() &&
3617 T == E->getTypeAsWritten() &&
3618 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003619 return SemaRef.Owned(E->Retain());
3620
Douglas Gregora16548e2009-08-11 05:31:07 +00003621 return getDerived().RebuildCStyleCaseExpr(E->getLParenLoc(), T,
3622 E->getRParenLoc(),
3623 move(SubExpr));
3624}
Mike Stump11289f42009-09-09 15:08:12 +00003625
Douglas Gregora16548e2009-08-11 05:31:07 +00003626template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003627Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003628TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
3629 QualType T;
3630 {
3631 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003632 SourceLocation FakeTypeLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003633 = SemaRef.PP.getLocForEndOfToken(E->getLParenLoc());
3634 TemporaryBase Rebase(*this, FakeTypeLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003635
Douglas Gregora16548e2009-08-11 05:31:07 +00003636 T = getDerived().TransformType(E->getType());
3637 if (T.isNull())
3638 return SemaRef.ExprError();
3639 }
Mike Stump11289f42009-09-09 15:08:12 +00003640
Douglas Gregora16548e2009-08-11 05:31:07 +00003641 OwningExprResult Init = getDerived().TransformExpr(E->getInitializer());
3642 if (Init.isInvalid())
3643 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003644
Douglas Gregora16548e2009-08-11 05:31:07 +00003645 if (!getDerived().AlwaysRebuild() &&
3646 T == E->getType() &&
3647 Init.get() == E->getInitializer())
Mike Stump11289f42009-09-09 15:08:12 +00003648 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003649
3650 return getDerived().RebuildCompoundLiteralExpr(E->getLParenLoc(), T,
3651 /*FIXME:*/E->getInitializer()->getLocEnd(),
3652 move(Init));
3653}
Mike Stump11289f42009-09-09 15:08:12 +00003654
Douglas Gregora16548e2009-08-11 05:31:07 +00003655template<typename Derived>
3656Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003657TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003658 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
3659 if (Base.isInvalid())
3660 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003661
Douglas Gregora16548e2009-08-11 05:31:07 +00003662 if (!getDerived().AlwaysRebuild() &&
3663 Base.get() == E->getBase())
Mike Stump11289f42009-09-09 15:08:12 +00003664 return SemaRef.Owned(E->Retain());
3665
Douglas Gregora16548e2009-08-11 05:31:07 +00003666 // FIXME: Bad source location
Mike Stump11289f42009-09-09 15:08:12 +00003667 SourceLocation FakeOperatorLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003668 = SemaRef.PP.getLocForEndOfToken(E->getBase()->getLocEnd());
3669 return getDerived().RebuildExtVectorElementExpr(move(Base), FakeOperatorLoc,
3670 E->getAccessorLoc(),
3671 E->getAccessor());
3672}
Mike Stump11289f42009-09-09 15:08:12 +00003673
Douglas Gregora16548e2009-08-11 05:31:07 +00003674template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003675Sema::OwningExprResult
3676TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003677 bool InitChanged = false;
Mike Stump11289f42009-09-09 15:08:12 +00003678
Douglas Gregora16548e2009-08-11 05:31:07 +00003679 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3680 for (unsigned I = 0, N = E->getNumInits(); I != N; ++I) {
3681 OwningExprResult Init = getDerived().TransformExpr(E->getInit(I));
3682 if (Init.isInvalid())
3683 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003684
Douglas Gregora16548e2009-08-11 05:31:07 +00003685 InitChanged = InitChanged || Init.get() != E->getInit(I);
3686 Inits.push_back(Init.takeAs<Expr>());
3687 }
Mike Stump11289f42009-09-09 15:08:12 +00003688
Douglas Gregora16548e2009-08-11 05:31:07 +00003689 if (!getDerived().AlwaysRebuild() && !InitChanged)
Mike Stump11289f42009-09-09 15:08:12 +00003690 return SemaRef.Owned(E->Retain());
3691
Douglas Gregora16548e2009-08-11 05:31:07 +00003692 return getDerived().RebuildInitList(E->getLBraceLoc(), move_arg(Inits),
3693 E->getRBraceLoc());
3694}
Mike Stump11289f42009-09-09 15:08:12 +00003695
Douglas Gregora16548e2009-08-11 05:31:07 +00003696template<typename Derived>
3697Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003698TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003699 Designation Desig;
Mike Stump11289f42009-09-09 15:08:12 +00003700
Douglas Gregorebe10102009-08-20 07:17:43 +00003701 // transform the initializer value
Douglas Gregora16548e2009-08-11 05:31:07 +00003702 OwningExprResult Init = getDerived().TransformExpr(E->getInit());
3703 if (Init.isInvalid())
3704 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003705
Douglas Gregorebe10102009-08-20 07:17:43 +00003706 // transform the designators.
Douglas Gregora16548e2009-08-11 05:31:07 +00003707 ASTOwningVector<&ActionBase::DeleteExpr, 4> ArrayExprs(SemaRef);
3708 bool ExprChanged = false;
3709 for (DesignatedInitExpr::designators_iterator D = E->designators_begin(),
3710 DEnd = E->designators_end();
3711 D != DEnd; ++D) {
3712 if (D->isFieldDesignator()) {
3713 Desig.AddDesignator(Designator::getField(D->getFieldName(),
3714 D->getDotLoc(),
3715 D->getFieldLoc()));
3716 continue;
3717 }
Mike Stump11289f42009-09-09 15:08:12 +00003718
Douglas Gregora16548e2009-08-11 05:31:07 +00003719 if (D->isArrayDesignator()) {
3720 OwningExprResult Index = getDerived().TransformExpr(E->getArrayIndex(*D));
3721 if (Index.isInvalid())
3722 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003723
3724 Desig.AddDesignator(Designator::getArray(Index.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003725 D->getLBracketLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003726
Douglas Gregora16548e2009-08-11 05:31:07 +00003727 ExprChanged = ExprChanged || Init.get() != E->getArrayIndex(*D);
3728 ArrayExprs.push_back(Index.release());
3729 continue;
3730 }
Mike Stump11289f42009-09-09 15:08:12 +00003731
Douglas Gregora16548e2009-08-11 05:31:07 +00003732 assert(D->isArrayRangeDesignator() && "New kind of designator?");
Mike Stump11289f42009-09-09 15:08:12 +00003733 OwningExprResult Start
Douglas Gregora16548e2009-08-11 05:31:07 +00003734 = getDerived().TransformExpr(E->getArrayRangeStart(*D));
3735 if (Start.isInvalid())
3736 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003737
Douglas Gregora16548e2009-08-11 05:31:07 +00003738 OwningExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(*D));
3739 if (End.isInvalid())
3740 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003741
3742 Desig.AddDesignator(Designator::getArrayRange(Start.get(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003743 End.get(),
3744 D->getLBracketLoc(),
3745 D->getEllipsisLoc()));
Mike Stump11289f42009-09-09 15:08:12 +00003746
Douglas Gregora16548e2009-08-11 05:31:07 +00003747 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(*D) ||
3748 End.get() != E->getArrayRangeEnd(*D);
Mike Stump11289f42009-09-09 15:08:12 +00003749
Douglas Gregora16548e2009-08-11 05:31:07 +00003750 ArrayExprs.push_back(Start.release());
3751 ArrayExprs.push_back(End.release());
3752 }
Mike Stump11289f42009-09-09 15:08:12 +00003753
Douglas Gregora16548e2009-08-11 05:31:07 +00003754 if (!getDerived().AlwaysRebuild() &&
3755 Init.get() == E->getInit() &&
3756 !ExprChanged)
3757 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003758
Douglas Gregora16548e2009-08-11 05:31:07 +00003759 return getDerived().RebuildDesignatedInitExpr(Desig, move_arg(ArrayExprs),
3760 E->getEqualOrColonLoc(),
3761 E->usesGNUSyntax(), move(Init));
3762}
Mike Stump11289f42009-09-09 15:08:12 +00003763
Douglas Gregora16548e2009-08-11 05:31:07 +00003764template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003765Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003766TreeTransform<Derived>::TransformImplicitValueInitExpr(
Mike Stump11289f42009-09-09 15:08:12 +00003767 ImplicitValueInitExpr *E) {
Douglas Gregor3da3c062009-10-28 00:29:27 +00003768 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
3769
3770 // FIXME: Will we ever have proper type location here? Will we actually
3771 // need to transform the type?
Douglas Gregora16548e2009-08-11 05:31:07 +00003772 QualType T = getDerived().TransformType(E->getType());
3773 if (T.isNull())
3774 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003775
Douglas Gregora16548e2009-08-11 05:31:07 +00003776 if (!getDerived().AlwaysRebuild() &&
3777 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00003778 return SemaRef.Owned(E->Retain());
3779
Douglas Gregora16548e2009-08-11 05:31:07 +00003780 return getDerived().RebuildImplicitValueInitExpr(T);
3781}
Mike Stump11289f42009-09-09 15:08:12 +00003782
Douglas Gregora16548e2009-08-11 05:31:07 +00003783template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003784Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003785TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
3786 // FIXME: Do we want the type as written?
3787 QualType T;
Mike Stump11289f42009-09-09 15:08:12 +00003788
Douglas Gregora16548e2009-08-11 05:31:07 +00003789 {
3790 // FIXME: Source location isn't quite accurate.
3791 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
3792 T = getDerived().TransformType(E->getType());
3793 if (T.isNull())
3794 return SemaRef.ExprError();
3795 }
Mike Stump11289f42009-09-09 15:08:12 +00003796
Douglas Gregora16548e2009-08-11 05:31:07 +00003797 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3798 if (SubExpr.isInvalid())
3799 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003800
Douglas Gregora16548e2009-08-11 05:31:07 +00003801 if (!getDerived().AlwaysRebuild() &&
3802 T == E->getType() &&
3803 SubExpr.get() == E->getSubExpr())
3804 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003805
Douglas Gregora16548e2009-08-11 05:31:07 +00003806 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), move(SubExpr),
3807 T, E->getRParenLoc());
3808}
3809
3810template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003811Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003812TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
3813 bool ArgumentChanged = false;
3814 ASTOwningVector<&ActionBase::DeleteExpr, 4> Inits(SemaRef);
3815 for (unsigned I = 0, N = E->getNumExprs(); I != N; ++I) {
3816 OwningExprResult Init = getDerived().TransformExpr(E->getExpr(I));
3817 if (Init.isInvalid())
3818 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003819
Douglas Gregora16548e2009-08-11 05:31:07 +00003820 ArgumentChanged = ArgumentChanged || Init.get() != E->getExpr(I);
3821 Inits.push_back(Init.takeAs<Expr>());
3822 }
Mike Stump11289f42009-09-09 15:08:12 +00003823
Douglas Gregora16548e2009-08-11 05:31:07 +00003824 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
3825 move_arg(Inits),
3826 E->getRParenLoc());
3827}
Mike Stump11289f42009-09-09 15:08:12 +00003828
Douglas Gregora16548e2009-08-11 05:31:07 +00003829/// \brief Transform an address-of-label expression.
3830///
3831/// By default, the transformation of an address-of-label expression always
3832/// rebuilds the expression, so that the label identifier can be resolved to
3833/// the corresponding label statement by semantic analysis.
3834template<typename Derived>
3835Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003836TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003837 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
3838 E->getLabel());
3839}
Mike Stump11289f42009-09-09 15:08:12 +00003840
3841template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00003842Sema::OwningExprResult TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
Mike Stump11289f42009-09-09 15:08:12 +00003843 OwningStmtResult SubStmt
Douglas Gregora16548e2009-08-11 05:31:07 +00003844 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
3845 if (SubStmt.isInvalid())
3846 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003847
Douglas Gregora16548e2009-08-11 05:31:07 +00003848 if (!getDerived().AlwaysRebuild() &&
3849 SubStmt.get() == E->getSubStmt())
3850 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00003851
3852 return getDerived().RebuildStmtExpr(E->getLParenLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003853 move(SubStmt),
3854 E->getRParenLoc());
3855}
Mike Stump11289f42009-09-09 15:08:12 +00003856
Douglas Gregora16548e2009-08-11 05:31:07 +00003857template<typename Derived>
3858Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003859TreeTransform<Derived>::TransformTypesCompatibleExpr(TypesCompatibleExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003860 QualType T1, T2;
3861 {
3862 // FIXME: Source location isn't quite accurate.
3863 TemporaryBase Rebase(*this, E->getBuiltinLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003864
Douglas Gregora16548e2009-08-11 05:31:07 +00003865 T1 = getDerived().TransformType(E->getArgType1());
3866 if (T1.isNull())
3867 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003868
Douglas Gregora16548e2009-08-11 05:31:07 +00003869 T2 = getDerived().TransformType(E->getArgType2());
3870 if (T2.isNull())
3871 return SemaRef.ExprError();
3872 }
3873
3874 if (!getDerived().AlwaysRebuild() &&
3875 T1 == E->getArgType1() &&
3876 T2 == E->getArgType2())
Mike Stump11289f42009-09-09 15:08:12 +00003877 return SemaRef.Owned(E->Retain());
3878
Douglas Gregora16548e2009-08-11 05:31:07 +00003879 return getDerived().RebuildTypesCompatibleExpr(E->getBuiltinLoc(),
3880 T1, T2, E->getRParenLoc());
3881}
Mike Stump11289f42009-09-09 15:08:12 +00003882
Douglas Gregora16548e2009-08-11 05:31:07 +00003883template<typename Derived>
3884Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003885TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003886 OwningExprResult Cond = getDerived().TransformExpr(E->getCond());
3887 if (Cond.isInvalid())
3888 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003889
Douglas Gregora16548e2009-08-11 05:31:07 +00003890 OwningExprResult LHS = getDerived().TransformExpr(E->getLHS());
3891 if (LHS.isInvalid())
3892 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003893
Douglas Gregora16548e2009-08-11 05:31:07 +00003894 OwningExprResult RHS = getDerived().TransformExpr(E->getRHS());
3895 if (RHS.isInvalid())
3896 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003897
Douglas Gregora16548e2009-08-11 05:31:07 +00003898 if (!getDerived().AlwaysRebuild() &&
3899 Cond.get() == E->getCond() &&
3900 LHS.get() == E->getLHS() &&
3901 RHS.get() == E->getRHS())
Mike Stump11289f42009-09-09 15:08:12 +00003902 return SemaRef.Owned(E->Retain());
3903
Douglas Gregora16548e2009-08-11 05:31:07 +00003904 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
3905 move(Cond), move(LHS), move(RHS),
3906 E->getRParenLoc());
3907}
Mike Stump11289f42009-09-09 15:08:12 +00003908
Douglas Gregora16548e2009-08-11 05:31:07 +00003909template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003910Sema::OwningExprResult
3911TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
3912 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00003913}
3914
3915template<typename Derived>
3916Sema::OwningExprResult
3917TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
3918 OwningExprResult Callee = getDerived().TransformExpr(E->getCallee());
3919 if (Callee.isInvalid())
3920 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003921
Douglas Gregora16548e2009-08-11 05:31:07 +00003922 OwningExprResult First = getDerived().TransformExpr(E->getArg(0));
3923 if (First.isInvalid())
3924 return SemaRef.ExprError();
3925
3926 OwningExprResult Second(SemaRef);
3927 if (E->getNumArgs() == 2) {
3928 Second = getDerived().TransformExpr(E->getArg(1));
3929 if (Second.isInvalid())
3930 return SemaRef.ExprError();
3931 }
Mike Stump11289f42009-09-09 15:08:12 +00003932
Douglas Gregora16548e2009-08-11 05:31:07 +00003933 if (!getDerived().AlwaysRebuild() &&
3934 Callee.get() == E->getCallee() &&
3935 First.get() == E->getArg(0) &&
Mike Stump11289f42009-09-09 15:08:12 +00003936 (E->getNumArgs() != 2 || Second.get() == E->getArg(1)))
3937 return SemaRef.Owned(E->Retain());
3938
Douglas Gregora16548e2009-08-11 05:31:07 +00003939 return getDerived().RebuildCXXOperatorCallExpr(E->getOperator(),
3940 E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003941 move(Callee),
Douglas Gregora16548e2009-08-11 05:31:07 +00003942 move(First),
3943 move(Second));
3944}
Mike Stump11289f42009-09-09 15:08:12 +00003945
Douglas Gregora16548e2009-08-11 05:31:07 +00003946template<typename Derived>
3947Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003948TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003949 return getDerived().TransformCallExpr(E);
3950}
Mike Stump11289f42009-09-09 15:08:12 +00003951
Douglas Gregora16548e2009-08-11 05:31:07 +00003952template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00003953Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00003954TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
3955 QualType ExplicitTy;
3956 {
3957 // FIXME: Source location isn't quite accurate.
Mike Stump11289f42009-09-09 15:08:12 +00003958 SourceLocation TypeStartLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003959 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3960 TemporaryBase Rebase(*this, TypeStartLoc, DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00003961
Douglas Gregora16548e2009-08-11 05:31:07 +00003962 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
3963 if (ExplicitTy.isNull())
3964 return SemaRef.ExprError();
3965 }
Mike Stump11289f42009-09-09 15:08:12 +00003966
Douglas Gregora16548e2009-08-11 05:31:07 +00003967 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
3968 if (SubExpr.isInvalid())
3969 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00003970
Douglas Gregora16548e2009-08-11 05:31:07 +00003971 if (!getDerived().AlwaysRebuild() &&
3972 ExplicitTy == E->getTypeAsWritten() &&
3973 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00003974 return SemaRef.Owned(E->Retain());
3975
Douglas Gregora16548e2009-08-11 05:31:07 +00003976 // FIXME: Poor source location information here.
Mike Stump11289f42009-09-09 15:08:12 +00003977 SourceLocation FakeLAngleLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00003978 = SemaRef.PP.getLocForEndOfToken(E->getOperatorLoc());
3979 SourceLocation FakeRAngleLoc = E->getSubExpr()->getSourceRange().getBegin();
3980 SourceLocation FakeRParenLoc
3981 = SemaRef.PP.getLocForEndOfToken(
3982 E->getSubExpr()->getSourceRange().getEnd());
3983 return getDerived().RebuildCXXNamedCastExpr(E->getOperatorLoc(),
Mike Stump11289f42009-09-09 15:08:12 +00003984 E->getStmtClass(),
Douglas Gregora16548e2009-08-11 05:31:07 +00003985 FakeLAngleLoc,
3986 ExplicitTy,
3987 FakeRAngleLoc,
3988 FakeRAngleLoc,
3989 move(SubExpr),
3990 FakeRParenLoc);
3991}
Mike Stump11289f42009-09-09 15:08:12 +00003992
Douglas Gregora16548e2009-08-11 05:31:07 +00003993template<typename Derived>
3994Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00003995TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00003996 return getDerived().TransformCXXNamedCastExpr(E);
3997}
Mike Stump11289f42009-09-09 15:08:12 +00003998
3999template<typename Derived>
4000Sema::OwningExprResult
4001TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
4002 return getDerived().TransformCXXNamedCastExpr(E);
4003}
4004
Douglas Gregora16548e2009-08-11 05:31:07 +00004005template<typename Derived>
4006Sema::OwningExprResult
4007TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004008 CXXReinterpretCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004009 return getDerived().TransformCXXNamedCastExpr(E);
4010}
Mike Stump11289f42009-09-09 15:08:12 +00004011
Douglas Gregora16548e2009-08-11 05:31:07 +00004012template<typename Derived>
4013Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004014TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004015 return getDerived().TransformCXXNamedCastExpr(E);
4016}
Mike Stump11289f42009-09-09 15:08:12 +00004017
Douglas Gregora16548e2009-08-11 05:31:07 +00004018template<typename Derived>
4019Sema::OwningExprResult
4020TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004021 CXXFunctionalCastExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004022 QualType ExplicitTy;
4023 {
4024 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004025
Douglas Gregora16548e2009-08-11 05:31:07 +00004026 ExplicitTy = getDerived().TransformType(E->getTypeAsWritten());
4027 if (ExplicitTy.isNull())
4028 return SemaRef.ExprError();
4029 }
Mike Stump11289f42009-09-09 15:08:12 +00004030
Douglas Gregora16548e2009-08-11 05:31:07 +00004031 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4032 if (SubExpr.isInvalid())
4033 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004034
Douglas Gregora16548e2009-08-11 05:31:07 +00004035 if (!getDerived().AlwaysRebuild() &&
4036 ExplicitTy == E->getTypeAsWritten() &&
4037 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004038 return SemaRef.Owned(E->Retain());
4039
Douglas Gregora16548e2009-08-11 05:31:07 +00004040 // FIXME: The end of the type's source range is wrong
4041 return getDerived().RebuildCXXFunctionalCastExpr(
4042 /*FIXME:*/SourceRange(E->getTypeBeginLoc()),
4043 ExplicitTy,
4044 /*FIXME:*/E->getSubExpr()->getLocStart(),
4045 move(SubExpr),
4046 E->getRParenLoc());
4047}
Mike Stump11289f42009-09-09 15:08:12 +00004048
Douglas Gregora16548e2009-08-11 05:31:07 +00004049template<typename Derived>
4050Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004051TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004052 if (E->isTypeOperand()) {
4053 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004054
Douglas Gregora16548e2009-08-11 05:31:07 +00004055 QualType T = getDerived().TransformType(E->getTypeOperand());
4056 if (T.isNull())
4057 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004058
Douglas Gregora16548e2009-08-11 05:31:07 +00004059 if (!getDerived().AlwaysRebuild() &&
4060 T == E->getTypeOperand())
4061 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004062
Douglas Gregora16548e2009-08-11 05:31:07 +00004063 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4064 /*FIXME:*/E->getLocStart(),
4065 T,
4066 E->getLocEnd());
4067 }
Mike Stump11289f42009-09-09 15:08:12 +00004068
Douglas Gregora16548e2009-08-11 05:31:07 +00004069 // We don't know whether the expression is potentially evaluated until
4070 // after we perform semantic analysis, so the expression is potentially
4071 // potentially evaluated.
Mike Stump11289f42009-09-09 15:08:12 +00004072 EnterExpressionEvaluationContext Unevaluated(SemaRef,
Douglas Gregora16548e2009-08-11 05:31:07 +00004073 Action::PotentiallyPotentiallyEvaluated);
Mike Stump11289f42009-09-09 15:08:12 +00004074
Douglas Gregora16548e2009-08-11 05:31:07 +00004075 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
4076 if (SubExpr.isInvalid())
4077 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004078
Douglas Gregora16548e2009-08-11 05:31:07 +00004079 if (!getDerived().AlwaysRebuild() &&
4080 SubExpr.get() == E->getExprOperand())
Mike Stump11289f42009-09-09 15:08:12 +00004081 return SemaRef.Owned(E->Retain());
4082
Douglas Gregora16548e2009-08-11 05:31:07 +00004083 return getDerived().RebuildCXXTypeidExpr(E->getLocStart(),
4084 /*FIXME:*/E->getLocStart(),
4085 move(SubExpr),
4086 E->getLocEnd());
4087}
4088
4089template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004090Sema::OwningExprResult
4091TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
4092 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004093}
Mike Stump11289f42009-09-09 15:08:12 +00004094
Douglas Gregora16548e2009-08-11 05:31:07 +00004095template<typename Derived>
4096Sema::OwningExprResult
4097TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004098 CXXNullPtrLiteralExpr *E) {
4099 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004100}
Mike Stump11289f42009-09-09 15:08:12 +00004101
Douglas Gregora16548e2009-08-11 05:31:07 +00004102template<typename Derived>
4103Sema::OwningExprResult
4104TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
4105 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004106
Douglas Gregora16548e2009-08-11 05:31:07 +00004107 QualType T = getDerived().TransformType(E->getType());
4108 if (T.isNull())
4109 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004110
Douglas Gregora16548e2009-08-11 05:31:07 +00004111 if (!getDerived().AlwaysRebuild() &&
4112 T == E->getType())
4113 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004114
Douglas Gregora16548e2009-08-11 05:31:07 +00004115 return getDerived().RebuildCXXThisExpr(E->getLocStart(), T);
4116}
Mike Stump11289f42009-09-09 15:08:12 +00004117
Douglas Gregora16548e2009-08-11 05:31:07 +00004118template<typename Derived>
4119Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004120TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004121 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4122 if (SubExpr.isInvalid())
4123 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004124
Douglas Gregora16548e2009-08-11 05:31:07 +00004125 if (!getDerived().AlwaysRebuild() &&
4126 SubExpr.get() == E->getSubExpr())
Mike Stump11289f42009-09-09 15:08:12 +00004127 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004128
4129 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), move(SubExpr));
4130}
Mike Stump11289f42009-09-09 15:08:12 +00004131
Douglas Gregora16548e2009-08-11 05:31:07 +00004132template<typename Derived>
4133Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004134TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
4135 ParmVarDecl *Param
Douglas Gregora16548e2009-08-11 05:31:07 +00004136 = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
4137 if (!Param)
4138 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004139
Douglas Gregora16548e2009-08-11 05:31:07 +00004140 if (getDerived().AlwaysRebuild() &&
4141 Param == E->getParam())
4142 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004143
Douglas Gregora16548e2009-08-11 05:31:07 +00004144 return getDerived().RebuildCXXDefaultArgExpr(Param);
4145}
Mike Stump11289f42009-09-09 15:08:12 +00004146
Douglas Gregora16548e2009-08-11 05:31:07 +00004147template<typename Derived>
4148Sema::OwningExprResult
4149TreeTransform<Derived>::TransformCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
4150 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4151
4152 QualType T = getDerived().TransformType(E->getType());
4153 if (T.isNull())
4154 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004155
Douglas Gregora16548e2009-08-11 05:31:07 +00004156 if (!getDerived().AlwaysRebuild() &&
4157 T == E->getType())
Mike Stump11289f42009-09-09 15:08:12 +00004158 return SemaRef.Owned(E->Retain());
4159
4160 return getDerived().RebuildCXXZeroInitValueExpr(E->getTypeBeginLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004161 /*FIXME:*/E->getTypeBeginLoc(),
4162 T,
4163 E->getRParenLoc());
4164}
Mike Stump11289f42009-09-09 15:08:12 +00004165
Douglas Gregora16548e2009-08-11 05:31:07 +00004166template<typename Derived>
4167Sema::OwningExprResult
4168TreeTransform<Derived>::TransformCXXConditionDeclExpr(CXXConditionDeclExpr *E) {
Mike Stump11289f42009-09-09 15:08:12 +00004169 VarDecl *Var
Douglas Gregorebe10102009-08-20 07:17:43 +00004170 = cast_or_null<VarDecl>(getDerived().TransformDefinition(E->getVarDecl()));
Douglas Gregora16548e2009-08-11 05:31:07 +00004171 if (!Var)
4172 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004173
Douglas Gregora16548e2009-08-11 05:31:07 +00004174 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004175 Var == E->getVarDecl())
Douglas Gregora16548e2009-08-11 05:31:07 +00004176 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004177
4178 return getDerived().RebuildCXXConditionDeclExpr(E->getStartLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004179 /*FIXME:*/E->getStartLoc(),
4180 Var);
4181}
Mike Stump11289f42009-09-09 15:08:12 +00004182
Douglas Gregora16548e2009-08-11 05:31:07 +00004183template<typename Derived>
4184Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004185TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004186 // Transform the type that we're allocating
4187 TemporaryBase Rebase(*this, E->getLocStart(), DeclarationName());
4188 QualType AllocType = getDerived().TransformType(E->getAllocatedType());
4189 if (AllocType.isNull())
4190 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004191
Douglas Gregora16548e2009-08-11 05:31:07 +00004192 // Transform the size of the array we're allocating (if any).
4193 OwningExprResult ArraySize = getDerived().TransformExpr(E->getArraySize());
4194 if (ArraySize.isInvalid())
4195 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004196
Douglas Gregora16548e2009-08-11 05:31:07 +00004197 // Transform the placement arguments (if any).
4198 bool ArgumentChanged = false;
4199 ASTOwningVector<&ActionBase::DeleteExpr> PlacementArgs(SemaRef);
4200 for (unsigned I = 0, N = E->getNumPlacementArgs(); I != N; ++I) {
4201 OwningExprResult Arg = getDerived().TransformExpr(E->getPlacementArg(I));
4202 if (Arg.isInvalid())
4203 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004204
Douglas Gregora16548e2009-08-11 05:31:07 +00004205 ArgumentChanged = ArgumentChanged || Arg.get() != E->getPlacementArg(I);
4206 PlacementArgs.push_back(Arg.take());
4207 }
Mike Stump11289f42009-09-09 15:08:12 +00004208
Douglas Gregorebe10102009-08-20 07:17:43 +00004209 // transform the constructor arguments (if any).
Douglas Gregora16548e2009-08-11 05:31:07 +00004210 ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(SemaRef);
4211 for (unsigned I = 0, N = E->getNumConstructorArgs(); I != N; ++I) {
4212 OwningExprResult Arg = getDerived().TransformExpr(E->getConstructorArg(I));
4213 if (Arg.isInvalid())
4214 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004215
Douglas Gregora16548e2009-08-11 05:31:07 +00004216 ArgumentChanged = ArgumentChanged || Arg.get() != E->getConstructorArg(I);
4217 ConstructorArgs.push_back(Arg.take());
4218 }
Mike Stump11289f42009-09-09 15:08:12 +00004219
Douglas Gregora16548e2009-08-11 05:31:07 +00004220 if (!getDerived().AlwaysRebuild() &&
4221 AllocType == E->getAllocatedType() &&
4222 ArraySize.get() == E->getArraySize() &&
4223 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004224 return SemaRef.Owned(E->Retain());
4225
Douglas Gregora16548e2009-08-11 05:31:07 +00004226 return getDerived().RebuildCXXNewExpr(E->getLocStart(),
4227 E->isGlobalNew(),
4228 /*FIXME:*/E->getLocStart(),
4229 move_arg(PlacementArgs),
4230 /*FIXME:*/E->getLocStart(),
4231 E->isParenTypeId(),
4232 AllocType,
4233 /*FIXME:*/E->getLocStart(),
4234 /*FIXME:*/SourceRange(),
4235 move(ArraySize),
4236 /*FIXME:*/E->getLocStart(),
4237 move_arg(ConstructorArgs),
Mike Stump11289f42009-09-09 15:08:12 +00004238 E->getLocEnd());
Douglas Gregora16548e2009-08-11 05:31:07 +00004239}
Mike Stump11289f42009-09-09 15:08:12 +00004240
Douglas Gregora16548e2009-08-11 05:31:07 +00004241template<typename Derived>
4242Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004243TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004244 OwningExprResult Operand = getDerived().TransformExpr(E->getArgument());
4245 if (Operand.isInvalid())
4246 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004247
Douglas Gregora16548e2009-08-11 05:31:07 +00004248 if (!getDerived().AlwaysRebuild() &&
Mike Stump11289f42009-09-09 15:08:12 +00004249 Operand.get() == E->getArgument())
4250 return SemaRef.Owned(E->Retain());
4251
Douglas Gregora16548e2009-08-11 05:31:07 +00004252 return getDerived().RebuildCXXDeleteExpr(E->getLocStart(),
4253 E->isGlobalDelete(),
4254 E->isArrayForm(),
4255 move(Operand));
4256}
Mike Stump11289f42009-09-09 15:08:12 +00004257
Douglas Gregora16548e2009-08-11 05:31:07 +00004258template<typename Derived>
4259Sema::OwningExprResult
Douglas Gregorad8a3362009-09-04 17:36:40 +00004260TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
4261 CXXPseudoDestructorExpr *E) {
4262 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4263 if (Base.isInvalid())
4264 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004265
Douglas Gregorad8a3362009-09-04 17:36:40 +00004266 NestedNameSpecifier *Qualifier
4267 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4268 E->getQualifierRange());
4269 if (E->getQualifier() && !Qualifier)
4270 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004271
Douglas Gregorad8a3362009-09-04 17:36:40 +00004272 QualType DestroyedType;
4273 {
4274 TemporaryBase Rebase(*this, E->getDestroyedTypeLoc(), DeclarationName());
4275 DestroyedType = getDerived().TransformType(E->getDestroyedType());
4276 if (DestroyedType.isNull())
4277 return SemaRef.ExprError();
4278 }
Mike Stump11289f42009-09-09 15:08:12 +00004279
Douglas Gregorad8a3362009-09-04 17:36:40 +00004280 if (!getDerived().AlwaysRebuild() &&
4281 Base.get() == E->getBase() &&
4282 Qualifier == E->getQualifier() &&
4283 DestroyedType == E->getDestroyedType())
4284 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004285
Douglas Gregorad8a3362009-09-04 17:36:40 +00004286 return getDerived().RebuildCXXPseudoDestructorExpr(move(Base),
4287 E->getOperatorLoc(),
4288 E->isArrow(),
4289 E->getDestroyedTypeLoc(),
4290 DestroyedType,
4291 Qualifier,
4292 E->getQualifierRange());
4293}
Mike Stump11289f42009-09-09 15:08:12 +00004294
Douglas Gregorad8a3362009-09-04 17:36:40 +00004295template<typename Derived>
4296Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004297TreeTransform<Derived>::TransformUnresolvedFunctionNameExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004298 UnresolvedFunctionNameExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004299 // There is no transformation we can apply to an unresolved function name.
Mike Stump11289f42009-09-09 15:08:12 +00004300 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004301}
Mike Stump11289f42009-09-09 15:08:12 +00004302
Douglas Gregora16548e2009-08-11 05:31:07 +00004303template<typename Derived>
4304Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004305TreeTransform<Derived>::TransformUnaryTypeTraitExpr(UnaryTypeTraitExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004306 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
Mike Stump11289f42009-09-09 15:08:12 +00004307
Douglas Gregora16548e2009-08-11 05:31:07 +00004308 QualType T = getDerived().TransformType(E->getQueriedType());
4309 if (T.isNull())
4310 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004311
Douglas Gregora16548e2009-08-11 05:31:07 +00004312 if (!getDerived().AlwaysRebuild() &&
4313 T == E->getQueriedType())
4314 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004315
Douglas Gregora16548e2009-08-11 05:31:07 +00004316 // FIXME: Bad location information
4317 SourceLocation FakeLParenLoc
4318 = SemaRef.PP.getLocForEndOfToken(E->getLocStart());
Mike Stump11289f42009-09-09 15:08:12 +00004319
4320 return getDerived().RebuildUnaryTypeTrait(E->getTrait(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004321 E->getLocStart(),
4322 /*FIXME:*/FakeLParenLoc,
4323 T,
4324 E->getLocEnd());
4325}
Mike Stump11289f42009-09-09 15:08:12 +00004326
Douglas Gregora16548e2009-08-11 05:31:07 +00004327template<typename Derived>
4328Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004329TreeTransform<Derived>::TransformUnresolvedDeclRefExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004330 UnresolvedDeclRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004331 NestedNameSpecifier *NNS
Douglas Gregord019ff62009-10-22 17:20:55 +00004332 = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4333 E->getQualifierRange());
Douglas Gregora16548e2009-08-11 05:31:07 +00004334 if (!NNS)
4335 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004336
4337 DeclarationName Name
Douglas Gregorf816bd72009-09-03 22:13:48 +00004338 = getDerived().TransformDeclarationName(E->getDeclName(), E->getLocation());
4339 if (!Name)
4340 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004341
4342 if (!getDerived().AlwaysRebuild() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00004343 NNS == E->getQualifier() &&
4344 Name == E->getDeclName())
Mike Stump11289f42009-09-09 15:08:12 +00004345 return SemaRef.Owned(E->Retain());
4346
4347 return getDerived().RebuildUnresolvedDeclRefExpr(NNS,
Douglas Gregora16548e2009-08-11 05:31:07 +00004348 E->getQualifierRange(),
4349 Name,
4350 E->getLocation(),
4351 /*FIXME:*/false);
4352}
4353
4354template<typename Derived>
4355Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004356TreeTransform<Derived>::TransformTemplateIdRefExpr(TemplateIdRefExpr *E) {
4357 TemplateName Template
Douglas Gregora16548e2009-08-11 05:31:07 +00004358 = getDerived().TransformTemplateName(E->getTemplateName());
4359 if (Template.isNull())
4360 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004361
Douglas Gregord019ff62009-10-22 17:20:55 +00004362 NestedNameSpecifier *Qualifier = 0;
4363 if (E->getQualifier()) {
4364 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4365 E->getQualifierRange());
4366 if (!Qualifier)
4367 return SemaRef.ExprError();
4368 }
4369
Douglas Gregora16548e2009-08-11 05:31:07 +00004370 llvm::SmallVector<TemplateArgument, 4> TransArgs;
4371 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +00004372 TemplateArgument TransArg
Douglas Gregora16548e2009-08-11 05:31:07 +00004373 = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
4374 if (TransArg.isNull())
4375 return SemaRef.ExprError();
4376
4377 TransArgs.push_back(TransArg);
4378 }
4379
4380 // FIXME: Would like to avoid rebuilding if nothing changed, but we can't
4381 // compare template arguments (yet).
Mike Stump11289f42009-09-09 15:08:12 +00004382
4383 // FIXME: It's possible that we'll find out now that the template name
Douglas Gregora16548e2009-08-11 05:31:07 +00004384 // actually refers to a type, in which case the caller is actually dealing
4385 // with a functional cast. Give a reasonable error message!
Douglas Gregord019ff62009-10-22 17:20:55 +00004386 return getDerived().RebuildTemplateIdExpr(Qualifier, E->getQualifierRange(),
4387 Template, E->getTemplateNameLoc(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004388 E->getLAngleLoc(),
4389 TransArgs.data(),
4390 TransArgs.size(),
4391 E->getRAngleLoc());
4392}
4393
4394template<typename Derived>
4395Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004396TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004397 TemporaryBase Rebase(*this, /*FIXME*/E->getLocStart(), DeclarationName());
4398
4399 QualType T = getDerived().TransformType(E->getType());
4400 if (T.isNull())
4401 return SemaRef.ExprError();
4402
4403 CXXConstructorDecl *Constructor
4404 = cast_or_null<CXXConstructorDecl>(
4405 getDerived().TransformDecl(E->getConstructor()));
4406 if (!Constructor)
4407 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004408
Douglas Gregora16548e2009-08-11 05:31:07 +00004409 bool ArgumentChanged = false;
4410 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
Mike Stump11289f42009-09-09 15:08:12 +00004411 for (CXXConstructExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004412 ArgEnd = E->arg_end();
4413 Arg != ArgEnd; ++Arg) {
4414 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4415 if (TransArg.isInvalid())
4416 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004417
Douglas Gregora16548e2009-08-11 05:31:07 +00004418 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4419 Args.push_back(TransArg.takeAs<Expr>());
4420 }
4421
4422 if (!getDerived().AlwaysRebuild() &&
4423 T == E->getType() &&
4424 Constructor == E->getConstructor() &&
4425 !ArgumentChanged)
4426 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004427
Douglas Gregora16548e2009-08-11 05:31:07 +00004428 return getDerived().RebuildCXXConstructExpr(T, Constructor, E->isElidable(),
4429 move_arg(Args));
4430}
Mike Stump11289f42009-09-09 15:08:12 +00004431
Douglas Gregora16548e2009-08-11 05:31:07 +00004432/// \brief Transform a C++ temporary-binding expression.
4433///
Mike Stump11289f42009-09-09 15:08:12 +00004434/// The transformation of a temporary-binding expression always attempts to
4435/// bind a new temporary variable to its subexpression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004436/// subexpression itself did not change, because the temporary variable itself
4437/// must be unique.
4438template<typename Derived>
4439Sema::OwningExprResult
4440TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
4441 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4442 if (SubExpr.isInvalid())
4443 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004444
Douglas Gregora16548e2009-08-11 05:31:07 +00004445 return SemaRef.MaybeBindToTemporary(SubExpr.takeAs<Expr>());
4446}
Mike Stump11289f42009-09-09 15:08:12 +00004447
4448/// \brief Transform a C++ expression that contains temporaries that should
Douglas Gregora16548e2009-08-11 05:31:07 +00004449/// be destroyed after the expression is evaluated.
4450///
Mike Stump11289f42009-09-09 15:08:12 +00004451/// The transformation of a full expression always attempts to build a new
4452/// CXXExprWithTemporaries expression, even if the
Douglas Gregora16548e2009-08-11 05:31:07 +00004453/// subexpression itself did not change, because it will need to capture the
4454/// the new temporary variables introduced in the subexpression.
4455template<typename Derived>
4456Sema::OwningExprResult
4457TreeTransform<Derived>::TransformCXXExprWithTemporaries(
Mike Stump11289f42009-09-09 15:08:12 +00004458 CXXExprWithTemporaries *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004459 OwningExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
4460 if (SubExpr.isInvalid())
4461 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004462
Douglas Gregora16548e2009-08-11 05:31:07 +00004463 return SemaRef.Owned(
4464 SemaRef.MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>(),
4465 E->shouldDestroyTemporaries()));
4466}
Mike Stump11289f42009-09-09 15:08:12 +00004467
Douglas Gregora16548e2009-08-11 05:31:07 +00004468template<typename Derived>
4469Sema::OwningExprResult
4470TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004471 CXXTemporaryObjectExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004472 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4473 QualType T = getDerived().TransformType(E->getType());
4474 if (T.isNull())
4475 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004476
Douglas Gregora16548e2009-08-11 05:31:07 +00004477 CXXConstructorDecl *Constructor
4478 = cast_or_null<CXXConstructorDecl>(
4479 getDerived().TransformDecl(E->getConstructor()));
4480 if (!Constructor)
4481 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004482
Douglas Gregora16548e2009-08-11 05:31:07 +00004483 bool ArgumentChanged = false;
4484 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4485 Args.reserve(E->getNumArgs());
Mike Stump11289f42009-09-09 15:08:12 +00004486 for (CXXTemporaryObjectExpr::arg_iterator Arg = E->arg_begin(),
Douglas Gregora16548e2009-08-11 05:31:07 +00004487 ArgEnd = E->arg_end();
4488 Arg != ArgEnd; ++Arg) {
4489 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4490 if (TransArg.isInvalid())
4491 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004492
Douglas Gregora16548e2009-08-11 05:31:07 +00004493 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4494 Args.push_back((Expr *)TransArg.release());
4495 }
Mike Stump11289f42009-09-09 15:08:12 +00004496
Douglas Gregora16548e2009-08-11 05:31:07 +00004497 if (!getDerived().AlwaysRebuild() &&
4498 T == E->getType() &&
4499 Constructor == E->getConstructor() &&
4500 !ArgumentChanged)
4501 return SemaRef.Owned(E->Retain());
Mike Stump11289f42009-09-09 15:08:12 +00004502
Douglas Gregora16548e2009-08-11 05:31:07 +00004503 // FIXME: Bogus location information
4504 SourceLocation CommaLoc;
4505 if (Args.size() > 1) {
4506 Expr *First = (Expr *)Args[0];
Mike Stump11289f42009-09-09 15:08:12 +00004507 CommaLoc
Douglas Gregora16548e2009-08-11 05:31:07 +00004508 = SemaRef.PP.getLocForEndOfToken(First->getSourceRange().getEnd());
4509 }
4510 return getDerived().RebuildCXXTemporaryObjectExpr(E->getTypeBeginLoc(),
4511 T,
4512 /*FIXME:*/E->getTypeBeginLoc(),
4513 move_arg(Args),
4514 &CommaLoc,
4515 E->getLocEnd());
4516}
Mike Stump11289f42009-09-09 15:08:12 +00004517
Douglas Gregora16548e2009-08-11 05:31:07 +00004518template<typename Derived>
4519Sema::OwningExprResult
4520TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004521 CXXUnresolvedConstructExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004522 TemporaryBase Rebase(*this, E->getTypeBeginLoc(), DeclarationName());
4523 QualType T = getDerived().TransformType(E->getTypeAsWritten());
4524 if (T.isNull())
4525 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004526
Douglas Gregora16548e2009-08-11 05:31:07 +00004527 bool ArgumentChanged = false;
4528 ASTOwningVector<&ActionBase::DeleteExpr> Args(SemaRef);
4529 llvm::SmallVector<SourceLocation, 8> FakeCommaLocs;
4530 for (CXXUnresolvedConstructExpr::arg_iterator Arg = E->arg_begin(),
4531 ArgEnd = E->arg_end();
4532 Arg != ArgEnd; ++Arg) {
4533 OwningExprResult TransArg = getDerived().TransformExpr(*Arg);
4534 if (TransArg.isInvalid())
4535 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004536
Douglas Gregora16548e2009-08-11 05:31:07 +00004537 ArgumentChanged = ArgumentChanged || TransArg.get() != *Arg;
4538 FakeCommaLocs.push_back(
4539 SemaRef.PP.getLocForEndOfToken((*Arg)->getLocEnd()));
4540 Args.push_back(TransArg.takeAs<Expr>());
4541 }
Mike Stump11289f42009-09-09 15:08:12 +00004542
Douglas Gregora16548e2009-08-11 05:31:07 +00004543 if (!getDerived().AlwaysRebuild() &&
4544 T == E->getTypeAsWritten() &&
4545 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004546 return SemaRef.Owned(E->Retain());
4547
Douglas Gregora16548e2009-08-11 05:31:07 +00004548 // FIXME: we're faking the locations of the commas
4549 return getDerived().RebuildCXXUnresolvedConstructExpr(E->getTypeBeginLoc(),
4550 T,
4551 E->getLParenLoc(),
4552 move_arg(Args),
4553 FakeCommaLocs.data(),
4554 E->getRParenLoc());
4555}
Mike Stump11289f42009-09-09 15:08:12 +00004556
Douglas Gregora16548e2009-08-11 05:31:07 +00004557template<typename Derived>
4558Sema::OwningExprResult
4559TreeTransform<Derived>::TransformCXXUnresolvedMemberExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004560 CXXUnresolvedMemberExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004561 // Transform the base of the expression.
4562 OwningExprResult Base = getDerived().TransformExpr(E->getBase());
4563 if (Base.isInvalid())
4564 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004565
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004566 // Start the member reference and compute the object's type.
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004567 Sema::TypeTy *ObjectType = 0;
Mike Stump11289f42009-09-09 15:08:12 +00004568 Base = SemaRef.ActOnStartCXXMemberReference(0, move(Base),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004569 E->getOperatorLoc(),
4570 E->isArrow()? tok::arrow : tok::period,
4571 ObjectType);
4572 if (Base.isInvalid())
4573 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004574
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004575 // Transform the first part of the nested-name-specifier that qualifies
4576 // the member name.
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004577 NamedDecl *FirstQualifierInScope
Douglas Gregora5cb6da2009-10-20 05:58:46 +00004578 = getDerived().TransformFirstQualifierInScope(
4579 E->getFirstQualifierFoundInScope(),
4580 E->getQualifierRange().getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00004581
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004582 NestedNameSpecifier *Qualifier = 0;
4583 if (E->getQualifier()) {
4584 Qualifier = getDerived().TransformNestedNameSpecifier(E->getQualifier(),
4585 E->getQualifierRange(),
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004586 QualType::getFromOpaquePtr(ObjectType),
4587 FirstQualifierInScope);
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004588 if (!Qualifier)
4589 return SemaRef.ExprError();
4590 }
Mike Stump11289f42009-09-09 15:08:12 +00004591
4592 DeclarationName Name
Douglas Gregorc59e5612009-10-19 22:04:39 +00004593 = getDerived().TransformDeclarationName(E->getMember(), E->getMemberLoc(),
4594 QualType::getFromOpaquePtr(ObjectType));
Douglas Gregorf816bd72009-09-03 22:13:48 +00004595 if (!Name)
4596 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004597
Douglas Gregor308047d2009-09-09 00:23:06 +00004598 if (!E->hasExplicitTemplateArgumentList()) {
4599 // This is a reference to a member without an explicitly-specified
4600 // template argument list. Optimize for this common case.
4601 if (!getDerived().AlwaysRebuild() &&
4602 Base.get() == E->getBase() &&
4603 Qualifier == E->getQualifier() &&
4604 Name == E->getMember() &&
4605 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
Mike Stump11289f42009-09-09 15:08:12 +00004606 return SemaRef.Owned(E->Retain());
4607
Douglas Gregor308047d2009-09-09 00:23:06 +00004608 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4609 E->isArrow(),
4610 E->getOperatorLoc(),
4611 Qualifier,
4612 E->getQualifierRange(),
4613 Name,
4614 E->getMemberLoc(),
4615 FirstQualifierInScope);
4616 }
4617
4618 // FIXME: This is an ugly hack, which forces the same template name to
4619 // be looked up multiple times. Yuck!
4620 // FIXME: This also won't work for, e.g., x->template operator+<int>
4621 TemplateName OrigTemplateName
4622 = SemaRef.Context.getDependentTemplateName(0, Name.getAsIdentifierInfo());
Mike Stump11289f42009-09-09 15:08:12 +00004623
4624 TemplateName Template
4625 = getDerived().TransformTemplateName(OrigTemplateName,
Douglas Gregor308047d2009-09-09 00:23:06 +00004626 QualType::getFromOpaquePtr(ObjectType));
4627 if (Template.isNull())
4628 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004629
Douglas Gregor308047d2009-09-09 00:23:06 +00004630 llvm::SmallVector<TemplateArgument, 4> TransArgs;
4631 for (unsigned I = 0, N = E->getNumTemplateArgs(); I != N; ++I) {
Mike Stump11289f42009-09-09 15:08:12 +00004632 TemplateArgument TransArg
Douglas Gregor308047d2009-09-09 00:23:06 +00004633 = getDerived().TransformTemplateArgument(E->getTemplateArgs()[I]);
4634 if (TransArg.isNull())
4635 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004636
Douglas Gregor308047d2009-09-09 00:23:06 +00004637 TransArgs.push_back(TransArg);
4638 }
Mike Stump11289f42009-09-09 15:08:12 +00004639
Douglas Gregora16548e2009-08-11 05:31:07 +00004640 return getDerived().RebuildCXXUnresolvedMemberExpr(move(Base),
4641 E->isArrow(),
4642 E->getOperatorLoc(),
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004643 Qualifier,
4644 E->getQualifierRange(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004645 Template,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004646 E->getMemberLoc(),
Douglas Gregor308047d2009-09-09 00:23:06 +00004647 FirstQualifierInScope,
4648 E->getLAngleLoc(),
4649 TransArgs.data(),
4650 TransArgs.size(),
4651 E->getRAngleLoc());
Douglas Gregora16548e2009-08-11 05:31:07 +00004652}
4653
4654template<typename Derived>
4655Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004656TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
4657 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004658}
4659
Mike Stump11289f42009-09-09 15:08:12 +00004660template<typename Derived>
4661Sema::OwningExprResult
4662TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004663 // FIXME: poor source location
4664 TemporaryBase Rebase(*this, E->getAtLoc(), DeclarationName());
4665 QualType EncodedType = getDerived().TransformType(E->getEncodedType());
4666 if (EncodedType.isNull())
4667 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004668
Douglas Gregora16548e2009-08-11 05:31:07 +00004669 if (!getDerived().AlwaysRebuild() &&
4670 EncodedType == E->getEncodedType())
Mike Stump11289f42009-09-09 15:08:12 +00004671 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004672
4673 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
4674 EncodedType,
4675 E->getRParenLoc());
4676}
Mike Stump11289f42009-09-09 15:08:12 +00004677
Douglas Gregora16548e2009-08-11 05:31:07 +00004678template<typename Derived>
4679Sema::OwningExprResult
Mike Stump11289f42009-09-09 15:08:12 +00004680TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004681 // FIXME: Implement this!
4682 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004683 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004684}
4685
Mike Stump11289f42009-09-09 15:08:12 +00004686template<typename Derived>
4687Sema::OwningExprResult
4688TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
4689 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004690}
4691
Mike Stump11289f42009-09-09 15:08:12 +00004692template<typename Derived>
4693Sema::OwningExprResult
4694TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
4695 ObjCProtocolDecl *Protocol
Douglas Gregora16548e2009-08-11 05:31:07 +00004696 = cast_or_null<ObjCProtocolDecl>(
4697 getDerived().TransformDecl(E->getProtocol()));
4698 if (!Protocol)
4699 return SemaRef.ExprError();
4700
4701 if (!getDerived().AlwaysRebuild() &&
4702 Protocol == E->getProtocol())
Mike Stump11289f42009-09-09 15:08:12 +00004703 return SemaRef.Owned(E->Retain());
4704
Douglas Gregora16548e2009-08-11 05:31:07 +00004705 return getDerived().RebuildObjCProtocolExpr(Protocol,
4706 E->getAtLoc(),
4707 /*FIXME:*/E->getAtLoc(),
4708 /*FIXME:*/E->getAtLoc(),
4709 E->getRParenLoc());
Mike Stump11289f42009-09-09 15:08:12 +00004710
Douglas Gregora16548e2009-08-11 05:31:07 +00004711}
4712
Mike Stump11289f42009-09-09 15:08:12 +00004713template<typename Derived>
4714Sema::OwningExprResult
4715TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004716 // FIXME: Implement this!
4717 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004718 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004719}
4720
Mike Stump11289f42009-09-09 15:08:12 +00004721template<typename Derived>
4722Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00004723TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
4724 // FIXME: Implement this!
4725 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004726 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004727}
4728
Mike Stump11289f42009-09-09 15:08:12 +00004729template<typename Derived>
4730Sema::OwningExprResult
Fariborz Jahanian9a846652009-08-20 17:02:02 +00004731TreeTransform<Derived>::TransformObjCImplicitSetterGetterRefExpr(
Mike Stump11289f42009-09-09 15:08:12 +00004732 ObjCImplicitSetterGetterRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004733 // FIXME: Implement this!
4734 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004735 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004736}
4737
Mike Stump11289f42009-09-09 15:08:12 +00004738template<typename Derived>
4739Sema::OwningExprResult
4740TreeTransform<Derived>::TransformObjCSuperExpr(ObjCSuperExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004741 // FIXME: Implement this!
4742 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004743 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004744}
4745
Mike Stump11289f42009-09-09 15:08:12 +00004746template<typename Derived>
4747Sema::OwningExprResult
4748TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004749 // FIXME: Implement this!
4750 assert(false && "Cannot transform Objective-C expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004751 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004752}
4753
Mike Stump11289f42009-09-09 15:08:12 +00004754template<typename Derived>
4755Sema::OwningExprResult
4756TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004757 bool ArgumentChanged = false;
4758 ASTOwningVector<&ActionBase::DeleteExpr> SubExprs(SemaRef);
4759 for (unsigned I = 0, N = E->getNumSubExprs(); I != N; ++I) {
4760 OwningExprResult SubExpr = getDerived().TransformExpr(E->getExpr(I));
4761 if (SubExpr.isInvalid())
4762 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00004763
Douglas Gregora16548e2009-08-11 05:31:07 +00004764 ArgumentChanged = ArgumentChanged || SubExpr.get() != E->getExpr(I);
4765 SubExprs.push_back(SubExpr.takeAs<Expr>());
4766 }
Mike Stump11289f42009-09-09 15:08:12 +00004767
Douglas Gregora16548e2009-08-11 05:31:07 +00004768 if (!getDerived().AlwaysRebuild() &&
4769 !ArgumentChanged)
Mike Stump11289f42009-09-09 15:08:12 +00004770 return SemaRef.Owned(E->Retain());
4771
Douglas Gregora16548e2009-08-11 05:31:07 +00004772 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
4773 move_arg(SubExprs),
4774 E->getRParenLoc());
4775}
4776
Mike Stump11289f42009-09-09 15:08:12 +00004777template<typename Derived>
4778Sema::OwningExprResult
4779TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004780 // FIXME: Implement this!
4781 assert(false && "Cannot transform block expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004782 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004783}
4784
Mike Stump11289f42009-09-09 15:08:12 +00004785template<typename Derived>
4786Sema::OwningExprResult
4787TreeTransform<Derived>::TransformBlockDeclRefExpr(BlockDeclRefExpr *E) {
Douglas Gregora16548e2009-08-11 05:31:07 +00004788 // FIXME: Implement this!
4789 assert(false && "Cannot transform block-related expressions yet");
Mike Stump11289f42009-09-09 15:08:12 +00004790 return SemaRef.Owned(E->Retain());
Douglas Gregora16548e2009-08-11 05:31:07 +00004791}
Mike Stump11289f42009-09-09 15:08:12 +00004792
Douglas Gregora16548e2009-08-11 05:31:07 +00004793//===----------------------------------------------------------------------===//
Douglas Gregord6ff3322009-08-04 16:50:30 +00004794// Type reconstruction
4795//===----------------------------------------------------------------------===//
4796
Mike Stump11289f42009-09-09 15:08:12 +00004797template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00004798QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004799 return SemaRef.BuildPointerType(PointeeType, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004800 getDerived().getBaseLocation(),
4801 getDerived().getBaseEntity());
4802}
4803
Mike Stump11289f42009-09-09 15:08:12 +00004804template<typename Derived>
Douglas Gregord6ff3322009-08-04 16:50:30 +00004805QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004806 return SemaRef.BuildBlockPointerType(PointeeType, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004807 getDerived().getBaseLocation(),
4808 getDerived().getBaseEntity());
4809}
4810
Mike Stump11289f42009-09-09 15:08:12 +00004811template<typename Derived>
4812QualType
Douglas Gregord6ff3322009-08-04 16:50:30 +00004813TreeTransform<Derived>::RebuildLValueReferenceType(QualType ReferentType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004814 return SemaRef.BuildReferenceType(ReferentType, true, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004815 getDerived().getBaseLocation(),
4816 getDerived().getBaseEntity());
4817}
4818
4819template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004820QualType
4821TreeTransform<Derived>::RebuildRValueReferenceType(QualType ReferentType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004822 return SemaRef.BuildReferenceType(ReferentType, false, Qualifiers(),
Mike Stump11289f42009-09-09 15:08:12 +00004823 getDerived().getBaseLocation(),
4824 getDerived().getBaseEntity());
4825}
4826
4827template<typename Derived>
4828QualType TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004829 QualType ClassType) {
John McCall8ccfcb52009-09-24 19:53:00 +00004830 return SemaRef.BuildMemberPointerType(PointeeType, ClassType, Qualifiers(),
Douglas Gregord6ff3322009-08-04 16:50:30 +00004831 getDerived().getBaseLocation(),
4832 getDerived().getBaseEntity());
4833}
4834
4835template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004836QualType
John McCall550e0c22009-10-21 00:40:46 +00004837TreeTransform<Derived>::RebuildObjCObjectPointerType(QualType PointeeType) {
4838 return SemaRef.BuildPointerType(PointeeType, Qualifiers(),
4839 getDerived().getBaseLocation(),
4840 getDerived().getBaseEntity());
4841}
4842
4843template<typename Derived>
4844QualType
Douglas Gregord6ff3322009-08-04 16:50:30 +00004845TreeTransform<Derived>::RebuildArrayType(QualType ElementType,
4846 ArrayType::ArraySizeModifier SizeMod,
4847 const llvm::APInt *Size,
4848 Expr *SizeExpr,
4849 unsigned IndexTypeQuals,
4850 SourceRange BracketsRange) {
4851 if (SizeExpr || !Size)
4852 return SemaRef.BuildArrayType(ElementType, SizeMod, SizeExpr,
4853 IndexTypeQuals, BracketsRange,
4854 getDerived().getBaseEntity());
Mike Stump11289f42009-09-09 15:08:12 +00004855
4856 QualType Types[] = {
4857 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
4858 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
4859 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
Douglas Gregord6ff3322009-08-04 16:50:30 +00004860 };
4861 const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
4862 QualType SizeType;
4863 for (unsigned I = 0; I != NumTypes; ++I)
4864 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
4865 SizeType = Types[I];
4866 break;
4867 }
Mike Stump11289f42009-09-09 15:08:12 +00004868
Douglas Gregord6ff3322009-08-04 16:50:30 +00004869 if (SizeType.isNull())
4870 SizeType = SemaRef.Context.getFixedWidthIntType(Size->getBitWidth(), false);
Mike Stump11289f42009-09-09 15:08:12 +00004871
Douglas Gregord6ff3322009-08-04 16:50:30 +00004872 IntegerLiteral ArraySize(*Size, SizeType, /*FIXME*/BracketsRange.getBegin());
Mike Stump11289f42009-09-09 15:08:12 +00004873 return SemaRef.BuildArrayType(ElementType, SizeMod, &ArraySize,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004874 IndexTypeQuals, BracketsRange,
Mike Stump11289f42009-09-09 15:08:12 +00004875 getDerived().getBaseEntity());
Douglas Gregord6ff3322009-08-04 16:50:30 +00004876}
Mike Stump11289f42009-09-09 15:08:12 +00004877
Douglas Gregord6ff3322009-08-04 16:50:30 +00004878template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004879QualType
4880TreeTransform<Derived>::RebuildConstantArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004881 ArrayType::ArraySizeModifier SizeMod,
4882 const llvm::APInt &Size,
4883 unsigned IndexTypeQuals) {
Mike Stump11289f42009-09-09 15:08:12 +00004884 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004885 IndexTypeQuals, SourceRange());
4886}
4887
4888template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004889QualType
Mike Stump11289f42009-09-09 15:08:12 +00004890TreeTransform<Derived>::RebuildIncompleteArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004891 ArrayType::ArraySizeModifier SizeMod,
4892 unsigned IndexTypeQuals) {
Mike Stump11289f42009-09-09 15:08:12 +00004893 return getDerived().RebuildArrayType(ElementType, SizeMod, 0, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004894 IndexTypeQuals, SourceRange());
4895}
Mike Stump11289f42009-09-09 15:08:12 +00004896
Douglas Gregord6ff3322009-08-04 16:50:30 +00004897template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004898QualType
4899TreeTransform<Derived>::RebuildVariableArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004900 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00004901 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004902 unsigned IndexTypeQuals,
4903 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00004904 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004905 SizeExpr.takeAs<Expr>(),
4906 IndexTypeQuals, BracketsRange);
4907}
4908
4909template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004910QualType
4911TreeTransform<Derived>::RebuildDependentSizedArrayType(QualType ElementType,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004912 ArrayType::ArraySizeModifier SizeMod,
Douglas Gregora16548e2009-08-11 05:31:07 +00004913 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004914 unsigned IndexTypeQuals,
4915 SourceRange BracketsRange) {
Mike Stump11289f42009-09-09 15:08:12 +00004916 return getDerived().RebuildArrayType(ElementType, SizeMod, 0,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004917 SizeExpr.takeAs<Expr>(),
4918 IndexTypeQuals, BracketsRange);
4919}
4920
4921template<typename Derived>
4922QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
4923 unsigned NumElements) {
4924 // FIXME: semantic checking!
4925 return SemaRef.Context.getVectorType(ElementType, NumElements);
4926}
Mike Stump11289f42009-09-09 15:08:12 +00004927
Douglas Gregord6ff3322009-08-04 16:50:30 +00004928template<typename Derived>
4929QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
4930 unsigned NumElements,
4931 SourceLocation AttributeLoc) {
4932 llvm::APInt numElements(SemaRef.Context.getIntWidth(SemaRef.Context.IntTy),
4933 NumElements, true);
4934 IntegerLiteral *VectorSize
Mike Stump11289f42009-09-09 15:08:12 +00004935 = new (SemaRef.Context) IntegerLiteral(numElements, SemaRef.Context.IntTy,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004936 AttributeLoc);
4937 return SemaRef.BuildExtVectorType(ElementType, SemaRef.Owned(VectorSize),
4938 AttributeLoc);
4939}
Mike Stump11289f42009-09-09 15:08:12 +00004940
Douglas Gregord6ff3322009-08-04 16:50:30 +00004941template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00004942QualType
4943TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
Douglas Gregora16548e2009-08-11 05:31:07 +00004944 ExprArg SizeExpr,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004945 SourceLocation AttributeLoc) {
4946 return SemaRef.BuildExtVectorType(ElementType, move(SizeExpr), AttributeLoc);
4947}
Mike Stump11289f42009-09-09 15:08:12 +00004948
Douglas Gregord6ff3322009-08-04 16:50:30 +00004949template<typename Derived>
4950QualType TreeTransform<Derived>::RebuildFunctionProtoType(QualType T,
Mike Stump11289f42009-09-09 15:08:12 +00004951 QualType *ParamTypes,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004952 unsigned NumParamTypes,
Mike Stump11289f42009-09-09 15:08:12 +00004953 bool Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004954 unsigned Quals) {
Mike Stump11289f42009-09-09 15:08:12 +00004955 return SemaRef.BuildFunctionType(T, ParamTypes, NumParamTypes, Variadic,
Douglas Gregord6ff3322009-08-04 16:50:30 +00004956 Quals,
4957 getDerived().getBaseLocation(),
4958 getDerived().getBaseEntity());
4959}
Mike Stump11289f42009-09-09 15:08:12 +00004960
Douglas Gregord6ff3322009-08-04 16:50:30 +00004961template<typename Derived>
John McCall550e0c22009-10-21 00:40:46 +00004962QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
4963 return SemaRef.Context.getFunctionNoProtoType(T);
4964}
4965
4966template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00004967QualType TreeTransform<Derived>::RebuildTypeOfExprType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00004968 return SemaRef.BuildTypeofExprType(E.takeAs<Expr>());
4969}
4970
4971template<typename Derived>
4972QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying) {
4973 return SemaRef.Context.getTypeOfType(Underlying);
4974}
4975
4976template<typename Derived>
Douglas Gregora16548e2009-08-11 05:31:07 +00004977QualType TreeTransform<Derived>::RebuildDecltypeType(ExprArg E) {
Douglas Gregord6ff3322009-08-04 16:50:30 +00004978 return SemaRef.BuildDecltypeType(E.takeAs<Expr>());
4979}
4980
4981template<typename Derived>
4982QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
4983 TemplateName Template,
4984 const TemplateArgument *Args,
4985 unsigned NumArgs) {
4986 // FIXME: Missing source locations for the template name, <, >.
4987 return SemaRef.CheckTemplateIdType(Template, getDerived().getBaseLocation(),
Mike Stump11289f42009-09-09 15:08:12 +00004988 SourceLocation(), Args, NumArgs,
4989 SourceLocation());
Douglas Gregord6ff3322009-08-04 16:50:30 +00004990}
Mike Stump11289f42009-09-09 15:08:12 +00004991
Douglas Gregor1135c352009-08-06 05:28:30 +00004992template<typename Derived>
4993NestedNameSpecifier *
4994TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
4995 SourceRange Range,
Douglas Gregorc26e0f62009-09-03 16:14:30 +00004996 IdentifierInfo &II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00004997 QualType ObjectType,
4998 NamedDecl *FirstQualifierInScope) {
Douglas Gregor1135c352009-08-06 05:28:30 +00004999 CXXScopeSpec SS;
5000 // FIXME: The source location information is all wrong.
5001 SS.setRange(Range);
5002 SS.setScopeRep(Prefix);
5003 return static_cast<NestedNameSpecifier *>(
Mike Stump11289f42009-09-09 15:08:12 +00005004 SemaRef.BuildCXXNestedNameSpecifier(0, SS, Range.getEnd(),
Douglas Gregore861bac2009-08-25 22:51:20 +00005005 Range.getEnd(), II,
Douglas Gregor2b6ca462009-09-03 21:38:09 +00005006 ObjectType,
5007 FirstQualifierInScope,
Douglas Gregore861bac2009-08-25 22:51:20 +00005008 false));
Douglas Gregor1135c352009-08-06 05:28:30 +00005009}
5010
5011template<typename Derived>
5012NestedNameSpecifier *
5013TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5014 SourceRange Range,
5015 NamespaceDecl *NS) {
5016 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, NS);
5017}
5018
5019template<typename Derived>
5020NestedNameSpecifier *
5021TreeTransform<Derived>::RebuildNestedNameSpecifier(NestedNameSpecifier *Prefix,
5022 SourceRange Range,
5023 bool TemplateKW,
5024 QualType T) {
5025 if (T->isDependentType() || T->isRecordType() ||
5026 (SemaRef.getLangOptions().CPlusPlus0x && T->isEnumeralType())) {
John McCall8ccfcb52009-09-24 19:53:00 +00005027 assert(!T.hasQualifiers() && "Can't get cv-qualifiers here");
Douglas Gregor1135c352009-08-06 05:28:30 +00005028 return NestedNameSpecifier::Create(SemaRef.Context, Prefix, TemplateKW,
5029 T.getTypePtr());
5030 }
Mike Stump11289f42009-09-09 15:08:12 +00005031
Douglas Gregor1135c352009-08-06 05:28:30 +00005032 SemaRef.Diag(Range.getBegin(), diag::err_nested_name_spec_non_tag) << T;
5033 return 0;
5034}
Mike Stump11289f42009-09-09 15:08:12 +00005035
Douglas Gregor71dc5092009-08-06 06:41:21 +00005036template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005037TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005038TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5039 bool TemplateKW,
5040 TemplateDecl *Template) {
Mike Stump11289f42009-09-09 15:08:12 +00005041 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW,
Douglas Gregor71dc5092009-08-06 06:41:21 +00005042 Template);
5043}
5044
5045template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005046TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005047TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
5048 bool TemplateKW,
5049 OverloadedFunctionDecl *Ovl) {
5050 return SemaRef.Context.getQualifiedTemplateName(Qualifier, TemplateKW, Ovl);
5051}
5052
5053template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005054TemplateName
Douglas Gregor71dc5092009-08-06 06:41:21 +00005055TreeTransform<Derived>::RebuildTemplateName(NestedNameSpecifier *Qualifier,
Douglas Gregor308047d2009-09-09 00:23:06 +00005056 const IdentifierInfo &II,
5057 QualType ObjectType) {
Douglas Gregor71dc5092009-08-06 06:41:21 +00005058 CXXScopeSpec SS;
5059 SS.setRange(SourceRange(getDerived().getBaseLocation()));
Mike Stump11289f42009-09-09 15:08:12 +00005060 SS.setScopeRep(Qualifier);
Douglas Gregor308047d2009-09-09 00:23:06 +00005061 return getSema().ActOnDependentTemplateName(
5062 /*FIXME:*/getDerived().getBaseLocation(),
5063 II,
5064 /*FIXME:*/getDerived().getBaseLocation(),
5065 SS,
5066 ObjectType.getAsOpaquePtr())
5067 .template getAsVal<TemplateName>();
Douglas Gregor71dc5092009-08-06 06:41:21 +00005068}
Mike Stump11289f42009-09-09 15:08:12 +00005069
Douglas Gregora16548e2009-08-11 05:31:07 +00005070template<typename Derived>
Mike Stump11289f42009-09-09 15:08:12 +00005071Sema::OwningExprResult
Douglas Gregora16548e2009-08-11 05:31:07 +00005072TreeTransform<Derived>::RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
5073 SourceLocation OpLoc,
5074 ExprArg Callee,
5075 ExprArg First,
5076 ExprArg Second) {
5077 Expr *FirstExpr = (Expr *)First.get();
5078 Expr *SecondExpr = (Expr *)Second.get();
5079 bool isPostIncDec = SecondExpr && (Op == OO_PlusPlus || Op == OO_MinusMinus);
Mike Stump11289f42009-09-09 15:08:12 +00005080
Douglas Gregora16548e2009-08-11 05:31:07 +00005081 // Determine whether this should be a builtin operation.
5082 if (SecondExpr == 0 || isPostIncDec) {
5083 if (!FirstExpr->getType()->isOverloadableType()) {
5084 // The argument is not of overloadable type, so try to create a
5085 // built-in unary operation.
Mike Stump11289f42009-09-09 15:08:12 +00005086 UnaryOperator::Opcode Opc
Douglas Gregora16548e2009-08-11 05:31:07 +00005087 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
Mike Stump11289f42009-09-09 15:08:12 +00005088
Douglas Gregora16548e2009-08-11 05:31:07 +00005089 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, move(First));
5090 }
5091 } else {
Mike Stump11289f42009-09-09 15:08:12 +00005092 if (!FirstExpr->getType()->isOverloadableType() &&
Douglas Gregora16548e2009-08-11 05:31:07 +00005093 !SecondExpr->getType()->isOverloadableType()) {
5094 // Neither of the arguments is an overloadable type, so try to
5095 // create a built-in binary operation.
5096 BinaryOperator::Opcode Opc = BinaryOperator::getOverloadedOpcode(Op);
Mike Stump11289f42009-09-09 15:08:12 +00005097 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00005098 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, FirstExpr, SecondExpr);
5099 if (Result.isInvalid())
5100 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005101
Douglas Gregora16548e2009-08-11 05:31:07 +00005102 First.release();
5103 Second.release();
5104 return move(Result);
5105 }
5106 }
Mike Stump11289f42009-09-09 15:08:12 +00005107
5108 // Compute the transformed set of functions (and function templates) to be
Douglas Gregora16548e2009-08-11 05:31:07 +00005109 // used during overload resolution.
5110 Sema::FunctionSet Functions;
Mike Stump11289f42009-09-09 15:08:12 +00005111
5112 DeclRefExpr *DRE
Douglas Gregor32e2c842009-09-01 16:58:52 +00005113 = cast<DeclRefExpr>(((Expr *)Callee.get())->IgnoreParenCasts());
Mike Stump11289f42009-09-09 15:08:12 +00005114
Douglas Gregora16548e2009-08-11 05:31:07 +00005115 // FIXME: Do we have to check
5116 // IsAcceptableNonMemberOperatorCandidate for each of these?
Douglas Gregor32e2c842009-09-01 16:58:52 +00005117 for (OverloadIterator F(DRE->getDecl()), FEnd; F != FEnd; ++F)
Douglas Gregora16548e2009-08-11 05:31:07 +00005118 Functions.insert(*F);
Mike Stump11289f42009-09-09 15:08:12 +00005119
Douglas Gregora16548e2009-08-11 05:31:07 +00005120 // Add any functions found via argument-dependent lookup.
5121 Expr *Args[2] = { FirstExpr, SecondExpr };
5122 unsigned NumArgs = 1 + (SecondExpr != 0);
Mike Stump11289f42009-09-09 15:08:12 +00005123 DeclarationName OpName
Douglas Gregora16548e2009-08-11 05:31:07 +00005124 = SemaRef.Context.DeclarationNames.getCXXOperatorName(Op);
Sebastian Redlc057f422009-10-23 19:23:15 +00005125 SemaRef.ArgumentDependentLookup(OpName, /*Operator*/true, Args, NumArgs,
5126 Functions);
Mike Stump11289f42009-09-09 15:08:12 +00005127
Douglas Gregora16548e2009-08-11 05:31:07 +00005128 // Create the overloaded operator invocation for unary operators.
5129 if (NumArgs == 1 || isPostIncDec) {
Mike Stump11289f42009-09-09 15:08:12 +00005130 UnaryOperator::Opcode Opc
Douglas Gregora16548e2009-08-11 05:31:07 +00005131 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
5132 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Functions, move(First));
5133 }
Mike Stump11289f42009-09-09 15:08:12 +00005134
Douglas Gregora16548e2009-08-11 05:31:07 +00005135 // Create the overloaded operator invocation for binary operators.
Mike Stump11289f42009-09-09 15:08:12 +00005136 BinaryOperator::Opcode Opc =
Douglas Gregora16548e2009-08-11 05:31:07 +00005137 BinaryOperator::getOverloadedOpcode(Op);
Mike Stump11289f42009-09-09 15:08:12 +00005138 OwningExprResult Result
Douglas Gregora16548e2009-08-11 05:31:07 +00005139 = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Functions, Args[0], Args[1]);
5140 if (Result.isInvalid())
5141 return SemaRef.ExprError();
Mike Stump11289f42009-09-09 15:08:12 +00005142
Douglas Gregora16548e2009-08-11 05:31:07 +00005143 First.release();
5144 Second.release();
Mike Stump11289f42009-09-09 15:08:12 +00005145 return move(Result);
Douglas Gregora16548e2009-08-11 05:31:07 +00005146}
Mike Stump11289f42009-09-09 15:08:12 +00005147
Douglas Gregord6ff3322009-08-04 16:50:30 +00005148} // end namespace clang
5149
5150#endif // LLVM_CLANG_SEMA_TREETRANSFORM_H